source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncEntropy.cpp

Last change on this file was 1413, checked in by tech, 6 years ago

Merged HTM-16.2-dev@1412

  • Property svn:eol-style set to native
File size: 25.9 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-2017, 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
79Void TEncEntropy::encodePPS( const TComPPS* pcPPS )
80{
81  m_pcEntropyCoderIf->codePPS( pcPPS );
82  return;
83}
84
85Void TEncEntropy::encodeSPS( const TComSPS* pcSPS )
86{
87  m_pcEntropyCoderIf->codeSPS( pcSPS );
88  return;
89}
90
91Void TEncEntropy::encodeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
92{
93  if( bRD )
94  {
95    uiAbsPartIdx = 0;
96  }
97  m_pcEntropyCoderIf->codeCUTransquantBypassFlag( pcCU, uiAbsPartIdx );
98}
99
100Void TEncEntropy::encodeVPS( const TComVPS* pcVPS )
101{
102  m_pcEntropyCoderIf->codeVPS( pcVPS );
103  return;
104}
105
106Void TEncEntropy::encodeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
107{
108  if ( pcCU->getSlice()->isIntra() )
109  {
110    return;
111  }
112  if( bRD )
113  {
114    uiAbsPartIdx = 0;
115  }
116  m_pcEntropyCoderIf->codeSkipFlag( pcCU, uiAbsPartIdx );
117}
118#if NH_3D
119Void TEncEntropy::encodeDIS( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
120{
121  if( !pcCU->getSlice()->getDepthIntraSkipFlag() )
122  {
123    return;
124  }
125  if( bRD )
126  {
127    uiAbsPartIdx = 0;
128  }
129  m_pcEntropyCoderIf->codeDIS( pcCU, uiAbsPartIdx );
130}
131#endif
132//! encode merge flag
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
140Void TEncEntropy::encodeMergeIndex( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
141{
142  if( bRD )
143  {
144    uiAbsPartIdx = 0;
145    assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
146  }
147  m_pcEntropyCoderIf->codeMergeIndex( pcCU, uiAbsPartIdx );
148}
149
150#if NH_3D
151Void TEncEntropy::encodeICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
152{
153  if ( pcCU->isIntra( uiAbsPartIdx ) || ( pcCU->getSlice()->getViewIndex() == 0 ) || pcCU->getSlice()->getIsDepth() || pcCU->getARPW( uiAbsPartIdx ) > 0 )
154  {
155    return;
156  }
157
158  if( !pcCU->getSlice()->getApplyIC() )
159  {
160    return;
161  }
162
163  if( bRD )
164  {
165    uiAbsPartIdx = 0;
166  }
167  else
168  {
169    Int ICEnableCandidate = pcCU->getSlice()->getICEnableCandidate(pcCU->getSlice()->getDepth());
170    Int ICEnableNum = pcCU->getSlice()->getICEnableNum(pcCU->getSlice()->getDepth());
171    ICEnableCandidate++;
172    if(pcCU->getICFlag(uiAbsPartIdx))
173    {
174      ICEnableNum++;
175    }
176    pcCU->getSlice()->setICEnableCandidate(pcCU->getSlice()->getDepth(), ICEnableCandidate);
177    pcCU->getSlice()->setICEnableNum(pcCU->getSlice()->getDepth(), ICEnableNum);
178  }
179  if( pcCU->isICFlagRequired( uiAbsPartIdx ) )
180  {
181    m_pcEntropyCoderIf->codeICFlag( pcCU, uiAbsPartIdx );
182  }
183}
184
185Void TEncEntropy::encodeARPW( TComDataCU* pcCU, UInt uiAbsPartIdx )
186{
187  if( !pcCU->getSlice()->getARPStepNum() || pcCU->isIntra( uiAbsPartIdx ) ) 
188  {
189    return;
190  }
191
192  if ( pcCU->getPartitionSize(uiAbsPartIdx)!=SIZE_2Nx2N )
193  {
194    assert(pcCU->getARPW (uiAbsPartIdx) == 0);
195  }
196  else
197  {
198    m_pcEntropyCoderIf->codeARPW( pcCU, uiAbsPartIdx );
199  }
200}
201#endif
202
203
204//! encode prediction mode
205Void TEncEntropy::encodePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
206{
207  if( bRD )
208  {
209    uiAbsPartIdx = 0;
210  }
211
212  if ( pcCU->getSlice()->isIntra() )
213  {
214    return;
215  }
216
217  m_pcEntropyCoderIf->codePredMode( pcCU, uiAbsPartIdx );
218}
219
220//! encode split flag
221Void TEncEntropy::encodeSplitFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
222{
223  if( bRD )
224  {
225    uiAbsPartIdx = 0;
226  }
227
228  m_pcEntropyCoderIf->codeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
229}
230
231//! encode partition size
232Void TEncEntropy::encodePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
233{
234  if( bRD )
235  {
236    uiAbsPartIdx = 0;
237  }
238
239  m_pcEntropyCoderIf->codePartSize( pcCU, uiAbsPartIdx, uiDepth );
240}
241
242
243/** Encode I_PCM information.
244 * \param pcCU          pointer to CU
245 * \param uiAbsPartIdx  CU index
246 * \param bRD           flag indicating estimation or encoding
247 */
248Void TEncEntropy::encodeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
249{
250  if(!pcCU->getSlice()->getSPS()->getUsePCM()
251    || pcCU->getWidth(uiAbsPartIdx) > (1<<pcCU->getSlice()->getSPS()->getPCMLog2MaxSize())
252    || pcCU->getWidth(uiAbsPartIdx) < (1<<pcCU->getSlice()->getSPS()->getPCMLog2MinSize()))
253  {
254    return;
255  }
256
257  if( bRD )
258  {
259    uiAbsPartIdx = 0;
260  }
261
262  m_pcEntropyCoderIf->codeIPCMInfo ( pcCU, uiAbsPartIdx );
263
264}
265
266Void TEncEntropy::xEncodeTransform( Bool& bCodeDQP, Bool& codeChromaQpAdj, TComTU &rTu )
267{
268
269//pcCU, absPartIdxCU, uiAbsPartIdx, uiDepth+1, uiTrIdx+1, quadrant,
270  TComDataCU *pcCU=rTu.getCU();
271  const UInt uiAbsPartIdx=rTu.GetAbsPartIdxTU();
272
273  const UInt numValidComponent = pcCU->getPic()->getNumberValidComponents();
274  const Bool bChroma = isChromaEnabled(pcCU->getPic()->getChromaFormat());
275  const UInt uiTrIdx = rTu.GetTransformDepthRel();
276  const UInt uiDepth = rTu.GetTransformDepthTotal();
277#if NH_MV_ENC_DEC_TRAC
278#if ENC_DEC_TRACE
279  UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
280  UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
281
282  DTRACE_TU_S("=========== transform_tree ===========\n")
283    DTRACE_TU("x0", uiLPelX)
284    DTRACE_TU("x1", uiTPelY)
285    DTRACE_TU("log2TrafoSize", pcCU->getSlice()->getSPS()->getMaxCUWidth()  >> uiDepth )
286    DTRACE_TU("trafoDepth"  , uiDepth)
287#endif
288#endif
289
290#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
291  const Bool bDebugRQT=pcCU->getSlice()->getFinalized() && DebugOptionList::DebugRQT.getInt()!=0;
292  if (bDebugRQT)
293  {
294    printf("x..codeTransform: offsetLuma=%d offsetChroma=%d absPartIdx=%d, uiDepth=%d\n width=%d, height=%d, uiTrIdx=%d, uiInnerQuadIdx=%d\n",
295           rTu.getCoefficientOffset(COMPONENT_Y), rTu.getCoefficientOffset(COMPONENT_Cb), uiAbsPartIdx, uiDepth, rTu.getRect(COMPONENT_Y).width, rTu.getRect(COMPONENT_Y).height, rTu.GetTransformDepthRel(), rTu.GetSectionNumber());
296  }
297#endif
298  const UInt uiSubdiv = pcCU->getTransformIdx( uiAbsPartIdx ) > uiTrIdx;// + pcCU->getDepth( uiAbsPartIdx ) > uiDepth;
299  const UInt uiLog2TrafoSize = rTu.GetLog2LumaTrSize();
300
301
302  UInt cbf[MAX_NUM_COMPONENT] = {0,0,0};
303  Bool bHaveACodedBlock       = false;
304  Bool bHaveACodedChromaBlock = false;
305
306  for(UInt ch=0; ch<numValidComponent; ch++)
307  {
308    const ComponentID compID = ComponentID(ch);
309
310    cbf[compID] = pcCU->getCbf( uiAbsPartIdx, compID , uiTrIdx );
311   
312    if (cbf[ch] != 0)
313    {
314      bHaveACodedBlock = true;
315      if (isChroma(compID))
316      {
317        bHaveACodedChromaBlock = true;
318      }
319    }
320  }
321
322  if( pcCU->isIntra(uiAbsPartIdx) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
323  {
324    assert( uiSubdiv );
325  }
326  else if( pcCU->isInter(uiAbsPartIdx) && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) &&  (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) )
327  {
328    if ( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
329    {
330      assert( uiSubdiv );
331    }
332    else
333    {
334      assert(!uiSubdiv );
335    }
336  }
337  else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
338  {
339    assert( uiSubdiv );
340  }
341  else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
342  {
343    assert( !uiSubdiv );
344  }
345  else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
346  {
347    assert( !uiSubdiv );
348  }
349  else
350  {
351    assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
352    m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSubdiv, 5 - uiLog2TrafoSize );
353  }
354
355  const UInt uiTrDepthCurr = uiDepth - pcCU->getDepth( uiAbsPartIdx );
356  const Bool bFirstCbfOfCU = uiTrDepthCurr == 0;
357
358  for(UInt ch=COMPONENT_Cb; ch<numValidComponent; ch++)
359  {
360    const ComponentID compID=ComponentID(ch);
361    if( bFirstCbfOfCU || rTu.ProcessingAllQuadrants(compID) )
362    {
363      if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) )
364      {
365        m_pcEntropyCoderIf->codeQtCbf( rTu, compID, (uiSubdiv == 0) );
366      }
367    }
368    else
369    {
370      assert( pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) );
371    }
372  }
373
374  if( uiSubdiv )
375  {
376    TComTURecurse tuRecurseChild(rTu, true);
377    do
378    {
379      xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurseChild );
380    } while (tuRecurseChild.nextSection(rTu));
381  }
382  else
383  {
384#if !NH_MV_ENC_DEC_TRAC
385    {
386      DTRACE_CABAC_VL( g_nSymbolCounter++ );
387      DTRACE_CABAC_T( "\tTrIdx: abspart=" );
388      DTRACE_CABAC_V( uiAbsPartIdx );
389      DTRACE_CABAC_T( "\tdepth=" );
390      DTRACE_CABAC_V( uiDepth );
391      DTRACE_CABAC_T( "\ttrdepth=" );
392      DTRACE_CABAC_V( pcCU->getTransformIdx( uiAbsPartIdx ) );
393      DTRACE_CABAC_T( "\n" );
394    }
395#endif
396    if( !pcCU->isIntra(uiAbsPartIdx) && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && (!bChroma || (!pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cb, 0 ) && !pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cr, 0 ) ) ) )
397    {
398      assert( pcCU->getCbf( uiAbsPartIdx, COMPONENT_Y, 0 ) );
399      //      printf( "saved one bin! " );
400    }
401    else
402    {
403      m_pcEntropyCoderIf->codeQtCbf( rTu, COMPONENT_Y, true ); //luma CBF is always at the lowest level
404    }
405
406    if ( bHaveACodedBlock )
407    {
408      // dQP: only for CTU once
409      if ( pcCU->getSlice()->getPPS()->getUseDQP() )
410      {
411        if ( bCodeDQP )
412        {
413          encodeQP( pcCU, rTu.GetAbsPartIdxCU() );
414          bCodeDQP = false;
415        }
416      }
417
418      if ( pcCU->getSlice()->getUseChromaQpAdj() )
419      {
420        if ( bHaveACodedChromaBlock && codeChromaQpAdj && !pcCU->getCUTransquantBypass(rTu.GetAbsPartIdxCU()) )
421        {
422          encodeChromaQpAdjustment( pcCU, rTu.GetAbsPartIdxCU() );
423          codeChromaQpAdj = false;
424        }
425      }
426
427      const UInt numValidComp=pcCU->getPic()->getNumberValidComponents();
428
429      for(UInt ch=COMPONENT_Y; ch<numValidComp; ch++)
430      {
431        const ComponentID compID=ComponentID(ch);
432
433        if (rTu.ProcessComponentSection(compID))
434        {
435#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
436          if (bDebugRQT)
437          {
438            printf("Call NxN for chan %d width=%d height=%d cbf=%d\n", compID, rTu.getRect(compID).width, rTu.getRect(compID).height, 1);
439          }
440#endif
441
442          if (rTu.getRect(compID).width != rTu.getRect(compID).height)
443          {
444            //code two sub-TUs
445            TComTURecurse subTUIterator(rTu, false, TComTU::VERTICAL_SPLIT, true, compID);
446
447            do
448            {
449              const UChar subTUCBF = pcCU->getCbf(subTUIterator.GetAbsPartIdxTU(compID), compID, (uiTrIdx + 1));
450
451              if (subTUCBF != 0)
452              {
453#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
454                if (bDebugRQT)
455                {
456                  printf("Call NxN for chan %d width=%d height=%d cbf=%d\n", compID, subTUIterator.getRect(compID).width, subTUIterator.getRect(compID).height, 1);
457                }
458#endif
459                m_pcEntropyCoderIf->codeCoeffNxN( subTUIterator, (pcCU->getCoeff(compID) + subTUIterator.getCoefficientOffset(compID)), compID );
460              }
461            }
462            while (subTUIterator.nextSection(rTu));
463          }
464          else
465          {
466            if (isChroma(compID) && (cbf[COMPONENT_Y] != 0))
467            {
468              m_pcEntropyCoderIf->codeCrossComponentPrediction( rTu, compID );
469            }
470
471            if (cbf[compID] != 0)
472            {
473              m_pcEntropyCoderIf->codeCoeffNxN( rTu, (pcCU->getCoeff(compID) + rTu.getCoefficientOffset(compID)), compID );
474            }
475          }
476        }
477      }
478    }
479  }
480}
481
482
483//! encode intra direction for luma
484Void TEncEntropy::encodeIntraDirModeLuma  ( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiplePU )
485{
486  m_pcEntropyCoderIf->codeIntraDirLumaAng( pcCU, absPartIdx , isMultiplePU);
487}
488
489
490//! encode intra direction for chroma
491Void TEncEntropy::encodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx )
492{
493  m_pcEntropyCoderIf->codeIntraDirChroma( pcCU, uiAbsPartIdx );
494
495#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
496  if (bDebugPredEnabled && pcCU->getSlice()->getFinalized())
497  {
498    UInt cdir=pcCU->getIntraDir(CHANNEL_TYPE_CHROMA, uiAbsPartIdx);
499    if (cdir==36)
500    {
501      cdir=pcCU->getIntraDir(CHANNEL_TYPE_LUMA, uiAbsPartIdx);
502    }
503    printf("coding chroma Intra dir: %d, uiAbsPartIdx: %d, luma dir: %d\n", cdir, uiAbsPartIdx, pcCU->getIntraDir(CHANNEL_TYPE_LUMA, uiAbsPartIdx));
504  }
505#endif
506}
507
508
509Void TEncEntropy::encodePredInfo( TComDataCU* pcCU, UInt uiAbsPartIdx )
510{
511  if( pcCU->isIntra( uiAbsPartIdx ) )                                 // If it is Intra mode, encode intra prediction mode.
512  {
513    encodeIntraDirModeLuma  ( pcCU, uiAbsPartIdx,true );
514   
515    if (pcCU->getPic()->getChromaFormat()!=CHROMA_400)
516    {
517      encodeIntraDirModeChroma( pcCU, uiAbsPartIdx );
518
519      if (enable4ChromaPUsInIntraNxNCU(pcCU->getPic()->getChromaFormat()) && pcCU->getPartitionSize( uiAbsPartIdx )==SIZE_NxN)
520      {
521        UInt uiPartOffset = ( pcCU->getPic()->getNumPartitionsInCtu() >> ( pcCU->getDepth(uiAbsPartIdx) << 1 ) ) >> 2;
522        encodeIntraDirModeChroma( pcCU, uiAbsPartIdx + uiPartOffset   );
523        encodeIntraDirModeChroma( pcCU, uiAbsPartIdx + uiPartOffset*2 );
524        encodeIntraDirModeChroma( pcCU, uiAbsPartIdx + uiPartOffset*3 );
525      }
526    }
527  }
528  else                                                                // if it is Inter mode, encode motion vector and reference index
529  {
530    encodePUWise( pcCU, uiAbsPartIdx );
531  }
532}
533
534Void TEncEntropy::encodeCrossComponentPrediction( TComTU &rTu, ComponentID compID )
535{
536  m_pcEntropyCoderIf->codeCrossComponentPrediction( rTu, compID );
537}
538
539//! encode motion information for every PU block
540Void TEncEntropy::encodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx )
541{
542#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
543  const Bool bDebugPred = bDebugPredEnabled && pcCU->getSlice()->getFinalized();
544#endif
545
546  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
547  UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) );
548  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
549  UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxTotalCUDepth() - uiDepth ) << 1 ) ) >> 4;
550
551  for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset )
552  {
553#if NH_MV_ENC_DEC_TRAC
554    DTRACE_PU_S("=========== prediction_unit ===========\n")
555       //Todo:
556      //DTRACE_PU("x0", uiLPelX)
557      //DTRACE_PU("x1", uiTPelY)
558#endif
559    encodeMergeFlag( pcCU, uiSubPartIdx );
560    if ( pcCU->getMergeFlag( uiSubPartIdx ) )
561    {
562      encodeMergeIndex( pcCU, uiSubPartIdx );
563#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
564      if (bDebugPred)
565      {
566        std::cout << "Coded merge flag, CU absPartIdx: " << uiAbsPartIdx << " PU(" << uiPartIdx << ") absPartIdx: " << uiSubPartIdx;
567        std::cout << " merge index: " << (UInt)pcCU->getMergeIndex(uiSubPartIdx) << std::endl;
568      }
569#endif
570    }
571    else
572    {
573      encodeInterDirPU( pcCU, uiSubPartIdx );
574      for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
575      {
576        if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
577        {
578          encodeRefFrmIdxPU ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
579          encodeMvdPU       ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
580          encodeMVPIdxPU    ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
581#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
582          if (bDebugPred)
583          {
584            std::cout << "refListIdx: " << uiRefListIdx << std::endl;
585            std::cout << "MVD horizontal: " << pcCU->getCUMvField(RefPicList(uiRefListIdx))->getMvd( uiAbsPartIdx ).getHor() << std::endl;
586            std::cout << "MVD vertical:   " << pcCU->getCUMvField(RefPicList(uiRefListIdx))->getMvd( uiAbsPartIdx ).getVer() << std::endl;
587            std::cout << "MVPIdxPU: " << pcCU->getMVPIdx(RefPicList( uiRefListIdx ), uiSubPartIdx) << std::endl;
588            std::cout << "InterDir: " << (UInt)pcCU->getInterDir(uiSubPartIdx) << std::endl;
589          }
590#endif
591        }
592      }
593    }
594  }
595
596  return;
597}
598
599Void TEncEntropy::encodeInterDirPU( TComDataCU* pcCU, UInt uiAbsPartIdx )
600{
601  if ( !pcCU->getSlice()->isInterB() )
602  {
603    return;
604  }
605
606  m_pcEntropyCoderIf->codeInterDir( pcCU, uiAbsPartIdx );
607
608  return;
609}
610
611//! encode reference frame index for a PU block
612Void TEncEntropy::encodeRefFrmIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
613{
614  assert( pcCU->isInter( uiAbsPartIdx ) );
615
616  if ( ( pcCU->getSlice()->getNumRefIdx( eRefList ) == 1 ) )
617  {
618    return;
619  }
620
621  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
622  {
623    m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, eRefList );
624  }
625
626  return;
627}
628
629//! encode motion vector difference for a PU block
630Void TEncEntropy::encodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
631{
632  assert( pcCU->isInter( uiAbsPartIdx ) );
633
634  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
635  {
636    m_pcEntropyCoderIf->codeMvd( pcCU, uiAbsPartIdx, eRefList );
637  }
638  return;
639}
640
641Void TEncEntropy::encodeMVPIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
642{
643  if ( (pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList )) )
644  {
645    m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList );
646  }
647
648  return;
649}
650
651Void TEncEntropy::encodeQtCbf( TComTU &rTu, const ComponentID compID, const Bool lowestLevel )
652{
653  m_pcEntropyCoderIf->codeQtCbf( rTu, compID, lowestLevel );
654}
655
656Void TEncEntropy::encodeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx )
657{
658  m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSymbol, uiCtx );
659}
660
661Void TEncEntropy::encodeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx )
662{
663  m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
664}
665
666Void TEncEntropy::encodeQtCbfZero( TComTU &rTu, const ChannelType chType )
667{
668  m_pcEntropyCoderIf->codeQtCbfZero( rTu, chType );
669}
670
671Void TEncEntropy::encodeQtRootCbfZero( )
672{
673  m_pcEntropyCoderIf->codeQtRootCbfZero( );
674}
675
676// dQP
677Void TEncEntropy::encodeQP( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
678{
679  if( bRD )
680  {
681    uiAbsPartIdx = 0;
682  }
683
684  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
685  {
686    m_pcEntropyCoderIf->codeDeltaQP( pcCU, uiAbsPartIdx );
687  }
688}
689
690//! encode chroma qp adjustment
691Void TEncEntropy::encodeChromaQpAdjustment( TComDataCU* cu, UInt absPartIdx, Bool inRd )
692{
693  if( inRd )
694  {
695    absPartIdx = 0;
696  }
697
698  m_pcEntropyCoderIf->codeChromaQpAdjustment( cu, absPartIdx );
699}
700
701// texture
702
703//! encode coefficients
704Void TEncEntropy::encodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool& bCodeDQP, Bool& codeChromaQpAdj )
705{
706
707#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
708  const Bool bDebugRQT=pcCU->getSlice()->getFinalized() && DebugOptionList::DebugRQT.getInt()!=0;
709#endif
710
711#if NH_3D
712  if( pcCU->getSDCFlag( uiAbsPartIdx ) && pcCU->isIntra( uiAbsPartIdx ) )
713  {
714    assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
715    assert( pcCU->getTransformIdx(uiAbsPartIdx) == 0 );
716    assert( pcCU->getCbf(uiAbsPartIdx, COMPONENT_Y) == 1 );
717  }
718
719  if( pcCU->getSDCFlag( uiAbsPartIdx ) && !pcCU->isIntra( uiAbsPartIdx ) )
720  {
721    assert( !pcCU->isSkipped( uiAbsPartIdx ) );
722    assert( !pcCU->isIntra( uiAbsPartIdx) );
723    assert( pcCU->getSlice()->getIsDepth() );
724  }
725  if( pcCU->getSlice()->getIsDepth() )
726  {
727    if( pcCU->getSDCFlag( uiAbsPartIdx ) )
728    {
729      m_pcEntropyCoderIf->codeDeltaDC( pcCU, uiAbsPartIdx );
730      return;
731    }
732    if( pcCU->isIntra(uiAbsPartIdx) )
733  {
734    Int iPartNum = ( pcCU->isIntra( uiAbsPartIdx ) && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_NxN ) ? 4 : 1;
735      UInt uiPartOffset = ( pcCU->getPic()->getNumPartitionsInCtu() >> ( pcCU->getDepth( uiAbsPartIdx ) << 1 ) ) >> 2;
736      for( Int iPart = 0; iPart < iPartNum; iPart++ )
737      {
738        if( isDmmMode( pcCU->getIntraDir( CHANNEL_TYPE_LUMA, uiAbsPartIdx + uiPartOffset*iPart ) ) ) 
739        {
740          m_pcEntropyCoderIf->codeDeltaDC( pcCU, uiAbsPartIdx + uiPartOffset*iPart );
741        }
742      }
743    }
744  }
745#endif
746
747  if( pcCU->isIntra(uiAbsPartIdx) )
748  {
749#if !NH_MV
750    if (false)
751    {
752      DTRACE_CABAC_VL( g_nSymbolCounter++ )
753      DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" )
754      DTRACE_CABAC_V( uiDepth )
755      DTRACE_CABAC_T( "\n" )
756    }
757#endif
758  }
759  else
760  {
761    if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ) )
762    {
763      m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
764    }
765    if ( !pcCU->getQtRootCbf( uiAbsPartIdx ) )
766    {
767      return;
768    }
769  }
770
771  TComTURecurse tuRecurse(pcCU, uiAbsPartIdx, uiDepth);
772#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
773  if (bDebugRQT)
774  {
775    printf("..codeCoeff: uiAbsPartIdx=%d, PU format=%d, 2Nx2N=%d, NxN=%d\n", uiAbsPartIdx, pcCU->getPartitionSize(uiAbsPartIdx), SIZE_2Nx2N, SIZE_NxN);
776  }
777#endif
778
779  xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurse );
780}
781
782Void TEncEntropy::encodeCoeffNxN( TComTU &rTu, TCoeff* pcCoef, const ComponentID compID)
783{
784#if ENC_DEC_TRACE && NH_MV_ENC_DEC_TRAC
785  Bool oldTraceFracBits = g_traceEncFracBits; 
786  g_traceEncFracBits = false; 
787#endif
788
789  TComDataCU *pcCU = rTu.getCU();
790
791  if (pcCU->getCbf(rTu.GetAbsPartIdxTU(), compID, rTu.GetTransformDepthRel()) != 0)
792  {
793    if (rTu.getRect(compID).width != rTu.getRect(compID).height)
794    {
795      //code two sub-TUs
796      TComTURecurse subTUIterator(rTu, false, TComTU::VERTICAL_SPLIT, true, compID);
797
798      const UInt subTUSize = subTUIterator.getRect(compID).width * subTUIterator.getRect(compID).height;
799
800      do
801      {
802        const UChar subTUCBF = pcCU->getCbf(subTUIterator.GetAbsPartIdxTU(compID), compID, (subTUIterator.GetTransformDepthRel() + 1));
803
804        if (subTUCBF != 0)
805        {
806          m_pcEntropyCoderIf->codeCoeffNxN( subTUIterator, (pcCoef + (subTUIterator.GetSectionNumber() * subTUSize)), compID);
807        }
808      }
809      while (subTUIterator.nextSection(rTu));
810    }
811    else
812    {
813      m_pcEntropyCoderIf->codeCoeffNxN(rTu, pcCoef, compID);
814    }
815  }
816#if ENC_DEC_TRACE && NH_MV_ENC_DEC_TRAC
817  g_traceEncFracBits = oldTraceFracBits; 
818#endif
819}
820
821Void TEncEntropy::estimateBit (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, const ChannelType chType, COEFF_SCAN_TYPE scanType )
822{
823  const UInt heightAtEntropyCoding = (width != height) ? (height >> 1) : height;
824
825  m_pcEntropyCoderIf->estBit ( pcEstBitsSbac, width, heightAtEntropyCoding, chType, scanType );
826}
827
828Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
829{
830  Int count = 0;
831
832  for ( Int i = 0; i < uiSize; i++ )
833  {
834    count += pcCoef[i] != 0;
835  }
836
837  return count;
838}
839
840#if NH_3D
841Void TEncEntropy::encodeDeltaDC  ( TComDataCU* pcCU, UInt absPartIdx )
842{
843  m_pcEntropyCoderIf->codeDeltaDC( pcCU, absPartIdx );
844}
845
846Void TEncEntropy::encodeSDCFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
847{
848  if( bRD )
849  {
850    uiAbsPartIdx = 0;
851  }
852 
853  if( ( !pcCU->isIntra( uiAbsPartIdx ) && !pcCU->getSlice()->getInterSdcFlag() ) || 
854    ( pcCU->isIntra( uiAbsPartIdx ) && !pcCU->getSlice()->getIntraSdcWedgeFlag() ) )
855  {
856    return;
857  }
858
859  if( !pcCU->getSlice()->getIsDepth() || pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_2Nx2N || pcCU->isSkipped( uiAbsPartIdx ) )
860  {
861    return;
862  }
863
864  assert( pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N );
865
866  m_pcEntropyCoderIf->codeSDCFlag( pcCU, uiAbsPartIdx );
867}
868
869
870Void TEncEntropy::encodeDBBPFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
871{
872  if( bRD )
873  {
874    uiAbsPartIdx = 0;
875  }
876 
877  if( pcCU->getSlice()->getDepthBasedBlkPartFlag() && 
878    ( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2NxN || 
879      pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_Nx2N) && 
880      pcCU->getWidth(uiAbsPartIdx) > 8 && 
881      pcCU->getSlice()->getDefaultRefViewIdxAvailableFlag() )
882  {
883    m_pcEntropyCoderIf->codeDBBPFlag( pcCU, uiAbsPartIdx );
884  }
885}
886#endif
887
888//! \}
Note: See TracBrowser for help on using the repository browser.