source: SHVCSoftware/branches/SHM-upgrade/source/Lib/TLibEncoder/TEncEntropy.cpp @ 918

Last change on this file since 918 was 916, checked in by seregin, 10 years ago

initial porting

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