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

Last change on this file since 1510 was 1335, checked in by seregin, 9 years ago

port rev 4413

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