source: 3DVCSoftware/branches/HTM-14.1-update-dev1-RWTH/source/Lib/TLibEncoder/TEncEntropy.cpp @ 1221

Last change on this file since 1221 was 1221, checked in by rwth, 9 years ago
  • initial implementation of INTRA SDC (still not fully functional)
  • Property svn:eol-style set to native
File size: 25.9 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-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 H_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   
517    if (pcCU->getPic()->getChromaFormat()!=CHROMA_400)
518    {
519      encodeIntraDirModeChroma( pcCU, uiAbsPartIdx );
520
521      if (enable4ChromaPUsInIntraNxNCU(pcCU->getPic()->getChromaFormat()) && pcCU->getPartitionSize( uiAbsPartIdx )==SIZE_NxN)
522      {
523        UInt uiPartOffset = ( pcCU->getPic()->getNumPartitionsInCtu() >> ( pcCU->getDepth(uiAbsPartIdx) << 1 ) ) >> 2;
524        encodeIntraDirModeChroma( pcCU, uiAbsPartIdx + uiPartOffset   );
525        encodeIntraDirModeChroma( pcCU, uiAbsPartIdx + uiPartOffset*2 );
526        encodeIntraDirModeChroma( pcCU, uiAbsPartIdx + uiPartOffset*3 );
527      }
528    }
529  }
530  else                                                                // if it is Inter mode, encode motion vector and reference index
531  {
532    encodePUWise( pcCU, uiAbsPartIdx );
533  }
534}
535
536Void TEncEntropy::encodeCrossComponentPrediction( TComTU &rTu, ComponentID compID )
537{
538  m_pcEntropyCoderIf->codeCrossComponentPrediction( rTu, compID );
539}
540
541//! encode motion information for every PU block
542Void TEncEntropy::encodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx )
543{
544#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
545  const Bool bDebugPred = bDebugPredEnabled && pcCU->getSlice()->getFinalized();
546#endif
547
548  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
549  UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) );
550  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
551  UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxTotalCUDepth() - uiDepth ) << 1 ) ) >> 4;
552
553  for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset )
554  {
555#if H_MV_ENC_DEC_TRAC
556    DTRACE_PU_S("=========== prediction_unit ===========\n")
557       //Todo:
558      //DTRACE_PU("x0", uiLPelX)
559      //DTRACE_PU("x1", uiTPelY)
560#endif
561    encodeMergeFlag( pcCU, uiSubPartIdx );
562    if ( pcCU->getMergeFlag( uiSubPartIdx ) )
563    {
564      encodeMergeIndex( pcCU, uiSubPartIdx );
565#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
566      if (bDebugPred)
567      {
568        std::cout << "Coded merge flag, CU absPartIdx: " << uiAbsPartIdx << " PU(" << uiPartIdx << ") absPartIdx: " << uiSubPartIdx;
569        std::cout << " merge index: " << (UInt)pcCU->getMergeIndex(uiSubPartIdx) << std::endl;
570      }
571#endif
572    }
573    else
574    {
575      encodeInterDirPU( pcCU, uiSubPartIdx );
576      for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
577      {
578        if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
579        {
580          encodeRefFrmIdxPU ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
581          encodeMvdPU       ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
582          encodeMVPIdxPU    ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
583#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
584          if (bDebugPred)
585          {
586            std::cout << "refListIdx: " << uiRefListIdx << std::endl;
587            std::cout << "MVD horizontal: " << pcCU->getCUMvField(RefPicList(uiRefListIdx))->getMvd( uiAbsPartIdx ).getHor() << std::endl;
588            std::cout << "MVD vertical:   " << pcCU->getCUMvField(RefPicList(uiRefListIdx))->getMvd( uiAbsPartIdx ).getVer() << std::endl;
589            std::cout << "MVPIdxPU: " << pcCU->getMVPIdx(RefPicList( uiRefListIdx ), uiSubPartIdx) << std::endl;
590            std::cout << "InterDir: " << (UInt)pcCU->getInterDir(uiSubPartIdx) << std::endl;
591          }
592#endif
593        }
594      }
595    }
596  }
597
598  return;
599}
600
601Void TEncEntropy::encodeInterDirPU( TComDataCU* pcCU, UInt uiAbsPartIdx )
602{
603  if ( !pcCU->getSlice()->isInterB() )
604  {
605    return;
606  }
607
608  m_pcEntropyCoderIf->codeInterDir( pcCU, uiAbsPartIdx );
609
610  return;
611}
612
613//! encode reference frame index for a PU block
614Void TEncEntropy::encodeRefFrmIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
615{
616  assert( pcCU->isInter( uiAbsPartIdx ) );
617
618  if ( ( pcCU->getSlice()->getNumRefIdx( eRefList ) == 1 ) )
619  {
620    return;
621  }
622
623  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
624  {
625    m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, eRefList );
626  }
627
628  return;
629}
630
631//! encode motion vector difference for a PU block
632Void TEncEntropy::encodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
633{
634  assert( pcCU->isInter( uiAbsPartIdx ) );
635
636  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
637  {
638    m_pcEntropyCoderIf->codeMvd( pcCU, uiAbsPartIdx, eRefList );
639  }
640  return;
641}
642
643Void TEncEntropy::encodeMVPIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
644{
645  if ( (pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList )) )
646  {
647    m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList );
648  }
649
650  return;
651}
652
653Void TEncEntropy::encodeQtCbf( TComTU &rTu, const ComponentID compID, const Bool lowestLevel )
654{
655  m_pcEntropyCoderIf->codeQtCbf( rTu, compID, lowestLevel );
656}
657
658Void TEncEntropy::encodeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx )
659{
660  m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSymbol, uiCtx );
661}
662
663Void TEncEntropy::encodeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx )
664{
665  m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
666}
667
668Void TEncEntropy::encodeQtCbfZero( TComTU &rTu, const ChannelType chType )
669{
670  m_pcEntropyCoderIf->codeQtCbfZero( rTu, chType );
671}
672
673Void TEncEntropy::encodeQtRootCbfZero( )
674{
675  m_pcEntropyCoderIf->codeQtRootCbfZero( );
676}
677
678// dQP
679Void TEncEntropy::encodeQP( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
680{
681  if( bRD )
682  {
683    uiAbsPartIdx = 0;
684  }
685
686  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
687  {
688    m_pcEntropyCoderIf->codeDeltaQP( pcCU, uiAbsPartIdx );
689  }
690}
691
692//! encode chroma qp adjustment
693Void TEncEntropy::encodeChromaQpAdjustment( TComDataCU* cu, UInt absPartIdx, Bool inRd )
694{
695  if( inRd )
696  {
697    absPartIdx = 0;
698  }
699
700  m_pcEntropyCoderIf->codeChromaQpAdjustment( cu, absPartIdx );
701}
702
703// texture
704
705//! encode coefficients
706Void TEncEntropy::encodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool& bCodeDQP, Bool& codeChromaQpAdj )
707{
708
709#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
710  const Bool bDebugRQT=pcCU->getSlice()->getFinalized() && DebugOptionList::DebugRQT.getInt()!=0;
711#endif
712
713#if NH_3D_INTRA_SDC
714  if( pcCU->getSDCFlag( uiAbsPartIdx ) && pcCU->isIntra( uiAbsPartIdx ) )
715  {
716    assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
717    assert( pcCU->getTransformIdx(uiAbsPartIdx) == 0 );
718    assert( pcCU->getCbf(uiAbsPartIdx, COMPONENT_Y) == 1 );
719  }
720#endif
721#if H_3D_INTER_SDC
722  if( pcCU->getSDCFlag( uiAbsPartIdx ) && !pcCU->isIntra( uiAbsPartIdx ) )
723  {
724    assert( !pcCU->isSkipped( uiAbsPartIdx ) );
725    assert( !pcCU->isIntra( uiAbsPartIdx) );
726    assert( pcCU->getSlice()->getIsDepth() );
727  }
728#endif
729#if NH_3D
730  if( pcCU->getSlice()->getIsDepth() )
731  {
732#if NH_3D_INTRA_SDC || H_3D_INTER_SDC
733    if( pcCU->getSDCFlag( uiAbsPartIdx ) )
734    {
735      m_pcEntropyCoderIf->codeDeltaDC( pcCU, uiAbsPartIdx );
736      return;
737    }
738#endif
739#if NH_3D_DMM
740    if( pcCU->isIntra(uiAbsPartIdx) )
741  {
742    Int iPartNum = ( pcCU->isIntra( uiAbsPartIdx ) && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_NxN ) ? 4 : 1;
743      UInt uiPartOffset = ( pcCU->getPic()->getNumPartitionsInCtu() >> ( pcCU->getDepth( uiAbsPartIdx ) << 1 ) ) >> 2;
744      for( Int iPart = 0; iPart < iPartNum; iPart++ )
745      {
746        if( isDmmMode( pcCU->getIntraDir( CHANNEL_TYPE_LUMA, uiAbsPartIdx + uiPartOffset*iPart ) ) ) 
747        {
748          m_pcEntropyCoderIf->codeDeltaDC( pcCU, uiAbsPartIdx + uiPartOffset*iPart );
749        }
750      }
751    }
752#endif
753  }
754#endif
755
756  if( pcCU->isIntra(uiAbsPartIdx) )
757  {
758#if !NH_MV
759    if (false)
760    {
761      DTRACE_CABAC_VL( g_nSymbolCounter++ )
762      DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" )
763      DTRACE_CABAC_V( uiDepth )
764      DTRACE_CABAC_T( "\n" )
765    }
766#endif
767  }
768  else
769  {
770    if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ) )
771    {
772      m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
773    }
774    if ( !pcCU->getQtRootCbf( uiAbsPartIdx ) )
775    {
776      return;
777    }
778  }
779
780  TComTURecurse tuRecurse(pcCU, uiAbsPartIdx, uiDepth);
781#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
782  if (bDebugRQT)
783  {
784    printf("..codeCoeff: uiAbsPartIdx=%d, PU format=%d, 2Nx2N=%d, NxN=%d\n", uiAbsPartIdx, pcCU->getPartitionSize(uiAbsPartIdx), SIZE_2Nx2N, SIZE_NxN);
785  }
786#endif
787
788  xEncodeTransform( bCodeDQP, codeChromaQpAdj, tuRecurse );
789}
790
791Void TEncEntropy::encodeCoeffNxN( TComTU &rTu, TCoeff* pcCoef, const ComponentID compID)
792{
793  TComDataCU *pcCU = rTu.getCU();
794
795  if (pcCU->getCbf(rTu.GetAbsPartIdxTU(), compID, rTu.GetTransformDepthRel()) != 0)
796  {
797    if (rTu.getRect(compID).width != rTu.getRect(compID).height)
798    {
799      //code two sub-TUs
800      TComTURecurse subTUIterator(rTu, false, TComTU::VERTICAL_SPLIT, true, compID);
801
802      const UInt subTUSize = subTUIterator.getRect(compID).width * subTUIterator.getRect(compID).height;
803
804      do
805      {
806        const UChar subTUCBF = pcCU->getCbf(subTUIterator.GetAbsPartIdxTU(compID), compID, (subTUIterator.GetTransformDepthRel() + 1));
807
808        if (subTUCBF != 0)
809        {
810          m_pcEntropyCoderIf->codeCoeffNxN( subTUIterator, (pcCoef + (subTUIterator.GetSectionNumber() * subTUSize)), compID);
811        }
812      }
813      while (subTUIterator.nextSection(rTu));
814    }
815    else
816    {
817      m_pcEntropyCoderIf->codeCoeffNxN(rTu, pcCoef, compID);
818    }
819  }
820}
821
822Void TEncEntropy::estimateBit (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, const ChannelType chType)
823{
824  const UInt heightAtEntropyCoding = (width != height) ? (height >> 1) : height;
825
826  m_pcEntropyCoderIf->estBit ( pcEstBitsSbac, width, heightAtEntropyCoding, chType );
827}
828
829Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
830{
831  Int count = 0;
832
833  for ( Int i = 0; i < uiSize; i++ )
834  {
835    count += pcCoef[i] != 0;
836  }
837
838  return count;
839}
840
841#if NH_3D_DMM || NH_3D_INTRA_SDC || H_3D_INTER_SDC
842Void TEncEntropy::encodeDeltaDC  ( TComDataCU* pcCU, UInt absPartIdx )
843{
844  m_pcEntropyCoderIf->codeDeltaDC( pcCU, absPartIdx );
845}
846#endif
847#if NH_3D_INTRA_SDC || H_3D_INTER_SDC
848Void TEncEntropy::encodeSDCFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
849{
850  if( bRD )
851  {
852    uiAbsPartIdx = 0;
853  }
854 
855  if( ( !pcCU->isIntra( uiAbsPartIdx ) && !pcCU->getSlice()->getInterSdcFlag() ) || 
856    ( pcCU->isIntra( uiAbsPartIdx ) && !pcCU->getSlice()->getIntraSdcWedgeFlag() ) )
857  {
858    return;
859  }
860
861  if( !pcCU->getSlice()->getIsDepth() || pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_2Nx2N || pcCU->isSkipped( uiAbsPartIdx ) )
862  {
863    return;
864  }
865
866  assert( pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N );
867
868  m_pcEntropyCoderIf->codeSDCFlag( pcCU, uiAbsPartIdx );
869}
870
871#endif
872#if H_3D_DBBP
873Void TEncEntropy::encodeDBBPFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
874{
875  if( pcCU->getSlice()->getDepthBasedBlkPartFlag() && 
876    ( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2NxN || 
877      pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_Nx2N) && 
878      pcCU->getWidth(uiAbsPartIdx) > 8 && 
879      pcCU->getSlice()->getDefaultRefViewIdxAvailableFlag() )
880  {
881    if( bRD )
882    {
883      uiAbsPartIdx = 0;
884    }
885    m_pcEntropyCoderIf->codeDBBPFlag( pcCU, uiAbsPartIdx );
886  }
887}
888#endif
889
890//! \}
Note: See TracBrowser for help on using the repository browser.