source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncSlice.cpp @ 109

Last change on this file since 109 was 102, checked in by tech, 12 years ago

SAIT_VSO_EST_A0033 code improvement

  • Property svn:eol-style set to native
File size: 64.9 KB
RevLine 
[5]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
[56]4 * granted under this license. 
[5]5 *
[56]6 * Copyright (c) 2010-2012, ITU/ISO/IEC
[5]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.
[56]17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
[5]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 */
[2]33
34/** \file     TEncSlice.cpp
35    \brief    slice encoder class
36*/
37
38#include "TEncTop.h"
39#include "TEncSlice.h"
[101]40#if HHI_VSO_SPEEDUP_A0033
[100]41#include "../../App/TAppEncoder/TAppEncTop.h"
42#endif
[56]43#include <math.h>
[2]44
[56]45//! \ingroup TLibEncoder
46//! \{
47
[2]48// ====================================================================================================================
49// Constructor / destructor / create / destroy
50// ====================================================================================================================
51
52TEncSlice::TEncSlice()
53{
54  m_apcPicYuvPred = NULL;
55  m_apcPicYuvResi = NULL;
[56]56 
[2]57  m_pdRdPicLambda = NULL;
58  m_pdRdPicQp     = NULL;
59  m_piRdPicQp     = NULL;
[56]60  m_pcBufferSbacCoders    = NULL;
61  m_pcBufferBinCoderCABACs  = NULL;
62  m_pcBufferLowLatSbacCoders    = NULL;
63  m_pcBufferLowLatBinCoderCABACs  = NULL;
[2]64}
65
66TEncSlice::~TEncSlice()
67{
68}
69
70Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
71{
72  // create prediction picture
73  if ( m_apcPicYuvPred == NULL )
74  {
75    m_apcPicYuvPred  = new TComPicYuv;
76    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
77  }
[56]78 
[2]79  // create residual picture
80  if( m_apcPicYuvResi == NULL )
81  {
82    m_apcPicYuvResi  = new TComPicYuv;
83    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
84  }
85}
86
87Void TEncSlice::destroy()
88{
89  // destroy prediction picture
90  if ( m_apcPicYuvPred )
91  {
92    m_apcPicYuvPred->destroy();
93    delete m_apcPicYuvPred;
94    m_apcPicYuvPred  = NULL;
95  }
[56]96 
[2]97  // destroy residual picture
98  if ( m_apcPicYuvResi )
99  {
100    m_apcPicYuvResi->destroy();
101    delete m_apcPicYuvResi;
102    m_apcPicYuvResi  = NULL;
103  }
[56]104 
[2]105  // free lambda and QP arrays
106  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
107  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
108  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
[56]109
110  if ( m_pcBufferSbacCoders )
111  {
112    delete[] m_pcBufferSbacCoders;
113  }
114  if ( m_pcBufferBinCoderCABACs )
115  {
116    delete[] m_pcBufferBinCoderCABACs;
117  }
118  if ( m_pcBufferLowLatSbacCoders )
119    delete[] m_pcBufferLowLatSbacCoders;
120  if ( m_pcBufferLowLatBinCoderCABACs )
121    delete[] m_pcBufferLowLatBinCoderCABACs;
[2]122}
123
124Void TEncSlice::init( TEncTop* pcEncTop )
125{
126  m_pcCfg             = pcEncTop;
127  m_pcListPic         = pcEncTop->getListPic();
[56]128 
129  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
[2]130  m_pcCuEncoder       = pcEncTop->getCuEncoder();
131  m_pcPredSearch      = pcEncTop->getPredSearch();
[56]132 
[2]133  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
134  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
135  m_pcSbacCoder       = pcEncTop->getSbacCoder();
136  m_pcBinCABAC        = pcEncTop->getBinCABAC();
137  m_pcTrQuant         = pcEncTop->getTrQuant();
[56]138 
[2]139  m_pcBitCounter      = pcEncTop->getBitCounter();
140  m_pcRdCost          = pcEncTop->getRdCost();
141  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
142  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
[56]143 
[2]144  // create lambda and QP arrays
145  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
146  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
147  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
148}
149
150/**
151 - non-referenced frame marking
152 - QP computation based on temporal structure
153 - lambda computation based on QP
[56]154 - set temporal layer ID and the parameter sets
[2]155 .
156 \param pcPic         picture class
157 \param iPOCLast      POC of last picture
158 \param uiPOCCurr     current POC
159 \param iNumPicRcvd   number of received pictures
160 \param iTimeOffset   POC offset for hierarchical structure
161 \param iDepth        temporal layer depth
162 \param rpcSlice      slice header class
[56]163 \param pSPS          SPS associated with the slice
164 \param pPPS          PPS associated with the slice
[2]165 */
[77]166#if VIDYO_VPS_INTEGRATION
167Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComVPS * pVPS, TComSPS* pSPS, TComPPS *pPPS )
168#else
[56]169Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
[77]170#endif
[2]171{
172  Double dQP;
173  Double dLambda;
[56]174 
[2]175  rpcSlice = pcPic->getSlice(0);
[77]176#if VIDYO_VPS_INTEGRATION
177  rpcSlice->setVPS( pVPS );
178#endif
[56]179  rpcSlice->setSPS( pSPS );
180  rpcSlice->setPPS( pPPS );
[2]181  rpcSlice->setSliceBits(0);
182  rpcSlice->setPic( pcPic );
183  rpcSlice->initSlice();
[56]184  rpcSlice->initTiles();
185#if H0388
186  rpcSlice->setPicOutputFlag( true );
[42]187#endif
[56]188  rpcSlice->setPOC( uiPOCCurr );
189 
[21]190#if SONY_COLPIC_AVAILABILITY
191  rpcSlice->setViewOrderIdx(m_pcCfg->getViewOrderIdx());
192#endif
[5]193
[56]194  // set mutliview parameters
195  rpcSlice->initMultiviewSlice( pcPic->getCodedScale(), pcPic->getCodedOffset() );
196
197  // depth computation based on GOP size
198  int iDepth;
199  {
200    Int i, j;
201    Int iPOC = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
202    if ( iPOC == 0 )
203    {
204      iDepth = 0;
205    }
206    else
207    {
208      Int iStep = m_pcCfg->getGOPSize();
209      iDepth    = 0;
210      for( i=iStep>>1; i>=1; i>>=1 )
211      {
212        for ( j=i; j<m_pcCfg->getGOPSize(); j+=iStep )
213        {
214          if ( j == iPOC )
215          {
216            i=0;
217            break;
218          }
219        }
220        iStep>>=1;
221        iDepth++;
222      }
223    }
224  }
225 
[2]226  // slice type
[56]227  SliceType eSliceTypeBaseView;
228  if( iPOCLast == 0 || uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0 )
229  {
230    eSliceTypeBaseView = I_SLICE;
231  }
232  else
233  {
234    eSliceTypeBaseView = B_SLICE;
235  }
236  SliceType eSliceType = eSliceTypeBaseView;
237  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
238  {
239    eSliceType = B_SLICE; 
240  }
241  rpcSlice->setSliceType( eSliceType );
242 
[2]243  // ------------------------------------------------------------------------------------------------------------------
244  // Non-referenced frame marking
245  // ------------------------------------------------------------------------------------------------------------------
[56]246  rpcSlice->setReferenced( m_pcCfg->getGOPEntry(iGOPid).m_refPic );
247  if( eSliceTypeBaseView == I_SLICE )
248  {
249    rpcSlice->setReferenced(true);
250  }
251 
[2]252  // ------------------------------------------------------------------------------------------------------------------
253  // QP setting
254  // ------------------------------------------------------------------------------------------------------------------
[56]255 
256  dQP = m_pcCfg->getQP();
257  if( eSliceType != I_SLICE )
258  {
259#if LOSSLESS_CODING
260#if H0736_AVC_STYLE_QP_RANGE
261    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless()))) 
262#else
263    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == 0 ) && (rpcSlice->getSPS()->getUseLossless())))
264#endif
265#endif
266    {
267    dQP += m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPOffset;
268    }
269  }
270 
271  // modify QP
272  Int* pdQPs = m_pcCfg->getdQPs();
273  if ( pdQPs )
274  {
275    dQP += pdQPs[ rpcSlice->getPOC() ];
276  }
277 
[2]278  // ------------------------------------------------------------------------------------------------------------------
279  // Lambda computation
280  // ------------------------------------------------------------------------------------------------------------------
[56]281 
[2]282  Int iQP;
[56]283  Double dOrigQP = dQP;
[2]284
285  // pre-compute lambda and QP values for all possible QP candidates
286  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
287  {
288    // compute QP value
289    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
[56]290   
[2]291    // compute lambda value
[56]292    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
[2]293    Int    SHIFT_QP = 12;
294    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
295#if FULL_NBIT
296    Int    bitdepth_luma_qp_scale = 6 * (g_uiBitDepth - 8);
297#else
298    Int    bitdepth_luma_qp_scale = 0;
299#endif
[56]300    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
[2]301#if FULL_NBIT
[56]302    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
[2]303#endif
304    // Case #1: I or P-slices (key-frame)
[56]305    Double dQPFactor;
306    if( eSliceType != I_SLICE ) 
[2]307    {
[56]308      dQPFactor = m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPFactor;
[2]309    }
[56]310    else
[2]311    {
[56]312      dQPFactor = 0.57 * dLambda_scale;
313    }
314
315    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
316
317    if ( iDepth>0 )
318    {
[2]319#if FULL_NBIT
320        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
321#else
322        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
323#endif
324    }
[56]325   
[2]326    // if hadamard is used in ME process
[56]327    if ( !m_pcCfg->getUseHADME() )
328    {
329      dLambda *= 0.95;
330    }
331   
332#if H0736_AVC_STYLE_QP_RANGE
333    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
334#else
335    iQP = max( MIN_QP, min( MAX_QP, (Int)floor( dQP + 0.5 ) ) );
336#endif
[5]337
[2]338    m_pdRdPicLambda[iDQpIdx] = dLambda;
339    m_pdRdPicQp    [iDQpIdx] = dQP;
340    m_piRdPicQp    [iDQpIdx] = iQP;
341  }
[56]342 
[2]343  // obtain dQP = 0 case
344  dLambda = m_pdRdPicLambda[0];
345  dQP     = m_pdRdPicQp    [0];
346  iQP     = m_piRdPicQp    [0];
[56]347 
348  if( rpcSlice->getSliceType( ) != I_SLICE )
349  {
350    dLambda *= m_pcCfg->getLambdaModifier( iDepth );
351  }
[5]352
[2]353  // store lambda
[56]354  m_pcRdCost ->setLambda( dLambda );
355#if WEIGHTED_CHROMA_DISTORTION
356// for RDO
357  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
358#if H0736_AVC_STYLE_QP_RANGE
359  Double weight = 1.0;
360  if(iQP >= 0)
361  {
362    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
363  }
364#else
365  Double weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
366#endif
367  m_pcRdCost ->setChromaDistortionWeight( weight );     
368#endif
369
[5]370#if HHI_VSO
371  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->isDepthCoder()  );
372  m_pcRdCost->setLambdaVSO( dLambda * m_pcCfg->getLambdaScaleVSO() );
373#endif
[2]374
[102]375#if SAIT_VSO_EST_A0033
376  m_pcRdCost->setDisparityCoeff( m_pcCfg->getDispCoeff() );
377#endif
378
[56]379#if RDOQ_CHROMA_LAMBDA
380// for RDOQ
381  m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
382#else
383  m_pcTrQuant->setLambda( dLambda );
384#endif
385
386#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
387// For ALF or SAO
388  rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
389#else
390  rpcSlice   ->setLambda( dLambda );
391#endif
392 
[5]393#if HHI_INTER_VIEW_MOTION_PRED
[2]394  m_pcRdCost ->setLambdaMVReg ( dLambda * m_pcCfg->getMultiviewMvRegLambdaScale() );
[5]395#endif
[56]396 
397#if HB_LAMBDA_FOR_LDC
398  // restore original slice type
399  eSliceType = eSliceTypeBaseView;
400  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
401  {
402    eSliceType = B_SLICE;
403  }
404  rpcSlice->setSliceType( eSliceType );
405#endif
406 
[2]407  rpcSlice->setSliceQp          ( iQP );
[56]408#if ADAPTIVE_QP_SELECTION
409  rpcSlice->setSliceQpBase      ( iQP );
410#endif
[2]411  rpcSlice->setSliceQpDelta     ( 0 );
[56]412  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
413  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
414 
415  rpcSlice->setLoopFilterOffsetInAPS( m_pcCfg->getLoopFilterOffsetInAPS() );
416#if DBL_CONTROL
417  if (rpcSlice->getPPS()->getDeblockingFilterControlPresent())
418  {
419#endif
420    rpcSlice->setInheritDblParamFromAPS( m_pcCfg->getLoopFilterOffsetInAPS() ? 1 : 0 );
421    rpcSlice->setLoopFilterDisable( m_pcCfg->getLoopFilterDisable() );
422    if ( !rpcSlice->getLoopFilterDisable())
423    {
424      rpcSlice->setLoopFilterBetaOffset( m_pcCfg->getLoopFilterBetaOffset() );
425      rpcSlice->setLoopFilterTcOffset( m_pcCfg->getLoopFilterTcOffset() );
426    }
427#if DBL_CONTROL
428  }
429#endif
[5]430
[56]431  rpcSlice->setDepth            ( iDepth );
432 
433  pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId );
434  if( eSliceType == I_SLICE )
435  {
436    pcPic->setTLayer(0);
437  }
438  rpcSlice->setTLayer( pcPic->getTLayer() );
439#if !H0566_TLA
440  rpcSlice->setTLayerSwitchingFlag( pPPS->getTLayerSwitchingFlag( pcPic->getTLayer() ) );
441#endif
[5]442
[2]443  assert( m_apcPicYuvPred );
444  assert( m_apcPicYuvResi );
[56]445 
[2]446  pcPic->setPicYuvPred( m_apcPicYuvPred );
447  pcPic->setPicYuvResi( m_apcPicYuvResi );
448  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
449  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
450  rpcSlice->setEntropySliceMode     ( m_pcCfg->getEntropySliceMode()     );
451  rpcSlice->setEntropySliceArgument ( m_pcCfg->getEntropySliceArgument() );
[56]452
453#if ( HHI_MPI || HHI_INTER_VIEW_MOTION_PRED )
454  #if ( HHI_MPI && HHI_INTER_VIEW_MOTION_PRED )
455  const int iExtraMergeCandidates = ( pSPS->getUseMVI() || pSPS->getMultiviewMvPredMode() ) ? 1 : 0;
456  #elif HHI_MPI
457  const int iExtraMergeCandidates = pSPS->getUseMVI() ? 1 : 0;
458  #else
459  const int iExtraMergeCandidates = pSPS->getMultiviewMvPredMode() ? 1 : 0;
460  #endif
461  rpcSlice->setMaxNumMergeCand      (MRG_MAX_NUM_CANDS_SIGNALED+iExtraMergeCandidates);
462#else
463  rpcSlice->setMaxNumMergeCand      (MRG_MAX_NUM_CANDS_SIGNALED);
464#endif
465  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPredIdc() );
[2]466}
467
468// ====================================================================================================================
469// Public member functions
470// ====================================================================================================================
471
472Void TEncSlice::setSearchRange( TComSlice* pcSlice )
473{
474  Int iCurrPOC = pcSlice->getPOC();
475  Int iRefPOC;
[56]476  Int iGOPSize = m_pcCfg->getGOPSize();
477  Int iOffset = (iGOPSize >> 1);
[2]478  Int iMaxSR = m_pcCfg->getSearchRange();
479  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
[56]480 
[2]481  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
482  {
483    RefPicList e = (RefPicList)iDir;
484    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
485    {
486      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
[56]487      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
[2]488      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
489    }
490  }
491}
492
493/**
494 - multi-loop slice encoding for different slice QP
495 .
496 \param rpcPic    picture class
497 */
498Void TEncSlice::precompressSlice( TComPic*& rpcPic )
499{
500  // if deltaQP RD is not used, simply return
[56]501  if ( m_pcCfg->getDeltaQpRD() == 0 )
502  {
503    return;
504  }
505 
[2]506  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
507  Double     dPicRdCostBest = MAX_DOUBLE;
508  UInt       uiQpIdxBest = 0;
[56]509 
[2]510  Double dFrameLambda;
511#if FULL_NBIT
512  Int    SHIFT_QP = 12 + 6 * (g_uiBitDepth - 8);
513#else
514  Int    SHIFT_QP = 12;
515#endif
[56]516 
[2]517  // set frame lambda
518  if (m_pcCfg->getGOPSize() > 1)
519  {
520    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
521  }
522  else
523  {
524    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
525  }
526  m_pcRdCost      ->setFrameLambda(dFrameLambda);
[56]527 
[2]528  // for each QP candidate
529  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
530  {
531    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
[56]532#if ADAPTIVE_QP_SELECTION
533    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
534#endif
[2]535    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
[56]536#if WEIGHTED_CHROMA_DISTORTION
537    // for RDO
538    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
539    int iQP = m_piRdPicQp    [uiQpIdx];
540#if H0736_AVC_STYLE_QP_RANGE
541    Double weight = 1.0;
542    if(iQP >= 0)
543    {
544      weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
545    }
546#else
547    Double weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
548#endif
549    m_pcRdCost    ->setChromaDistortionWeight( weight );     
550#endif
551
552#if RDOQ_CHROMA_LAMBDA
553    // for RDOQ
554    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
555#else
[2]556    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
[56]557#endif
558#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
559    // For ALF or SAO
560    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
561#else
[2]562    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
[56]563#endif
[5]564#if HHI_INTER_VIEW_MOTION_PRED
[2]565    m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdx] * m_pcCfg->getMultiviewMvRegLambdaScale() );
[5]566#endif
[56]567   
[2]568    // try compress
569    compressSlice   ( rpcPic );
[56]570   
[2]571    Double dPicRdCost;
572    UInt64 uiPicDist        = m_uiPicDist;
573    UInt64 uiALFBits        = 0;
[56]574   
575    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
576   
[2]577    // compute RD cost and choose the best
578    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
[56]579   
[2]580    if ( dPicRdCost < dPicRdCostBest )
581    {
582      uiQpIdxBest    = uiQpIdx;
583      dPicRdCostBest = dPicRdCost;
584    }
585  }
[56]586 
[2]587  // set best values
588  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
[56]589#if ADAPTIVE_QP_SELECTION
590  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
591#endif
[2]592  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
[56]593#if WEIGHTED_CHROMA_DISTORTION
594  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
595  int iQP = m_piRdPicQp    [uiQpIdxBest];
596#if H0736_AVC_STYLE_QP_RANGE
597  Double weight = 1.0;
598  if(iQP >= 0)
599  {
600    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
601  }
602#else
603  Double weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
604#endif
605  m_pcRdCost ->setChromaDistortionWeight( weight );     
606#endif
607
608#if RDOQ_CHROMA_LAMBDA
609  // for RDOQ
610  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
611#else
[2]612  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
[56]613#endif
614#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
615  // For ALF or SAO
616  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
617#else
[2]618  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
[56]619#endif
[5]620#if HHI_INTER_VIEW_MOTION_PRED
[2]621  m_pcRdCost    ->setLambdaMVReg         ( m_pdRdPicLambda[uiQpIdxBest] * m_pcCfg->getMultiviewMvRegLambdaScale() );
[5]622#endif
[2]623}
624
625/** \param rpcPic   picture class
626 */
627Void TEncSlice::compressSlice( TComPic*& rpcPic )
628{
629  UInt  uiCUAddr;
630  UInt   uiStartCUAddr;
631  UInt   uiBoundingCUAddr;
[56]632  rpcPic->getSlice(getSliceIdx())->setEntropySliceCounter(0);
[2]633  TEncBinCABAC* pppcRDSbacCoder = NULL;
634  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
635  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
[100]636#if LG_ZEROINTRADEPTHRESI_M26039
637  rpcPic->setIntraPeriod(this->m_pcCfg->getIntraPeriod());
638#endif
[56]639 
[2]640  // initialize cost values
641  m_uiPicTotalBits  = 0;
642  m_dPicRdCost      = 0;
643  m_uiPicDist       = 0;
[56]644 
[101]645#if CABAC_INIT_FLAG && POZNAN_CABAC_INIT_FLAG_FIX
646  Bool bReset =(pcSlice->getPOC() == 0) || 
647    (pcSlice->getPOC() % m_pcCfg->getIntraPeriod() == 0) ||
648    (pcSlice->getPPS()->getEncPrevPOC() % m_pcCfg->getIntraPeriod() == 0) ||
649    (pcSlice->getPOC()/m_pcCfg->getIntraPeriod() > pcSlice->getPPS()->getEncPrevPOC()/m_pcCfg->getIntraPeriod()) ||
650    (m_pcGOPEncoder->getGOPSize() == 0);
651
652  if ( bReset && pcSlice->getPPS()->getCabacInitPresentFlag())
653  {
654    pcSlice->getPPS()->setEncCABACTableIdx(pcSlice->getSliceType()); // reset cabac initialization table index
655  };
656#endif
657
[2]658  // set entropy coder
659  if( m_pcCfg->getUseSBACRD() )
660  {
661    m_pcSbacCoder->init( m_pcBinCABAC );
662    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
663    m_pcEntropyCoder->resetEntropy      ();
664    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
665    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
666    pppcRDSbacCoder->setBinCountingEnableFlag( false );
667    pppcRDSbacCoder->setBinsCoded( 0 );
668  }
669  else
670  {
671    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
672    m_pcEntropyCoder->resetEntropy      ();
673    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
674  }
[56]675 
676  //------------------------------------------------------------------------------
677  //  Weighted Prediction parameters estimation.
678  //------------------------------------------------------------------------------
679  // calculate AC/DC values for current picture
680  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPredIdc() )
681  {
682    xCalcACDCParamSlice(pcSlice);
683  }
[5]684
[56]685  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==1);
686  Bool bWp_implicit = (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPredIdc()==2);
687
688  if ( bWp_explicit || bWp_implicit )
689  {
690    //------------------------------------------------------------------------------
691    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
692    //------------------------------------------------------------------------------
693    if ( pcSlice->getSliceMode()==2 || pcSlice->getEntropySliceMode()==2 )
694    {
695      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
696    }
697
698    if( bWp_explicit )
699    {
700      xEstimateWPParamSlice( pcSlice );
701    }
702   
703    pcSlice->initWpScaling();
704
705    // check WP on/off
706    if( bWp_explicit )
707    {
708      xCheckWPEnable( pcSlice );
709    }
710  }
711
712#if ADAPTIVE_QP_SELECTION
713  if( m_pcCfg->getUseAdaptQpSelect() )
714  {
715    m_pcTrQuant->clearSliceARLCnt();
716    if(pcSlice->getSliceType()!=I_SLICE)
717    {
718      Int qpBase = pcSlice->getSliceQpBase();
719      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
720    }
721  }
722#endif
[2]723  // initialize ALF parameters
724  m_pcEntropyCoder->setAlfCtrl(false);
725  m_pcEntropyCoder->setMaxAlfCtrlDepth(0); //unnecessary
[56]726 
[100]727#if SAIT_VSO_EST_A0033
728 if( m_pcCfg->getUseVSO() )
729 {
730
731   Int frameWidth = m_pcCfg->getSourceWidth();
732   Pel* pVideoRec = m_pcRdCost->getVideoRecPicYuv()->getLumaAddr();
733   Int iVideoRecStride = m_pcRdCost->getVideoRecPicYuv()->getStride();
734
735   Pel* pDepthOrg = m_pcRdCost->getDepthPicYuv()->getLumaAddr();
736   Int iDepthOrgStride = m_pcRdCost->getDepthPicYuv()->getStride();
737
738   for( Int y = 0 ; y < m_pcCfg->getSourceHeight() ; y++ )
739   {
[102]740     pVideoRec[-1] = pVideoRec[0];
741     pVideoRec[frameWidth] = pVideoRec[frameWidth-1];
742     pDepthOrg[-1] = pDepthOrg[0];
743     pDepthOrg[frameWidth] = pDepthOrg[frameWidth-1];
[100]744
745     pVideoRec += iVideoRecStride;
746     pDepthOrg += iDepthOrgStride;
747   }
748 }
749#endif
[102]750
[56]751  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
752  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
753  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
754  Int  iNumSubstreams = 1;
755  UInt uiTilesAcross  = 0;
[5]756
[56]757  if( m_pcCfg->getUseSBACRD() )
758  {
759    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
760    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
761    delete[] m_pcBufferSbacCoders;
762    delete[] m_pcBufferBinCoderCABACs;
763    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
764    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
765    for (int ui = 0; ui < uiTilesAcross; ui++)
766    {
767      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
768    }
769    for (UInt ui = 0; ui < uiTilesAcross; ui++)
770    {
771      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
772    }
773
774    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
775    {
776      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
777    }
778  }
779  //if( m_pcCfg->getUseSBACRD() )
780  {
781    delete[] m_pcBufferLowLatSbacCoders;
782    delete[] m_pcBufferLowLatBinCoderCABACs;
783    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
784    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
785    for (int ui = 0; ui < uiTilesAcross; ui++)
786    {
787      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
788    }
789    for (UInt ui = 0; ui < uiTilesAcross; ui++)
790      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
791  }
792  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
793  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
794  UInt uiCol=0, uiLin=0, uiSubStrm=0;
795#if !REMOVE_TILE_DEPENDENCE
796  Int  iBreakDep      = 0;
797#endif
798  UInt uiTileCol      = 0;
799  UInt uiTileStartLCU = 0;
800  UInt uiTileLCUX     = 0;
801
[101]802#if HHI_VSO_SPEEDUP_A0033
[100]803  Int iLastPosY = -1;
804#endif
805
[2]806  // for every CU in slice
[56]807  UInt uiEncCUOrder;
808  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
809  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
810       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
811       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
[2]812  {
813    // initialize CU encoder
814    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
815    pcCU->initCU( rpcPic, uiCUAddr );
[5]816
[101]817#if HHI_VSO_SPEEDUP_A0033
[100]818    if ( m_pcRdCost->getUseRenModel() )
819    {
820      // updated renderer model if necessary
821      Int iCurPosX;
822      Int iCurPosY; 
823      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
824      if ( iCurPosY != iLastPosY )
825      {
826        iLastPosY = iCurPosY; 
827       
828        m_pcGOPEncoder->getEncTop()->getEncTop()->setupRenModel( rpcPic->getCurrSlice()->getPOC() , rpcPic->getCurrSlice()->getSPS()->getViewId(), rpcPic->getCurrSlice()->getSPS()->isDepth() ? 1 : 0, iCurPosY );
829      }
830    }   
831#endif
832
833
[56]834    // inherit from TR if necessary, select substream to use.
835    if( m_pcCfg->getUseSBACRD() )
836    {
837#if !REMOVE_TILE_DEPENDENCE
838      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
839#endif
840      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
841      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
842      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
843      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
844      uiCol     = uiCUAddr % uiWidthInLCUs;
845      uiLin     = uiCUAddr / uiWidthInLCUs;
846#if !REMOVE_TILE_DEPENDENCE
847#if WPP_SIMPLIFICATION
848      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
849#else
850      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
851#endif
852#else
853#if WPP_SIMPLIFICATION
854      if (pcSlice->getPPS()->getNumSubstreams() > 1)
855#else
856      if (pcSlice->getPPS()->getEntropyCodingSynchro())
857#endif
858#endif
859      {
860        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
861        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
862        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
863                      + uiLin%iNumSubstreamsPerTile;
864      }
865      else
866      {
867        // dependent tiles => substreams are "per frame".
868        uiSubStrm = uiLin % iNumSubstreams;
869      }
870#if WPP_SIMPLIFICATION
871      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
872#else
873      if ( pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX) )
874#endif
875      {
876        // We'll sync if the TR is available.
877        TComDataCU *pcCUUp = pcCU->getCUAbove();
878        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
879        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
880        TComDataCU *pcCUTR = NULL;
881#if WPP_SIMPLIFICATION
882        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
883        {
884          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
885        }
886#else
887        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
888        {
889          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
890        }
891#endif
892        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
893             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
894#if !REMOVE_TILE_DEPENDENCE
895             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
896#else
897             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
898#endif
899             )||
900             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
901             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
902#if !REMOVE_TILE_DEPENDENCE
903             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
904#else
905             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
906#endif
907             )
908           )
909        {
910          // TR not available.
911        }
912        else
913        {
914          // TR is available, we use it.
915          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
916        }
917      }
918      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
919    }
920
921    // reset the entropy coder
922    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
923        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
924        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
925    {
926#if CABAC_INIT_FLAG
927      SliceType sliceType = pcSlice->getSliceType();
928      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
929      {
930        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
931      }
932      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
933      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
934      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
935      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
936#else
937      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp(), false );
938      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
939      m_pcEntropyCoder->updateContextTables ( pcSlice->getSliceType(), pcSlice->getSliceQp() );
940      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
941#endif
942    }
943#if !REMOVE_TILE_DEPENDENCE
944    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
945    {
946      // Synchronize cabac probabilities with LCU among Tiles
947      if( (uiTileLCUX != 0) &&
948          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
949      { 
950        TComDataCU *pcCULeft = pcCU->getCULeft();
951        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
952
953        if ( (true/*bEnforceSliceRestriction*/ &&
954              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
955               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
956              )
957             )||
958             (true/*bEnforceEntropySliceRestriction*/ &&
959              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
960               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
961              )
962             )
963           )
964        {
965          // Left not available.
966        }
967        else
968        {
969          // Left is available, we use it.
970          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
971          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
972        }
973      }
974    }
975#endif
[2]976    // if RD based on SBAC is used
977    if( m_pcCfg->getUseSBACRD() )
978    {
979      // set go-on entropy coder
980      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
[56]981      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
982     
983      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
[2]984      // run CU encoder
985      m_pcCuEncoder->compressCU( pcCU );
[56]986     
[2]987      // restore entropy coder to an initial stage
988      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
[56]989      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
990      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
991      m_pcBitCounter = &pcBitCounters[uiSubStrm];
[2]992      pppcRDSbacCoder->setBinCountingEnableFlag( true );
[56]993      m_pcBitCounter->resetBits();
994      pppcRDSbacCoder->setBinsCoded( 0 );
[2]995      m_pcCuEncoder->encodeCU( pcCU );
996
997      pppcRDSbacCoder->setBinCountingEnableFlag( false );
[56]998      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
[2]999      {
1000        pcSlice->setNextSlice( true );
1001        break;
1002      }
[56]1003      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
[2]1004      {
1005        pcSlice->setNextEntropySlice( true );
1006        break;
1007      }
[56]1008      if( m_pcCfg->getUseSBACRD() )
1009      {
1010         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1011       
1012         //Store probabilties of second LCU in line into buffer
1013#if WPP_SIMPLIFICATION
1014        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
1015#else
1016        if (pcSlice->getPPS()->getEntropyCodingSynchro() && uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro())
1017#endif
1018        {
1019          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1020        }
1021      }
1022#if !REMOVE_TILE_DEPENDENCE
1023      if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1024      {
1025         //Store probabilties for next tile
1026        if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1027            (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1028        {
1029          m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1030        }
1031      }
1032#endif
[2]1033    }
1034    // other case: encodeCU is not called
1035    else
1036    {
1037      m_pcCuEncoder->compressCU( pcCU );
1038      m_pcCuEncoder->encodeCU( pcCU );
[56]1039      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
[2]1040      {
1041        pcSlice->setNextSlice( true );
1042        break;
1043      }
[56]1044      if (m_pcCfg->getEntropySliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE && pcSlice->getEntropySliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getEntropySliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getEntropySliceCurEndCUAddr())
[2]1045      {
1046        pcSlice->setNextEntropySlice( true );
1047        break;
1048      }
1049    }
[56]1050   
[2]1051    m_uiPicTotalBits += pcCU->getTotalBits();
1052    m_dPicRdCost     += pcCU->getTotalCost();
1053    m_uiPicDist      += pcCU->getTotalDistortion();
1054  }
[56]1055  xRestoreWPparam( pcSlice );
[2]1056}
1057
1058/**
1059 \param  rpcPic        picture class
1060 \retval rpcBitstream  bitstream class
1061 */
[56]1062Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcBitstream, TComOutputBitstream* pcSubstreams )
[2]1063{
1064  UInt       uiCUAddr;
1065  UInt       uiStartCUAddr;
1066  UInt       uiBoundingCUAddr;
1067  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1068
[56]1069  uiStartCUAddr=pcSlice->getEntropySliceCurStartCUAddr();
1070  uiBoundingCUAddr=pcSlice->getEntropySliceCurEndCUAddr();
[2]1071  // choose entropy coder
1072  {
1073    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1074    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1075  }
[56]1076 
1077  m_pcCuEncoder->setBitCounter( NULL );
1078  m_pcBitCounter = NULL;
1079  // Appropriate substream bitstream is switched later.
[2]1080  // for every CU
1081#if ENC_DEC_TRACE
1082  g_bJustDoIt = g_bEncDecTraceEnable;
1083#endif
[56]1084  DTRACE_CABAC_VL( g_nSymbolCounter++ );
[2]1085  DTRACE_CABAC_T( "\tPOC: " );
1086  DTRACE_CABAC_V( rpcPic->getPOC() );
1087  DTRACE_CABAC_T( "\n" );
1088#if ENC_DEC_TRACE
1089  g_bJustDoIt = g_bEncDecTraceDisable;
1090#endif
1091
[56]1092  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1093  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1094  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1095  UInt uiBitsOriginallyInSubstreams = 0;
[2]1096  {
[56]1097    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1098    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1099    {
1100      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1101    }
1102   
1103    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1104    {
1105      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1106    }
1107
1108    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1109    {
1110      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1111    }
1112  }
1113
1114  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1115  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1116#if !REMOVE_TILE_DEPENDENCE
1117  Int  iBreakDep      = 0;
1118#endif
1119  UInt uiTileCol      = 0;
1120  UInt uiTileStartLCU = 0;
1121  UInt uiTileLCUX     = 0;
1122
1123  UInt uiEncCUOrder;
1124  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1125                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
1126                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
1127  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1128       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1129       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1130  {
1131    if( m_pcCfg->getUseSBACRD() )
1132    {
1133#if !REMOVE_TILE_DEPENDENCE
1134      iBreakDep = rpcPic->getPicSym()->getTileBoundaryIndependenceIdr();
1135#endif
1136      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1137      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1138      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1139      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1140      uiCol     = uiCUAddr % uiWidthInLCUs;
1141      uiLin     = uiCUAddr / uiWidthInLCUs;
1142#if !REMOVE_TILE_DEPENDENCE
1143#if WPP_SIMPLIFICATION
1144      if (iBreakDep && pcSlice->getPPS()->getNumSubstreams() > 1)
1145#else
1146      if (iBreakDep && pcSlice->getPPS()->getEntropyCodingSynchro())
1147#endif
1148#else
1149#if WPP_SIMPLIFICATION
1150      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1151#else
1152      if (pcSlice->getPPS()->getEntropyCodingSynchro())
1153#endif
1154#endif
1155      {
1156        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1157        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1158        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1159                      + uiLin%iNumSubstreamsPerTile;
1160      }
1161      else
1162      {
1163        // dependent tiles => substreams are "per frame".
1164        uiSubStrm = uiLin % iNumSubstreams;
1165      }
1166
1167      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1168
1169      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1170#if WPP_SIMPLIFICATION
1171      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
1172#else
1173      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX))
1174#endif
1175      {
1176        // We'll sync if the TR is available.
1177        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1178        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1179        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1180        TComDataCU *pcCUTR = NULL;
1181#if WPP_SIMPLIFICATION
1182        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1183        {
1184          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1185        }
1186#else
1187        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+pcSlice->getPPS()->getEntropyCodingSynchro()) < uiWidthInCU)  )
1188        {
1189          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + pcSlice->getPPS()->getEntropyCodingSynchro() );
1190        }
1191#endif
1192        if ( (true/*bEnforceSliceRestriction*/ &&
1193             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1194             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1195#if !REMOVE_TILE_DEPENDENCE
1196             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1197#else
1198             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1199#endif
1200             ))||
1201             (true/*bEnforceEntropySliceRestriction*/ &&
1202             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1203             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getEntropySliceCurStartCUAddr()) ||
1204#if !REMOVE_TILE_DEPENDENCE
1205             (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr() && (rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1206#else
1207             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1208#endif
1209             ))
1210           )
1211        {
1212          // TR not available.
1213        }
1214        else
1215        {
1216          // TR is available, we use it.
1217          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1218        }
1219      }
1220      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1221    }
1222    // reset the entropy coder
1223    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1224        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1225        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1226    {
1227      Int iTileIdx            = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr);
1228      Bool bWriteTileMarker   = false;
1229      // check if current iTileIdx should have a marker
1230      for (Int iEntryIdx=0; iEntryIdx<m_pcCfg->getMaxTileMarkerEntryPoints()-1; iEntryIdx++)
1231      {
1232        bWriteTileMarker = ( (((Int)((iEntryIdx+1)*m_pcCfg->getMaxTileMarkerOffset()+0.5)) == iTileIdx ) && iEntryIdx < (m_pcCfg->getMaxTileMarkerEntryPoints()-1)) ? true : false;
1233        if (bWriteTileMarker)
1234        {
1235          break;
1236        }
1237      }
1238      {
1239        // We're crossing into another tile, tiles are independent.
1240        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1241        // have to perform it here.
1242#if WPP_SIMPLIFICATION
1243        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1244#else
1245        if (pcSlice->getPPS()->getEntropyCodingSynchro())
1246#endif
1247        {
1248          ; // do nothing.
1249        }
1250        else
1251        {
1252#if CABAC_INIT_FLAG
1253          SliceType sliceType  = pcSlice->getSliceType();
1254          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=0)
1255          {
1256            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1257          }
1258          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1259#else
1260          m_pcEntropyCoder->updateContextTables( pcSlice->getSliceType(), pcSlice->getSliceQp() );
1261#endif
1262          pcSubstreams[uiSubStrm].write( 1, 1 );
1263          pcSubstreams[uiSubStrm].writeAlignZero();
1264        }
1265      }
1266      {
1267        // Write TileMarker into the appropriate substream (nothing has been written to it yet).
1268        if (m_pcCfg->getTileMarkerFlag() && bWriteTileMarker)
1269        {
1270          // Log locations where tile markers are to be inserted during emulation prevention
1271          UInt uiMarkerCount = pcSubstreams[uiSubStrm].getTileMarkerLocationCount();
1272          pcSubstreams[uiSubStrm].setTileMarkerLocation     ( uiMarkerCount, pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3 );
1273          pcSubstreams[uiSubStrm].setTileMarkerLocationCount( uiMarkerCount + 1 );
1274          // Write tile index
1275          m_pcEntropyCoder->writeTileMarker(iTileIdx, rpcPic->getPicSym()->getBitsUsedByTileIdx()); // Tile index
1276        }
1277
1278       
1279        UInt uiAccumulatedSubstreamLength = 0;
1280        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1281        {
1282          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1283        }
1284        UInt uiLocationCount = pcSlice->getTileLocationCount();
1285        // add bits coded in previous entropy slices + bits coded so far
1286        pcSlice->setTileLocation( uiLocationCount, (pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3 ); 
1287        pcSlice->setTileLocationCount( uiLocationCount + 1 );
1288      }
1289    }
1290
1291    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1292#if !REMOVE_TILE_DEPENDENCE
1293    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1294    {   
1295      // Synchronize cabac probabilities with LCU among Tiles
1296      if( (uiTileLCUX != 0) &&
1297          (uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr()) )
1298      {
1299        TComDataCU *pcCULeft = pcCU->getCULeft();
1300        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1301
1302        if ( (true/*bEnforceSliceRestriction*/ &&
1303              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1304               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getSliceCurStartCUAddr()) 
1305              )
1306             )||
1307             (true/*bEnforceEntropySliceRestriction*/ &&
1308              ((pcCULeft==NULL) || (pcCULeft->getSlice()==NULL) || 
1309               ((pcCULeft->getSCUAddr()+uiMaxParts-1) < pcSlice->getEntropySliceCurStartCUAddr())
1310              )
1311             )
1312           )
1313        {
1314          // Left not available.
1315        }
1316        else
1317        {
1318          // Left is available, we use it.
1319          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferLowLatSbacCoders[uiTileCol-1] );
1320          m_pcSbacCoder->loadContexts(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1321        }
1322      }
1323    }
1324#endif
1325
1326#if SAO_UNIT_INTERLEAVING
1327    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getAPS()->getSaoInterleavingFlag() && pcSlice->getSaoEnabledFlag() )
1328    {
1329      Int iNumCuInWidth     = pcSlice->getAPS()->getSaoParam()->numCuInWidth;
1330      Int iCUAddrInSlice    = uiCUAddr - (pcSlice->getSliceCurStartCUAddr() /rpcPic->getNumPartInCU());
1331      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1332      Int rx = uiCUAddr % iNumCuInWidth;
1333      Int ry = uiCUAddr / iNumCuInWidth;
1334      m_pcEntropyCoder->encodeSaoUnitInterleaving( rx, ry, pcSlice->getAPS()->getSaoParam(),pcCU, iCUAddrInSlice, iCUAddrUpInSlice, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag());
1335    }
1336#endif
[2]1337#if ENC_DEC_TRACE
1338    g_bJustDoIt = g_bEncDecTraceEnable;
1339#endif
[56]1340    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getEntropySliceMode()!=0) && 
1341      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
[2]1342    {
1343      m_pcCuEncoder->encodeCU( pcCU, true );
1344    }
1345    else
1346    {
1347      m_pcCuEncoder->encodeCU( pcCU );
1348    }
1349#if ENC_DEC_TRACE
1350    g_bJustDoIt = g_bEncDecTraceDisable;
[56]1351#endif   
1352    if( m_pcCfg->getUseSBACRD() )
1353    {
1354       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1355       
1356
1357       //Store probabilties of second LCU in line into buffer
1358#if WPP_SIMPLIFICATION
1359      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
1360#else
1361      if (pcSlice->getPPS()->getEntropyCodingSynchro() && (uiCol == uiTileLCUX+pcSlice->getPPS()->getEntropyCodingSynchro()))
[5]1362#endif
[56]1363      {
1364        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1365      }
1366    }
1367#if !REMOVE_TILE_DEPENDENCE
1368    if( (rpcPic->getPicSym()->getTileBoundaryIndependenceIdr()==0) && (rpcPic->getPicSym()->getNumColumnsMinus1()!=0) )
1369    {
1370      pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1371       //Store probabilties for next tile
1372      if( (uiLin == (rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() / uiWidthInLCUs )) && 
1373          (uiCol == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getRightEdgePosInCU()) )
1374      {
1375        m_pcBufferLowLatSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1376      }
1377    }
1378#endif
[2]1379  }
[56]1380
1381#if ADAPTIVE_QP_SELECTION
1382  if( m_pcCfg->getUseAdaptQpSelect() )
1383  {
1384    m_pcTrQuant->storeSliceQpNext(pcSlice);
1385  }
1386#endif
1387#if CABAC_INIT_FLAG
1388  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1389  {
1390    m_pcEntropyCoder->determineCabacInitIdx();
1391  }
1392#endif
[2]1393}
1394
1395/** Determines the starting and bounding LCU address of current slice / entropy slice
1396 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1397 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1398 */
1399Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1400{
1401  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1402  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
[56]1403#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1404  UInt tileIdxIncrement;
1405  UInt tileIdx;
1406  UInt tileWidthInLcu;
1407  UInt tileHeightInLcu;
1408  UInt tileTotalCount;
1409#endif
1410
[2]1411  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1412  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1413  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
[56]1414  if (bEncodeSlice) 
[2]1415  {
1416    UInt uiCUAddrIncrement;
1417    switch (m_pcCfg->getSliceMode())
1418    {
1419    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1420      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
[56]1421      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1422      break;
1423    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
1424      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1425      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1426      break;
[56]1427#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1428    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1429      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1430        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1431        );
1432      uiCUAddrIncrement        = 0;
1433      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1434
1435      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1436      {
1437        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1438        {
1439          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1440          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1441          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1442        }
1443      }
1444
1445      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1446      break;
1447#endif
[2]1448    default:
1449      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
[56]1450      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1451      break;
[56]1452    } 
[2]1453    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1454  }
1455  else
1456  {
1457    UInt uiCUAddrIncrement     ;
1458    switch (m_pcCfg->getSliceMode())
1459    {
1460    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1461      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
[56]1462      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1463      break;
[56]1464#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1465    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1466      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1467        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1468        );
1469      uiCUAddrIncrement        = 0;
1470      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1471
1472      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1473      {
1474        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1475        {
1476          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1477          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1478          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1479        }
1480      }
1481
1482      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1483      break;
1484#endif
[2]1485    default:
1486      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
[56]1487      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1488      break;
[56]1489    } 
[2]1490    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1491  }
1492
[56]1493#if COMPLETE_SLICES_IN_TILE
1494  Bool tileBoundary = false;
1495  if ((m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE || m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE) && 
1496      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1497  {
1498    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1499    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1500    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1501    UInt tileBoundingCUAddrSlice = 0;
1502    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1503    {
1504      lcuEncAddr++;
1505      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1506    }
1507    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1508   
1509    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1510    {
1511      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1512      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1513      tileBoundary = true;
1514    }
1515  }
1516#endif
1517
[2]1518  // Entropy slice
1519  UInt uiStartCUAddrEntropySlice, uiBoundingCUAddrEntropySlice;
1520  uiStartCUAddrEntropySlice    = pcSlice->getEntropySliceCurStartCUAddr();
1521  uiBoundingCUAddrEntropySlice = uiNumberOfCUsInFrame;
[56]1522  if (bEncodeSlice) 
[2]1523  {
1524    UInt uiCUAddrIncrement;
1525    switch (m_pcCfg->getEntropySliceMode())
1526    {
1527    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1528      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
[56]1529      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1530      break;
1531    case SHARP_MULTIPLE_CONSTRAINT_BASED_ENTROPY_SLICE:
1532      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1533      uiBoundingCUAddrEntropySlice    = pcSlice->getEntropySliceCurEndCUAddr();
1534      break;
1535    default:
1536      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
[56]1537      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1538      break;
[56]1539    } 
[2]1540    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1541  }
1542  else
1543  {
1544    UInt uiCUAddrIncrement;
1545    switch (m_pcCfg->getEntropySliceMode())
1546    {
1547    case SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE:
1548      uiCUAddrIncrement               = m_pcCfg->getEntropySliceArgument();
[56]1549      uiBoundingCUAddrEntropySlice    = ((uiStartCUAddrEntropySlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrEntropySlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1550      break;
1551    default:
1552      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
[56]1553      uiBoundingCUAddrEntropySlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
[2]1554      break;
[56]1555    } 
[2]1556    pcSlice->setEntropySliceCurEndCUAddr( uiBoundingCUAddrEntropySlice );
1557  }
[56]1558  if(uiBoundingCUAddrEntropySlice>uiBoundingCUAddrSlice)
1559  {
1560    uiBoundingCUAddrEntropySlice = uiBoundingCUAddrSlice;
1561    pcSlice->setEntropySliceCurEndCUAddr(uiBoundingCUAddrSlice);
1562  }
1563  //calculate real entropy slice start address
1564  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1565  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1566  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1567  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1568  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1569  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1570  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1571  {
1572    uiInternalAddress++;
1573    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1574    {
1575      uiInternalAddress=0;
1576      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1577    }
1578    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1579    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1580  }
1581  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1582 
1583  pcSlice->setEntropySliceCurStartCUAddr(uiRealStartAddress);
1584  uiStartCUAddrEntropySlice=uiRealStartAddress;
1585 
1586  //calculate real slice start address
1587  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1588  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1589  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1590  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1591  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1592  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1593  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1594  {
1595    uiInternalAddress++;
1596    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1597    {
1598      uiInternalAddress=0;
1599      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1600    }
1601    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1602    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1603  }
1604  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1605 
1606  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1607  uiStartCUAddrSlice=uiRealStartAddress;
1608 
[2]1609  // Make a joint decision based on reconstruction and entropy slice bounds
1610  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrEntropySlice   );
1611  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrEntropySlice);
1612
1613
1614  if (!bEncodeSlice)
1615  {
1616    // For fixed number of LCU within an entropy and reconstruction slice we already know whether we will encounter end of entropy and/or reconstruction slice
1617    // first. Set the flags accordingly.
1618    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1619      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
[56]1620      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1621#if FIXED_NUMBER_OF_TILES_SLICE_MODE
1622      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE)
1623      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getEntropySliceMode()==0) 
1624#endif
1625#if COMPLETE_SLICES_IN_TILE
1626      || tileBoundary
1627#endif
1628)
[2]1629    {
1630      if (uiBoundingCUAddrSlice < uiBoundingCUAddrEntropySlice)
1631      {
1632        pcSlice->setNextSlice       ( true );
1633        pcSlice->setNextEntropySlice( false );
1634      }
1635      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrEntropySlice)
1636      {
1637        pcSlice->setNextSlice       ( false );
1638        pcSlice->setNextEntropySlice( true );
1639      }
1640      else
1641      {
1642        pcSlice->setNextSlice       ( true );
1643        pcSlice->setNextEntropySlice( true );
1644      }
1645    }
1646    else
1647    {
1648      pcSlice->setNextSlice       ( false );
1649      pcSlice->setNextEntropySlice( false );
1650    }
1651  }
1652}
[56]1653//! \}
Note: See TracBrowser for help on using the repository browser.