source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncEntropy.cpp @ 345

Last change on this file since 345 was 345, checked in by seregin, 11 years ago

merge SHM-3.0-dev branch

  • Property svn:eol-style set to native
File size: 21.2 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  m_pcEntropyCoderIf->codePredMode( pcCU, uiAbsPartIdx );
169}
170
171// Split mode
172Void TEncEntropy::encodeSplitFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
173{
174  if( bRD )
175  {
176    uiAbsPartIdx = 0;
177  }
178  m_pcEntropyCoderIf->codeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );
179}
180
181/** encode partition size
182 * \param pcCU
183 * \param uiAbsPartIdx
184 * \param uiDepth
185 * \param bRD
186 * \returns Void
187 */
188Void TEncEntropy::encodePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD )
189{
190  if( bRD )
191  {
192    uiAbsPartIdx = 0;
193  }
194  m_pcEntropyCoderIf->codePartSize( pcCU, uiAbsPartIdx, uiDepth );
195}
196
197/** Encode I_PCM information.
198 * \param pcCU pointer to CU
199 * \param uiAbsPartIdx CU index
200 * \param bRD flag indicating estimation or encoding
201 * \returns Void
202 */
203Void TEncEntropy::encodeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
204{
205  if(!pcCU->getSlice()->getSPS()->getUsePCM()
206    || pcCU->getWidth(uiAbsPartIdx) > (1<<pcCU->getSlice()->getSPS()->getPCMLog2MaxSize())
207    || pcCU->getWidth(uiAbsPartIdx) < (1<<pcCU->getSlice()->getSPS()->getPCMLog2MinSize()))
208  {
209    return;
210  }
211 
212  if( bRD )
213  {
214    uiAbsPartIdx = 0;
215  }
216 
217  m_pcEntropyCoderIf->codeIPCMInfo ( pcCU, uiAbsPartIdx );
218}
219
220Void TEncEntropy::xEncodeTransform( TComDataCU* pcCU,UInt offsetLuma, UInt offsetChroma, UInt uiAbsPartIdx, UInt uiDepth, UInt width, UInt height, UInt uiTrIdx, Bool& bCodeDQP )
221{
222  const UInt uiSubdiv = pcCU->getTransformIdx( uiAbsPartIdx ) + pcCU->getDepth( uiAbsPartIdx ) > uiDepth;
223  const UInt uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()]+2 - uiDepth;
224  UInt cbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA    , uiTrIdx );
225  UInt cbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
226  UInt cbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
227
228  if(uiTrIdx==0)
229  {
230    m_bakAbsPartIdxCU = uiAbsPartIdx;
231  }
232  if( uiLog2TrafoSize == 2 )
233  {
234    UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
235    if( ( uiAbsPartIdx % partNum ) == 0 )
236    {
237      m_uiBakAbsPartIdx   = uiAbsPartIdx;
238      m_uiBakChromaOffset = offsetChroma;
239    }
240    else if( ( uiAbsPartIdx % partNum ) == (partNum - 1) )
241    {
242      cbfU = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_U, uiTrIdx );
243      cbfV = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_V, uiTrIdx );
244    }
245  }
246 
247  if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTRA && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) )
248  {
249    assert( uiSubdiv );
250  }
251  else if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && (pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N) && uiDepth == pcCU->getDepth(uiAbsPartIdx) &&  (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) )
252  {
253    if ( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
254    {
255      assert( uiSubdiv );
256    }
257    else
258    {
259      assert(!uiSubdiv );
260    }
261  }
262  else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() )
263  {
264    assert( uiSubdiv );
265  }
266  else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() )
267  {
268    assert( !uiSubdiv );
269  }
270  else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) )
271  {
272    assert( !uiSubdiv );
273  }
274  else
275  {
276    assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) );
277    m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSubdiv, 5 - uiLog2TrafoSize );
278  }
279
280  const UInt uiTrDepthCurr = uiDepth - pcCU->getDepth( uiAbsPartIdx );
281  const Bool bFirstCbfOfCU = uiTrDepthCurr == 0;
282  if( bFirstCbfOfCU || uiLog2TrafoSize > 2 )
283  {
284    if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr - 1 ) )
285    {
286      m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr );
287    }
288    if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr - 1 ) )
289    {
290      m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr );
291    }
292  }
293  else if( uiLog2TrafoSize == 2 )
294  {
295    assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepthCurr - 1 ) );
296    assert( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr ) == pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepthCurr - 1 ) );
297  }
298 
299  if( uiSubdiv )
300  {
301    UInt size;
302    width  >>= 1;
303    height >>= 1;
304    size = width*height;
305    uiTrIdx++;
306    ++uiDepth;
307    const UInt partNum = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1);
308   
309    xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
310
311    uiAbsPartIdx += partNum;  offsetLuma += size;  offsetChroma += (size>>2);
312    xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
313
314    uiAbsPartIdx += partNum;  offsetLuma += size;  offsetChroma += (size>>2);
315    xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
316
317    uiAbsPartIdx += partNum;  offsetLuma += size;  offsetChroma += (size>>2);
318    xEncodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, uiDepth, width, height, uiTrIdx, bCodeDQP );
319  }
320  else
321  {
322    {
323      DTRACE_CABAC_VL( g_nSymbolCounter++ );
324      DTRACE_CABAC_T( "\tTrIdx: abspart=" );
325      DTRACE_CABAC_V( uiAbsPartIdx );
326      DTRACE_CABAC_T( "\tdepth=" );
327      DTRACE_CABAC_V( uiDepth );
328      DTRACE_CABAC_T( "\ttrdepth=" );
329      DTRACE_CABAC_V( pcCU->getTransformIdx( uiAbsPartIdx ) );
330      DTRACE_CABAC_T( "\n" );
331    }
332   
333    if( pcCU->getPredictionMode(uiAbsPartIdx) != MODE_INTRA && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, 0 ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, 0 ) )
334    {
335      assert( pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, 0 ) );
336      //      printf( "saved one bin! " );
337    }
338    else
339    {
340      m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA, pcCU->getTransformIdx( uiAbsPartIdx ) );
341    }
342
343
344    if ( cbfY || cbfU || cbfV )
345    {
346      // dQP: only for LCU once
347      if ( pcCU->getSlice()->getPPS()->getUseDQP() )
348      {
349        if ( bCodeDQP )
350        {
351          encodeQP( pcCU, m_bakAbsPartIdxCU );
352          bCodeDQP = false;
353        }
354      }
355    }
356    if( cbfY )
357    {
358      Int trWidth = width;
359      Int trHeight = height;
360      m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffY()+offsetLuma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_LUMA );
361    }
362    if( uiLog2TrafoSize > 2 )
363    {
364      Int trWidth = width >> 1;
365      Int trHeight = height >> 1;
366      if( cbfU )
367      {
368        m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
369      }
370      if( cbfV )
371      {
372        m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
373      }
374    }
375    else
376    {
377      UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
378      if( ( uiAbsPartIdx % partNum ) == (partNum - 1) )
379      {
380        Int trWidth = width;
381        Int trHeight = height;
382        if( cbfU )
383        {
384          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
385        }
386        if( cbfV )
387        {
388          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
389        }
390      }
391    }
392  }
393}
394
395// Intra direction for Luma
396Void TEncEntropy::encodeIntraDirModeLuma  ( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiplePU )
397{
398  m_pcEntropyCoderIf->codeIntraDirLumaAng( pcCU, absPartIdx , isMultiplePU);
399}
400
401// Intra direction for Chroma
402Void TEncEntropy::encodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
403{
404  if( bRD )
405  {
406    uiAbsPartIdx = 0;
407  }
408 
409  m_pcEntropyCoderIf->codeIntraDirChroma( pcCU, uiAbsPartIdx );
410}
411
412Void TEncEntropy::encodePredInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
413{
414  if( bRD )
415  {
416    uiAbsPartIdx = 0;
417  }
418  if( pcCU->isIntra( uiAbsPartIdx ) )                                 // If it is Intra mode, encode intra prediction mode.
419  {
420    encodeIntraDirModeLuma  ( pcCU, uiAbsPartIdx,true );
421    encodeIntraDirModeChroma( pcCU, uiAbsPartIdx, bRD );
422  }
423  else                                                                // if it is Inter mode, encode motion vector and reference index
424  {
425    encodePUWise( pcCU, uiAbsPartIdx, bRD );
426  }
427}
428
429/** encode motion information for every PU block
430 * \param pcCU
431 * \param uiAbsPartIdx
432 * \param bRD
433 * \returns Void
434 */
435Void TEncEntropy::encodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
436{
437  if ( bRD )
438  {
439    uiAbsPartIdx = 0;
440  }
441 
442  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
443  UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) );
444  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
445  UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() - uiDepth ) << 1 ) ) >> 4;
446
447  for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset )
448  {
449    encodeMergeFlag( pcCU, uiSubPartIdx );
450    if ( pcCU->getMergeFlag( uiSubPartIdx ) )
451    {
452      encodeMergeIndex( pcCU, uiSubPartIdx );
453    }
454    else
455    {
456      encodeInterDirPU( pcCU, uiSubPartIdx );
457      for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
458      {
459        if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
460        {
461          encodeRefFrmIdxPU ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
462          encodeMvdPU       ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
463          encodeMVPIdxPU    ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
464        }
465      }
466    }
467  }
468
469  return;
470}
471
472Void TEncEntropy::encodeInterDirPU( TComDataCU* pcCU, UInt uiAbsPartIdx )
473{
474  if ( !pcCU->getSlice()->isInterB() )
475  {
476    return;
477  }
478
479  m_pcEntropyCoderIf->codeInterDir( pcCU, uiAbsPartIdx );
480  return;
481}
482
483/** encode reference frame index for a PU block
484 * \param pcCU
485 * \param uiAbsPartIdx
486 * \param eRefList
487 * \returns Void
488 */
489Void TEncEntropy::encodeRefFrmIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
490{
491  assert( !pcCU->isIntra( uiAbsPartIdx ) );
492  {
493    if ( ( pcCU->getSlice()->getNumRefIdx( eRefList ) == 1 ) )
494    {
495      return;
496    }
497
498    if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
499    {
500      m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, eRefList );
501    }
502  }
503
504  return;
505}
506
507/** encode motion vector difference for a PU block
508 * \param pcCU
509 * \param uiAbsPartIdx
510 * \param eRefList
511 * \returns Void
512 */
513Void TEncEntropy::encodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
514{
515  assert( !pcCU->isIntra( uiAbsPartIdx ) );
516
517  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
518  {
519    m_pcEntropyCoderIf->codeMvd( pcCU, uiAbsPartIdx, eRefList );
520  }
521  return;
522}
523
524Void TEncEntropy::encodeMVPIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
525{
526  if ( (pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList )) )
527  {
528    m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList );
529  }
530
531  return;
532}
533
534Void TEncEntropy::encodeQtCbf( TComDataCU* pcCU, UInt uiAbsPartIdx, TextType eType, UInt uiTrDepth )
535{
536  m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, eType, uiTrDepth );
537}
538
539Void TEncEntropy::encodeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx )
540{
541  m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSymbol, uiCtx );
542}
543
544Void TEncEntropy::encodeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx )
545{
546  m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
547}
548
549Void TEncEntropy::encodeQtCbfZero( TComDataCU* pcCU, TextType eType, UInt uiTrDepth )
550{
551  m_pcEntropyCoderIf->codeQtCbfZero( pcCU, eType, uiTrDepth );
552}
553Void TEncEntropy::encodeQtRootCbfZero( TComDataCU* pcCU )
554{
555  m_pcEntropyCoderIf->codeQtRootCbfZero( pcCU );
556}
557
558// dQP
559Void TEncEntropy::encodeQP( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
560{
561  if( bRD )
562  {
563    uiAbsPartIdx = 0;
564  }
565 
566  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
567  {
568    m_pcEntropyCoderIf->codeDeltaQP( pcCU, uiAbsPartIdx );
569  }
570}
571
572
573// texture
574/** encode coefficients
575 * \param pcCU
576 * \param uiAbsPartIdx
577 * \param uiDepth
578 * \param uiWidth
579 * \param uiHeight
580 */
581Void TEncEntropy::encodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, Bool& bCodeDQP )
582{
583  UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
584  UInt uiLumaOffset   = uiMinCoeffSize*uiAbsPartIdx;
585  UInt uiChromaOffset = uiLumaOffset>>2;
586   
587  if( pcCU->isIntra(uiAbsPartIdx) )
588  {
589    DTRACE_CABAC_VL( g_nSymbolCounter++ )
590    DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" )
591    DTRACE_CABAC_V( uiDepth )
592    DTRACE_CABAC_T( "\n" )
593  }
594  else
595  {
596    if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ) )
597    {
598      m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
599    }
600    if ( !pcCU->getQtRootCbf( uiAbsPartIdx ) )
601    {
602      return;
603    }
604  }
605 
606  xEncodeTransform( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, bCodeDQP);
607}
608
609Void TEncEntropy::encodeCoeffNxN( TComDataCU* pcCU, TCoeff* pcCoeff, UInt uiAbsPartIdx, UInt uiTrWidth, UInt uiTrHeight, UInt uiDepth, TextType eType )
610{
611  // This is for Transform unit processing. This may be used at mode selection stage for Inter.
612  m_pcEntropyCoderIf->codeCoeffNxN( pcCU, pcCoeff, uiAbsPartIdx, uiTrWidth, uiTrHeight, uiDepth, eType );
613}
614
615Void TEncEntropy::estimateBit (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, TextType eTType)
616{ 
617  eTType = eTType == TEXT_LUMA ? TEXT_LUMA : TEXT_CHROMA;
618 
619  m_pcEntropyCoderIf->estBit ( pcEstBitsSbac, width, height, eTType );
620}
621
622/** Encode SAO Offset
623 * \param  saoLcuParam SAO LCU paramters
624 */
625Void TEncEntropy::encodeSaoOffset(SaoLcuParam* saoLcuParam, UInt compIdx)
626{
627  UInt uiSymbol;
628  Int i;
629
630  uiSymbol = saoLcuParam->typeIdx + 1;
631  if (compIdx!=2)
632  {
633    m_pcEntropyCoderIf->codeSaoTypeIdx(uiSymbol);
634  }
635  if (uiSymbol)
636  {
637    if (saoLcuParam->typeIdx < 4 && compIdx != 2)
638    {
639      saoLcuParam->subTypeIdx = saoLcuParam->typeIdx;
640    }
641    Int bitDepth = compIdx ? g_bitDepthC : g_bitDepthY;
642    Int offsetTh = 1 << min(bitDepth - 5,5);
643    if( saoLcuParam->typeIdx == SAO_BO )
644    {
645      for( i=0; i< saoLcuParam->length; i++)
646      {
647        UInt absOffset = ( (saoLcuParam->offset[i] < 0) ? -saoLcuParam->offset[i] : saoLcuParam->offset[i]);
648        m_pcEntropyCoderIf->codeSaoMaxUvlc(absOffset, offsetTh-1);
649      } 
650      for( i=0; i< saoLcuParam->length; i++)
651      {
652        if (saoLcuParam->offset[i] != 0)
653        {
654          UInt sign = (saoLcuParam->offset[i] < 0) ? 1 : 0 ;
655          m_pcEntropyCoderIf->codeSAOSign(sign);
656        }
657      }
658      uiSymbol = (UInt) (saoLcuParam->subTypeIdx);
659      m_pcEntropyCoderIf->codeSaoUflc(5, uiSymbol);
660    }
661    else if( saoLcuParam->typeIdx < 4 )
662    {
663      m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[0], offsetTh-1);
664      m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[1], offsetTh-1);
665      m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[2], offsetTh-1);
666      m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[3], offsetTh-1);
667      if (compIdx!=2)
668      {
669        uiSymbol = (UInt) (saoLcuParam->subTypeIdx);
670        m_pcEntropyCoderIf->codeSaoUflc(2, uiSymbol);
671      }
672    }
673  }
674}
675
676/** Encode SAO unit interleaving
677* \param  rx
678* \param  ry
679* \param  pSaoParam
680* \param  pcCU
681* \param  iCUAddrInSlice
682* \param  iCUAddrUpInSlice
683* \param  bLFCrossSliceBoundaryFlag
684 */
685Void TEncEntropy::encodeSaoUnitInterleaving(Int compIdx, Bool saoFlag, Int rx, Int ry, SaoLcuParam* saoLcuParam, Int cuAddrInSlice, Int cuAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp)
686{
687  if (saoFlag)
688  {
689    if (rx>0 && cuAddrInSlice!=0 && allowMergeLeft)
690    {
691      m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeLeftFlag);
692    }
693    else
694    {
695      saoLcuParam->mergeLeftFlag = 0;
696    }
697    if (saoLcuParam->mergeLeftFlag == 0)
698    {
699      if ( (ry > 0) && (cuAddrUpInSlice>=0) && allowMergeUp )
700      {
701        m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeUpFlag);
702      }
703      else
704      {
705        saoLcuParam->mergeUpFlag = 0;
706      }
707      if (!saoLcuParam->mergeUpFlag)
708      {
709        encodeSaoOffset(saoLcuParam, compIdx);
710      }
711    }
712  }
713}
714
715Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
716{
717  Int count = 0;
718 
719  for ( Int i = 0; i < uiSize; i++ )
720  {
721    count += pcCoef[i] != 0;
722  }
723 
724  return count;
725}
726
727/** encode quantization matrix
728 * \param scalingList quantization matrix information
729 */
730Void TEncEntropy::encodeScalingList( TComScalingList* scalingList )
731{
732  m_pcEntropyCoderIf->codeScalingList( scalingList );
733}
734
735//! \}
Note: See TracBrowser for help on using the repository browser.