source: 3DVCSoftware/branches/HTM-14.1-update-dev0/source/Lib/TLibEncoder/TEncEntropy.cpp @ 1314

Last change on this file since 1314 was 1200, checked in by tech, 10 years ago

Update to HM-16.5.
Starting point for further re-activation of 3D-tools.

Includes:

active:

  • MV-HEVC
  • 3D-HLS (apart from DLT)
  • VSO

inactive:

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