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

Last change on this file since 1257 was 1246, checked in by seregin, 9 years ago

port rev 4240

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