source: SHVCSoftware/branches/SHM-2.0-dev/source/Lib/TLibEncoder/TEncEntropy.cpp @ 577

Last change on this file since 577 was 125, checked in by seregin, 12 years ago

copy from HM-10.0-dev-SHM

File size: 22.3 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-2013, 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/TypeDef.h"
40#include "TLibCommon/TComSampleAdaptiveOffset.h"
41
42//! \ingroup TLibEncoder
43//! \{
44
45Void TEncEntropy::setEntropyCoder ( TEncEntropyIf* e, TComSlice* pcSlice )
46{
47  m_pcEntropyCoderIf = e;
48  m_pcEntropyCoderIf->setSlice ( pcSlice );
49}
50
51Void TEncEntropy::encodeSliceHeader ( TComSlice* pcSlice )
52{
53  if (pcSlice->getSPS()->getUseSAO())
54  {
55    SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
56    pcSlice->setSaoEnabledFlag     (saoParam->bSaoFlag[0]);
57    {
58      pcSlice->setSaoEnabledFlagChroma   (saoParam->bSaoFlag[1]);
59    }
60  }
61
62  m_pcEntropyCoderIf->codeSliceHeader( pcSlice );
63  return;
64}
65
66Void  TEncEntropy::encodeTilesWPPEntryPoint( TComSlice* pSlice )
67{
68  m_pcEntropyCoderIf->codeTilesWPPEntryPoint( pSlice );
69}
70
71Void TEncEntropy::encodeTerminatingBit      ( UInt uiIsLast )
72{
73  m_pcEntropyCoderIf->codeTerminatingBit( uiIsLast );
74 
75  return;
76}
77
78Void TEncEntropy::encodeSliceFinish()
79{
80  m_pcEntropyCoderIf->codeSliceFinish();
81}
82
83Void TEncEntropy::encodePPS( TComPPS* pcPPS )
84{
85  m_pcEntropyCoderIf->codePPS( pcPPS );
86  return;
87}
88
89Void TEncEntropy::encodeSPS( TComSPS* pcSPS )
90{
91  m_pcEntropyCoderIf->codeSPS( pcSPS );
92  return;
93}
94
95Void TEncEntropy::encodeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
96{
97  if( bRD )
98  {
99    uiAbsPartIdx = 0;
100  }
101  m_pcEntropyCoderIf->codeCUTransquantBypassFlag( pcCU, uiAbsPartIdx );
102}
103
104Void TEncEntropy::encodeVPS( TComVPS* pcVPS )
105{
106  m_pcEntropyCoderIf->codeVPS( pcVPS );
107  return;
108}
109
110Void TEncEntropy::encodeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
111{
112  if ( pcCU->getSlice()->isIntra() )
113  {
114    return;
115  }
116  if( bRD )
117  {
118    uiAbsPartIdx = 0;
119  }
120  m_pcEntropyCoderIf->codeSkipFlag( pcCU, uiAbsPartIdx );
121}
122
123/** encode merge flag
124 * \param pcCU
125 * \param uiAbsPartIdx
126 * \returns Void
127 */
128Void TEncEntropy::encodeMergeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
129{ 
130  // at least one merge candidate exists
131  m_pcEntropyCoderIf->codeMergeFlag( pcCU, uiAbsPartIdx );
132}
133
134/** encode merge index
135 * \param pcCU
136 * \param uiAbsPartIdx
137 * \param uiPUIdx
138 * \param bRD
139 * \returns Void
140 */
141Void TEncEntropy::encodeMergeIndex( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
142{
143  if( bRD )
144  {
145    uiAbsPartIdx = 0;
146    assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N );
147  }
148  m_pcEntropyCoderIf->codeMergeIndex( pcCU, uiAbsPartIdx );
149}
150
151/** encode prediction mode
152 * \param pcCU
153 * \param uiAbsPartIdx
154 * \param bRD
155 * \returns Void
156 */
157Void TEncEntropy::encodePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
158{
159  if( bRD )
160  {
161    uiAbsPartIdx = 0;
162  }
163  if ( pcCU->getSlice()->isIntra() )
164  {
165    return;
166  }
167
168#if INTRA_BL
169  if( pcCU->isIntraBL( uiAbsPartIdx ) )
170  {
171    return;
172  }
173#endif
174
175  m_pcEntropyCoderIf->codePredMode( pcCU, uiAbsPartIdx );
176}
177
178// Split mode
179Void TEncEntropy::encodeSplitFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
180{
181  if( bRD )
182  {
183    uiAbsPartIdx = 0;
184  }
185  m_pcEntropyCoderIf->codeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
186}
187
188/** encode partition size
189 * \param pcCU
190 * \param uiAbsPartIdx
191 * \param uiDepth
192 * \param bRD
193 * \returns Void
194 */
195Void TEncEntropy::encodePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
196{
197  if( bRD )
198  {
199    uiAbsPartIdx = 0;
200  }
201  m_pcEntropyCoderIf->codePartSize( pcCU, uiAbsPartIdx, uiDepth );
202}
203
204/** Encode I_PCM information.
205 * \param pcCU pointer to CU
206 * \param uiAbsPartIdx CU index
207 * \param bRD flag indicating estimation or encoding
208 * \returns Void
209 */
210Void TEncEntropy::encodeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
211{
212  if(!pcCU->getSlice()->getSPS()->getUsePCM()
213    || pcCU->getWidth(uiAbsPartIdx) > (1<<pcCU->getSlice()->getSPS()->getPCMLog2MaxSize())
214    || pcCU->getWidth(uiAbsPartIdx) < (1<<pcCU->getSlice()->getSPS()->getPCMLog2MinSize()))
215  {
216    return;
217  }
218 
219  if( bRD )
220  {
221    uiAbsPartIdx = 0;
222  }
223 
224  m_pcEntropyCoderIf->codeIPCMInfo ( pcCU, uiAbsPartIdx );
225}
226
227Void TEncEntropy::xEncodeTransform( TComDataCU* pcCU,UInt offsetLuma, UInt offsetChroma, UInt uiAbsPartIdx, UInt uiDepth, UInt width, UInt height, UInt uiTrIdx, Bool& bCodeDQP )
228{
229  const UInt uiSubdiv = pcCU->getTransformIdx( uiAbsPartIdx ) + pcCU->getDepth( uiAbsPartIdx ) > uiDepth;
230  const UInt uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()]+2 - uiDepth;
231  UInt cbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA    , uiTrIdx );
232  UInt cbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
233  UInt cbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
234
235  if(uiTrIdx==0)
236  {
237    m_bakAbsPartIdxCU = uiAbsPartIdx;
238  }
239  if( uiLog2TrafoSize == 2 )
240  {
241    UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
242    if( ( uiAbsPartIdx % partNum ) == 0 )
243    {
244      m_uiBakAbsPartIdx   = uiAbsPartIdx;
245      m_uiBakChromaOffset = offsetChroma;
246    }
247    else if( ( uiAbsPartIdx % partNum ) == (partNum - 1) )
248    {
249      cbfU = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
250      cbfV = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
251    }
252  }
253#if INTRA_BL
254    if( pcCU->isIntra(uiAbsPartIdx) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
255#else
256 
257  if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTRA && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
258#endif
259  {
260    assert( uiSubdiv );
261  }
262  else if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) &&  (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) )
263  {
264    if ( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
265    {
266      assert( uiSubdiv );
267    }
268    else
269    {
270      assert(!uiSubdiv );
271    }
272  }
273  else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
274  {
275    assert( uiSubdiv );
276  }
277  else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
278  {
279    assert( !uiSubdiv );
280  }
281  else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
282  {
283    assert( !uiSubdiv );
284  }
285  else
286  {
287    assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
288    m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSubdiv, 5 - uiLog2TrafoSize );
289  }
290
291  const UInt uiTrDepthCurr = uiDepth - pcCU->getDepth( uiAbsPartIdx );
292  const Bool bFirstCbfOfCU = uiTrDepthCurr == 0;
293  if( bFirstCbfOfCU || uiLog2TrafoSize > 2 )
294  {
295    if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr - 1 ) )
296    {
297      m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr );
298    }
299    if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr - 1 ) )
300    {
301      m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr );
302    }
303  }
304  else if( uiLog2TrafoSize == 2 )
305  {
306    assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr - 1 ) );
307    assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr - 1 ) );
308  }
309 
310  if( uiSubdiv )
311  {
312    UInt size;
313    width  >>= 1;
314    height >>= 1;
315    size = width*height;
316    uiTrIdx++;
317    ++uiDepth;
318    const UInt partNum = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1);
319   
320    xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
321
322    uiAbsPartIdx += partNum;  offsetLuma += size;  offsetChroma += (size>>2);
323    xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
324
325    uiAbsPartIdx += partNum;  offsetLuma += size;  offsetChroma += (size>>2);
326    xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
327
328    uiAbsPartIdx += partNum;  offsetLuma += size;  offsetChroma += (size>>2);
329    xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
330  }
331  else
332  {
333    {
334      DTRACE_CABAC_VL( g_nSymbolCounter++ );
335      DTRACE_CABAC_T( "\tTrIdx: abspart=" );
336      DTRACE_CABAC_V( uiAbsPartIdx );
337      DTRACE_CABAC_T( "\tdepth=" );
338      DTRACE_CABAC_V( uiDepth );
339      DTRACE_CABAC_T( "\ttrdepth=" );
340      DTRACE_CABAC_V( pcCU->getTransformIdx( uiAbsPartIdx ) );
341      DTRACE_CABAC_T( "\n" );
342    }
343   
344#if INTRA_BL
345#if NO_RESIDUAL_FLAG_FOR_BLPRED
346    if( ( !pcCU->isIntra( uiAbsPartIdx ) || pcCU->isIntraBL(uiAbsPartIdx)) && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, 0 ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, 0 ) )
347#else
348    if( ( !pcCU->isIntra( uiAbsPartIdx ) ) && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, 0 ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, 0 ) )
349#endif
350#else
351    if( pcCU->getPredictionMode(uiAbsPartIdx) != MODE_INTRA && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, 0 ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, 0 ) )
352#endif
353    {
354      assert( pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, 0 ) );
355      //      printf( "saved one bin! " );
356    }
357    else
358    {
359      m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA, pcCU->getTransformIdx( uiAbsPartIdx ) );
360    }
361
362
363    if ( cbfY || cbfU || cbfV )
364    {
365      // dQP: only for LCU once
366      if ( pcCU->getSlice()->getPPS()->getUseDQP() )
367      {
368        if ( bCodeDQP )
369        {
370          encodeQP( pcCU, m_bakAbsPartIdxCU );
371          bCodeDQP = false;
372        }
373      }
374    }
375    if( cbfY )
376    {
377      Int trWidth = width;
378      Int trHeight = height;
379      m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffY()+offsetLuma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_LUMA );
380    }
381    if( uiLog2TrafoSize > 2 )
382    {
383      Int trWidth = width >> 1;
384      Int trHeight = height >> 1;
385      if( cbfU )
386      {
387        m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
388      }
389      if( cbfV )
390      {
391        m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
392      }
393    }
394    else
395    {
396      UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
397      if( ( uiAbsPartIdx % partNum ) == (partNum - 1) )
398      {
399        Int trWidth = width;
400        Int trHeight = height;
401        if( cbfU )
402        {
403          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
404        }
405        if( cbfV )
406        {
407          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
408        }
409      }
410    }
411  }
412}
413
414// Intra direction for Luma
415Void TEncEntropy::encodeIntraDirModeLuma  ( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiplePU )
416{
417  m_pcEntropyCoderIf->codeIntraDirLumaAng( pcCU, absPartIdx , isMultiplePU);
418}
419
420// Intra direction for Chroma
421Void TEncEntropy::encodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
422{
423  if( bRD )
424  {
425    uiAbsPartIdx = 0;
426  }
427 
428  m_pcEntropyCoderIf->codeIntraDirChroma( pcCU, uiAbsPartIdx );
429}
430
431Void TEncEntropy::encodePredInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
432{
433#if INTRA_BL
434  assert ( !pcCU->isIntraBL( uiAbsPartIdx ) );
435#endif
436  if( bRD )
437  {
438    uiAbsPartIdx = 0;
439  }
440  if( pcCU->isIntra( uiAbsPartIdx ) )                                 // If it is Intra mode, encode intra prediction mode.
441  {
442    encodeIntraDirModeLuma  ( pcCU, uiAbsPartIdx,true );
443    encodeIntraDirModeChroma( pcCU, uiAbsPartIdx, bRD );
444  }
445  else                                                                // if it is Inter mode, encode motion vector and reference index
446  {
447    encodePUWise( pcCU, uiAbsPartIdx, bRD );
448  }
449}
450
451/** encode motion information for every PU block
452 * \param pcCU
453 * \param uiAbsPartIdx
454 * \param bRD
455 * \returns Void
456 */
457Void TEncEntropy::encodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
458{
459  if ( bRD )
460  {
461    uiAbsPartIdx = 0;
462  }
463 
464  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
465  UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) );
466  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
467  UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() - uiDepth ) << 1 ) ) >> 4;
468
469  for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset )
470  {
471    encodeMergeFlag( pcCU, uiSubPartIdx );
472    if ( pcCU->getMergeFlag( uiSubPartIdx ) )
473    {
474      encodeMergeIndex( pcCU, uiSubPartIdx );
475    }
476    else
477    {
478      encodeInterDirPU( pcCU, uiSubPartIdx );
479      for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
480      {
481        if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
482        {
483          encodeRefFrmIdxPU ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
484          encodeMvdPU       ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
485          encodeMVPIdxPU    ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
486        }
487      }
488    }
489  }
490
491  return;
492}
493
494Void TEncEntropy::encodeInterDirPU( TComDataCU* pcCU, UInt uiAbsPartIdx )
495{
496  if ( !pcCU->getSlice()->isInterB() )
497  {
498    return;
499  }
500
501  m_pcEntropyCoderIf->codeInterDir( pcCU, uiAbsPartIdx );
502  return;
503}
504
505/** encode reference frame index for a PU block
506 * \param pcCU
507 * \param uiAbsPartIdx
508 * \param eRefList
509 * \returns Void
510 */
511Void TEncEntropy::encodeRefFrmIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
512{
513  assert( !pcCU->isIntra( uiAbsPartIdx ) );
514  {
515    if ( ( pcCU->getSlice()->getNumRefIdx( eRefList ) == 1 ) )
516    {
517      return;
518    }
519
520    if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
521    {
522      m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, eRefList );
523    }
524  }
525
526  return;
527}
528
529/** encode motion vector difference for a PU block
530 * \param pcCU
531 * \param uiAbsPartIdx
532 * \param eRefList
533 * \returns Void
534 */
535Void TEncEntropy::encodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
536{
537  assert( !pcCU->isIntra( uiAbsPartIdx ) );
538
539  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
540  {
541    m_pcEntropyCoderIf->codeMvd( pcCU, uiAbsPartIdx, eRefList );
542  }
543  return;
544}
545
546Void TEncEntropy::encodeMVPIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
547{
548  if ( (pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList )) )
549  {
550    m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList );
551  }
552
553  return;
554}
555
556Void TEncEntropy::encodeQtCbf( TComDataCU* pcCU, UInt uiAbsPartIdx, TextType eType, UInt uiTrDepth )
557{
558  m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, eType, uiTrDepth );
559}
560
561Void TEncEntropy::encodeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx )
562{
563  m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSymbol, uiCtx );
564}
565
566Void TEncEntropy::encodeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx )
567{
568  m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
569}
570
571Void TEncEntropy::encodeQtCbfZero( TComDataCU* pcCU, TextType eType, UInt uiTrDepth )
572{
573  m_pcEntropyCoderIf->codeQtCbfZero( pcCU, eType, uiTrDepth );
574}
575Void TEncEntropy::encodeQtRootCbfZero( TComDataCU* pcCU )
576{
577  m_pcEntropyCoderIf->codeQtRootCbfZero( pcCU );
578}
579
580// dQP
581Void TEncEntropy::encodeQP( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
582{
583  if( bRD )
584  {
585    uiAbsPartIdx = 0;
586  }
587 
588  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
589  {
590    m_pcEntropyCoderIf->codeDeltaQP( pcCU, uiAbsPartIdx );
591  }
592}
593
594
595// texture
596/** encode coefficients
597 * \param pcCU
598 * \param uiAbsPartIdx
599 * \param uiDepth
600 * \param uiWidth
601 * \param uiHeight
602 */
603Void TEncEntropy::encodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, Bool& bCodeDQP )
604{
605  UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
606  UInt uiLumaOffset   = uiMinCoeffSize*uiAbsPartIdx;
607  UInt uiChromaOffset = uiLumaOffset>>2;
608   
609#if NO_RESIDUAL_FLAG_FOR_BLPRED
610  if( pcCU->isIntra(uiAbsPartIdx) && !pcCU->isIntraBL(uiAbsPartIdx) )
611#else
612  if( pcCU->isIntra(uiAbsPartIdx) )
613#endif
614  {
615    DTRACE_CABAC_VL( g_nSymbolCounter++ )
616    DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" )
617    DTRACE_CABAC_V( uiDepth )
618    DTRACE_CABAC_T( "\n" )
619  }
620  else
621  {
622    if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ) )
623    {
624      m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
625    }
626    if ( !pcCU->getQtRootCbf( uiAbsPartIdx ) )
627    {
628      return;
629    }
630  }
631 
632  xEncodeTransform( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, bCodeDQP);
633}
634
635Void TEncEntropy::encodeCoeffNxN( TComDataCU* pcCU, TCoeff* pcCoeff, UInt uiAbsPartIdx, UInt uiTrWidth, UInt uiTrHeight, UInt uiDepth, TextType eType )
636{
637  // This is for Transform unit processing. This may be used at mode selection stage for Inter.
638  m_pcEntropyCoderIf->codeCoeffNxN( pcCU, pcCoeff, uiAbsPartIdx, uiTrWidth, uiTrHeight, uiDepth, eType );
639}
640
641Void TEncEntropy::estimateBit (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, TextType eTType)
642{ 
643  eTType = eTType == TEXT_LUMA ? TEXT_LUMA : TEXT_CHROMA;
644 
645  m_pcEntropyCoderIf->estBit ( pcEstBitsSbac, width, height, eTType );
646}
647
648/** Encode SAO Offset
649 * \param  saoLcuParam SAO LCU paramters
650 */
651Void TEncEntropy::encodeSaoOffset(SaoLcuParam* saoLcuParam, UInt compIdx)
652{
653  UInt uiSymbol;
654  Int i;
655
656  uiSymbol = saoLcuParam->typeIdx + 1;
657  if (compIdx!=2)
658  {
659    m_pcEntropyCoderIf->codeSaoTypeIdx(uiSymbol);
660  }
661  if (uiSymbol)
662  {
663    if (saoLcuParam->typeIdx < 4 && compIdx != 2)
664    {
665      saoLcuParam->subTypeIdx = saoLcuParam->typeIdx;
666    }
667    Int bitDepth = compIdx ? g_bitDepthC : g_bitDepthY;
668    Int offsetTh = 1 << min(bitDepth - 5,5);
669    if( saoLcuParam->typeIdx == SAO_BO )
670    {
671      for( i=0; i< saoLcuParam->length; i++)
672      {
673        UInt absOffset = ( (saoLcuParam->offset[i] < 0) ? -saoLcuParam->offset[i] : saoLcuParam->offset[i]);
674        m_pcEntropyCoderIf->codeSaoMaxUvlc(absOffset, offsetTh-1);
675      } 
676      for( i=0; i< saoLcuParam->length; i++)
677      {
678        if (saoLcuParam->offset[i] != 0)
679        {
680          UInt sign = (saoLcuParam->offset[i] < 0) ? 1 : 0 ;
681          m_pcEntropyCoderIf->codeSAOSign(sign);
682        }
683      }
684      uiSymbol = (UInt) (saoLcuParam->subTypeIdx);
685      m_pcEntropyCoderIf->codeSaoUflc(5, uiSymbol);
686    }
687    else if( saoLcuParam->typeIdx < 4 )
688    {
689      m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[0], offsetTh-1);
690      m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[1], offsetTh-1);
691      m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[2], offsetTh-1);
692      m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[3], offsetTh-1);
693      if (compIdx!=2)
694      {
695        uiSymbol = (UInt) (saoLcuParam->subTypeIdx);
696        m_pcEntropyCoderIf->codeSaoUflc(2, uiSymbol);
697      }
698    }
699  }
700}
701
702/** Encode SAO unit interleaving
703* \param  rx
704* \param  ry
705* \param  pSaoParam
706* \param  pcCU
707* \param  iCUAddrInSlice
708* \param  iCUAddrUpInSlice
709* \param  bLFCrossSliceBoundaryFlag
710 */
711Void TEncEntropy::encodeSaoUnitInterleaving(Int compIdx, Bool saoFlag, Int rx, Int ry, SaoLcuParam* saoLcuParam, Int cuAddrInSlice, Int cuAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp)
712{
713  if (saoFlag)
714  {
715    if (rx>0 && cuAddrInSlice!=0 && allowMergeLeft)
716    {
717      m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeLeftFlag);
718    }
719    else
720    {
721      saoLcuParam->mergeLeftFlag = 0;
722    }
723    if (saoLcuParam->mergeLeftFlag == 0)
724    {
725      if ( (ry > 0) && (cuAddrUpInSlice>=0) && allowMergeUp )
726      {
727        m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeUpFlag);
728      }
729      else
730      {
731        saoLcuParam->mergeUpFlag = 0;
732      }
733      if (!saoLcuParam->mergeUpFlag)
734      {
735        encodeSaoOffset(saoLcuParam, compIdx);
736      }
737    }
738  }
739}
740
741Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
742{
743  Int count = 0;
744 
745  for ( Int i = 0; i < uiSize; i++ )
746  {
747    count += pcCoef[i] != 0;
748  }
749 
750  return count;
751}
752
753/** encode quantization matrix
754 * \param scalingList quantization matrix information
755 */
756Void TEncEntropy::encodeScalingList( TComScalingList* scalingList )
757{
758  m_pcEntropyCoderIf->codeScalingList( scalingList );
759}
760
761#if INTRA_BL
762Void TEncEntropy::encodeIntraBLFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
763{
764  if( pcCU->getLayerId() == 0 )
765  {
766    return;
767  }
768
769  if( bRD )
770  {
771    uiAbsPartIdx = 0;
772  }
773  m_pcEntropyCoderIf->codeIntraBLFlag( pcCU, uiAbsPartIdx );
774}
775#endif
776//! \}
Note: See TracBrowser for help on using the repository browser.