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

Last change on this file since 1590 was 1549, checked in by seregin, 9 years ago

port rev 4732, update copyright notice to include 2016

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