source: 3DVCSoftware/branches/HTM-14.1-update-dev3/source/Lib/TLibEncoder/TEncEntropy.cpp

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

Merged 14.1-update-dev4-Qualcomm@1266

  • Property svn:eol-style set to native
File size: 26.0 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2015, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncEntropy.cpp
35    \brief    entropy encoder class
36*/
37
38#include "TEncEntropy.h"
39#include "TLibCommon/CommonDef.h"
40#include "TLibCommon/TComSampleAdaptiveOffset.h"
41#include "TLibCommon/TComTU.h"
42
43#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
44#include "../TLibCommon/Debug.h"
45static const Bool bDebugPredEnabled = DebugOptionList::DebugPred.getInt()!=0;
46#endif
47
48//! \ingroup TLibEncoder
49//! \{
50
51Void TEncEntropy::setEntropyCoder ( TEncEntropyIf* e )
52{
53  m_pcEntropyCoderIf = e;
54}
55
56Void TEncEntropy::encodeSliceHeader ( TComSlice* pcSlice )
57{
58  m_pcEntropyCoderIf->codeSliceHeader( pcSlice );
59  return;
60}
61
62Void  TEncEntropy::encodeTilesWPPEntryPoint( TComSlice* pSlice )
63{
64  m_pcEntropyCoderIf->codeTilesWPPEntryPoint( pSlice );
65}
66
67Void TEncEntropy::encodeTerminatingBit      ( UInt uiIsLast )
68{
69  m_pcEntropyCoderIf->codeTerminatingBit( uiIsLast );
70
71  return;
72}
73
74Void TEncEntropy::encodeSliceFinish()
75{
76  m_pcEntropyCoderIf->codeSliceFinish();
77}
78
79Void TEncEntropy::encodePPS( const TComPPS* pcPPS )
80{
81  m_pcEntropyCoderIf->codePPS( pcPPS );
82  return;
83}
84
85Void TEncEntropy::encodeSPS( const TComSPS* pcSPS )
86{
87  m_pcEntropyCoderIf->codeSPS( pcSPS );
88  return;
89}
90
91Void TEncEntropy::encodeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
92{
93  if( bRD )
94  {
95    uiAbsPartIdx = 0;
96  }
97  m_pcEntropyCoderIf->codeCUTransquantBypassFlag( pcCU, uiAbsPartIdx );
98}
99
100Void TEncEntropy::encodeVPS( const TComVPS* pcVPS )
101{
102  m_pcEntropyCoderIf->codeVPS( pcVPS );
103  return;
104}
105
106Void TEncEntropy::encodeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
107{
108  if ( pcCU->getSlice()->isIntra() )
109  {
110    return;
111  }
112  if( bRD )
113  {
114    uiAbsPartIdx = 0;
115  }
116  m_pcEntropyCoderIf->codeSkipFlag( pcCU, uiAbsPartIdx );
117}
118#if H_3D
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}
131#endif
132//! encode merge flag
133Void TEncEntropy::encodeMergeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
134{
135  // at least one merge candidate exists
136  m_pcEntropyCoderIf->codeMergeFlag( pcCU, uiAbsPartIdx );
137}
138
139//! encode merge index
140Void TEncEntropy::encodeMergeIndex( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
141{
142  if( bRD )
143  {
144    uiAbsPartIdx = 0;
145    assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
146  }
147  m_pcEntropyCoderIf->codeMergeIndex( pcCU, uiAbsPartIdx );
148}
149
150#if H_3D_IC
151Void TEncEntropy::encodeICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
152{
153  if ( pcCU->isIntra( uiAbsPartIdx ) || ( pcCU->getSlice()->getViewIndex() == 0 ) || pcCU->getSlice()->getIsDepth() || pcCU->getARPW( uiAbsPartIdx ) > 0 )
154  {
155    return;
156  }
157
158  if( !pcCU->getSlice()->getApplyIC() )
159  {
160    return;
161  }
162
163  if( bRD )
164  {
165    uiAbsPartIdx = 0;
166  }
167  else
168  {
169    Int ICEnableCandidate = pcCU->getSlice()->getICEnableCandidate(pcCU->getSlice()->getDepth());
170    Int ICEnableNum = pcCU->getSlice()->getICEnableNum(pcCU->getSlice()->getDepth());
171    ICEnableCandidate++;
172    if(pcCU->getICFlag(uiAbsPartIdx))
173    {
174      ICEnableNum++;
175    }
176    pcCU->getSlice()->setICEnableCandidate(pcCU->getSlice()->getDepth(), ICEnableCandidate);
177    pcCU->getSlice()->setICEnableNum(pcCU->getSlice()->getDepth(), ICEnableNum);
178  }
179  if( pcCU->isICFlagRequired( uiAbsPartIdx ) )
180  {
181    m_pcEntropyCoderIf->codeICFlag( pcCU, uiAbsPartIdx );
182  }
183}
184#endif
185
186#if NH_3D_ARP
187Void TEncEntropy::encodeARPW( TComDataCU* pcCU, UInt uiAbsPartIdx )
188{
189  if( !pcCU->getSlice()->getARPStepNum() || pcCU->isIntra( uiAbsPartIdx ) ) 
190  {
191    return;
192  }
193
194  if ( pcCU->getPartitionSize(uiAbsPartIdx)!=SIZE_2Nx2N )
195  {
196    assert(pcCU->getARPW (uiAbsPartIdx) == 0);
197  }
198  else
199  {
200    m_pcEntropyCoderIf->codeARPW( pcCU, uiAbsPartIdx );
201  }
202}
203#endif
204
205
206//! encode prediction mode
207Void TEncEntropy::encodePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
208{
209  if( bRD )
210  {
211    uiAbsPartIdx = 0;
212  }
213
214  if ( pcCU->getSlice()->isIntra() )
215  {
216    return;
217  }
218
219  m_pcEntropyCoderIf->codePredMode( pcCU, uiAbsPartIdx );
220}
221
222//! encode split flag
223Void TEncEntropy::encodeSplitFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
224{
225  if( bRD )
226  {
227    uiAbsPartIdx = 0;
228  }
229
230  m_pcEntropyCoderIf->codeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
231}
232
233//! encode partition size
234Void TEncEntropy::encodePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
235{
236  if( bRD )
237  {
238    uiAbsPartIdx = 0;
239  }
240
241  m_pcEntropyCoderIf->codePartSize( pcCU, uiAbsPartIdx, uiDepth );
242}
243
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
249 */
250Void TEncEntropy::encodeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
251{
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  }
258
259  if( bRD )
260  {
261    uiAbsPartIdx = 0;
262  }
263
264  m_pcEntropyCoderIf->codeIPCMInfo ( pcCU, uiAbsPartIdx );
265
266}
267
268Void TEncEntropy::xEncodeTransform( Bool& bCodeDQP, Bool& codeChromaQpAdj, TComTU &rTu )
269{
270
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();
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")
285    DTRACE_TU("x0", uiLPelX)
286    DTRACE_TU("x1", uiTPelY)
287    DTRACE_TU("log2TrafoSize", pcCU->getSlice()->getSPS()->getMaxCUWidth()  >> uiDepth )
288    DTRACE_TU("trafoDepth"  , uiDepth)
289#endif
290#endif
291
292#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
293  const Bool bDebugRQT=pcCU->getSlice()->getFinalized() && DebugOptionList::DebugRQT.getInt()!=0;
294  if (bDebugRQT)
295  {
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());
298  }
299#endif
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++)
309  {
310    const ComponentID compID = ComponentID(ch);
311
312    cbf[compID] = pcCU->getCbf( uiAbsPartIdx, compID , uiTrIdx );
313   
314    if (cbf[ch] != 0)
315    {
316      bHaveACodedBlock = true;
317      if (isChroma(compID))
318      {
319        bHaveACodedChromaBlock = true;
320      }
321    }
322  }
323
324  if( pcCU->isIntra(uiAbsPartIdx) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
325  {
326    assert( uiSubdiv );
327  }
328  else if( pcCU->isInter(uiAbsPartIdx) && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) &&  (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) )
329  {
330    if ( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
331    {
332      assert( uiSubdiv );
333    }
334    else
335    {
336      assert(!uiSubdiv );
337    }
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;
359
360  for(UInt ch=COMPONENT_Cb; ch<numValidComponent; ch++)
361  {
362    const ComponentID compID=ComponentID(ch);
363    if( bFirstCbfOfCU || rTu.ProcessingAllQuadrants(compID) )
364    {
365      if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) )
366      {
367        m_pcEntropyCoderIf->codeQtCbf( rTu, compID, (uiSubdiv == 0) );
368      }
369    }
370    else
371    {
372      assert( pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, compID, uiTrDepthCurr - 1 ) );
373    }
374  }
375
376  if( uiSubdiv )
377  {
378    TComTURecurse tuRecurseChild(rTu, true);
379    do
380    {
381      xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurseChild );
382    } while (tuRecurseChild.nextSection(rTu));
383  }
384  else
385  {
386#if !H_MV_ENC_DEC_TRAC
387    {
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" );
396    }
397#endif
398    if( !pcCU->isIntra(uiAbsPartIdx) && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && (!bChroma || (!pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cb, 0 ) && !pcCU->getCbf( uiAbsPartIdx, COMPONENT_Cr, 0 ) ) ) )
399    {
400      assert( pcCU->getCbf( uiAbsPartIdx, COMPONENT_Y, 0 ) );
401      //      printf( "saved one bin! " );
402    }
403    else
404    {
405      m_pcEntropyCoderIf->codeQtCbf( rTu, COMPONENT_Y, true ); //luma CBF is always at the lowest level
406    }
407
408    if ( bHaveACodedBlock )
409    {
410      // dQP: only for CTU once
411      if ( pcCU->getSlice()->getPPS()->getUseDQP() )
412      {
413        if ( bCodeDQP )
414        {
415          encodeQP( pcCU, rTu.GetAbsPartIdxCU() );
416          bCodeDQP = false;
417        }
418      }
419
420      if ( pcCU->getSlice()->getUseChromaQpAdj() )
421      {
422        if ( bHaveACodedChromaBlock && codeChromaQpAdj && !pcCU->getCUTransquantBypass(rTu.GetAbsPartIdxCU()) )
423        {
424          encodeChromaQpAdjustment( pcCU, rTu.GetAbsPartIdxCU() );
425          codeChromaQpAdj = false;
426        }
427      }
428
429      const UInt numValidComp=pcCU->getPic()->getNumberValidComponents();
430
431      for(UInt ch=COMPONENT_Y; ch<numValidComp; ch++)
432      {
433        const ComponentID compID=ComponentID(ch);
434
435        if (rTu.ProcessComponentSection(compID))
436        {
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          }
478        }
479      }
480    }
481  }
482}
483
484
485//! encode intra direction for luma
486Void TEncEntropy::encodeIntraDirModeLuma  ( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiplePU )
487{
488  m_pcEntropyCoderIf->codeIntraDirLumaAng( pcCU, absPartIdx , isMultiplePU);
489}
490
491
492//! encode intra direction for chroma
493Void TEncEntropy::encodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx )
494{
495  m_pcEntropyCoderIf->codeIntraDirChroma( pcCU, uiAbsPartIdx );
496
497#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
498  if (bDebugPredEnabled && pcCU->getSlice()->getFinalized())
499  {
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));
506  }
507#endif
508}
509
510
511Void TEncEntropy::encodePredInfo( TComDataCU* pcCU, UInt uiAbsPartIdx )
512{
513  if( pcCU->isIntra( uiAbsPartIdx ) )                                 // If it is Intra mode, encode intra prediction mode.
514  {
515    encodeIntraDirModeLuma  ( pcCU, uiAbsPartIdx,true );
516#if H_3D_DIM_SDC
517    if(!pcCU->getSDCFlag(uiAbsPartIdx))
518#endif
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    }
531  }
532  else                                                                // if it is Inter mode, encode motion vector and reference index
533  {
534    encodePUWise( pcCU, uiAbsPartIdx );
535  }
536}
537
538Void TEncEntropy::encodeCrossComponentPrediction( TComTU &rTu, ComponentID compID )
539{
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
550  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
551  UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) );
552  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
553  UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxTotalCUDepth() - uiDepth ) << 1 ) ) >> 4;
554
555  for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset )
556  {
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 );
564    if ( pcCU->getMergeFlag( uiSubPartIdx ) )
565    {
566      encodeMergeIndex( pcCU, uiSubPartIdx );
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
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 ) );
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
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 );
611
612  return;
613}
614
615//! encode reference frame index for a PU block
616Void TEncEntropy::encodeRefFrmIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
617{
618  assert( pcCU->isInter( uiAbsPartIdx ) );
619
620  if ( ( pcCU->getSlice()->getNumRefIdx( eRefList ) == 1 ) )
621  {
622    return;
623  }
624
625  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
626  {
627    m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, eRefList );
628  }
629
630  return;
631}
632
633//! encode motion vector difference for a PU block
634Void TEncEntropy::encodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
635{
636  assert( pcCU->isInter( uiAbsPartIdx ) );
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{
647  if ( (pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList )) )
648  {
649    m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList );
650  }
651
652  return;
653}
654
655Void TEncEntropy::encodeQtCbf( TComTU &rTu, const ComponentID compID, const Bool lowestLevel )
656{
657  m_pcEntropyCoderIf->codeQtCbf( rTu, compID, lowestLevel );
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
670Void TEncEntropy::encodeQtCbfZero( TComTU &rTu, const ChannelType chType )
671{
672  m_pcEntropyCoderIf->codeQtCbfZero( rTu, chType );
673}
674
675Void TEncEntropy::encodeQtRootCbfZero( )
676{
677  m_pcEntropyCoderIf->codeQtRootCbfZero( );
678}
679
680// dQP
681Void TEncEntropy::encodeQP( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
682{
683  if( bRD )
684  {
685    uiAbsPartIdx = 0;
686  }
687
688  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
689  {
690    m_pcEntropyCoderIf->codeDeltaQP( pcCU, uiAbsPartIdx );
691  }
692}
693
694//! encode chroma qp adjustment
695Void TEncEntropy::encodeChromaQpAdjustment( TComDataCU* cu, UInt absPartIdx, Bool inRd )
696{
697  if( inRd )
698  {
699    absPartIdx = 0;
700  }
701
702  m_pcEntropyCoderIf->codeChromaQpAdjustment( cu, absPartIdx );
703}
704
705// texture
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;
713#endif
714
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
725
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  }
732
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;
737   
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  }
754#endif
755
756
757  if( pcCU->isIntra(uiAbsPartIdx) )
758  {
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    }
767#endif
768  }
769  else
770  {
771    if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ) )
772    {
773      m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
774    }
775    if ( !pcCU->getQtRootCbf( uiAbsPartIdx ) )
776    {
777      return;
778    }
779  }
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  }
787#endif
788
789  xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurse );
790}
791
792Void TEncEntropy::encodeCoeffNxN( TComTU &rTu, TCoeff* pcCoef, const ComponentID compID)
793{
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  }
821}
822
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 );
828}
829
830Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
831{
832  Int count = 0;
833
834  for ( Int i = 0; i < uiSize; i++ )
835  {
836    count += pcCoef[i] != 0;
837  }
838
839  return count;
840}
841
842#if H_3D_INTER_SDC
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{
850  if( ( !pcCU->isIntra( uiAbsPartIdx ) && !pcCU->getSlice()->getInterSdcFlag() ) || 
851    ( pcCU->isIntra( uiAbsPartIdx ) && !pcCU->getSlice()->getIntraSdcWedgeFlag() ) )
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}
870
871#endif
872#if NH_3D_DBBP
873Void TEncEntropy::encodeDBBPFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
874{
875  if( bRD )
876  {
877    uiAbsPartIdx = 0;
878  }
879 
880  if( pcCU->getSlice()->getDepthBasedBlkPartFlag() && 
881    ( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2NxN || 
882      pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_Nx2N) && 
883      pcCU->getWidth(uiAbsPartIdx) > 8 && 
884      pcCU->getSlice()->getDefaultRefViewIdxAvailableFlag() )
885  {
886    m_pcEntropyCoderIf->codeDBBPFlag( pcCU, uiAbsPartIdx );
887  }
888}
889#endif
890
891//! \}
Note: See TracBrowser for help on using the repository browser.