source: 3DVCSoftware/branches/HTM-15.1-MV-draft-4/source/Lib/TLibEncoder/TEncEntropy.cpp @ 1325

Last change on this file since 1325 was 1325, checked in by tech, 10 years ago

Removed 3D-HEVC.

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