source: SHVCSoftware/branches/0.1.1-bugfix/source/Lib/TLibEncoder/TEncEntropy.cpp @ 8

Last change on this file since 8 was 6, checked in by seregin, 12 years ago

Correct IntraBL cost and fix for couple of compiler warnings.

File size: 27.5 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( ( !pcCU->isIntra( uiAbsPartIdx ) ) && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, 0 ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, 0 ) )
479#else   
480    if( pcCU->getPredictionMode(uiAbsPartIdx) != MODE_INTRA && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, 0 ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, 0 ) )
481#endif
482    {
483      assert( pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, 0 ) );
484      //      printf( "saved one bin! " );
485    }
486    else
487    {
488      m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA, uiLumaTrMode );
489    }
490
491
492    if ( cbfY || cbfU || cbfV )
493    {
494      // dQP: only for LCU once
495      if ( pcCU->getSlice()->getPPS()->getUseDQP() )
496      {
497        if ( bCodeDQP )
498        {
499          encodeQP( pcCU, m_bakAbsPartIdxCU );
500          bCodeDQP = false;
501        }
502      }
503    }
504    if( cbfY )
505    {
506      Int trWidth = width;
507      Int trHeight = height;
508#if !REMOVE_NSQT
509      pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight );
510#endif
511      m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffY()+offsetLuma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_LUMA );
512    }
513    if( uiLog2TrafoSize > 2 )
514    {
515      Int trWidth = width >> 1;
516      Int trHeight = height >> 1;
517#if !REMOVE_NSQT
518      pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight );
519#endif
520      if( cbfU )
521      {
522        m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
523      }
524      if( cbfV )
525      {
526        m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
527      }
528    }
529    else
530    {
531      UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 );
532      if( ( uiAbsPartIdx % partNum ) == (partNum - 1) )
533      {
534        Int trWidth = width;
535        Int trHeight = height;
536#if !REMOVE_NSQT
537        pcCU->getNSQTSize( uiTrIdx - 1, uiAbsPartIdx, trWidth, trHeight );
538#endif
539        if( cbfU )
540        {
541          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCb()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U );
542        }
543        if( cbfV )
544        {
545          m_pcEntropyCoderIf->codeCoeffNxN( pcCU, (pcCU->getCoeffCr()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V );
546        }
547      }
548    }
549  }
550}
551
552// Intra direction for Luma
553Void TEncEntropy::encodeIntraDirModeLuma  ( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiplePU )
554{
555  m_pcEntropyCoderIf->codeIntraDirLumaAng( pcCU, absPartIdx , isMultiplePU);
556}
557
558// Intra direction for Chroma
559Void TEncEntropy::encodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
560{
561  if( bRD )
562  {
563    uiAbsPartIdx = 0;
564  }
565 
566  m_pcEntropyCoderIf->codeIntraDirChroma( pcCU, uiAbsPartIdx );
567}
568
569Void TEncEntropy::encodePredInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
570{
571#if INTRA_BL
572  assert ( !pcCU->isIntraBL( uiAbsPartIdx ) );
573#endif
574  if( bRD )
575  {
576    uiAbsPartIdx = 0;
577  }
578  if( pcCU->isIntra( uiAbsPartIdx ) )                                 // If it is Intra mode, encode intra prediction mode.
579  {
580    encodeIntraDirModeLuma  ( pcCU, uiAbsPartIdx,true );
581    encodeIntraDirModeChroma( pcCU, uiAbsPartIdx, bRD );
582  }
583  else                                                                // if it is Inter mode, encode motion vector and reference index
584  {
585    encodePUWise( pcCU, uiAbsPartIdx, bRD );
586  }
587}
588
589/** encode motion information for every PU block
590 * \param pcCU
591 * \param uiAbsPartIdx
592 * \param bRD
593 * \returns Void
594 */
595Void TEncEntropy::encodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
596{
597  if ( bRD )
598  {
599    uiAbsPartIdx = 0;
600  }
601 
602  PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx );
603  UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) );
604  UInt uiDepth = pcCU->getDepth( uiAbsPartIdx );
605  UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() - uiDepth ) << 1 ) ) >> 4;
606
607  for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset )
608  {
609    encodeMergeFlag( pcCU, uiSubPartIdx, uiPartIdx );
610    if ( pcCU->getMergeFlag( uiSubPartIdx ) )
611    {
612      encodeMergeIndex( pcCU, uiSubPartIdx, uiPartIdx );
613    }
614    else
615    {
616      encodeInterDirPU( pcCU, uiSubPartIdx );
617      for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
618      {
619        if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )
620        {
621          encodeRefFrmIdxPU ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
622          encodeMvdPU       ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
623          encodeMVPIdxPU    ( pcCU, uiSubPartIdx, RefPicList( uiRefListIdx ) );
624        }
625      }
626    }
627  }
628
629  return;
630}
631
632Void TEncEntropy::encodeInterDirPU( TComDataCU* pcCU, UInt uiAbsPartIdx )
633{
634  if ( !pcCU->getSlice()->isInterB() )
635  {
636    return;
637  }
638
639  m_pcEntropyCoderIf->codeInterDir( pcCU, uiAbsPartIdx );
640  return;
641}
642
643/** encode reference frame index for a PU block
644 * \param pcCU
645 * \param uiAbsPartIdx
646 * \param eRefList
647 * \returns Void
648 */
649Void TEncEntropy::encodeRefFrmIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
650{
651  assert( !pcCU->isIntra( uiAbsPartIdx ) );
652  {
653    if ( ( pcCU->getSlice()->getNumRefIdx( eRefList ) == 1 ) )
654    {
655      return;
656    }
657
658    if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
659    {
660      m_pcEntropyCoderIf->codeRefFrmIdx( pcCU, uiAbsPartIdx, eRefList );
661    }
662  }
663
664  return;
665}
666
667/** encode motion vector difference for a PU block
668 * \param pcCU
669 * \param uiAbsPartIdx
670 * \param eRefList
671 * \returns Void
672 */
673Void TEncEntropy::encodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
674{
675  assert( !pcCU->isIntra( uiAbsPartIdx ) );
676
677  if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) )
678  {
679    m_pcEntropyCoderIf->codeMvd( pcCU, uiAbsPartIdx, eRefList );
680  }
681  return;
682}
683
684Void TEncEntropy::encodeMVPIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
685{
686#if !SPS_AMVP_CLEANUP
687  if ( (pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList )) && (pcCU->getAMVPMode(uiAbsPartIdx) == AM_EXPL) )
688#else
689  if ( (pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList )) )
690#endif
691  {
692    m_pcEntropyCoderIf->codeMVPIdx( pcCU, uiAbsPartIdx, eRefList );
693  }
694
695  return;
696}
697
698Void TEncEntropy::encodeQtCbf( TComDataCU* pcCU, UInt uiAbsPartIdx, TextType eType, UInt uiTrDepth )
699{
700  m_pcEntropyCoderIf->codeQtCbf( pcCU, uiAbsPartIdx, eType, uiTrDepth );
701}
702
703Void TEncEntropy::encodeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx )
704{
705  m_pcEntropyCoderIf->codeTransformSubdivFlag( uiSymbol, uiCtx );
706}
707
708Void TEncEntropy::encodeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx )
709{
710  m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
711}
712
713#if TU_ZERO_CBF_RDO
714Void TEncEntropy::encodeQtCbfZero( TComDataCU* pcCU, UInt uiAbsPartIdx, TextType eType, UInt uiTrDepth )
715{
716  m_pcEntropyCoderIf->codeQtCbfZero( pcCU, uiAbsPartIdx, eType, uiTrDepth );
717}
718Void TEncEntropy::encodeQtRootCbfZero( TComDataCU* pcCU, UInt uiAbsPartIdx )
719{
720  m_pcEntropyCoderIf->codeQtRootCbfZero( pcCU, uiAbsPartIdx );
721}
722#endif
723
724// dQP
725Void TEncEntropy::encodeQP( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
726{
727  if( bRD )
728  {
729    uiAbsPartIdx = 0;
730  }
731 
732  if ( pcCU->getSlice()->getPPS()->getUseDQP() )
733  {
734    m_pcEntropyCoderIf->codeDeltaQP( pcCU, uiAbsPartIdx );
735  }
736}
737
738
739// texture
740/** encode coefficients
741 * \param pcCU
742 * \param uiAbsPartIdx
743 * \param uiDepth
744 * \param uiWidth
745 * \param uiHeight
746 */
747Void TEncEntropy::encodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, Bool& bCodeDQP )
748{
749  UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
750  UInt uiLumaOffset   = uiMinCoeffSize*uiAbsPartIdx;
751  UInt uiChromaOffset = uiLumaOffset>>2;
752 
753  UInt uiLumaTrMode, uiChromaTrMode;
754  pcCU->convertTransIdx( uiAbsPartIdx, pcCU->getTransformIdx(uiAbsPartIdx), uiLumaTrMode, uiChromaTrMode );
755 
756  if( pcCU->isIntra(uiAbsPartIdx) )
757  {
758    DTRACE_CABAC_VL( g_nSymbolCounter++ )
759    DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" )
760    DTRACE_CABAC_V( uiDepth )
761    DTRACE_CABAC_T( "\n" )
762  }
763  else
764  {
765    if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ) )
766    {
767      m_pcEntropyCoderIf->codeQtRootCbf( pcCU, uiAbsPartIdx );
768    }
769    if ( !pcCU->getQtRootCbf( uiAbsPartIdx ) )
770    {
771#if !REMOVE_NSQT
772      pcCU->setNSQTIdxSubParts( uiAbsPartIdx, uiDepth );
773#endif
774      return;
775    }
776  }
777 
778  xEncodeTransform( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, 0, bCodeDQP);
779}
780
781Void TEncEntropy::encodeCoeffNxN( TComDataCU* pcCU, TCoeff* pcCoeff, UInt uiAbsPartIdx, UInt uiTrWidth, UInt uiTrHeight, UInt uiDepth, TextType eType )
782{
783  // This is for Transform unit processing. This may be used at mode selection stage for Inter.
784  m_pcEntropyCoderIf->codeCoeffNxN( pcCU, pcCoeff, uiAbsPartIdx, uiTrWidth, uiTrHeight, uiDepth, eType );
785}
786
787Void TEncEntropy::estimateBit (estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, TextType eTType)
788{ 
789  eTType = eTType == TEXT_LUMA ? TEXT_LUMA : TEXT_CHROMA;
790 
791  m_pcEntropyCoderIf->estBit ( pcEstBitsSbac, width, height, eTType );
792}
793
794/** Encode SAO Offset
795 * \param  saoLcuParam SAO LCU paramters
796 */
797#if SAO_TYPE_SHARING
798Void TEncEntropy::encodeSaoOffset(SaoLcuParam* saoLcuParam, UInt compIdx)
799#else
800Void TEncEntropy::encodeSaoOffset(SaoLcuParam* saoLcuParam)
801#endif
802{
803  UInt uiSymbol;
804  Int i;
805
806  uiSymbol = saoLcuParam->typeIdx + 1;
807#if SAO_TYPE_SHARING
808  if (compIdx!=2)
809  {
810    m_pcEntropyCoderIf->codeSaoTypeIdx(uiSymbol);
811  }
812#else
813  m_pcEntropyCoderIf->codeSaoTypeIdx(uiSymbol);
814#endif
815  if (uiSymbol)
816  {
817#if SAO_TYPE_CODING
818#if SAO_TYPE_SHARING
819    if (saoLcuParam->typeIdx < 4 && compIdx != 2)
820#else
821    if (saoLcuParam->typeIdx < 4)
822#endif
823    {
824      saoLcuParam->subTypeIdx = saoLcuParam->typeIdx;
825    }
826#endif
827#if FULL_NBIT
828    Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + (g_uiBitDepth-8)-5),5) );
829#else
830    Int offsetTh = 1 << ( min((Int)(g_uiBitDepth + g_uiBitIncrement-5),5) );
831#endif
832    if( saoLcuParam->typeIdx == SAO_BO )
833    {
834#if !SAO_TYPE_CODING
835      // Code Left Band Index
836      uiSymbol = (UInt) (saoLcuParam->bandPosition);
837      m_pcEntropyCoderIf->codeSaoUflc(uiSymbol);
838#endif
839      for( i=0; i< saoLcuParam->length; i++)
840      {
841        UInt absOffset = ( (saoLcuParam->offset[i] < 0) ? -saoLcuParam->offset[i] : saoLcuParam->offset[i]);
842        m_pcEntropyCoderIf->codeSaoMaxUvlc(absOffset, offsetTh-1);
843      } 
844      for( i=0; i< saoLcuParam->length; i++)
845      {
846        if (saoLcuParam->offset[i] != 0)
847        {
848          UInt sign = (saoLcuParam->offset[i] < 0) ? 1 : 0 ;
849          m_pcEntropyCoderIf->codeSAOSign(sign);
850        }
851      }
852#if SAO_TYPE_CODING
853      uiSymbol = (UInt) (saoLcuParam->subTypeIdx);
854      m_pcEntropyCoderIf->codeSaoUflc(5, uiSymbol);
855#endif
856    }
857    else if( saoLcuParam->typeIdx < 4 )
858    {
859      m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[0], offsetTh-1);
860      m_pcEntropyCoderIf->codeSaoMaxUvlc( saoLcuParam->offset[1], offsetTh-1);
861      m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[2], offsetTh-1);
862      m_pcEntropyCoderIf->codeSaoMaxUvlc(-saoLcuParam->offset[3], offsetTh-1);
863#if SAO_TYPE_CODING
864#if SAO_TYPE_SHARING
865      if (compIdx!=2)
866      {
867        uiSymbol = (UInt) (saoLcuParam->subTypeIdx);
868        m_pcEntropyCoderIf->codeSaoUflc(2, uiSymbol);
869      }
870#else
871     uiSymbol = (UInt) (saoLcuParam->subTypeIdx);
872     m_pcEntropyCoderIf->codeSaoUflc(2, uiSymbol);
873#endif
874#endif
875    }
876  }
877}
878
879/** Encode SAO unit interleaving
880* \param  rx
881* \param  ry
882* \param  pSaoParam
883* \param  pcCU
884* \param  iCUAddrInSlice
885* \param  iCUAddrUpInSlice
886* \param  bLFCrossSliceBoundaryFlag
887 */
888Void TEncEntropy::encodeSaoUnitInterleaving(Int compIdx, Bool saoFlag, Int rx, Int ry, SaoLcuParam* saoLcuParam, Int cuAddrInSlice, Int cuAddrUpInSlice, Int allowMergeLeft, Int allowMergeUp)
889{
890  if (saoFlag)
891  {
892    if (rx>0 && cuAddrInSlice!=0 && allowMergeLeft)
893    {
894#if SAO_MERGE_ONE_CTX
895      m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeLeftFlag);
896#else
897      m_pcEntropyCoderIf->codeSaoMergeLeft(saoLcuParam->mergeLeftFlag,compIdx);
898#endif
899    }
900    else
901    {
902      saoLcuParam->mergeLeftFlag = 0;
903    }
904    if (saoLcuParam->mergeLeftFlag == 0)
905    {
906      if ( (ry > 0) && (cuAddrUpInSlice>=0) && allowMergeUp )
907      {
908#if SAO_MERGE_ONE_CTX
909        m_pcEntropyCoderIf->codeSaoMerge(saoLcuParam->mergeUpFlag);
910#else
911        m_pcEntropyCoderIf->codeSaoMergeUp(saoLcuParam->mergeUpFlag);
912#endif
913      }
914      else
915      {
916        saoLcuParam->mergeUpFlag = 0;
917      }
918      if (!saoLcuParam->mergeUpFlag)
919      {
920#if SAO_TYPE_SHARING
921        encodeSaoOffset(saoLcuParam, compIdx);
922#else
923        encodeSaoOffset(saoLcuParam);
924#endif
925      }
926    }
927  }
928}
929
930Int TEncEntropy::countNonZeroCoeffs( TCoeff* pcCoef, UInt uiSize )
931{
932  Int count = 0;
933 
934  for ( Int i = 0; i < uiSize; i++ )
935  {
936    count += pcCoef[i] != 0;
937  }
938 
939  return count;
940}
941
942/** encode quantization matrix
943 * \param scalingList quantization matrix information
944 */
945Void TEncEntropy::encodeScalingList( TComScalingList* scalingList )
946{
947  m_pcEntropyCoderIf->codeScalingList( scalingList );
948}
949
950//! \}
Note: See TracBrowser for help on using the repository browser.