source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncSbac.cpp @ 718

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

merge with SHM-6-dev

  • Property svn:eol-style set to native
File size: 57.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-2014, 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     TEncSbac.cpp
35    \brief    SBAC encoder class
36*/
37
38#include "TEncTop.h"
39#include "TEncSbac.h"
40
41#include <map>
42#include <algorithm>
43
44//! \ingroup TLibEncoder
45//! \{
46
47// ====================================================================================================================
48// Constructor / destructor / create / destroy
49// ====================================================================================================================
50
51TEncSbac::TEncSbac()
52// new structure here
53: m_pcBitIf                   ( NULL )
54, m_pcSlice                   ( NULL )
55, m_pcBinIf                   ( NULL )
56, m_uiCoeffCost               ( 0 )
57, m_numContextModels          ( 0 )
58, m_cCUSplitFlagSCModel       ( 1,             1,               NUM_SPLIT_FLAG_CTX            , m_contextModels + m_numContextModels, m_numContextModels )
59, m_cCUSkipFlagSCModel        ( 1,             1,               NUM_SKIP_FLAG_CTX             , m_contextModels + m_numContextModels, m_numContextModels)
60, m_cCUMergeFlagExtSCModel    ( 1,             1,               NUM_MERGE_FLAG_EXT_CTX        , m_contextModels + m_numContextModels, m_numContextModels)
61, m_cCUMergeIdxExtSCModel     ( 1,             1,               NUM_MERGE_IDX_EXT_CTX         , m_contextModels + m_numContextModels, m_numContextModels)
62, m_cCUPartSizeSCModel        ( 1,             1,               NUM_PART_SIZE_CTX             , m_contextModels + m_numContextModels, m_numContextModels)
63, m_cCUPredModeSCModel        ( 1,             1,               NUM_PRED_MODE_CTX             , m_contextModels + m_numContextModels, m_numContextModels)
64, m_cCUIntraPredSCModel       ( 1,             1,               NUM_ADI_CTX                   , m_contextModels + m_numContextModels, m_numContextModels)
65, m_cCUChromaPredSCModel      ( 1,             1,               NUM_CHROMA_PRED_CTX           , m_contextModels + m_numContextModels, m_numContextModels)
66, m_cCUDeltaQpSCModel         ( 1,             1,               NUM_DELTA_QP_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
67, m_cCUInterDirSCModel        ( 1,             1,               NUM_INTER_DIR_CTX             , m_contextModels + m_numContextModels, m_numContextModels)
68, m_cCURefPicSCModel          ( 1,             1,               NUM_REF_NO_CTX                , m_contextModels + m_numContextModels, m_numContextModels)
69, m_cCUMvdSCModel             ( 1,             1,               NUM_MV_RES_CTX                , m_contextModels + m_numContextModels, m_numContextModels)
70, m_cCUQtCbfSCModel           ( 1,             2,               NUM_QT_CBF_CTX                , m_contextModels + m_numContextModels, m_numContextModels)
71, m_cCUTransSubdivFlagSCModel ( 1,             1,               NUM_TRANS_SUBDIV_FLAG_CTX     , m_contextModels + m_numContextModels, m_numContextModels)
72, m_cCUQtRootCbfSCModel       ( 1,             1,               NUM_QT_ROOT_CBF_CTX           , m_contextModels + m_numContextModels, m_numContextModels)
73, m_cCUSigCoeffGroupSCModel   ( 1,             2,               NUM_SIG_CG_FLAG_CTX           , m_contextModels + m_numContextModels, m_numContextModels)
74, m_cCUSigSCModel             ( 1,             1,               NUM_SIG_FLAG_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
75, m_cCuCtxLastX               ( 1,             2,               NUM_CTX_LAST_FLAG_XY          , m_contextModels + m_numContextModels, m_numContextModels)
76, m_cCuCtxLastY               ( 1,             2,               NUM_CTX_LAST_FLAG_XY          , m_contextModels + m_numContextModels, m_numContextModels)
77, m_cCUOneSCModel             ( 1,             1,               NUM_ONE_FLAG_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
78, m_cCUAbsSCModel             ( 1,             1,               NUM_ABS_FLAG_CTX              , m_contextModels + m_numContextModels, m_numContextModels)
79, m_cMVPIdxSCModel            ( 1,             1,               NUM_MVP_IDX_CTX               , m_contextModels + m_numContextModels, m_numContextModels)
80, m_cSaoMergeSCModel          ( 1,             1,               NUM_SAO_MERGE_FLAG_CTX   , m_contextModels + m_numContextModels, m_numContextModels)
81, m_cSaoTypeIdxSCModel        ( 1,             1,               NUM_SAO_TYPE_IDX_CTX          , m_contextModels + m_numContextModels, m_numContextModels)
82, m_cTransformSkipSCModel     ( 1,             2,               NUM_TRANSFORMSKIP_FLAG_CTX    , m_contextModels + m_numContextModels, m_numContextModels)
83, m_CUTransquantBypassFlagSCModel( 1,          1,               NUM_CU_TRANSQUANT_BYPASS_FLAG_CTX, m_contextModels + m_numContextModels, m_numContextModels)
84{
85  assert( m_numContextModels <= MAX_NUM_CTX_MOD );
86}
87
88TEncSbac::~TEncSbac()
89{
90}
91
92// ====================================================================================================================
93// Public member functions
94// ====================================================================================================================
95
96Void TEncSbac::resetEntropy           ()
97{
98  Int  iQp              = m_pcSlice->getSliceQp();
99  SliceType eSliceType  = m_pcSlice->getSliceType();
100 
101  Int  encCABACTableIdx = m_pcSlice->getPPS()->getEncCABACTableIdx();
102  if (!m_pcSlice->isIntra() && (encCABACTableIdx==B_SLICE || encCABACTableIdx==P_SLICE) && m_pcSlice->getPPS()->getCabacInitPresentFlag())
103  {
104    eSliceType = (SliceType) encCABACTableIdx;
105  }
106
107  m_cCUSplitFlagSCModel.initBuffer       ( eSliceType, iQp, (UChar*)INIT_SPLIT_FLAG );
108 
109  m_cCUSkipFlagSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SKIP_FLAG );
110  m_cCUMergeFlagExtSCModel.initBuffer    ( eSliceType, iQp, (UChar*)INIT_MERGE_FLAG_EXT);
111  m_cCUMergeIdxExtSCModel.initBuffer     ( eSliceType, iQp, (UChar*)INIT_MERGE_IDX_EXT);
112  m_cCUPartSizeSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_PART_SIZE );
113  m_cCUPredModeSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_PRED_MODE );
114  m_cCUIntraPredSCModel.initBuffer       ( eSliceType, iQp, (UChar*)INIT_INTRA_PRED_MODE );
115  m_cCUChromaPredSCModel.initBuffer      ( eSliceType, iQp, (UChar*)INIT_CHROMA_PRED_MODE );
116  m_cCUInterDirSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_INTER_DIR );
117  m_cCUMvdSCModel.initBuffer             ( eSliceType, iQp, (UChar*)INIT_MVD );
118  m_cCURefPicSCModel.initBuffer          ( eSliceType, iQp, (UChar*)INIT_REF_PIC );
119  m_cCUDeltaQpSCModel.initBuffer         ( eSliceType, iQp, (UChar*)INIT_DQP );
120  m_cCUQtCbfSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_QT_CBF );
121  m_cCUQtRootCbfSCModel.initBuffer       ( eSliceType, iQp, (UChar*)INIT_QT_ROOT_CBF );
122  m_cCUSigCoeffGroupSCModel.initBuffer   ( eSliceType, iQp, (UChar*)INIT_SIG_CG_FLAG );
123  m_cCUSigSCModel.initBuffer             ( eSliceType, iQp, (UChar*)INIT_SIG_FLAG );
124  m_cCuCtxLastX.initBuffer               ( eSliceType, iQp, (UChar*)INIT_LAST );
125  m_cCuCtxLastY.initBuffer               ( eSliceType, iQp, (UChar*)INIT_LAST );
126  m_cCUOneSCModel.initBuffer             ( eSliceType, iQp, (UChar*)INIT_ONE_FLAG );
127  m_cCUAbsSCModel.initBuffer             ( eSliceType, iQp, (UChar*)INIT_ABS_FLAG );
128  m_cMVPIdxSCModel.initBuffer            ( eSliceType, iQp, (UChar*)INIT_MVP_IDX );
129  m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANS_SUBDIV_FLAG );
130  m_cSaoMergeSCModel.initBuffer      ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_FLAG );
131  m_cSaoTypeIdxSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX );
132  m_cTransformSkipSCModel.initBuffer     ( eSliceType, iQp, (UChar*)INIT_TRANSFORMSKIP_FLAG );
133  m_CUTransquantBypassFlagSCModel.initBuffer( eSliceType, iQp, (UChar*)INIT_CU_TRANSQUANT_BYPASS_FLAG );
134  // new structure
135  m_uiLastQp = iQp;
136 
137  m_pcBinIf->start();
138 
139  return;
140}
141
142/** The function does the following:
143 * If current slice type is P/B then it determines the distance of initialisation type 1 and 2 from the current CABAC states and
144 * stores the index of the closest table.  This index is used for the next P/B slice when cabac_init_present_flag is true.
145 */
146Void TEncSbac::determineCabacInitIdx()
147{
148  Int  qp              = m_pcSlice->getSliceQp();
149
150  if (!m_pcSlice->isIntra())
151  {
152    SliceType aSliceTypeChoices[] = {B_SLICE, P_SLICE};
153
154    UInt bestCost             = MAX_UINT;
155    SliceType bestSliceType   = aSliceTypeChoices[0];
156    for (UInt idx=0; idx<2; idx++)
157    {
158      UInt curCost          = 0;
159      SliceType curSliceType  = aSliceTypeChoices[idx];
160
161      curCost  = m_cCUSplitFlagSCModel.calcCost       ( curSliceType, qp, (UChar*)INIT_SPLIT_FLAG );
162      curCost += m_cCUSkipFlagSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_SKIP_FLAG );
163      curCost += m_cCUMergeFlagExtSCModel.calcCost    ( curSliceType, qp, (UChar*)INIT_MERGE_FLAG_EXT);
164      curCost += m_cCUMergeIdxExtSCModel.calcCost     ( curSliceType, qp, (UChar*)INIT_MERGE_IDX_EXT);
165      curCost += m_cCUPartSizeSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_PART_SIZE );
166      curCost += m_cCUPredModeSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_PRED_MODE );
167      curCost += m_cCUIntraPredSCModel.calcCost       ( curSliceType, qp, (UChar*)INIT_INTRA_PRED_MODE );
168      curCost += m_cCUChromaPredSCModel.calcCost      ( curSliceType, qp, (UChar*)INIT_CHROMA_PRED_MODE );
169      curCost += m_cCUInterDirSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_INTER_DIR );
170      curCost += m_cCUMvdSCModel.calcCost             ( curSliceType, qp, (UChar*)INIT_MVD );
171      curCost += m_cCURefPicSCModel.calcCost          ( curSliceType, qp, (UChar*)INIT_REF_PIC );
172      curCost += m_cCUDeltaQpSCModel.calcCost         ( curSliceType, qp, (UChar*)INIT_DQP );
173      curCost += m_cCUQtCbfSCModel.calcCost           ( curSliceType, qp, (UChar*)INIT_QT_CBF );
174      curCost += m_cCUQtRootCbfSCModel.calcCost       ( curSliceType, qp, (UChar*)INIT_QT_ROOT_CBF );
175      curCost += m_cCUSigCoeffGroupSCModel.calcCost   ( curSliceType, qp, (UChar*)INIT_SIG_CG_FLAG );
176      curCost += m_cCUSigSCModel.calcCost             ( curSliceType, qp, (UChar*)INIT_SIG_FLAG );
177      curCost += m_cCuCtxLastX.calcCost               ( curSliceType, qp, (UChar*)INIT_LAST );
178      curCost += m_cCuCtxLastY.calcCost               ( curSliceType, qp, (UChar*)INIT_LAST );
179      curCost += m_cCUOneSCModel.calcCost             ( curSliceType, qp, (UChar*)INIT_ONE_FLAG );
180      curCost += m_cCUAbsSCModel.calcCost             ( curSliceType, qp, (UChar*)INIT_ABS_FLAG );
181      curCost += m_cMVPIdxSCModel.calcCost            ( curSliceType, qp, (UChar*)INIT_MVP_IDX );
182      curCost += m_cCUTransSubdivFlagSCModel.calcCost ( curSliceType, qp, (UChar*)INIT_TRANS_SUBDIV_FLAG );
183      curCost += m_cSaoMergeSCModel.calcCost      ( curSliceType, qp, (UChar*)INIT_SAO_MERGE_FLAG );
184      curCost += m_cSaoTypeIdxSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_SAO_TYPE_IDX );
185      curCost += m_cTransformSkipSCModel.calcCost     ( curSliceType, qp, (UChar*)INIT_TRANSFORMSKIP_FLAG );
186      curCost += m_CUTransquantBypassFlagSCModel.calcCost( curSliceType, qp, (UChar*)INIT_CU_TRANSQUANT_BYPASS_FLAG );
187      if (curCost < bestCost)
188      {
189        bestSliceType = curSliceType;
190        bestCost      = curCost;
191      }
192    }
193    m_pcSlice->getPPS()->setEncCABACTableIdx( bestSliceType );
194  }
195  else
196  {
197    m_pcSlice->getPPS()->setEncCABACTableIdx( I_SLICE );
198  } 
199}
200
201
202/** The function does the followng: Write out terminate bit. Flush CABAC. Intialize CABAC states. Start CABAC.
203 */
204Void TEncSbac::updateContextTables( SliceType eSliceType, Int iQp, Bool bExecuteFinish )
205{
206  m_pcBinIf->encodeBinTrm(1);
207  if (bExecuteFinish) m_pcBinIf->finish();
208  m_cCUSplitFlagSCModel.initBuffer       ( eSliceType, iQp, (UChar*)INIT_SPLIT_FLAG );
209 
210  m_cCUSkipFlagSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SKIP_FLAG );
211  m_cCUMergeFlagExtSCModel.initBuffer    ( eSliceType, iQp, (UChar*)INIT_MERGE_FLAG_EXT);
212  m_cCUMergeIdxExtSCModel.initBuffer     ( eSliceType, iQp, (UChar*)INIT_MERGE_IDX_EXT);
213  m_cCUPartSizeSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_PART_SIZE );
214  m_cCUPredModeSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_PRED_MODE );
215  m_cCUIntraPredSCModel.initBuffer       ( eSliceType, iQp, (UChar*)INIT_INTRA_PRED_MODE );
216  m_cCUChromaPredSCModel.initBuffer      ( eSliceType, iQp, (UChar*)INIT_CHROMA_PRED_MODE );
217  m_cCUInterDirSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_INTER_DIR );
218  m_cCUMvdSCModel.initBuffer             ( eSliceType, iQp, (UChar*)INIT_MVD );
219  m_cCURefPicSCModel.initBuffer          ( eSliceType, iQp, (UChar*)INIT_REF_PIC );
220  m_cCUDeltaQpSCModel.initBuffer         ( eSliceType, iQp, (UChar*)INIT_DQP );
221  m_cCUQtCbfSCModel.initBuffer           ( eSliceType, iQp, (UChar*)INIT_QT_CBF );
222  m_cCUQtRootCbfSCModel.initBuffer       ( eSliceType, iQp, (UChar*)INIT_QT_ROOT_CBF );
223  m_cCUSigCoeffGroupSCModel.initBuffer   ( eSliceType, iQp, (UChar*)INIT_SIG_CG_FLAG );
224  m_cCUSigSCModel.initBuffer             ( eSliceType, iQp, (UChar*)INIT_SIG_FLAG );
225  m_cCuCtxLastX.initBuffer               ( eSliceType, iQp, (UChar*)INIT_LAST );
226  m_cCuCtxLastY.initBuffer               ( eSliceType, iQp, (UChar*)INIT_LAST );
227  m_cCUOneSCModel.initBuffer             ( eSliceType, iQp, (UChar*)INIT_ONE_FLAG );
228  m_cCUAbsSCModel.initBuffer             ( eSliceType, iQp, (UChar*)INIT_ABS_FLAG );
229  m_cMVPIdxSCModel.initBuffer            ( eSliceType, iQp, (UChar*)INIT_MVP_IDX );
230  m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (UChar*)INIT_TRANS_SUBDIV_FLAG );
231  m_cSaoMergeSCModel.initBuffer      ( eSliceType, iQp, (UChar*)INIT_SAO_MERGE_FLAG );
232  m_cSaoTypeIdxSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_SAO_TYPE_IDX );
233  m_cTransformSkipSCModel.initBuffer     ( eSliceType, iQp, (UChar*)INIT_TRANSFORMSKIP_FLAG );
234  m_CUTransquantBypassFlagSCModel.initBuffer( eSliceType, iQp, (UChar*)INIT_CU_TRANSQUANT_BYPASS_FLAG );
235  m_pcBinIf->start();
236}
237
238Void TEncSbac::codeVPS( TComVPS* pcVPS )
239{
240  assert (0);
241  return;
242}
243
244Void TEncSbac::codeSPS( TComSPS* pcSPS )
245{
246  assert (0);
247  return;
248}
249
250Void TEncSbac::codePPS( TComPPS* pcPPS
251#if Q0048_CGS_3D_ASYMLUT
252  , TEnc3DAsymLUT * pc3DAsymLUT
253#endif
254  )
255{
256  assert (0);
257  return;
258}
259
260Void TEncSbac::codeSliceHeader( TComSlice* pcSlice )
261{
262  assert (0);
263  return;
264}
265
266Void TEncSbac::codeTilesWPPEntryPoint( TComSlice* pSlice )
267{
268  assert (0);
269  return;
270}
271
272#if POC_RESET_IDC_SIGNALLING
273Void  TEncSbac::codeSliceHeaderExtn( TComSlice* pSlice, Int shBitsWrittenTillNow )
274{
275  assert (0);
276  return;
277}
278#endif
279Void TEncSbac::codeTerminatingBit( UInt uilsLast )
280{
281  m_pcBinIf->encodeBinTrm( uilsLast );
282}
283
284Void TEncSbac::codeSliceFinish()
285{
286  m_pcBinIf->finish();
287}
288
289Void TEncSbac::xWriteUnarySymbol( UInt uiSymbol, ContextModel* pcSCModel, Int iOffset )
290{
291  m_pcBinIf->encodeBin( uiSymbol ? 1 : 0, pcSCModel[0] );
292 
293  if( 0 == uiSymbol)
294  {
295    return;
296  }
297 
298  while( uiSymbol-- )
299  {
300    m_pcBinIf->encodeBin( uiSymbol ? 1 : 0, pcSCModel[ iOffset ] );
301  }
302 
303  return;
304}
305
306Void TEncSbac::xWriteUnaryMaxSymbol( UInt uiSymbol, ContextModel* pcSCModel, Int iOffset, UInt uiMaxSymbol )
307{
308  if (uiMaxSymbol == 0)
309  {
310    return;
311  }
312 
313  m_pcBinIf->encodeBin( uiSymbol ? 1 : 0, pcSCModel[ 0 ] );
314 
315  if ( uiSymbol == 0 )
316  {
317    return;
318  }
319 
320  Bool bCodeLast = ( uiMaxSymbol > uiSymbol );
321 
322  while( --uiSymbol )
323  {
324    m_pcBinIf->encodeBin( 1, pcSCModel[ iOffset ] );
325  }
326  if( bCodeLast )
327  {
328    m_pcBinIf->encodeBin( 0, pcSCModel[ iOffset ] );
329  }
330 
331  return;
332}
333
334Void TEncSbac::xWriteEpExGolomb( UInt uiSymbol, UInt uiCount )
335{
336  UInt bins = 0;
337  Int numBins = 0;
338 
339  while( uiSymbol >= (UInt)(1<<uiCount) )
340  {
341    bins = 2 * bins + 1;
342    numBins++;
343    uiSymbol -= 1 << uiCount;
344    uiCount  ++;
345  }
346  bins = 2 * bins + 0;
347  numBins++;
348 
349  bins = (bins << uiCount) | uiSymbol;
350  numBins += uiCount;
351 
352  assert( numBins <= 32 );
353  m_pcBinIf->encodeBinsEP( bins, numBins );
354}
355
356/** Coding of coeff_abs_level_minus3
357 * \param uiSymbol value of coeff_abs_level_minus3
358 * \param ruiGoRiceParam reference to Rice parameter
359 * \returns Void
360 */
361Void TEncSbac::xWriteCoefRemainExGolomb ( UInt symbol, UInt &rParam )
362{
363  Int codeNumber  = (Int)symbol;
364  UInt length;
365  if (codeNumber < (COEF_REMAIN_BIN_REDUCTION << rParam))
366  {
367    length = codeNumber>>rParam;
368    m_pcBinIf->encodeBinsEP( (1<<(length+1))-2 , length+1);
369    m_pcBinIf->encodeBinsEP((codeNumber%(1<<rParam)),rParam);
370  }
371  else
372  {
373    length = rParam;
374    codeNumber  = codeNumber - ( COEF_REMAIN_BIN_REDUCTION << rParam);
375    while (codeNumber >= (1<<length))
376    {
377      codeNumber -=  (1<<(length++));   
378    }
379    m_pcBinIf->encodeBinsEP((1<<(COEF_REMAIN_BIN_REDUCTION+length+1-rParam))-2,COEF_REMAIN_BIN_REDUCTION+length+1-rParam);
380    m_pcBinIf->encodeBinsEP(codeNumber,length);
381  }
382}
383
384// SBAC RD
385Void  TEncSbac::load ( TEncSbac* pSrc)
386{
387  this->xCopyFrom(pSrc);
388}
389
390Void  TEncSbac::loadIntraDirModeLuma( TEncSbac* pSrc)
391{
392  m_pcBinIf->copyState( pSrc->m_pcBinIf );
393 
394  this->m_cCUIntraPredSCModel      .copyFrom( &pSrc->m_cCUIntraPredSCModel       );
395}
396
397
398Void  TEncSbac::store( TEncSbac* pDest)
399{
400  pDest->xCopyFrom( this );
401}
402
403
404Void TEncSbac::xCopyFrom( TEncSbac* pSrc )
405{
406  m_pcBinIf->copyState( pSrc->m_pcBinIf );
407 
408  this->m_uiCoeffCost = pSrc->m_uiCoeffCost;
409  this->m_uiLastQp    = pSrc->m_uiLastQp;
410 
411  memcpy( m_contextModels, pSrc->m_contextModels, m_numContextModels * sizeof( ContextModel ) );
412}
413
414Void TEncSbac::codeMVPIdx ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
415{
416  Int iSymbol = pcCU->getMVPIdx(eRefList, uiAbsPartIdx);
417  Int iNum = AMVP_MAX_NUM_CANDS;
418
419  xWriteUnaryMaxSymbol(iSymbol, m_cMVPIdxSCModel.get(0), 1, iNum-1);
420}
421
422Void TEncSbac::codePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
423{
424  PartSize eSize         = pcCU->getPartitionSize( uiAbsPartIdx );
425  if ( pcCU->isIntra( uiAbsPartIdx ) )
426  {
427    if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth )
428    {
429      m_pcBinIf->encodeBin( eSize == SIZE_2Nx2N? 1 : 0, m_cCUPartSizeSCModel.get( 0, 0, 0 ) );
430    }
431    return;
432  }
433 
434  switch(eSize)
435  {
436    case SIZE_2Nx2N:
437    {
438      m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 0) );
439      break;
440    }
441    case SIZE_2NxN:
442    case SIZE_2NxnU:
443    case SIZE_2NxnD:
444    {
445      m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) );
446      m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 1) );
447      if ( pcCU->getSlice()->getSPS()->getAMPAcc( uiDepth ) )
448      {
449        if (eSize == SIZE_2NxN)
450        {
451          m_pcBinIf->encodeBin(1, m_cCUPartSizeSCModel.get( 0, 0, 3 ));
452        }
453        else
454        {
455          m_pcBinIf->encodeBin(0, m_cCUPartSizeSCModel.get( 0, 0, 3 ));
456          m_pcBinIf->encodeBinEP((eSize == SIZE_2NxnU? 0: 1));
457        }
458      }
459      break;
460    }
461    case SIZE_Nx2N:
462    case SIZE_nLx2N:
463    case SIZE_nRx2N:
464    {
465      m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) );
466      m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 1) );
467      if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth && !( pcCU->getWidth(uiAbsPartIdx) == 8 && pcCU->getHeight(uiAbsPartIdx) == 8 ) )
468      {
469        m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 2) );
470      }
471      if ( pcCU->getSlice()->getSPS()->getAMPAcc( uiDepth ) )
472      {
473        if (eSize == SIZE_Nx2N)
474        {
475          m_pcBinIf->encodeBin(1, m_cCUPartSizeSCModel.get( 0, 0, 3 ));
476        }
477        else
478        {
479          m_pcBinIf->encodeBin(0, m_cCUPartSizeSCModel.get( 0, 0, 3 ));
480          m_pcBinIf->encodeBinEP((eSize == SIZE_nLx2N? 0: 1));
481        }
482      }
483      break;
484    }
485    case SIZE_NxN:
486    {
487      if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth && !( pcCU->getWidth(uiAbsPartIdx) == 8 && pcCU->getHeight(uiAbsPartIdx) == 8 ) )
488      {
489        m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) );
490        m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 1) );
491        m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 2) );
492      }
493      break;
494    }
495    default:
496    {
497      assert(0);
498    }
499  }
500}
501
502/** code prediction mode
503 * \param pcCU
504 * \param uiAbsPartIdx 
505 * \returns Void
506 */
507Void TEncSbac::codePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx )
508{
509  // get context function is here
510  Int iPredMode = pcCU->getPredictionMode( uiAbsPartIdx );
511  m_pcBinIf->encodeBin( iPredMode == MODE_INTER ? 0 : 1, m_cCUPredModeSCModel.get( 0, 0, 0 ) );
512}
513
514Void TEncSbac::codeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
515{
516  UInt uiSymbol = pcCU->getCUTransquantBypass(uiAbsPartIdx);
517  m_pcBinIf->encodeBin( uiSymbol, m_CUTransquantBypassFlagSCModel.get( 0, 0, 0 ) );
518}
519
520/** code skip flag
521 * \param pcCU
522 * \param uiAbsPartIdx
523 * \returns Void
524 */
525Void TEncSbac::codeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
526{
527  // get context function is here
528  UInt uiSymbol = pcCU->isSkipped( uiAbsPartIdx ) ? 1 : 0;
529  UInt uiCtxSkip = pcCU->getCtxSkipFlag( uiAbsPartIdx ) ;
530  m_pcBinIf->encodeBin( uiSymbol, m_cCUSkipFlagSCModel.get( 0, 0, uiCtxSkip ) );
531  DTRACE_CABAC_VL( g_nSymbolCounter++ );
532  DTRACE_CABAC_T( "\tSkipFlag" );
533  DTRACE_CABAC_T( "\tuiCtxSkip: ");
534  DTRACE_CABAC_V( uiCtxSkip );
535  DTRACE_CABAC_T( "\tuiSymbol: ");
536  DTRACE_CABAC_V( uiSymbol );
537  DTRACE_CABAC_T( "\n");
538}
539
540/** code merge flag
541 * \param pcCU
542 * \param uiAbsPartIdx
543 * \returns Void
544 */
545Void TEncSbac::codeMergeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
546{
547  const UInt uiSymbol = pcCU->getMergeFlag( uiAbsPartIdx ) ? 1 : 0;
548  m_pcBinIf->encodeBin( uiSymbol, *m_cCUMergeFlagExtSCModel.get( 0 ) );
549
550  DTRACE_CABAC_VL( g_nSymbolCounter++ );
551  DTRACE_CABAC_T( "\tMergeFlag: " );
552  DTRACE_CABAC_V( uiSymbol );
553  DTRACE_CABAC_T( "\tAddress: " );
554  DTRACE_CABAC_V( pcCU->getAddr() );
555  DTRACE_CABAC_T( "\tuiAbsPartIdx: " );
556  DTRACE_CABAC_V( uiAbsPartIdx );
557  DTRACE_CABAC_T( "\n" );
558}
559
560/** code merge index
561 * \param pcCU
562 * \param uiAbsPartIdx
563 * \returns Void
564 */
565Void TEncSbac::codeMergeIndex( TComDataCU* pcCU, UInt uiAbsPartIdx )
566{
567  UInt uiUnaryIdx = pcCU->getMergeIndex( uiAbsPartIdx );
568  UInt uiNumCand = pcCU->getSlice()->getMaxNumMergeCand();
569  if ( uiNumCand > 1 )
570  {
571    for( UInt ui = 0; ui < uiNumCand - 1; ++ui )
572    {
573      const UInt uiSymbol = ui == uiUnaryIdx ? 0 : 1;
574      if ( ui==0 )
575      {
576        m_pcBinIf->encodeBin( uiSymbol, m_cCUMergeIdxExtSCModel.get( 0, 0, 0 ) );
577      }
578      else
579      {
580        m_pcBinIf->encodeBinEP( uiSymbol );
581      }
582      if( uiSymbol == 0 )
583      {
584        break;
585      }
586    }
587  }
588  DTRACE_CABAC_VL( g_nSymbolCounter++ );
589  DTRACE_CABAC_T( "\tparseMergeIndex()" );
590  DTRACE_CABAC_T( "\tuiMRGIdx= " );
591  DTRACE_CABAC_V( pcCU->getMergeIndex( uiAbsPartIdx ) );
592  DTRACE_CABAC_T( "\n" );
593}
594
595Void TEncSbac::codeSplitFlag   ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
596{
597  if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth )
598    return;
599 
600  UInt uiCtx           = pcCU->getCtxSplitFlag( uiAbsPartIdx, uiDepth );
601  UInt uiCurrSplitFlag = ( pcCU->getDepth( uiAbsPartIdx ) > uiDepth ) ? 1 : 0;
602 
603  assert( uiCtx < 3 );
604  m_pcBinIf->encodeBin( uiCurrSplitFlag, m_cCUSplitFlagSCModel.get( 0, 0, uiCtx ) );
605  DTRACE_CABAC_VL( g_nSymbolCounter++ )
606  DTRACE_CABAC_T( "\tSplitFlag\n" )
607  return;
608}
609
610Void TEncSbac::codeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx )
611{
612  m_pcBinIf->encodeBin( uiSymbol, m_cCUTransSubdivFlagSCModel.get( 0, 0, uiCtx ) );
613  DTRACE_CABAC_VL( g_nSymbolCounter++ )
614  DTRACE_CABAC_T( "\tparseTransformSubdivFlag()" )
615  DTRACE_CABAC_T( "\tsymbol=" )
616  DTRACE_CABAC_V( uiSymbol )
617  DTRACE_CABAC_T( "\tctx=" )
618  DTRACE_CABAC_V( uiCtx )
619  DTRACE_CABAC_T( "\n" )
620}
621
622Void TEncSbac::codeIntraDirLumaAng( TComDataCU* pcCU, UInt absPartIdx, Bool isMultiple)
623{
624  UInt dir[4],j;
625  Int preds[4][3] = {{-1, -1, -1},{-1, -1, -1},{-1, -1, -1},{-1, -1, -1}};
626  Int predNum[4], predIdx[4] ={ -1,-1,-1,-1};
627  PartSize mode = pcCU->getPartitionSize( absPartIdx );
628  UInt partNum = isMultiple?(mode==SIZE_NxN?4:1):1;
629  UInt partOffset = ( pcCU->getPic()->getNumPartInCU() >> ( pcCU->getDepth(absPartIdx) << 1 ) ) >> 2;
630  for (j=0;j<partNum;j++)
631  {
632    dir[j] = pcCU->getLumaIntraDir( absPartIdx+partOffset*j );
633    predNum[j] = pcCU->getIntraDirLumaPredictor(absPartIdx+partOffset*j, preds[j]); 
634    for(UInt i = 0; i < predNum[j]; i++)
635    {
636      if(dir[j] == preds[j][i])
637      {
638        predIdx[j] = i;
639      }
640    }
641    m_pcBinIf->encodeBin((predIdx[j] != -1)? 1 : 0, m_cCUIntraPredSCModel.get( 0, 0, 0 ) );
642  } 
643  for (j=0;j<partNum;j++)
644  {
645    if(predIdx[j] != -1)
646    {
647      m_pcBinIf->encodeBinEP( predIdx[j] ? 1 : 0 );
648      if (predIdx[j])
649      {
650        m_pcBinIf->encodeBinEP( predIdx[j]-1 );
651      }
652    }
653    else
654    {
655      if (preds[j][0] > preds[j][1])
656      { 
657        std::swap(preds[j][0], preds[j][1]); 
658      }
659      if (preds[j][0] > preds[j][2])
660      {
661        std::swap(preds[j][0], preds[j][2]);
662      }
663      if (preds[j][1] > preds[j][2])
664      {
665        std::swap(preds[j][1], preds[j][2]);
666      }
667      for(Int i = (predNum[j] - 1); i >= 0; i--)
668      {
669        dir[j] = dir[j] > preds[j][i] ? dir[j] - 1 : dir[j];
670      }
671      m_pcBinIf->encodeBinsEP( dir[j], 5 );
672    }
673  }
674  return;
675}
676
677Void TEncSbac::codeIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx )
678{
679  UInt uiIntraDirChroma = pcCU->getChromaIntraDir( uiAbsPartIdx );
680
681  if( uiIntraDirChroma == DM_CHROMA_IDX ) 
682  {
683    m_pcBinIf->encodeBin( 0, m_cCUChromaPredSCModel.get( 0, 0, 0 ) );
684  }
685  else
686  { 
687    UInt uiAllowedChromaDir[ NUM_CHROMA_MODE ];
688    pcCU->getAllowedChromaDir( uiAbsPartIdx, uiAllowedChromaDir );
689
690    for( Int i = 0; i < NUM_CHROMA_MODE - 1; i++ )
691    {
692      if( uiIntraDirChroma == uiAllowedChromaDir[i] )
693      {
694        uiIntraDirChroma = i;
695        break;
696      }
697    }
698    m_pcBinIf->encodeBin( 1, m_cCUChromaPredSCModel.get( 0, 0, 0 ) );
699
700    m_pcBinIf->encodeBinsEP( uiIntraDirChroma, 2 );
701  }
702  return;
703}
704
705Void TEncSbac::codeInterDir( TComDataCU* pcCU, UInt uiAbsPartIdx )
706{
707  const UInt uiInterDir = pcCU->getInterDir( uiAbsPartIdx ) - 1;
708  const UInt uiCtx      = pcCU->getCtxInterDir( uiAbsPartIdx );
709  ContextModel *pCtx    = m_cCUInterDirSCModel.get( 0 );
710  if (pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N || pcCU->getHeight(uiAbsPartIdx) != 8 )
711  {
712    m_pcBinIf->encodeBin( uiInterDir == 2 ? 1 : 0, *( pCtx + uiCtx ) );
713  }
714  if (uiInterDir < 2)
715  {
716    m_pcBinIf->encodeBin( uiInterDir, *( pCtx + 4 ) );
717  }
718  return;
719}
720
721Void TEncSbac::codeRefFrmIdx( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
722{
723  {
724    Int iRefFrame = pcCU->getCUMvField( eRefList )->getRefIdx( uiAbsPartIdx );
725    ContextModel *pCtx = m_cCURefPicSCModel.get( 0 );
726    m_pcBinIf->encodeBin( ( iRefFrame == 0 ? 0 : 1 ), *pCtx );
727   
728    if( iRefFrame > 0 )
729    {
730      UInt uiRefNum = pcCU->getSlice()->getNumRefIdx( eRefList ) - 2;
731      pCtx++;
732      iRefFrame--;
733      for( UInt ui = 0; ui < uiRefNum; ++ui )
734      {
735        const UInt uiSymbol = ui == iRefFrame ? 0 : 1;
736        if( ui == 0 )
737        {
738          m_pcBinIf->encodeBin( uiSymbol, *pCtx );       
739        }
740        else
741        {
742          m_pcBinIf->encodeBinEP( uiSymbol );
743        }
744        if( uiSymbol == 0 )
745        {
746          break;
747        }
748      }
749    }
750  }
751  return;
752}
753
754Void TEncSbac::codeMvd( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList )
755{
756  if(pcCU->getSlice()->getMvdL1ZeroFlag() && eRefList == REF_PIC_LIST_1 && pcCU->getInterDir(uiAbsPartIdx)==3)
757  {
758    return;
759  }
760
761  const TComCUMvField* pcCUMvField = pcCU->getCUMvField( eRefList );
762  const Int iHor = pcCUMvField->getMvd( uiAbsPartIdx ).getHor();
763  const Int iVer = pcCUMvField->getMvd( uiAbsPartIdx ).getVer();
764  ContextModel* pCtx = m_cCUMvdSCModel.get( 0 );
765
766  m_pcBinIf->encodeBin( iHor != 0 ? 1 : 0, *pCtx );
767  m_pcBinIf->encodeBin( iVer != 0 ? 1 : 0, *pCtx );
768
769  const Bool bHorAbsGr0 = iHor != 0;
770  const Bool bVerAbsGr0 = iVer != 0;
771  const UInt uiHorAbs   = 0 > iHor ? -iHor : iHor;
772  const UInt uiVerAbs   = 0 > iVer ? -iVer : iVer;
773  pCtx++;
774
775  if( bHorAbsGr0 )
776  {
777    m_pcBinIf->encodeBin( uiHorAbs > 1 ? 1 : 0, *pCtx );
778  }
779
780  if( bVerAbsGr0 )
781  {
782    m_pcBinIf->encodeBin( uiVerAbs > 1 ? 1 : 0, *pCtx );
783  }
784
785  if( bHorAbsGr0 )
786  {
787    if( uiHorAbs > 1 )
788    {
789      xWriteEpExGolomb( uiHorAbs-2, 1 );
790    }
791
792    m_pcBinIf->encodeBinEP( 0 > iHor ? 1 : 0 );
793  }
794
795  if( bVerAbsGr0 )
796  {
797    if( uiVerAbs > 1 )
798    {
799      xWriteEpExGolomb( uiVerAbs-2, 1 );
800    }
801
802    m_pcBinIf->encodeBinEP( 0 > iVer ? 1 : 0 );
803  }
804 
805  return;
806}
807
808Void TEncSbac::codeDeltaQP( TComDataCU* pcCU, UInt uiAbsPartIdx )
809{
810  Int iDQp  = pcCU->getQP( uiAbsPartIdx ) - pcCU->getRefQP( uiAbsPartIdx );
811 
812#if REPN_FORMAT_IN_VPS
813  Int qpBdOffsetY =  pcCU->getSlice()->getQpBDOffsetY();
814#else
815  Int qpBdOffsetY =  pcCU->getSlice()->getSPS()->getQpBDOffsetY();
816#endif
817  iDQp = (iDQp + 78 + qpBdOffsetY + (qpBdOffsetY/2)) % (52 + qpBdOffsetY) - 26 - (qpBdOffsetY/2);
818
819  UInt uiAbsDQp = (UInt)((iDQp > 0)? iDQp  : (-iDQp));
820  UInt TUValue = min((Int)uiAbsDQp, CU_DQP_TU_CMAX);
821  xWriteUnaryMaxSymbol( TUValue, &m_cCUDeltaQpSCModel.get( 0, 0, 0 ), 1, CU_DQP_TU_CMAX);
822  if( uiAbsDQp >= CU_DQP_TU_CMAX )
823  {
824    xWriteEpExGolomb( uiAbsDQp - CU_DQP_TU_CMAX, CU_DQP_EG_k );
825  }
826
827  if ( uiAbsDQp > 0)
828  {
829    UInt uiSign = (iDQp > 0 ? 0 : 1);
830    m_pcBinIf->encodeBinEP(uiSign);
831  }
832
833  return;
834}
835
836Void TEncSbac::codeQtCbf( TComDataCU* pcCU, UInt uiAbsPartIdx, TextType eType, UInt uiTrDepth )
837{
838  UInt uiCbf = pcCU->getCbf     ( uiAbsPartIdx, eType, uiTrDepth );
839  UInt uiCtx = pcCU->getCtxQtCbf( eType, uiTrDepth );
840  m_pcBinIf->encodeBin( uiCbf , m_cCUQtCbfSCModel.get( 0, eType ? TEXT_CHROMA : eType, uiCtx ) );
841  DTRACE_CABAC_VL( g_nSymbolCounter++ )
842  DTRACE_CABAC_T( "\tparseQtCbf()" )
843  DTRACE_CABAC_T( "\tsymbol=" )
844  DTRACE_CABAC_V( uiCbf )
845  DTRACE_CABAC_T( "\tctx=" )
846  DTRACE_CABAC_V( uiCtx )
847  DTRACE_CABAC_T( "\tetype=" )
848  DTRACE_CABAC_V( eType )
849  DTRACE_CABAC_T( "\tuiAbsPartIdx=" )
850  DTRACE_CABAC_V( uiAbsPartIdx )
851  DTRACE_CABAC_T( "\n" )
852}
853
854void TEncSbac::codeTransformSkipFlags (TComDataCU* pcCU, UInt uiAbsPartIdx, UInt width, UInt height, TextType eTType )
855{
856  if (pcCU->getCUTransquantBypass(uiAbsPartIdx))
857  {
858    return;
859  }
860  if(width != 4 || height != 4)
861  {
862    return;
863  }
864
865  UInt useTransformSkip = pcCU->getTransformSkip( uiAbsPartIdx,eTType);
866  m_pcBinIf->encodeBin( useTransformSkip, m_cTransformSkipSCModel.get( 0, eTType? TEXT_CHROMA: TEXT_LUMA, 0 ) );
867  DTRACE_CABAC_VL( g_nSymbolCounter++ )
868  DTRACE_CABAC_T("\tparseTransformSkip()");
869  DTRACE_CABAC_T( "\tsymbol=" )
870  DTRACE_CABAC_V( useTransformSkip )
871  DTRACE_CABAC_T( "\tAddr=" )
872  DTRACE_CABAC_V( pcCU->getAddr() )
873  DTRACE_CABAC_T( "\tetype=" )
874  DTRACE_CABAC_V( eTType )
875  DTRACE_CABAC_T( "\tuiAbsPartIdx=" )
876  DTRACE_CABAC_V( uiAbsPartIdx )
877  DTRACE_CABAC_T( "\n" )
878}
879
880/** Code I_PCM information.
881 * \param pcCU pointer to CU
882 * \param uiAbsPartIdx CU index
883 * \returns Void
884 */
885Void TEncSbac::codeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx )
886{
887  UInt uiIPCM = (pcCU->getIPCMFlag(uiAbsPartIdx) == true)? 1 : 0;
888
889  Bool writePCMSampleFlag = pcCU->getIPCMFlag(uiAbsPartIdx);
890
891  m_pcBinIf->encodeBinTrm (uiIPCM);
892
893  if (writePCMSampleFlag)
894  {
895    m_pcBinIf->encodePCMAlignBits();
896
897    UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
898    UInt uiLumaOffset   = uiMinCoeffSize*uiAbsPartIdx;
899    UInt uiChromaOffset = uiLumaOffset>>2;
900    Pel* piPCMSample;
901    UInt uiWidth;
902    UInt uiHeight;
903    UInt uiSampleBits;
904    UInt uiX, uiY;
905
906    piPCMSample = pcCU->getPCMSampleY() + uiLumaOffset;
907    uiWidth = pcCU->getWidth(uiAbsPartIdx);
908    uiHeight = pcCU->getHeight(uiAbsPartIdx);
909    uiSampleBits = pcCU->getSlice()->getSPS()->getPCMBitDepthLuma();
910
911    for(uiY = 0; uiY < uiHeight; uiY++)
912    {
913      for(uiX = 0; uiX < uiWidth; uiX++)
914      {
915        UInt uiSample = piPCMSample[uiX];
916
917        m_pcBinIf->xWritePCMCode(uiSample, uiSampleBits);
918      }
919      piPCMSample += uiWidth;
920    }
921
922#if AUXILIARY_PICTURES
923    if (pcCU->getSlice()->getChromaFormatIdc() != CHROMA_400)
924    {
925#endif
926    piPCMSample = pcCU->getPCMSampleCb() + uiChromaOffset;
927    uiWidth = pcCU->getWidth(uiAbsPartIdx)/2;
928    uiHeight = pcCU->getHeight(uiAbsPartIdx)/2;
929    uiSampleBits = pcCU->getSlice()->getSPS()->getPCMBitDepthChroma();
930
931    for(uiY = 0; uiY < uiHeight; uiY++)
932    {
933      for(uiX = 0; uiX < uiWidth; uiX++)
934      {
935        UInt uiSample = piPCMSample[uiX];
936
937        m_pcBinIf->xWritePCMCode(uiSample, uiSampleBits);
938      }
939      piPCMSample += uiWidth;
940    }
941
942    piPCMSample = pcCU->getPCMSampleCr() + uiChromaOffset;
943    uiWidth = pcCU->getWidth(uiAbsPartIdx)/2;
944    uiHeight = pcCU->getHeight(uiAbsPartIdx)/2;
945    uiSampleBits = pcCU->getSlice()->getSPS()->getPCMBitDepthChroma();
946
947    for(uiY = 0; uiY < uiHeight; uiY++)
948    {
949      for(uiX = 0; uiX < uiWidth; uiX++)
950      {
951        UInt uiSample = piPCMSample[uiX];
952
953        m_pcBinIf->xWritePCMCode(uiSample, uiSampleBits);
954      }
955      piPCMSample += uiWidth;
956    }
957#if AUXILIARY_PICTURES
958    }
959#endif
960    m_pcBinIf->resetBac();
961  }
962}
963
964Void TEncSbac::codeQtRootCbf( TComDataCU* pcCU, UInt uiAbsPartIdx )
965{
966  UInt uiCbf = pcCU->getQtRootCbf( uiAbsPartIdx );
967  UInt uiCtx = 0;
968  m_pcBinIf->encodeBin( uiCbf , m_cCUQtRootCbfSCModel.get( 0, 0, uiCtx ) );
969  DTRACE_CABAC_VL( g_nSymbolCounter++ )
970  DTRACE_CABAC_T( "\tparseQtRootCbf()" )
971  DTRACE_CABAC_T( "\tsymbol=" )
972  DTRACE_CABAC_V( uiCbf )
973  DTRACE_CABAC_T( "\tctx=" )
974  DTRACE_CABAC_V( uiCtx )
975  DTRACE_CABAC_T( "\tuiAbsPartIdx=" )
976  DTRACE_CABAC_V( uiAbsPartIdx )
977  DTRACE_CABAC_T( "\n" )
978}
979
980Void TEncSbac::codeQtCbfZero( TComDataCU* pcCU, TextType eType, UInt uiTrDepth )
981{
982  // this function is only used to estimate the bits when cbf is 0
983  // and will never be called when writing the bistream. do not need to write log
984  UInt uiCbf = 0;
985  UInt uiCtx = pcCU->getCtxQtCbf( eType, uiTrDepth );
986  m_pcBinIf->encodeBin( uiCbf , m_cCUQtCbfSCModel.get( 0, eType ? TEXT_CHROMA : eType, uiCtx ) );
987}
988
989Void TEncSbac::codeQtRootCbfZero( TComDataCU* pcCU )
990{
991  // this function is only used to estimate the bits when cbf is 0
992  // and will never be called when writing the bistream. do not need to write log
993  UInt uiCbf = 0;
994  UInt uiCtx = 0;
995  m_pcBinIf->encodeBin( uiCbf , m_cCUQtRootCbfSCModel.get( 0, 0, uiCtx ) );
996}
997
998/** Encode (X,Y) position of the last significant coefficient
999 * \param uiPosX X component of last coefficient
1000 * \param uiPosY Y component of last coefficient
1001 * \param width  Block width
1002 * \param height Block height
1003 * \param eTType plane type / luminance or chrominance
1004 * \param uiScanIdx scan type (zig-zag, hor, ver)
1005 * This method encodes the X and Y component within a block of the last significant coefficient.
1006 */
1007Void TEncSbac::codeLastSignificantXY( UInt uiPosX, UInt uiPosY, Int width, Int height, TextType eTType, UInt uiScanIdx )
1008{ 
1009  // swap
1010  if( uiScanIdx == SCAN_VER )
1011  {
1012    swap( uiPosX, uiPosY );
1013  }
1014
1015  UInt uiCtxLast;
1016  ContextModel *pCtxX = m_cCuCtxLastX.get( 0, eTType );
1017  ContextModel *pCtxY = m_cCuCtxLastY.get( 0, eTType );
1018  UInt uiGroupIdxX    = g_uiGroupIdx[ uiPosX ];
1019  UInt uiGroupIdxY    = g_uiGroupIdx[ uiPosY ];
1020
1021
1022  Int blkSizeOffsetX, blkSizeOffsetY, shiftX, shiftY;
1023  blkSizeOffsetX = eTType ? 0: (g_aucConvertToBit[ width ] *3 + ((g_aucConvertToBit[ width ] +1)>>2));
1024  blkSizeOffsetY = eTType ? 0: (g_aucConvertToBit[ height ]*3 + ((g_aucConvertToBit[ height ]+1)>>2));
1025  shiftX= eTType ? g_aucConvertToBit[ width  ] :((g_aucConvertToBit[ width  ]+3)>>2);
1026  shiftY= eTType ? g_aucConvertToBit[ height ] :((g_aucConvertToBit[ height ]+3)>>2);
1027  // posX
1028  for( uiCtxLast = 0; uiCtxLast < uiGroupIdxX; uiCtxLast++ )
1029  {
1030      m_pcBinIf->encodeBin( 1, *( pCtxX + blkSizeOffsetX + (uiCtxLast >>shiftX) ) );
1031  }
1032  if( uiGroupIdxX < g_uiGroupIdx[ width - 1 ])
1033  {
1034      m_pcBinIf->encodeBin( 0, *( pCtxX + blkSizeOffsetX + (uiCtxLast >>shiftX) ) );
1035  }
1036
1037  // posY
1038  for( uiCtxLast = 0; uiCtxLast < uiGroupIdxY; uiCtxLast++ )
1039  {
1040    m_pcBinIf->encodeBin( 1, *( pCtxY + blkSizeOffsetY + (uiCtxLast >>shiftY) ) );
1041  }
1042  if( uiGroupIdxY < g_uiGroupIdx[ height - 1 ])
1043  {
1044    m_pcBinIf->encodeBin( 0, *( pCtxY + blkSizeOffsetY + (uiCtxLast >>shiftY) ) );
1045  }
1046  if ( uiGroupIdxX > 3 )
1047  {     
1048    UInt uiCount = ( uiGroupIdxX - 2 ) >> 1;
1049    uiPosX       = uiPosX - g_uiMinInGroup[ uiGroupIdxX ];
1050    for (Int i = uiCount - 1 ; i >= 0; i-- )
1051    {
1052      m_pcBinIf->encodeBinEP( ( uiPosX >> i ) & 1 );
1053    }
1054  }
1055  if ( uiGroupIdxY > 3 )
1056  {     
1057    UInt uiCount = ( uiGroupIdxY - 2 ) >> 1;
1058    uiPosY       = uiPosY - g_uiMinInGroup[ uiGroupIdxY ];
1059    for ( Int i = uiCount - 1 ; i >= 0; i-- )
1060    {
1061      m_pcBinIf->encodeBinEP( ( uiPosY >> i ) & 1 );
1062    }
1063  }
1064}
1065
1066Void TEncSbac::codeCoeffNxN( TComDataCU* pcCU, TCoeff* pcCoef, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt uiDepth, TextType eTType )
1067{
1068  DTRACE_CABAC_VL( g_nSymbolCounter++ )
1069  DTRACE_CABAC_T( "\tparseCoeffNxN()\teType=" )
1070  DTRACE_CABAC_V( eTType )
1071  DTRACE_CABAC_T( "\twidth=" )
1072  DTRACE_CABAC_V( uiWidth )
1073  DTRACE_CABAC_T( "\theight=" )
1074  DTRACE_CABAC_V( uiHeight )
1075  DTRACE_CABAC_T( "\tdepth=" )
1076  DTRACE_CABAC_V( uiDepth )
1077  DTRACE_CABAC_T( "\tabspartidx=" )
1078  DTRACE_CABAC_V( uiAbsPartIdx )
1079  DTRACE_CABAC_T( "\ttoCU-X=" )
1080  DTRACE_CABAC_V( pcCU->getCUPelX() )
1081  DTRACE_CABAC_T( "\ttoCU-Y=" )
1082  DTRACE_CABAC_V( pcCU->getCUPelY() )
1083  DTRACE_CABAC_T( "\tCU-addr=" )
1084  DTRACE_CABAC_V(  pcCU->getAddr() )
1085  DTRACE_CABAC_T( "\tinCU-X=" )
1086  DTRACE_CABAC_V( g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ] )
1087  DTRACE_CABAC_T( "\tinCU-Y=" )
1088  DTRACE_CABAC_V( g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ] )
1089  DTRACE_CABAC_T( "\tpredmode=" )
1090  DTRACE_CABAC_V(  pcCU->getPredictionMode( uiAbsPartIdx ) )
1091  DTRACE_CABAC_T( "\n" )
1092
1093  if( uiWidth > m_pcSlice->getSPS()->getMaxTrSize() )
1094  {
1095    uiWidth  = m_pcSlice->getSPS()->getMaxTrSize();
1096    uiHeight = m_pcSlice->getSPS()->getMaxTrSize();
1097  }
1098 
1099  UInt uiNumSig = 0;
1100 
1101  // compute number of significant coefficients
1102  uiNumSig = TEncEntropy::countNonZeroCoeffs(pcCoef, uiWidth * uiHeight);
1103 
1104  if ( uiNumSig == 0 )
1105    return;
1106  if(pcCU->getSlice()->getPPS()->getUseTransformSkip())
1107  {
1108    codeTransformSkipFlags( pcCU,uiAbsPartIdx, uiWidth, uiHeight, eTType );
1109  }
1110  eTType = eTType == TEXT_LUMA ? TEXT_LUMA : ( eTType == TEXT_NONE ? TEXT_NONE : TEXT_CHROMA );
1111 
1112  //----- encode significance map -----
1113  const UInt   uiLog2BlockSize = g_aucConvertToBit[ uiWidth ] + 2;
1114  UInt uiScanIdx = pcCU->getCoefScanIdx(uiAbsPartIdx, uiWidth, eTType==TEXT_LUMA, pcCU->isIntra(uiAbsPartIdx));
1115  const UInt *scan = g_auiSigLastScan[ uiScanIdx ][ uiLog2BlockSize - 1 ];
1116 
1117  Bool beValid;
1118  if (pcCU->getCUTransquantBypass(uiAbsPartIdx))
1119  {
1120    beValid = false;
1121  }
1122  else 
1123  {
1124    beValid = pcCU->getSlice()->getPPS()->getSignHideFlag() > 0;
1125  }
1126
1127  // Find position of last coefficient
1128  Int scanPosLast = -1;
1129  Int posLast;
1130
1131  const UInt * scanCG;
1132  {
1133    scanCG = g_auiSigLastScan[ uiScanIdx ][ uiLog2BlockSize > 3 ? uiLog2BlockSize-2-1 : 0 ];
1134    if( uiLog2BlockSize == 3 )
1135    {
1136      scanCG = g_sigLastScan8x8[ uiScanIdx ];
1137    }
1138    else if( uiLog2BlockSize == 5 )
1139    {
1140      scanCG = g_sigLastScanCG32x32;
1141    }
1142  }
1143  UInt uiSigCoeffGroupFlag[ MLS_GRP_NUM ];
1144  static const UInt uiShift = MLS_CG_SIZE >> 1;
1145  const UInt uiNumBlkSide = uiWidth >> uiShift;
1146
1147    ::memset( uiSigCoeffGroupFlag, 0, sizeof(UInt) * MLS_GRP_NUM );
1148
1149    do
1150    {
1151      posLast = scan[ ++scanPosLast ];
1152
1153      // get L1 sig map
1154      UInt uiPosY    = posLast >> uiLog2BlockSize;
1155      UInt uiPosX    = posLast - ( uiPosY << uiLog2BlockSize );
1156      UInt uiBlkIdx  = uiNumBlkSide * (uiPosY >> uiShift) + (uiPosX >> uiShift);
1157      if( pcCoef[ posLast ] )
1158      {
1159        uiSigCoeffGroupFlag[ uiBlkIdx ] = 1;
1160      }
1161
1162      uiNumSig -= ( pcCoef[ posLast ] != 0 );
1163    }
1164    while ( uiNumSig > 0 );
1165
1166  // Code position of last coefficient
1167  Int posLastY = posLast >> uiLog2BlockSize;
1168  Int posLastX = posLast - ( posLastY << uiLog2BlockSize );
1169  codeLastSignificantXY(posLastX, posLastY, uiWidth, uiHeight, eTType, uiScanIdx);
1170 
1171  //===== code significance flag =====
1172  ContextModel * const baseCoeffGroupCtx = m_cCUSigCoeffGroupSCModel.get( 0, eTType );
1173  ContextModel * const baseCtx = (eTType==TEXT_LUMA) ? m_cCUSigSCModel.get( 0, 0 ) : m_cCUSigSCModel.get( 0, 0 ) + NUM_SIG_FLAG_CTX_LUMA;
1174
1175
1176  const Int  iLastScanSet      = scanPosLast >> LOG2_SCAN_SET_SIZE;
1177  UInt c1 = 1;
1178  UInt uiGoRiceParam           = 0;
1179  Int  iScanPosSig             = scanPosLast;
1180
1181  for( Int iSubSet = iLastScanSet; iSubSet >= 0; iSubSet-- )
1182  {
1183    Int numNonZero = 0;
1184    Int  iSubPos     = iSubSet << LOG2_SCAN_SET_SIZE;
1185    uiGoRiceParam    = 0;
1186    Int absCoeff[16];
1187    UInt coeffSigns = 0;
1188
1189    Int lastNZPosInCG = -1, firstNZPosInCG = SCAN_SET_SIZE;
1190
1191    if( iScanPosSig == scanPosLast )
1192    {
1193      absCoeff[ 0 ] = abs( pcCoef[ posLast ] );
1194      coeffSigns    = ( pcCoef[ posLast ] < 0 );
1195      numNonZero    = 1;
1196      lastNZPosInCG  = iScanPosSig;
1197      firstNZPosInCG = iScanPosSig;
1198      iScanPosSig--;
1199    }
1200
1201      // encode significant_coeffgroup_flag
1202      Int iCGBlkPos = scanCG[ iSubSet ];
1203      Int iCGPosY   = iCGBlkPos / uiNumBlkSide;
1204      Int iCGPosX   = iCGBlkPos - (iCGPosY * uiNumBlkSide);
1205      if( iSubSet == iLastScanSet || iSubSet == 0)
1206      {
1207        uiSigCoeffGroupFlag[ iCGBlkPos ] = 1;
1208      }
1209      else
1210      {
1211          UInt uiSigCoeffGroup   = (uiSigCoeffGroupFlag[ iCGBlkPos ] != 0);
1212          UInt uiCtxSig  = TComTrQuant::getSigCoeffGroupCtxInc( uiSigCoeffGroupFlag, iCGPosX, iCGPosY, uiWidth, uiHeight );
1213          m_pcBinIf->encodeBin( uiSigCoeffGroup, baseCoeffGroupCtx[ uiCtxSig ] );
1214      }
1215     
1216      // encode significant_coeff_flag
1217      if( uiSigCoeffGroupFlag[ iCGBlkPos ] )
1218      {
1219        Int patternSigCtx = TComTrQuant::calcPatternSigCtx( uiSigCoeffGroupFlag, iCGPosX, iCGPosY, uiWidth, uiHeight );
1220        UInt uiBlkPos, uiPosY, uiPosX, uiSig, uiCtxSig;
1221        for( ; iScanPosSig >= iSubPos; iScanPosSig-- )
1222        {
1223          uiBlkPos  = scan[ iScanPosSig ]; 
1224          uiPosY    = uiBlkPos >> uiLog2BlockSize;
1225          uiPosX    = uiBlkPos - ( uiPosY << uiLog2BlockSize );
1226          uiSig     = (pcCoef[ uiBlkPos ] != 0);
1227          if( iScanPosSig > iSubPos || iSubSet == 0 || numNonZero )
1228          {
1229            uiCtxSig  = TComTrQuant::getSigCtxInc( patternSigCtx, uiScanIdx, uiPosX, uiPosY, uiLog2BlockSize, eTType );
1230            m_pcBinIf->encodeBin( uiSig, baseCtx[ uiCtxSig ] );
1231          }
1232          if( uiSig )
1233          {
1234            absCoeff[ numNonZero ] = abs( pcCoef[ uiBlkPos ] );
1235            coeffSigns = 2 * coeffSigns + ( pcCoef[ uiBlkPos ] < 0 );
1236            numNonZero++;
1237            if( lastNZPosInCG == -1 )
1238            {
1239              lastNZPosInCG = iScanPosSig;
1240            }
1241            firstNZPosInCG = iScanPosSig;
1242          }
1243        }
1244      }
1245      else
1246      {
1247        iScanPosSig = iSubPos - 1;
1248      }
1249
1250    if( numNonZero > 0 )
1251    {
1252      Bool signHidden = ( lastNZPosInCG - firstNZPosInCG >= SBH_THRESHOLD );
1253      UInt uiCtxSet = (iSubSet > 0 && eTType==TEXT_LUMA) ? 2 : 0;
1254     
1255      if( c1 == 0 )
1256      {
1257        uiCtxSet++;
1258      }
1259      c1 = 1;
1260      ContextModel *baseCtxMod = ( eTType==TEXT_LUMA ) ? m_cCUOneSCModel.get( 0, 0 ) + 4 * uiCtxSet : m_cCUOneSCModel.get( 0, 0 ) + NUM_ONE_FLAG_CTX_LUMA + 4 * uiCtxSet;
1261     
1262      Int numC1Flag = min(numNonZero, C1FLAG_NUMBER);
1263      Int firstC2FlagIdx = -1;
1264      for( Int idx = 0; idx < numC1Flag; idx++ )
1265      {
1266        UInt uiSymbol = absCoeff[ idx ] > 1;
1267        m_pcBinIf->encodeBin( uiSymbol, baseCtxMod[c1] );
1268        if( uiSymbol )
1269        {
1270          c1 = 0;
1271
1272          if (firstC2FlagIdx == -1)
1273          {
1274            firstC2FlagIdx = idx;
1275          }
1276        }
1277        else if( (c1 < 3) && (c1 > 0) )
1278        {
1279          c1++;
1280        }
1281      }
1282     
1283      if (c1 == 0)
1284      {
1285
1286        baseCtxMod = ( eTType==TEXT_LUMA ) ? m_cCUAbsSCModel.get( 0, 0 ) + uiCtxSet : m_cCUAbsSCModel.get( 0, 0 ) + NUM_ABS_FLAG_CTX_LUMA + uiCtxSet;
1287        if ( firstC2FlagIdx != -1)
1288        {
1289          UInt symbol = absCoeff[ firstC2FlagIdx ] > 2;
1290          m_pcBinIf->encodeBin( symbol, baseCtxMod[0] );
1291        }
1292      }
1293     
1294      if( beValid && signHidden )
1295      {
1296        m_pcBinIf->encodeBinsEP( (coeffSigns >> 1), numNonZero-1 );
1297      }
1298      else
1299      {
1300        m_pcBinIf->encodeBinsEP( coeffSigns, numNonZero );
1301      }
1302     
1303      Int iFirstCoeff2 = 1;   
1304      if (c1 == 0 || numNonZero > C1FLAG_NUMBER)
1305      {
1306        for ( Int idx = 0; idx < numNonZero; idx++ )
1307        {
1308          UInt baseLevel  = (idx < C1FLAG_NUMBER)? (2 + iFirstCoeff2 ) : 1;
1309
1310          if( absCoeff[ idx ] >= baseLevel)
1311          {
1312            xWriteCoefRemainExGolomb( absCoeff[ idx ] - baseLevel, uiGoRiceParam );
1313            if(absCoeff[idx] > 3*(1<<uiGoRiceParam))
1314            {
1315               uiGoRiceParam = min<UInt>(uiGoRiceParam+ 1, 4);
1316            }
1317          }
1318          if(absCoeff[ idx ] >= 2) 
1319          {
1320            iFirstCoeff2 = 0;
1321          }
1322        }       
1323      }
1324    }
1325  }
1326
1327  return;
1328}
1329
1330/** code SAO offset sign
1331 * \param code sign value
1332 */
1333Void TEncSbac::codeSAOSign( UInt code )
1334{
1335  m_pcBinIf->encodeBinEP( code );
1336}
1337
1338Void TEncSbac::codeSaoMaxUvlc    ( UInt code, UInt maxSymbol )
1339{
1340  if (maxSymbol == 0)
1341  {
1342    return;
1343  }
1344
1345  Int i;
1346  Bool bCodeLast = ( maxSymbol > code );
1347
1348  if ( code == 0 )
1349  {
1350    m_pcBinIf->encodeBinEP( 0 );
1351  }
1352  else
1353  {
1354    m_pcBinIf->encodeBinEP( 1 );
1355    for ( i=0; i<code-1; i++ )
1356    {
1357      m_pcBinIf->encodeBinEP( 1 );
1358    }
1359    if( bCodeLast )
1360    {
1361      m_pcBinIf->encodeBinEP( 0 );
1362    }
1363  }
1364}
1365
1366
1367/** Code SAO EO class or BO band position
1368 * \param uiLength
1369 * \param uiCode
1370 */
1371Void TEncSbac::codeSaoUflc       ( UInt uiLength, UInt uiCode )
1372{
1373   m_pcBinIf->encodeBinsEP ( uiCode, uiLength );
1374}
1375/** Code SAO merge flags
1376 * \param uiCode
1377 * \param uiCompIdx
1378 */
1379Void TEncSbac::codeSaoMerge       ( UInt uiCode )
1380{
1381  if (uiCode == 0)
1382  {
1383    m_pcBinIf->encodeBin(0,  m_cSaoMergeSCModel.get( 0, 0, 0 ));
1384  }
1385  else
1386  {
1387    m_pcBinIf->encodeBin(1,  m_cSaoMergeSCModel.get( 0, 0, 0 ));
1388  }
1389}
1390/** Code SAO type index
1391 * \param uiCode
1392 */
1393Void TEncSbac::codeSaoTypeIdx       ( UInt uiCode)
1394{
1395  if (uiCode == 0)
1396  {
1397    m_pcBinIf->encodeBin( 0, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) );
1398  }
1399  else
1400  {
1401    m_pcBinIf->encodeBin( 1, m_cSaoTypeIdxSCModel.get( 0, 0, 0 ) );
1402    m_pcBinIf->encodeBinEP( uiCode == 1 ? 0 : 1 );
1403  }
1404}
1405/*!
1406 ****************************************************************************
1407 * \brief
1408 *   estimate bit cost for CBP, significant map and significant coefficients
1409 ****************************************************************************
1410 */
1411Void TEncSbac::estBit( estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, TextType eTType )
1412{
1413  estCBFBit( pcEstBitsSbac );
1414
1415  estSignificantCoeffGroupMapBit( pcEstBitsSbac, eTType );
1416 
1417  // encode significance map
1418  estSignificantMapBit( pcEstBitsSbac, width, height, eTType );
1419 
1420  // encode significant coefficients
1421  estSignificantCoefficientsBit( pcEstBitsSbac, eTType );
1422}
1423
1424/*!
1425 ****************************************************************************
1426 * \brief
1427 *    estimate bit cost for each CBP bit
1428 ****************************************************************************
1429 */
1430Void TEncSbac::estCBFBit( estBitsSbacStruct* pcEstBitsSbac )
1431{
1432  ContextModel *pCtx = m_cCUQtCbfSCModel.get( 0 );
1433
1434  for( UInt uiCtxInc = 0; uiCtxInc < 3*NUM_QT_CBF_CTX; uiCtxInc++ )
1435  {
1436    pcEstBitsSbac->blockCbpBits[ uiCtxInc ][ 0 ] = pCtx[ uiCtxInc ].getEntropyBits( 0 );
1437    pcEstBitsSbac->blockCbpBits[ uiCtxInc ][ 1 ] = pCtx[ uiCtxInc ].getEntropyBits( 1 );
1438  }
1439
1440  pCtx = m_cCUQtRootCbfSCModel.get( 0 );
1441 
1442  for( UInt uiCtxInc = 0; uiCtxInc < 4; uiCtxInc++ )
1443  {
1444    pcEstBitsSbac->blockRootCbpBits[ uiCtxInc ][ 0 ] = pCtx[ uiCtxInc ].getEntropyBits( 0 );
1445    pcEstBitsSbac->blockRootCbpBits[ uiCtxInc ][ 1 ] = pCtx[ uiCtxInc ].getEntropyBits( 1 );
1446  }
1447}
1448
1449
1450/*!
1451 ****************************************************************************
1452 * \brief
1453 *    estimate SAMBAC bit cost for significant coefficient group map
1454 ****************************************************************************
1455 */
1456Void TEncSbac::estSignificantCoeffGroupMapBit( estBitsSbacStruct* pcEstBitsSbac, TextType eTType )
1457{
1458  Int firstCtx = 0, numCtx = NUM_SIG_CG_FLAG_CTX;
1459
1460  for ( Int ctxIdx = firstCtx; ctxIdx < firstCtx + numCtx; ctxIdx++ )
1461  {
1462    for( UInt uiBin = 0; uiBin < 2; uiBin++ )
1463    {
1464      pcEstBitsSbac->significantCoeffGroupBits[ ctxIdx ][ uiBin ] = m_cCUSigCoeffGroupSCModel.get(  0, eTType, ctxIdx ).getEntropyBits( uiBin );
1465    }
1466  }
1467}
1468
1469
1470/*!
1471 ****************************************************************************
1472 * \brief
1473 *    estimate SAMBAC bit cost for significant coefficient map
1474 ****************************************************************************
1475 */
1476Void TEncSbac::estSignificantMapBit( estBitsSbacStruct* pcEstBitsSbac, Int width, Int height, TextType eTType )
1477{
1478  Int firstCtx = 1, numCtx = 8;
1479  if (max(width, height) >= 16)
1480  {
1481    firstCtx = (eTType == TEXT_LUMA) ? 21 : 12;
1482    numCtx = (eTType == TEXT_LUMA) ? 6 : 3;
1483  }
1484  else if (width == 8)
1485  {
1486    firstCtx = 9;
1487    numCtx = (eTType == TEXT_LUMA) ? 12 : 3;
1488  }
1489 
1490  if (eTType == TEXT_LUMA )
1491  {
1492    for( UInt bin = 0; bin < 2; bin++ )
1493    {
1494      pcEstBitsSbac->significantBits[ 0 ][ bin ] = m_cCUSigSCModel.get(  0, 0, 0 ).getEntropyBits( bin );
1495    }
1496
1497    for ( Int ctxIdx = firstCtx; ctxIdx < firstCtx + numCtx; ctxIdx++ )
1498    {
1499      for( UInt uiBin = 0; uiBin < 2; uiBin++ )
1500      {
1501        pcEstBitsSbac->significantBits[ ctxIdx ][ uiBin ] = m_cCUSigSCModel.get(  0, 0, ctxIdx ).getEntropyBits( uiBin );
1502      }
1503    }
1504  }
1505  else
1506  {
1507    for( UInt bin = 0; bin < 2; bin++ )
1508    {
1509      pcEstBitsSbac->significantBits[ 0 ][ bin ] = m_cCUSigSCModel.get(  0, 0, NUM_SIG_FLAG_CTX_LUMA + 0 ).getEntropyBits( bin );
1510    }
1511    for ( Int ctxIdx = firstCtx; ctxIdx < firstCtx + numCtx; ctxIdx++ )
1512    {
1513      for( UInt uiBin = 0; uiBin < 2; uiBin++ )
1514      {
1515        pcEstBitsSbac->significantBits[ ctxIdx ][ uiBin ] = m_cCUSigSCModel.get(  0, 0, NUM_SIG_FLAG_CTX_LUMA + ctxIdx ).getEntropyBits( uiBin );
1516      }
1517    }
1518  }
1519  Int iBitsX = 0, iBitsY = 0;
1520  Int blkSizeOffsetX, blkSizeOffsetY, shiftX, shiftY;
1521
1522  blkSizeOffsetX = eTType ? 0: (g_aucConvertToBit[ width ] *3 + ((g_aucConvertToBit[ width ] +1)>>2));
1523  blkSizeOffsetY = eTType ? 0: (g_aucConvertToBit[ height ]*3 + ((g_aucConvertToBit[ height ]+1)>>2));
1524  shiftX = eTType ? g_aucConvertToBit[ width  ] :((g_aucConvertToBit[ width  ]+3)>>2);
1525  shiftY = eTType ? g_aucConvertToBit[ height ] :((g_aucConvertToBit[ height ]+3)>>2);
1526
1527  Int ctx;
1528  ContextModel *pCtxX      = m_cCuCtxLastX.get( 0, eTType );
1529  for (ctx = 0; ctx < g_uiGroupIdx[ width - 1 ]; ctx++)
1530  {
1531    Int ctxOffset = blkSizeOffsetX + (ctx >>shiftX);
1532    pcEstBitsSbac->lastXBits[ ctx ] = iBitsX + pCtxX[ ctxOffset ].getEntropyBits( 0 );
1533    iBitsX += pCtxX[ ctxOffset ].getEntropyBits( 1 );
1534  }
1535  pcEstBitsSbac->lastXBits[ctx] = iBitsX;
1536  ContextModel *pCtxY      = m_cCuCtxLastY.get( 0, eTType );
1537  for (ctx = 0; ctx < g_uiGroupIdx[ height - 1 ]; ctx++)
1538  {
1539    Int ctxOffset = blkSizeOffsetY + (ctx >>shiftY);
1540    pcEstBitsSbac->lastYBits[ ctx ] = iBitsY + pCtxY[ ctxOffset ].getEntropyBits( 0 );
1541    iBitsY += pCtxY[ ctxOffset ].getEntropyBits( 1 );
1542  }
1543  pcEstBitsSbac->lastYBits[ctx] = iBitsY;
1544}
1545
1546/*!
1547 ****************************************************************************
1548 * \brief
1549 *    estimate bit cost of significant coefficient
1550 ****************************************************************************
1551 */
1552Void TEncSbac::estSignificantCoefficientsBit( estBitsSbacStruct* pcEstBitsSbac, TextType eTType )
1553{
1554  if (eTType==TEXT_LUMA)
1555  {
1556    ContextModel *ctxOne = m_cCUOneSCModel.get(0, 0);
1557    ContextModel *ctxAbs = m_cCUAbsSCModel.get(0, 0);
1558
1559    for (Int ctxIdx = 0; ctxIdx < NUM_ONE_FLAG_CTX_LUMA; ctxIdx++)
1560    {
1561      pcEstBitsSbac->m_greaterOneBits[ ctxIdx ][ 0 ] = ctxOne[ ctxIdx ].getEntropyBits( 0 );
1562      pcEstBitsSbac->m_greaterOneBits[ ctxIdx ][ 1 ] = ctxOne[ ctxIdx ].getEntropyBits( 1 );   
1563    }
1564
1565    for (Int ctxIdx = 0; ctxIdx < NUM_ABS_FLAG_CTX_LUMA; ctxIdx++)
1566    {
1567      pcEstBitsSbac->m_levelAbsBits[ ctxIdx ][ 0 ] = ctxAbs[ ctxIdx ].getEntropyBits( 0 );
1568      pcEstBitsSbac->m_levelAbsBits[ ctxIdx ][ 1 ] = ctxAbs[ ctxIdx ].getEntropyBits( 1 );   
1569    }
1570  }
1571  else
1572  {
1573    ContextModel *ctxOne = m_cCUOneSCModel.get(0, 0) + NUM_ONE_FLAG_CTX_LUMA;
1574    ContextModel *ctxAbs = m_cCUAbsSCModel.get(0, 0) + NUM_ABS_FLAG_CTX_LUMA;
1575
1576    for (Int ctxIdx = 0; ctxIdx < NUM_ONE_FLAG_CTX_CHROMA; ctxIdx++)
1577    {
1578      pcEstBitsSbac->m_greaterOneBits[ ctxIdx ][ 0 ] = ctxOne[ ctxIdx ].getEntropyBits( 0 );
1579      pcEstBitsSbac->m_greaterOneBits[ ctxIdx ][ 1 ] = ctxOne[ ctxIdx ].getEntropyBits( 1 );   
1580    }
1581
1582    for (Int ctxIdx = 0; ctxIdx < NUM_ABS_FLAG_CTX_CHROMA; ctxIdx++)
1583    {
1584      pcEstBitsSbac->m_levelAbsBits[ ctxIdx ][ 0 ] = ctxAbs[ ctxIdx ].getEntropyBits( 0 );
1585      pcEstBitsSbac->m_levelAbsBits[ ctxIdx ][ 1 ] = ctxAbs[ ctxIdx ].getEntropyBits( 1 );   
1586    }
1587  }
1588}
1589
1590/**
1591 - Initialize our context information from the nominated source.
1592 .
1593 \param pSrc From where to copy context information.
1594 */
1595Void TEncSbac::xCopyContextsFrom( TEncSbac* pSrc )
1596{ 
1597  memcpy(m_contextModels, pSrc->m_contextModels, m_numContextModels*sizeof(m_contextModels[0]));
1598}
1599
1600Void  TEncSbac::loadContexts ( TEncSbac* pScr)
1601{
1602  this->xCopyContextsFrom(pScr);
1603}
1604
1605#if SVC_EXTENSION
1606Void TEncSbac::codeSAOOffsetParam(Int compIdx, SAOOffset& ctbParam, Bool sliceEnabled, UInt* saoMaxOffsetQVal)
1607#else
1608Void TEncSbac::codeSAOOffsetParam(Int compIdx, SAOOffset& ctbParam, Bool sliceEnabled)
1609#endif
1610{
1611  UInt uiSymbol;
1612  if(!sliceEnabled)
1613  {
1614    assert(ctbParam.modeIdc == SAO_MODE_OFF);
1615    return;
1616  }
1617
1618  //type
1619  if(compIdx == SAO_Y || compIdx == SAO_Cb)
1620  {
1621    //sao_type_idx_luma or sao_type_idx_chroma
1622    if(ctbParam.modeIdc == SAO_MODE_OFF)
1623    {
1624      uiSymbol =0;
1625    }
1626    else if(ctbParam.typeIdc == SAO_TYPE_BO) //BO
1627    {
1628      uiSymbol = 1;
1629    }
1630    else
1631    {
1632      assert(ctbParam.typeIdc < SAO_TYPE_START_BO); //EO
1633      uiSymbol = 2;
1634    }
1635    codeSaoTypeIdx(uiSymbol); 
1636  }
1637
1638  if(ctbParam.modeIdc == SAO_MODE_NEW)
1639  {
1640    Int numClasses = (ctbParam.typeIdc == SAO_TYPE_BO)?4:NUM_SAO_EO_CLASSES; 
1641    Int offset[4];
1642    Int k=0;
1643    for(Int i=0; i< numClasses; i++)
1644    {
1645      if(ctbParam.typeIdc != SAO_TYPE_BO && i == SAO_CLASS_EO_PLAIN)
1646      {
1647        continue;
1648      }
1649      Int classIdx = (ctbParam.typeIdc == SAO_TYPE_BO)?(  (ctbParam.typeAuxInfo+i)% NUM_SAO_BO_CLASSES   ):i;
1650      offset[k] = ctbParam.offset[classIdx];
1651      k++;
1652    }
1653
1654    for(Int i=0; i< 4; i++)
1655    {
1656#if SVC_EXTENSION
1657      codeSaoMaxUvlc((offset[i]<0)?(-offset[i]):(offset[i]),  saoMaxOffsetQVal[compIdx] ); //sao_offset_abs
1658#else
1659      codeSaoMaxUvlc((offset[i]<0)?(-offset[i]):(offset[i]),  g_saoMaxOffsetQVal[compIdx] ); //sao_offset_abs
1660#endif
1661    }
1662
1663
1664    if(ctbParam.typeIdc == SAO_TYPE_BO)
1665    {
1666      for(Int i=0; i< 4; i++)
1667      {
1668        if(offset[i] != 0)
1669        {
1670          codeSAOSign((offset[i]< 0)?1:0);
1671        }
1672      }
1673
1674      codeSaoUflc(NUM_SAO_BO_CLASSES_LOG2, ctbParam.typeAuxInfo ); //sao_band_position
1675    }
1676    else //EO
1677    {
1678      if(compIdx == SAO_Y || compIdx == SAO_Cb)
1679      {
1680        assert(ctbParam.typeIdc - SAO_TYPE_START_EO >=0);
1681        codeSaoUflc(NUM_SAO_EO_TYPES_LOG2, ctbParam.typeIdc - SAO_TYPE_START_EO ); //sao_eo_class_luma or sao_eo_class_chroma
1682      }
1683    }
1684
1685  }
1686}
1687
1688
1689Void TEncSbac::codeSAOBlkParam(SAOBlkParam& saoBlkParam
1690#if SVC_EXTENSION
1691                              , UInt* saoMaxOffsetQVal
1692#endif
1693                              , Bool* sliceEnabled
1694                              , Bool leftMergeAvail
1695                              , Bool aboveMergeAvail
1696                              , Bool onlyEstMergeInfo // = false
1697                              )
1698{
1699
1700  Bool isLeftMerge = false;
1701  Bool isAboveMerge= false;
1702
1703  if(leftMergeAvail)
1704  {
1705    isLeftMerge = ((saoBlkParam[SAO_Y].modeIdc == SAO_MODE_MERGE) && (saoBlkParam[SAO_Y].typeIdc == SAO_MERGE_LEFT));
1706    codeSaoMerge( isLeftMerge?1:0  ); //sao_merge_left_flag
1707  }
1708
1709  if( aboveMergeAvail && !isLeftMerge)
1710  {
1711    isAboveMerge = ((saoBlkParam[SAO_Y].modeIdc == SAO_MODE_MERGE) && (saoBlkParam[SAO_Y].typeIdc == SAO_MERGE_ABOVE)); 
1712    codeSaoMerge( isAboveMerge?1:0  ); //sao_merge_left_flag
1713  }
1714
1715  if(onlyEstMergeInfo)
1716  {
1717    return; //only for RDO
1718  }
1719
1720  if(!isLeftMerge && !isAboveMerge) //not merge mode
1721  {
1722    for(Int compIdx=0; compIdx < NUM_SAO_COMPONENTS; compIdx++)
1723    {
1724#if SVC_EXTENSION
1725      codeSAOOffsetParam(compIdx, saoBlkParam[compIdx], sliceEnabled[compIdx], saoMaxOffsetQVal);
1726#else
1727      codeSAOOffsetParam(compIdx, saoBlkParam[compIdx], sliceEnabled[compIdx]);
1728#endif
1729    }
1730  }
1731}
1732
1733//! \}
Note: See TracBrowser for help on using the repository browser.