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

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

Merged 15.0-dev0@1320.

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