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

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

initial porting

  • 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 Q0048_CGS_3D_ASYMLUT
81Void TEncEntropy::encodePPS( TComPPS* pcPPS, TEnc3DAsymLUT * pc3DAsymLUT  )
82{
83  m_pcEntropyCoderIf->codePPS( pcPPS, pc3DAsymLUT );
84  return;
85}
86#else
87Void TEncEntropy::encodePPS( TComPPS* pcPPS )
88{
89  m_pcEntropyCoderIf->codePPS( pcPPS );
90  return;
91}
92#endif
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 )
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    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();
247
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++)
254  {
255    const ComponentID compID = ComponentID(ch);
256
257    cbf[compID] = pcCU->getCbf( uiAbsPartIdx, compID , uiTrIdx );
258   
259    if (cbf[ch] != 0)
260    {
261      bHaveACodedBlock = true;
262      if (isChroma(compID)) bHaveACodedChromaBlock = true;
263    }
264  }
265
266  if( pcCU->isIntra(uiAbsPartIdx) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
267  {
268    assert( uiSubdiv );
269  }
270  else if( pcCU->isInter(uiAbsPartIdx) && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) &&  (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) )
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;
301
302  for(UInt ch=COMPONENT_Cb; ch<numValidComponent; ch++)
303  {
304    const ComponentID compID=ComponentID(ch);
305    if( bFirstCbfOfCU || rTu.ProcessingAllQuadrants(compID) )
306    {
307      if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) )
308      {
309        m_pcEntropyCoderIf->codeQtCbf( rTu, compID, (uiSubdiv == 0) );
310      }
311    }
312    else
313    {
314      assert( pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) );
315    }
316  }
317
318  if( uiSubdiv )
319  {
320    TComTURecurse tuRecurseChild(rTu, true);
321    do
322    {
323      xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurseChild );
324    }
325    while (tuRecurseChild.nextSection(rTu));
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    }
339
340    if( !pcCU->isIntra(uiAbsPartIdx) && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && (!bChroma || (!pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cb, 0 ) && !pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cr, 0 ) ) ) )
341    {
342      assert( pcCU->getCbf( uiAbsPartIdx, COMPONENT_Y, 0 ) );
343      //      printf( "saved one bin! " );
344    }
345    else
346    {
347      m_pcEntropyCoderIf->codeQtCbf( rTu, COMPONENT_Y, true ); //luma CBF is always at the lowest level
348    }
349
350    if ( bHaveACodedBlock )
351    {
352      // dQP: only for CTU once
353      if ( pcCU->getSlice()->getPPS()->getUseDQP() )
354      {
355        if ( bCodeDQP )
356        {
357          encodeQP( pcCU, rTu.GetAbsPartIdxCU() );
358          bCodeDQP = false;
359        }
360      }
361
362      if ( pcCU->getSlice()->getUseChromaQpAdj() )
363      {
364        if ( bHaveACodedChromaBlock && codeChromaQpAdj && !pcCU->getCUTransquantBypass(rTu.GetAbsPartIdxCU()) )
365        {
366          encodeChromaQpAdjustment( pcCU, rTu.GetAbsPartIdxCU() );
367          codeChromaQpAdj = false;
368        }
369      }
370
371      const UInt numValidComp=pcCU->getPic()->getNumberValidComponents();
372
373      for(UInt ch=COMPONENT_Y; ch<numValidComp; ch++)
374      {
375        const ComponentID compID=ComponentID(ch);
376
377        if (rTu.ProcessComponentSection(compID))
378        {
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          }
414        }
415      }
416    }
417  }
418}
419
420
421// Intra direction for Luma
422Void TEncEntropy::encodeIntraDirModeLuma  ( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiplePU )
423{
424  m_pcEntropyCoderIf->codeIntraDirLumaAng( pcCU, absPartIdx , isMultiplePU);
425}
426
427
428// Intra direction for Chroma
429Void TEncEntropy::encodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx )
430{
431  m_pcEntropyCoderIf->codeIntraDirChroma( pcCU, uiAbsPartIdx );
432
433#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
434  if (bDebugPredEnabled && g_bFinalEncode)
435  {
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));
439  }
440#endif
441}
442
443
444Void TEncEntropy::encodePredInfo( TComDataCU* pcCU, UInt uiAbsPartIdx )
445{
446  if( pcCU->isIntra( uiAbsPartIdx ) )                                 // If it is Intra mode, encode intra prediction mode.
447  {
448    encodeIntraDirModeLuma  ( pcCU, uiAbsPartIdx,true );
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    }
461  }
462  else                                                                // if it is Inter mode, encode motion vector and reference index
463  {
464    encodePUWise( pcCU, uiAbsPartIdx );
465  }
466}
467
468Void TEncEntropy::encodeCrossComponentPrediction( TComTU &rTu, ComponentID compID )
469{
470  m_pcEntropyCoderIf->codeCrossComponentPrediction( rTu, compID );
471}
472
473/** encode motion information for every PU block
474 * \param pcCU
475 * \param uiAbsPartIdx
476 * \param bRD
477 * \returns Void
478 */
479Void TEncEntropy::encodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx )
480{
481#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
482  const Bool bDebugPred = bDebugPredEnabled && g_bFinalEncode;
483#endif
484
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 );
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
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 ) );
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
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 );
540
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{
552  assert( pcCU->isInter( uiAbsPartIdx ) );
553
554  if ( ( pcCU->getSlice()->getNumRefIdx( eRefList ) == 1 ) )
555  {
556    return;
557  }
558
559  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
560  {
561    m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, eRefList );
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{
575  assert( pcCU->isInter( uiAbsPartIdx ) );
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
594Void TEncEntropy::encodeQtCbf( TComTU &rTu, const ComponentID compID, const Bool lowestLevel )
595{
596  m_pcEntropyCoderIf->codeQtCbf( rTu, compID, lowestLevel );
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
609Void TEncEntropy::encodeQtCbfZero( TComTU &rTu, const ChannelType chType )
610{
611  m_pcEntropyCoderIf->codeQtCbfZero( rTu, chType );
612}
613
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  }
626
627  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
628  {
629    m_pcEntropyCoderIf->codeDeltaQP( pcCU, uiAbsPartIdx );
630  }
631}
632
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  }
642
643  m_pcEntropyCoderIf->codeChromaQpAdjustment( cu, absPartIdx );
644}
645
646// texture
647
648/** encode coefficients
649 * \param pcCU
650 * \param uiAbsPartIdx
651 * \param uiDepth
652 * \param uiWidth
653 * \param uiHeight
654 */
655Void TEncEntropy::encodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool& bCodeDQP, Bool& codeChromaQpAdj )
656{
657#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
658  const Bool bDebugRQT=g_bFinalEncode && DebugOptionList::DebugRQT.getInt()!=0;
659#endif
660
661  if( pcCU->isIntra(uiAbsPartIdx) )
662  {
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    }
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  }
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 );
689}
690
691Void TEncEntropy::encodeCoeffNxN( TComTU &rTu, TCoeff* pcCoef, const ComponentID compID)
692{
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  }
720}
721
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 );
727}
728
729Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
730{
731  Int count = 0;
732
733  for ( Int i = 0; i < uiSize; i++ )
734  {
735    count += pcCoef[i] != 0;
736  }
737
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
749#if POC_RESET_IDC_SIGNALLING
750Void  TEncEntropy::encodeSliceHeaderExtn( TComSlice* pSlice, Int shBitsWrittenTillNow )
751{
752  m_pcEntropyCoderIf->codeSliceHeaderExtn( pSlice, shBitsWrittenTillNow );
753}
754#endif
755
756//! \}
Note: See TracBrowser for help on using the repository browser.