source: SHVCSoftware/branches/SHM-1.1-dev/source/Lib/TLibEncoder/TEncEntropy.cpp @ 35

Last change on this file since 35 was 17, checked in by seregin, 12 years ago

NO_RESIDUAL_FLAG_FOR_BLPRED: Root cbf for Intra_BL (L0437)

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