source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibEncoder/TEncEntropy.cpp @ 1265

Last change on this file since 1265 was 1260, checked in by seregin, 9 years ago

port rev 4257

  • Property svn:eol-style set to native
File size: 21.4 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2015, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncEntropy.cpp
35    \brief    entropy encoder class
36*/
37
38#include "TEncEntropy.h"
39#include "TLibCommon/TypeDef.h"
40#include "TLibCommon/TComSampleAdaptiveOffset.h"
41#include "TLibCommon/TComTU.h"
42
43#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
44#include "../TLibCommon/Debug.h"
45static const Bool bDebugPredEnabled = DebugOptionList::DebugPred.getInt()!=0;
46#endif
47
48//! \ingroup TLibEncoder
49//! \{
50
51Void TEncEntropy::setEntropyCoder ( TEncEntropyIf* e, TComSlice* pcSlice )
52{
53  m_pcEntropyCoderIf = e;
54  m_pcEntropyCoderIf->setSlice ( pcSlice );
55}
56
57Void TEncEntropy::encodeSliceHeader ( TComSlice* pcSlice )
58{
59  m_pcEntropyCoderIf->codeSliceHeader( pcSlice );
60  return;
61}
62
63Void  TEncEntropy::encodeTilesWPPEntryPoint( TComSlice* pSlice )
64{
65  m_pcEntropyCoderIf->codeTilesWPPEntryPoint( pSlice );
66}
67
68Void TEncEntropy::encodeTerminatingBit      ( UInt uiIsLast )
69{
70  m_pcEntropyCoderIf->codeTerminatingBit( uiIsLast );
71
72  return;
73}
74
75Void TEncEntropy::encodeSliceFinish()
76{
77  m_pcEntropyCoderIf->codeSliceFinish();
78}
79
80#if CGS_3D_ASYMLUT
81Void TEncEntropy::encodePPS( const TComPPS* pcPPS, TEnc3DAsymLUT * pc3DAsymLUT  )
82{
83  m_pcEntropyCoderIf->codePPS( pcPPS, pc3DAsymLUT );
84  return;
85}
86#else
87Void TEncEntropy::encodePPS( const TComPPS* pcPPS )
88{
89  m_pcEntropyCoderIf->codePPS( pcPPS );
90  return;
91}
92#endif
93
94Void TEncEntropy::encodeSPS( const TComSPS* pcSPS )
95{
96  m_pcEntropyCoderIf->codeSPS( pcSPS );
97  return;
98}
99
100Void TEncEntropy::encodeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
101{
102  if( bRD )
103  {
104    uiAbsPartIdx = 0;
105  }
106  m_pcEntropyCoderIf->codeCUTransquantBypassFlag( pcCU, uiAbsPartIdx );
107}
108
109Void TEncEntropy::encodeVPS( const TComVPS* pcVPS )
110{
111  m_pcEntropyCoderIf->codeVPS( pcVPS );
112  return;
113}
114
115Void TEncEntropy::encodeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
116{
117  if ( pcCU->getSlice()->isIntra() )
118  {
119    return;
120  }
121  if( bRD )
122  {
123    uiAbsPartIdx = 0;
124  }
125  m_pcEntropyCoderIf->codeSkipFlag( pcCU, uiAbsPartIdx );
126}
127
128//! encode merge flag
129Void TEncEntropy::encodeMergeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
130{
131  // at least one merge candidate exists
132  m_pcEntropyCoderIf->codeMergeFlag( pcCU, uiAbsPartIdx );
133}
134
135//! encode merge index
136Void TEncEntropy::encodeMergeIndex( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
137{
138  if( bRD )
139  {
140    uiAbsPartIdx = 0;
141    assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
142  }
143  m_pcEntropyCoderIf->codeMergeIndex( pcCU, uiAbsPartIdx );
144}
145
146
147//! encode prediction mode
148Void TEncEntropy::encodePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
149{
150  if( bRD )
151  {
152    uiAbsPartIdx = 0;
153  }
154
155  if ( pcCU->getSlice()->isIntra() )
156  {
157    return;
158  }
159
160  m_pcEntropyCoderIf->codePredMode( pcCU, uiAbsPartIdx );
161}
162
163//! encode split flag
164Void TEncEntropy::encodeSplitFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
165{
166  if( bRD )
167  {
168    uiAbsPartIdx = 0;
169  }
170
171  m_pcEntropyCoderIf->codeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
172}
173
174//! encode partition size
175Void TEncEntropy::encodePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
176{
177  if( bRD )
178  {
179    uiAbsPartIdx = 0;
180  }
181
182  m_pcEntropyCoderIf->codePartSize( pcCU, uiAbsPartIdx, uiDepth );
183}
184
185
186/** Encode I_PCM information.
187 * \param pcCU          pointer to CU
188 * \param uiAbsPartIdx  CU index
189 * \param bRD           flag indicating estimation or encoding
190 */
191Void TEncEntropy::encodeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
192{
193  if(!pcCU->getSlice()->getSPS()->getUsePCM()
194    || pcCU->getWidth(uiAbsPartIdx) > (1<<pcCU->getSlice()->getSPS()->getPCMLog2MaxSize())
195    || pcCU->getWidth(uiAbsPartIdx) < (1<<pcCU->getSlice()->getSPS()->getPCMLog2MinSize()))
196  {
197    return;
198  }
199
200  if( bRD )
201  {
202    uiAbsPartIdx = 0;
203  }
204
205  m_pcEntropyCoderIf->codeIPCMInfo ( pcCU, uiAbsPartIdx );
206
207}
208
209Void TEncEntropy::xEncodeTransform( Bool& bCodeDQP, Bool& codeChromaQpAdj, TComTU &rTu )
210{
211//pcCU, absPartIdxCU, uiAbsPartIdx, uiDepth+1, uiTrIdx+1, quadrant,
212  TComDataCU *pcCU=rTu.getCU();
213  const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU();
214  const UInt numValidComponent = pcCU->getPic()->getNumberValidComponents();
215  const Bool bChroma = isChromaEnabled(pcCU->getPic()->getChromaFormat());
216  const UInt uiTrIdx = rTu.GetTransformDepthRel();
217  const UInt uiDepth = rTu.GetTransformDepthTotal();
218#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
219  const Bool bDebugRQT=g_bFinalEncode && DebugOptionList::DebugRQT.getInt()!=0;
220  if (bDebugRQT)
221  {
222    printf("x..codeTransform: offsetLuma=%d offsetChroma=%d absPartIdx=%d, uiDepth=%d\n width=%d, height=%d, uiTrIdx=%d, uiInnerQuadIdx=%d\n",
223           rTu.getCoefficientOffset(COMPONENT_Y), rTu.getCoefficientOffset(COMPONENT_Cb), uiAbsPartIdx, uiDepth, rTu.getRect(COMPONENT_Y).width, rTu.getRect(COMPONENT_Y).height, rTu.GetTransformDepthRel(), rTu.GetSectionNumber());
224  }
225#endif
226  const UInt uiSubdiv = pcCU->getTransformIdx( uiAbsPartIdx ) > uiTrIdx;// + pcCU->getDepth( uiAbsPartIdx ) > uiDepth;
227  const UInt uiLog2TrafoSize = rTu.GetLog2LumaTrSize();
228
229
230  UInt cbf[MAX_NUM_COMPONENT] = {0,0,0};
231  Bool bHaveACodedBlock       = false;
232  Bool bHaveACodedChromaBlock = false;
233
234  for(UInt ch=0; ch<numValidComponent; ch++)
235  {
236    const ComponentID compID = ComponentID(ch);
237
238    cbf[compID] = pcCU->getCbf( uiAbsPartIdx, compID , uiTrIdx );
239   
240    if (cbf[ch] != 0)
241    {
242      bHaveACodedBlock = true;
243      if (isChroma(compID))
244      {
245        bHaveACodedChromaBlock = true;
246      }
247    }
248  }
249
250  if( pcCU->isIntra(uiAbsPartIdx) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
251  {
252    assert( uiSubdiv );
253  }
254  else if( pcCU->isInter(uiAbsPartIdx) && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) &&  (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) )
255  {
256    if ( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
257    {
258      assert( uiSubdiv );
259    }
260    else
261    {
262      assert(!uiSubdiv );
263    }
264  }
265  else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
266  {
267    assert( uiSubdiv );
268  }
269  else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
270  {
271    assert( !uiSubdiv );
272  }
273  else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
274  {
275    assert( !uiSubdiv );
276  }
277  else
278  {
279    assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
280    m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSubdiv, 5 - uiLog2TrafoSize );
281  }
282
283  const UInt uiTrDepthCurr = uiDepth - pcCU->getDepth( uiAbsPartIdx );
284  const Bool bFirstCbfOfCU = uiTrDepthCurr == 0;
285
286  for(UInt ch=COMPONENT_Cb; ch<numValidComponent; ch++)
287  {
288    const ComponentID compID=ComponentID(ch);
289    if( bFirstCbfOfCU || rTu.ProcessingAllQuadrants(compID) )
290    {
291      if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) )
292      {
293        m_pcEntropyCoderIf->codeQtCbf( rTu, compID, (uiSubdiv == 0) );
294      }
295    }
296    else
297    {
298      assert( pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) );
299    }
300  }
301
302  if( uiSubdiv )
303  {
304    TComTURecurse tuRecurseChild(rTu, true);
305    do
306    {
307      xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurseChild );
308    } while (tuRecurseChild.nextSection(rTu));
309  }
310  else
311  {
312    {
313      DTRACE_CABAC_VL( g_nSymbolCounter++ );
314      DTRACE_CABAC_T( "\tTrIdx: abspart=" );
315      DTRACE_CABAC_V( uiAbsPartIdx );
316      DTRACE_CABAC_T( "\tdepth=" );
317      DTRACE_CABAC_V( uiDepth );
318      DTRACE_CABAC_T( "\ttrdepth=" );
319      DTRACE_CABAC_V( pcCU->getTransformIdx( uiAbsPartIdx ) );
320      DTRACE_CABAC_T( "\n" );
321    }
322
323    if( !pcCU->isIntra(uiAbsPartIdx) && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && (!bChroma || (!pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cb, 0 ) && !pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cr, 0 ) ) ) )
324    {
325      assert( pcCU->getCbf( uiAbsPartIdx, COMPONENT_Y, 0 ) );
326      //      printf( "saved one bin! " );
327    }
328    else
329    {
330      m_pcEntropyCoderIf->codeQtCbf( rTu, COMPONENT_Y, true ); //luma CBF is always at the lowest level
331    }
332
333    if ( bHaveACodedBlock )
334    {
335      // dQP: only for CTU once
336      if ( pcCU->getSlice()->getPPS()->getUseDQP() )
337      {
338        if ( bCodeDQP )
339        {
340          encodeQP( pcCU, rTu.GetAbsPartIdxCU() );
341          bCodeDQP = false;
342        }
343      }
344
345      if ( pcCU->getSlice()->getUseChromaQpAdj() )
346      {
347        if ( bHaveACodedChromaBlock && codeChromaQpAdj && !pcCU->getCUTransquantBypass(rTu.GetAbsPartIdxCU()) )
348        {
349          encodeChromaQpAdjustment( pcCU, rTu.GetAbsPartIdxCU() );
350          codeChromaQpAdj = false;
351        }
352      }
353
354      const UInt numValidComp=pcCU->getPic()->getNumberValidComponents();
355
356      for(UInt ch=COMPONENT_Y; ch<numValidComp; ch++)
357      {
358        const ComponentID compID=ComponentID(ch);
359
360        if (rTu.ProcessComponentSection(compID))
361        {
362#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
363          if (bDebugRQT)
364          {
365            printf("Call NxN for chan %d width=%d height=%d cbf=%d\n", compID, rTu.getRect(compID).width, rTu.getRect(compID).height, 1);
366          }
367#endif
368
369          if (rTu.getRect(compID).width != rTu.getRect(compID).height)
370          {
371            //code two sub-TUs
372            TComTURecurse subTUIterator(rTu, false, TComTU::VERTICAL_SPLIT, true, compID);
373
374            do
375            {
376              const UChar subTUCBF = pcCU->getCbf(subTUIterator.GetAbsPartIdxTU(compID), compID, (uiTrIdx + 1));
377
378              if (subTUCBF != 0)
379              {
380#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
381                if (bDebugRQT)
382                {
383                  printf("Call NxN for chan %d width=%d height=%d cbf=%d\n", compID, subTUIterator.getRect(compID).width, subTUIterator.getRect(compID).height, 1);
384                }
385#endif
386                m_pcEntropyCoderIf->codeCoeffNxN( subTUIterator, (pcCU->getCoeff(compID) + subTUIterator.getCoefficientOffset(compID)), compID );
387              }
388            }
389            while (subTUIterator.nextSection(rTu));
390          }
391          else
392          {
393            if (isChroma(compID) && (cbf[COMPONENT_Y] != 0))
394            {
395              m_pcEntropyCoderIf->codeCrossComponentPrediction( rTu, compID );
396            }
397
398            if (cbf[compID] != 0)
399            {
400              m_pcEntropyCoderIf->codeCoeffNxN( rTu, (pcCU->getCoeff(compID) + rTu.getCoefficientOffset(compID)), compID );
401            }
402          }
403        }
404      }
405    }
406  }
407}
408
409
410//! encode intra direction for luma
411Void TEncEntropy::encodeIntraDirModeLuma  ( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiplePU )
412{
413  m_pcEntropyCoderIf->codeIntraDirLumaAng( pcCU, absPartIdx , isMultiplePU);
414}
415
416
417//! encode intra direction for chroma
418Void TEncEntropy::encodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx )
419{
420  m_pcEntropyCoderIf->codeIntraDirChroma( pcCU, uiAbsPartIdx );
421
422#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
423  if (bDebugPredEnabled && g_bFinalEncode)
424  {
425    UInt cdir=pcCU->getIntraDir(CHANNEL_TYPE_CHROMA, uiAbsPartIdx);
426    if (cdir==36)
427    {
428      cdir=pcCU->getIntraDir(CHANNEL_TYPE_LUMA, uiAbsPartIdx);
429    }
430    printf("coding chroma Intra dir: %d, uiAbsPartIdx: %d, luma dir: %d\n", cdir, uiAbsPartIdx, pcCU->getIntraDir(CHANNEL_TYPE_LUMA, uiAbsPartIdx));
431  }
432#endif
433}
434
435
436Void TEncEntropy::encodePredInfo( TComDataCU* pcCU, UInt uiAbsPartIdx )
437{
438  if( pcCU->isIntra( uiAbsPartIdx ) )                                 // If it is Intra mode, encode intra prediction mode.
439  {
440    encodeIntraDirModeLuma  ( pcCU, uiAbsPartIdx,true );
441    if (pcCU->getPic()->getChromaFormat()!=CHROMA_400)
442    {
443      encodeIntraDirModeChroma( pcCU, uiAbsPartIdx );
444
445      if (enable4ChromaPUsInIntraNxNCU(pcCU->getPic()->getChromaFormat()) && pcCU->getPartitionSize( uiAbsPartIdx )==SIZE_NxN)
446      {
447        UInt uiPartOffset = ( pcCU->getPic()->getNumPartitionsInCtu() >> ( pcCU->getDepth(uiAbsPartIdx) << 1 ) ) >> 2;
448        encodeIntraDirModeChroma( pcCU, uiAbsPartIdx + uiPartOffset   );
449        encodeIntraDirModeChroma( pcCU, uiAbsPartIdx + uiPartOffset*2 );
450        encodeIntraDirModeChroma( pcCU, uiAbsPartIdx + uiPartOffset*3 );
451      }
452    }
453  }
454  else                                                                // if it is Inter mode, encode motion vector and reference index
455  {
456    encodePUWise( pcCU, uiAbsPartIdx );
457  }
458}
459
460Void TEncEntropy::encodeCrossComponentPrediction( TComTU &rTu, ComponentID compID )
461{
462  m_pcEntropyCoderIf->codeCrossComponentPrediction( rTu, compID );
463}
464
465//! encode motion information for every PU block
466Void TEncEntropy::encodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx )
467{
468#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
469  const Bool bDebugPred = bDebugPredEnabled && g_bFinalEncode;
470#endif
471
472  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
473  UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) );
474  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
475  UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() - uiDepth ) << 1 ) ) >> 4;
476
477  for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset )
478  {
479    encodeMergeFlag( pcCU, uiSubPartIdx );
480    if ( pcCU->getMergeFlag( uiSubPartIdx ) )
481    {
482      encodeMergeIndex( pcCU, uiSubPartIdx );
483#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
484      if (bDebugPred)
485      {
486        std::cout << "Coded merge flag, CU absPartIdx: " << uiAbsPartIdx << " PU(" << uiPartIdx << ") absPartIdx: " << uiSubPartIdx;
487        std::cout << " merge index: " << (UInt)pcCU->getMergeIndex(uiSubPartIdx) << std::endl;
488      }
489#endif
490    }
491    else
492    {
493      encodeInterDirPU( pcCU, uiSubPartIdx );
494      for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
495      {
496        if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
497        {
498          encodeRefFrmIdxPU ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
499          encodeMvdPU       ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
500          encodeMVPIdxPU    ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
501#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
502          if (bDebugPred)
503          {
504            std::cout << "refListIdx: " << uiRefListIdx << std::endl;
505            std::cout << "MVD horizontal: " << pcCU->getCUMvField(RefPicList(uiRefListIdx))->getMvd( uiAbsPartIdx ).getHor() << std::endl;
506            std::cout << "MVD vertical:   " << pcCU->getCUMvField(RefPicList(uiRefListIdx))->getMvd( uiAbsPartIdx ).getVer() << std::endl;
507            std::cout << "MVPIdxPU: " << pcCU->getMVPIdx(RefPicList( uiRefListIdx ), uiSubPartIdx) << std::endl;
508            std::cout << "InterDir: " << (UInt)pcCU->getInterDir(uiSubPartIdx) << std::endl;
509          }
510#endif
511        }
512      }
513    }
514  }
515
516  return;
517}
518
519Void TEncEntropy::encodeInterDirPU( TComDataCU* pcCU, UInt uiAbsPartIdx )
520{
521  if ( !pcCU->getSlice()->isInterB() )
522  {
523    return;
524  }
525
526  m_pcEntropyCoderIf->codeInterDir( pcCU, uiAbsPartIdx );
527
528  return;
529}
530
531//! encode reference frame index for a PU block
532Void TEncEntropy::encodeRefFrmIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
533{
534  assert( pcCU->isInter( uiAbsPartIdx ) );
535
536  if ( ( pcCU->getSlice()->getNumRefIdx( eRefList ) == 1 ) )
537  {
538    return;
539  }
540
541  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
542  {
543    m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, eRefList );
544  }
545
546  return;
547}
548
549//! encode motion vector difference for a PU block
550Void TEncEntropy::encodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
551{
552  assert( pcCU->isInter( uiAbsPartIdx ) );
553
554  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
555  {
556    m_pcEntropyCoderIf->codeMvd( pcCU, uiAbsPartIdx, eRefList );
557  }
558  return;
559}
560
561Void TEncEntropy::encodeMVPIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
562{
563  if ( (pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList )) )
564  {
565    m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList );
566  }
567
568  return;
569}
570
571Void TEncEntropy::encodeQtCbf( TComTU &rTu, const ComponentID compID, const Bool lowestLevel )
572{
573  m_pcEntropyCoderIf->codeQtCbf( rTu, compID, lowestLevel );
574}
575
576Void TEncEntropy::encodeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx )
577{
578  m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSymbol, uiCtx );
579}
580
581Void TEncEntropy::encodeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx )
582{
583  m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
584}
585
586Void TEncEntropy::encodeQtCbfZero( TComTU &rTu, const ChannelType chType )
587{
588  m_pcEntropyCoderIf->codeQtCbfZero( rTu, chType );
589}
590
591Void TEncEntropy::encodeQtRootCbfZero( TComDataCU* pcCU )
592{
593  m_pcEntropyCoderIf->codeQtRootCbfZero( pcCU );
594}
595
596// dQP
597Void TEncEntropy::encodeQP( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
598{
599  if( bRD )
600  {
601    uiAbsPartIdx = 0;
602  }
603
604  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
605  {
606    m_pcEntropyCoderIf->codeDeltaQP( pcCU, uiAbsPartIdx );
607  }
608}
609
610//! encode chroma qp adjustment
611Void TEncEntropy::encodeChromaQpAdjustment( TComDataCU* cu, UInt absPartIdx, Bool inRd )
612{
613  if( inRd )
614  {
615    absPartIdx = 0;
616  }
617
618  m_pcEntropyCoderIf->codeChromaQpAdjustment( cu, absPartIdx );
619}
620
621// texture
622
623//! encode coefficients
624Void TEncEntropy::encodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool& bCodeDQP, Bool& codeChromaQpAdj )
625{
626#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
627  const Bool bDebugRQT=g_bFinalEncode && DebugOptionList::DebugRQT.getInt()!=0;
628#endif
629
630  if( pcCU->isIntra(uiAbsPartIdx) )
631  {
632    if (false)
633    {
634      DTRACE_CABAC_VL( g_nSymbolCounter++ )
635      DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" )
636      DTRACE_CABAC_V( uiDepth )
637      DTRACE_CABAC_T( "\n" )
638    }
639  }
640  else
641  {
642    if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ) )
643    {
644      m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
645    }
646    if ( !pcCU->getQtRootCbf( uiAbsPartIdx ) )
647    {
648      return;
649    }
650  }
651
652  TComTURecurse tuRecurse(pcCU, uiAbsPartIdx, uiDepth);
653#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
654  if (bDebugRQT)
655  {
656    printf("..codeCoeff: uiAbsPartIdx=%d, PU format=%d, 2Nx2N=%d, NxN=%d\n", uiAbsPartIdx, pcCU->getPartitionSize(uiAbsPartIdx), SIZE_2Nx2N, SIZE_NxN);
657  }
658#endif
659
660  xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurse );
661}
662
663Void TEncEntropy::encodeCoeffNxN( TComTU &rTu, TCoeff* pcCoef, const ComponentID compID)
664{
665  TComDataCU *pcCU = rTu.getCU();
666
667  if (pcCU->getCbf(rTu.GetAbsPartIdxTU(), compID, rTu.GetTransformDepthRel()) != 0)
668  {
669    if (rTu.getRect(compID).width != rTu.getRect(compID).height)
670    {
671      //code two sub-TUs
672      TComTURecurse subTUIterator(rTu, false, TComTU::VERTICAL_SPLIT, true, compID);
673
674      const UInt subTUSize = subTUIterator.getRect(compID).width * subTUIterator.getRect(compID).height;
675
676      do
677      {
678        const UChar subTUCBF = pcCU->getCbf(subTUIterator.GetAbsPartIdxTU(compID), compID, (subTUIterator.GetTransformDepthRel() + 1));
679
680        if (subTUCBF != 0)
681        {
682          m_pcEntropyCoderIf->codeCoeffNxN( subTUIterator, (pcCoef + (subTUIterator.GetSectionNumber() * subTUSize)), compID);
683        }
684      }
685      while (subTUIterator.nextSection(rTu));
686    }
687    else
688    {
689      m_pcEntropyCoderIf->codeCoeffNxN(rTu, pcCoef, compID);
690    }
691  }
692}
693
694Void TEncEntropy::estimateBit (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, const ChannelType chType)
695{
696  const UInt heightAtEntropyCoding = (width != height) ? (height >> 1) : height;
697
698  m_pcEntropyCoderIf->estBit ( pcEstBitsSbac, width, heightAtEntropyCoding, chType );
699}
700
701Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
702{
703  Int count = 0;
704
705  for ( Int i = 0; i < uiSize; i++ )
706  {
707    count += pcCoef[i] != 0;
708  }
709
710  return count;
711}
712
713#if SVC_EXTENSION
714Void TEncEntropy::encodeSliceHeaderExtn( TComSlice* pSlice, Int shBitsWrittenTillNow )
715{
716  m_pcEntropyCoderIf->codeSliceHeaderExtn( pSlice, shBitsWrittenTillNow );
717}
718#endif
719
720//! \}
Note: See TracBrowser for help on using the repository browser.