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

Last change on this file since 1313 was 1313, checked in by tech, 9 years ago

Merged 14.1-update-dev1@1312.

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