source: SHVCSoftware/branches/SHM-2.0-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 170

Last change on this file since 170 was 147, checked in by qualcomm, 12 years ago

M0259: lambda refinement for RA configurations

File size: 73.8 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2013, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncSlice.cpp
35    \brief    slice encoder class
36*/
37
38#include "TEncTop.h"
39#include "TEncSlice.h"
40#include <math.h>
41
42//! \ingroup TLibEncoder
43//! \{
44
45// ====================================================================================================================
46// Constructor / destructor / create / destroy
47// ====================================================================================================================
48
49TEncSlice::TEncSlice()
50{
51  m_apcPicYuvPred = NULL;
52  m_apcPicYuvResi = NULL;
53 
54  m_pdRdPicLambda = NULL;
55  m_pdRdPicQp     = NULL;
56  m_piRdPicQp     = NULL;
57  m_pcBufferSbacCoders    = NULL;
58  m_pcBufferBinCoderCABACs  = NULL;
59  m_pcBufferLowLatSbacCoders    = NULL;
60  m_pcBufferLowLatBinCoderCABACs  = NULL;
61}
62
63TEncSlice::~TEncSlice()
64{
65  for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
66  {
67    delete (*i);
68  }
69}
70
71Void TEncSlice::initCtxMem(  UInt i )               
72{   
73  for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
74  {
75    delete (*j);
76  }
77  CTXMem.clear(); 
78  CTXMem.resize(i); 
79}
80
81Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
82{
83  // create prediction picture
84  if ( m_apcPicYuvPred == NULL )
85  {
86    m_apcPicYuvPred  = new TComPicYuv;
87    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
88  }
89 
90  // create residual picture
91  if( m_apcPicYuvResi == NULL )
92  {
93    m_apcPicYuvResi  = new TComPicYuv;
94    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
95  }
96}
97
98Void TEncSlice::destroy()
99{
100  // destroy prediction picture
101  if ( m_apcPicYuvPred )
102  {
103    m_apcPicYuvPred->destroy();
104    delete m_apcPicYuvPred;
105    m_apcPicYuvPred  = NULL;
106  }
107 
108  // destroy residual picture
109  if ( m_apcPicYuvResi )
110  {
111    m_apcPicYuvResi->destroy();
112    delete m_apcPicYuvResi;
113    m_apcPicYuvResi  = NULL;
114  }
115 
116  // free lambda and QP arrays
117  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
118  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
119  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
120
121  if ( m_pcBufferSbacCoders )
122  {
123    delete[] m_pcBufferSbacCoders;
124  }
125  if ( m_pcBufferBinCoderCABACs )
126  {
127    delete[] m_pcBufferBinCoderCABACs;
128  }
129  if ( m_pcBufferLowLatSbacCoders )
130    delete[] m_pcBufferLowLatSbacCoders;
131  if ( m_pcBufferLowLatBinCoderCABACs )
132    delete[] m_pcBufferLowLatBinCoderCABACs;
133}
134
135Void TEncSlice::init( TEncTop* pcEncTop )
136{
137  m_pcCfg             = pcEncTop;
138  m_pcListPic         = pcEncTop->getListPic();
139#if SVC_EXTENSION
140  m_ppcTEncTop        = pcEncTop->getLayerEnc();
141#endif 
142  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
143  m_pcCuEncoder       = pcEncTop->getCuEncoder();
144  m_pcPredSearch      = pcEncTop->getPredSearch();
145 
146  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
147  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
148  m_pcSbacCoder       = pcEncTop->getSbacCoder();
149  m_pcBinCABAC        = pcEncTop->getBinCABAC();
150  m_pcTrQuant         = pcEncTop->getTrQuant();
151 
152  m_pcBitCounter      = pcEncTop->getBitCounter();
153  m_pcRdCost          = pcEncTop->getRdCost();
154  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
155  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
156 
157  // create lambda and QP arrays
158  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
159  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
160  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
161  m_pcRateCtrl        = pcEncTop->getRateCtrl();
162}
163
164/**
165 - non-referenced frame marking
166 - QP computation based on temporal structure
167 - lambda computation based on QP
168 - set temporal layer ID and the parameter sets
169 .
170 \param pcPic         picture class
171 \param pocLast       POC of last picture
172 \param pocCurr       current POC
173 \param iNumPicRcvd   number of received pictures
174 \param iTimeOffset   POC offset for hierarchical structure
175 \param iDepth        temporal layer depth
176 \param rpcSlice      slice header class
177 \param pSPS          SPS associated with the slice
178 \param pPPS          PPS associated with the slice
179 */
180Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
181{
182  Double dQP;
183  Double dLambda;
184 
185  rpcSlice = pcPic->getSlice(0);
186  rpcSlice->setSPS( pSPS );
187  rpcSlice->setPPS( pPPS );
188  rpcSlice->setSliceBits(0);
189  rpcSlice->setPic( pcPic );
190#if SVC_EXTENSION
191  rpcSlice->initSlice( pcPic->getLayerId() );
192#else
193  rpcSlice->initSlice();
194#endif
195  rpcSlice->setPicOutputFlag( true );
196  rpcSlice->setPOC( pocCurr );
197 
198  // depth computation based on GOP size
199  Int depth;
200  {
201    Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
202    if ( poc == 0 )
203    {
204      depth = 0;
205    }
206    else
207    {
208      Int step = m_pcCfg->getGOPSize();
209      depth    = 0;
210      for( Int i=step>>1; i>=1; i>>=1 )
211      {
212        for ( Int j=i; j<m_pcCfg->getGOPSize(); j+=step )
213        {
214          if ( j == poc )
215          {
216            i=0;
217            break;
218          }
219        }
220        step >>= 1;
221        depth++;
222      }
223    }
224  }
225 
226  // slice type
227  SliceType eSliceType;
228 
229  eSliceType=B_SLICE;
230  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
231 
232  rpcSlice->setSliceType    ( eSliceType );
233 
234  // ------------------------------------------------------------------------------------------------------------------
235  // Non-referenced frame marking
236  // ------------------------------------------------------------------------------------------------------------------
237 
238  if(pocLast == 0)
239  {
240    rpcSlice->setTemporalLayerNonReferenceFlag(false);
241  }
242  else
243  {
244    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
245  }
246  rpcSlice->setReferenced(true);
247 
248  // ------------------------------------------------------------------------------------------------------------------
249  // QP setting
250  // ------------------------------------------------------------------------------------------------------------------
251 
252  dQP = m_pcCfg->getQP();
253  if(eSliceType!=I_SLICE)
254  {
255    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless()))) 
256    {
257      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
258    }
259  }
260 
261  // modify QP
262  Int* pdQPs = m_pcCfg->getdQPs();
263  if ( pdQPs )
264  {
265    dQP += pdQPs[ rpcSlice->getPOC() ];
266  }
267#if !RATE_CONTROL_LAMBDA_DOMAIN
268  if ( m_pcCfg->getUseRateCtrl())
269  {
270    dQP = m_pcRateCtrl->getFrameQP(rpcSlice->isReferenced(), rpcSlice->getPOC());
271  }
272#endif
273  // ------------------------------------------------------------------------------------------------------------------
274  // Lambda computation
275  // ------------------------------------------------------------------------------------------------------------------
276 
277  Int iQP;
278  Double dOrigQP = dQP;
279
280  // pre-compute lambda and QP values for all possible QP candidates
281  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
282  {
283    // compute QP value
284    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
285   
286    // compute lambda value
287    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
288    Int    SHIFT_QP = 12;
289    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
290#if FULL_NBIT
291    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
292#else
293    Int    bitdepth_luma_qp_scale = 0;
294#endif
295    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
296#if FULL_NBIT
297    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
298#endif
299    // Case #1: I or P-slices (key-frame)
300    Double dQPFactor = m_pcCfg->getGOPEntry(iGOPid).m_QPFactor;
301    if ( eSliceType==I_SLICE )
302    {
303      dQPFactor=0.57*dLambda_scale;
304    }
305    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
306
307    if ( depth>0 )
308    {
309#if FULL_NBIT
310        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
311#else
312        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
313#endif
314    }
315   
316    // if hadamard is used in ME process
317    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
318    {
319      dLambda *= 0.95;
320    }
321   
322    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
323
324    m_pdRdPicLambda[iDQpIdx] = dLambda;
325    m_pdRdPicQp    [iDQpIdx] = dQP;
326    m_piRdPicQp    [iDQpIdx] = iQP;
327  }
328 
329  // obtain dQP = 0 case
330  dLambda = m_pdRdPicLambda[0];
331  dQP     = m_pdRdPicQp    [0];
332  iQP     = m_piRdPicQp    [0];
333 
334  if( rpcSlice->getSliceType( ) != I_SLICE )
335  {
336    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
337  }
338
339#if JCTVC_M0259_LAMBDAREFINEMENT
340  if( rpcSlice->getLayerId() > 0 && depth >= 3 && m_pcCfg->getGOPSize() == ( 1 << depth ) )
341  {
342    Int nCurLayer = rpcSlice->getLayerId();
343    Double gamma = xCalEnhLambdaFactor( m_ppcTEncTop[nCurLayer-1]->getQP() - m_ppcTEncTop[nCurLayer]->getQP() ,
344      1.0 * m_ppcTEncTop[nCurLayer]->getSourceWidth() * m_ppcTEncTop[nCurLayer]->getSourceHeight() 
345      / m_ppcTEncTop[nCurLayer-1]->getSourceWidth() / m_ppcTEncTop[nCurLayer-1]->getSourceHeight() );
346    dLambda *= gamma;
347  }
348#endif
349
350  // store lambda
351  m_pcRdCost ->setLambda( dLambda );
352#if WEIGHTED_CHROMA_DISTORTION
353// for RDO
354  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
355  Double weight = 1.0;
356  Int qpc;
357  Int chromaQPOffset;
358
359  chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
360  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
361  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
362  m_pcRdCost->setCbDistortionWeight(weight);
363
364  chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
365  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
366  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
367#if JCTVC_M0259_LAMBDAREFINEMENT
368  if( rpcSlice->getLayerId() > 0 && m_pcCfg->getGOPSize() >= 8 && rpcSlice->isIntra() == false && depth == 0 )
369  {
370    dLambda *= 1.1;
371    weight *= 1.15;
372  }
373#endif
374  m_pcRdCost->setCrDistortionWeight(weight);
375#endif
376
377#if RDOQ_CHROMA_LAMBDA
378// for RDOQ
379  m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
380#else
381  m_pcTrQuant->setLambda( dLambda );
382#endif
383
384#if SAO_CHROMA_LAMBDA
385// For SAO
386  rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
387#else
388  rpcSlice   ->setLambda( dLambda );
389#endif
390 
391#if HB_LAMBDA_FOR_LDC
392  // restore original slice type
393  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
394 
395#if REF_IDX_FRAMEWORK
396  if(m_pcCfg->getLayerId() > 0)
397  {
398    eSliceType=B_SLICE;
399  }
400#endif
401  rpcSlice->setSliceType        ( eSliceType );
402#endif
403 
404  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
405  {
406    dQP = xGetQPValueAccordingToLambda( dLambda );
407    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );   
408  }
409
410  rpcSlice->setSliceQp          ( iQP );
411#if ADAPTIVE_QP_SELECTION
412  rpcSlice->setSliceQpBase      ( iQP );
413#endif
414  rpcSlice->setSliceQpDelta     ( 0 );
415  rpcSlice->setSliceQpDeltaCb   ( 0 );
416  rpcSlice->setSliceQpDeltaCr   ( 0 );
417  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
418  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
419 
420#if L0386_DB_METRIC
421  if ( m_pcCfg->getDeblockingFilterMetric() )
422  {
423    rpcSlice->setDeblockingFilterOverrideFlag(true);
424    rpcSlice->setDeblockingFilterDisable(false);
425    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
426    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
427  } else
428#endif
429  if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
430  {
431    rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
432    rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
433    rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
434    rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
435    if ( !rpcSlice->getDeblockingFilterDisable())
436    {
437      if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
438      {
439        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
440        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
441        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
442        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
443      }
444      else
445      {
446      rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
447      rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
448      rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
449      rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
450      }
451    }
452  }
453  else
454  {
455    rpcSlice->setDeblockingFilterOverrideFlag( false );
456    rpcSlice->setDeblockingFilterDisable( false );
457    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
458    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
459  }
460
461  rpcSlice->setDepth            ( depth );
462 
463  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
464  if(eSliceType==I_SLICE)
465  {
466    pcPic->setTLayer(0);
467  }
468  rpcSlice->setTLayer( pcPic->getTLayer() );
469
470  assert( m_apcPicYuvPred );
471  assert( m_apcPicYuvResi );
472 
473  pcPic->setPicYuvPred( m_apcPicYuvPred );
474  pcPic->setPicYuvResi( m_apcPicYuvResi );
475  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
476  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
477  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
478  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
479  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
480  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
481}
482
483#if RATE_CONTROL_LAMBDA_DOMAIN
484Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
485{
486  TComSlice* slice = pic->getSlice(0);
487
488  // store lambda
489  slice->setSliceQp( sliceQP );
490#if L0033_RC_BUGFIX
491  slice->setSliceQpBase ( sliceQP );
492#endif
493  m_pcRdCost ->setLambda( lambda );
494#if WEIGHTED_CHROMA_DISTORTION
495  // for RDO
496  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
497  Double weight;
498  Int qpc;
499  Int chromaQPOffset;
500
501  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
502  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
503  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
504  m_pcRdCost->setCbDistortionWeight(weight);
505
506  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
507  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
508  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
509  m_pcRdCost->setCrDistortionWeight(weight);
510#endif
511
512#if RDOQ_CHROMA_LAMBDA
513  // for RDOQ
514  m_pcTrQuant->setLambda( lambda, lambda / weight );
515#else
516  m_pcTrQuant->setLambda( lambda );
517#endif
518
519#if SAO_CHROMA_LAMBDA
520  // For SAO
521  slice   ->setLambda( lambda, lambda / weight );
522#else
523  slice   ->setLambda( lambda );
524#endif
525}
526#else
527/**
528 - lambda re-computation based on rate control QP
529 */
530Void TEncSlice::xLamdaRecalculation(Int changeQP, Int idGOP, Int depth, SliceType eSliceType, TComSPS* pcSPS, TComSlice* pcSlice)
531{
532  Int qp;
533  Double recalQP= (Double)changeQP;
534  Double origQP = (Double)recalQP;
535  Double lambda;
536
537  // pre-compute lambda and QP values for all possible QP candidates
538  for ( Int deltqQpIdx = 0; deltqQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; deltqQpIdx++ )
539  {
540    // compute QP value
541    recalQP = origQP + ((deltqQpIdx+1)>>1)*(deltqQpIdx%2 ? -1 : 1);
542
543    // compute lambda value
544    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
545    Int    SHIFT_QP = 12;
546    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
547#if FULL_NBIT
548    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
549#else
550    Int    bitdepth_luma_qp_scale = 0;
551#endif
552    Double qp_temp = (Double) recalQP + bitdepth_luma_qp_scale - SHIFT_QP;
553#if FULL_NBIT
554    Double qp_temp_orig = (Double) recalQP - SHIFT_QP;
555#endif
556    // Case #1: I or P-slices (key-frame)
557    Double dQPFactor = m_pcCfg->getGOPEntry(idGOP).m_QPFactor;
558    if ( eSliceType==I_SLICE )
559    {
560      dQPFactor=0.57*dLambda_scale;
561    }
562    lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
563
564    if ( depth>0 )
565    {
566#if FULL_NBIT
567      lambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
568#else
569      lambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
570#endif
571    }
572
573    // if hadamard is used in ME process
574    if ( !m_pcCfg->getUseHADME() )
575    {
576      lambda *= 0.95;
577    }
578
579    qp = max( -pcSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( recalQP + 0.5 ) ) );
580
581    m_pdRdPicLambda[deltqQpIdx] = lambda;
582    m_pdRdPicQp    [deltqQpIdx] = recalQP;
583    m_piRdPicQp    [deltqQpIdx] = qp;
584  }
585
586  // obtain dQP = 0 case
587  lambda  = m_pdRdPicLambda[0];
588  recalQP = m_pdRdPicQp    [0];
589  qp      = m_piRdPicQp    [0];
590
591  if( pcSlice->getSliceType( ) != I_SLICE )
592  {
593    lambda *= m_pcCfg->getLambdaModifier( depth );
594  }
595
596  // store lambda
597  m_pcRdCost ->setLambda( lambda );
598#if WEIGHTED_CHROMA_DISTORTION
599  // for RDO
600  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
601  Double weight = 1.0;
602  Int qpc;
603  Int chromaQPOffset;
604
605  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
606  qpc = Clip3( 0, 57, qp + chromaQPOffset);
607  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
608  m_pcRdCost->setCbDistortionWeight(weight);
609
610  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
611  qpc = Clip3( 0, 57, qp + chromaQPOffset);
612  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
613  m_pcRdCost->setCrDistortionWeight(weight);
614#endif
615
616#if RDOQ_CHROMA_LAMBDA
617  // for RDOQ
618  m_pcTrQuant->setLambda( lambda, lambda / weight );   
619#else
620  m_pcTrQuant->setLambda( lambda );
621#endif
622
623#if SAO_CHROMA_LAMBDA
624  // For SAO
625  pcSlice   ->setLambda( lambda, lambda / weight ); 
626#else
627  pcSlice   ->setLambda( lambda );
628#endif
629}
630#endif
631// ====================================================================================================================
632// Public member functions
633// ====================================================================================================================
634
635Void TEncSlice::setSearchRange( TComSlice* pcSlice )
636{
637  Int iCurrPOC = pcSlice->getPOC();
638  Int iRefPOC;
639  Int iGOPSize = m_pcCfg->getGOPSize();
640  Int iOffset = (iGOPSize >> 1);
641  Int iMaxSR = m_pcCfg->getSearchRange();
642  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
643 
644  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
645  {
646    //RefPicList e = (RefPicList)iDir;
647    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
648    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
649    {
650      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
651      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
652      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
653    }
654  }
655}
656
657/**
658 - multi-loop slice encoding for different slice QP
659 .
660 \param rpcPic    picture class
661 */
662Void TEncSlice::precompressSlice( TComPic*& rpcPic )
663{
664  // if deltaQP RD is not used, simply return
665  if ( m_pcCfg->getDeltaQpRD() == 0 )
666  {
667    return;
668  }
669
670#if RATE_CONTROL_LAMBDA_DOMAIN
671  if ( m_pcCfg->getUseRateCtrl() )
672  {
673    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
674    assert(0);
675  }
676#endif
677 
678  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
679  Double     dPicRdCostBest = MAX_DOUBLE;
680  UInt       uiQpIdxBest = 0;
681 
682  Double dFrameLambda;
683#if FULL_NBIT
684  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
685#else
686  Int    SHIFT_QP = 12;
687#endif
688 
689  // set frame lambda
690  if (m_pcCfg->getGOPSize() > 1)
691  {
692    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
693  }
694  else
695  {
696    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
697  }
698  m_pcRdCost      ->setFrameLambda(dFrameLambda);
699 
700  // for each QP candidate
701  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
702  {
703    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
704#if ADAPTIVE_QP_SELECTION
705    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
706#endif
707    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
708#if WEIGHTED_CHROMA_DISTORTION
709    // for RDO
710    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
711    Int iQP = m_piRdPicQp    [uiQpIdx];
712    Double weight = 1.0;
713    Int qpc;
714    Int chromaQPOffset;
715
716    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
717    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
718    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
719    m_pcRdCost->setCbDistortionWeight(weight);
720
721    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
722    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
723    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
724    m_pcRdCost->setCrDistortionWeight(weight);
725#endif
726
727#if RDOQ_CHROMA_LAMBDA
728    // for RDOQ
729    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
730#else
731    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
732#endif
733#if SAO_CHROMA_LAMBDA
734    // For SAO
735    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
736#else
737    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
738#endif
739   
740    // try compress
741    compressSlice   ( rpcPic );
742   
743    Double dPicRdCost;
744    UInt64 uiPicDist        = m_uiPicDist;
745    UInt64 uiALFBits        = 0;
746   
747    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
748   
749    // compute RD cost and choose the best
750    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
751   
752    if ( dPicRdCost < dPicRdCostBest )
753    {
754      uiQpIdxBest    = uiQpIdx;
755      dPicRdCostBest = dPicRdCost;
756    }
757  }
758 
759  // set best values
760  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
761#if ADAPTIVE_QP_SELECTION
762  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
763#endif
764  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
765#if WEIGHTED_CHROMA_DISTORTION
766  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
767  Int iQP = m_piRdPicQp    [uiQpIdxBest];
768  Double weight = 1.0;
769  Int qpc;
770  Int chromaQPOffset;
771
772  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
773  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
774  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
775  m_pcRdCost->setCbDistortionWeight(weight);
776
777  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
778  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
779  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
780  m_pcRdCost->setCrDistortionWeight(weight);
781#endif
782
783#if RDOQ_CHROMA_LAMBDA
784  // for RDOQ
785  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
786#else
787  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
788#endif
789#if SAO_CHROMA_LAMBDA
790  // For SAO
791  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
792#else
793  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
794#endif
795}
796
797/** \param rpcPic   picture class
798 */
799Void TEncSlice::compressSlice( TComPic*& rpcPic )
800{
801  UInt  uiCUAddr;
802  UInt   uiStartCUAddr;
803  UInt   uiBoundingCUAddr;
804  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
805  TEncBinCABAC* pppcRDSbacCoder = NULL;
806  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
807  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
808 
809  // initialize cost values
810  m_uiPicTotalBits  = 0;
811  m_dPicRdCost      = 0;
812  m_uiPicDist       = 0;
813 
814  // set entropy coder
815  if( m_pcCfg->getUseSBACRD() )
816  {
817    m_pcSbacCoder->init( m_pcBinCABAC );
818    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
819    m_pcEntropyCoder->resetEntropy      ();
820    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
821    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
822    pppcRDSbacCoder->setBinCountingEnableFlag( false );
823    pppcRDSbacCoder->setBinsCoded( 0 );
824  }
825  else
826  {
827    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
828    m_pcEntropyCoder->resetEntropy      ();
829    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
830  }
831 
832  //------------------------------------------------------------------------------
833  //  Weighted Prediction parameters estimation.
834  //------------------------------------------------------------------------------
835  // calculate AC/DC values for current picture
836  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
837  {
838    xCalcACDCParamSlice(pcSlice);
839  }
840
841  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
842
843  if ( bWp_explicit )
844  {
845    //------------------------------------------------------------------------------
846    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
847    //------------------------------------------------------------------------------
848    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
849    {
850      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
851    }
852
853    xEstimateWPParamSlice( pcSlice );
854    pcSlice->initWpScaling();
855
856    // check WP on/off
857    xCheckWPEnable( pcSlice );
858  }
859
860#if ADAPTIVE_QP_SELECTION
861  if( m_pcCfg->getUseAdaptQpSelect() )
862  {
863    m_pcTrQuant->clearSliceARLCnt();
864    if(pcSlice->getSliceType()!=I_SLICE)
865    {
866      Int qpBase = pcSlice->getSliceQpBase();
867      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
868    }
869  }
870#endif
871  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
872  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
873  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
874  Int  iNumSubstreams = 1;
875  UInt uiTilesAcross  = 0;
876
877  if( m_pcCfg->getUseSBACRD() )
878  {
879    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
880    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
881    delete[] m_pcBufferSbacCoders;
882    delete[] m_pcBufferBinCoderCABACs;
883    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
884    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
885    for (Int ui = 0; ui < uiTilesAcross; ui++)
886    {
887      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
888    }
889    for (UInt ui = 0; ui < uiTilesAcross; ui++)
890    {
891      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
892    }
893
894    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
895    {
896      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
897    }
898  }
899  //if( m_pcCfg->getUseSBACRD() )
900  {
901    delete[] m_pcBufferLowLatSbacCoders;
902    delete[] m_pcBufferLowLatBinCoderCABACs;
903    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
904    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
905    for (Int ui = 0; ui < uiTilesAcross; ui++)
906    {
907      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
908    }
909    for (UInt ui = 0; ui < uiTilesAcross; ui++)
910      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
911  }
912  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
913  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
914  UInt uiCol=0, uiLin=0, uiSubStrm=0;
915  UInt uiTileCol      = 0;
916  UInt uiTileStartLCU = 0;
917  UInt uiTileLCUX     = 0;
918
919#if INTRA_BL
920  m_pcCuEncoder->setBaseRecPic( rpcPic->getLayerId() > 0 ? rpcPic->getFullPelBaseRec() : NULL);
921#endif
922
923  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
924  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
925  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
926  if( depSliceSegmentsEnabled )
927  {
928    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
929    {
930      if( m_pcCfg->getWaveFrontsynchro() )
931      {
932        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
933        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
934        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
935        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
936        uiLin     = uiCUAddr / uiWidthInLCUs;
937        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
938          + uiLin%iNumSubstreamsPerTile;
939        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
940        {
941          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
942          uiCol     = uiCUAddr % uiWidthInLCUs;
943          if(uiCol==uiTileStartLCU)
944          {
945            CTXMem[0]->loadContexts(m_pcSbacCoder);
946          }
947        }
948      }
949      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
950      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
951    }
952    else
953    {
954      if(m_pcCfg->getWaveFrontsynchro())
955      {
956        CTXMem[1]->loadContexts(m_pcSbacCoder);
957      }
958      CTXMem[0]->loadContexts(m_pcSbacCoder);
959    }
960  }
961  // for every CU in slice
962  UInt uiEncCUOrder;
963  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
964       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
965       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
966  {
967    // initialize CU encoder
968    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
969    pcCU->initCU( rpcPic, uiCUAddr );
970#if SVC_EXTENSION
971    pcCU->setLayerId(m_pcCfg->getLayerId());
972#endif
973
974#if !RATE_CONTROL_LAMBDA_DOMAIN
975    if(m_pcCfg->getUseRateCtrl())
976    {
977      if(m_pcRateCtrl->calculateUnitQP())
978      {
979        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
980      }
981    }
982#endif
983    // inherit from TR if necessary, select substream to use.
984    if( m_pcCfg->getUseSBACRD() )
985    {
986      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
987      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
988      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
989      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
990      uiCol     = uiCUAddr % uiWidthInLCUs;
991      uiLin     = uiCUAddr / uiWidthInLCUs;
992      if (pcSlice->getPPS()->getNumSubstreams() > 1)
993      {
994        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
995        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
996        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
997                      + uiLin%iNumSubstreamsPerTile;
998      }
999      else
1000      {
1001        // dependent tiles => substreams are "per frame".
1002        uiSubStrm = uiLin % iNumSubstreams;
1003      }
1004      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1005      {
1006        // We'll sync if the TR is available.
1007        TComDataCU *pcCUUp = pcCU->getCUAbove();
1008        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1009        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1010        TComDataCU *pcCUTR = NULL;
1011        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1012        {
1013          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1014        }
1015        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1016             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1017             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1018             )
1019           )
1020        {
1021          // TR not available.
1022        }
1023        else
1024        {
1025          // TR is available, we use it.
1026          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1027        }
1028      }
1029      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1030    }
1031
1032    // reset the entropy coder
1033    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1034        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1035        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1036        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1037    {
1038      SliceType sliceType = pcSlice->getSliceType();
1039      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1040      {
1041        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1042      }
1043      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1044      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1045      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1046      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1047    }
1048    // if RD based on SBAC is used
1049    if( m_pcCfg->getUseSBACRD() )
1050    {
1051      // set go-on entropy coder
1052      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1053      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1054     
1055      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1056
1057#if RATE_CONTROL_LAMBDA_DOMAIN
1058      Double oldLambda = m_pcRdCost->getLambda();
1059      if ( m_pcCfg->getUseRateCtrl() )
1060      {
1061        Int estQP        = pcSlice->getSliceQp();
1062        Double estLambda = -1.0;
1063        Double bpp       = -1.0;
1064
1065        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
1066        {
1067          estQP = pcSlice->getSliceQp();
1068        }
1069        else
1070        {
1071          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
1072          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1073          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1074          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1075
1076          m_pcRdCost->setLambda(estLambda);
1077        }
1078
1079        m_pcRateCtrl->setRCQP( estQP );
1080#if L0033_RC_BUGFIX
1081        pcCU->getSlice()->setSliceQpBase( estQP );
1082#endif
1083      }
1084#endif
1085
1086      // run CU encoder
1087      m_pcCuEncoder->compressCU( pcCU );
1088
1089#if RATE_CONTROL_LAMBDA_DOMAIN
1090      if ( m_pcCfg->getUseRateCtrl() )
1091      {
1092        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1093        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1094        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1095        Double MAD = (Double)SAD / (Double)(height * width);
1096        MAD = MAD * MAD;
1097        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1098
1099        Int actualQP        = g_RCInvalidQPValue;
1100        Double actualLambda = m_pcRdCost->getLambda();
1101        Int actualBits      = pcCU->getTotalBits();
1102        Int numberOfEffectivePixels    = 0;
1103        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1104        {
1105          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1106          {
1107            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1108            break;
1109          }
1110        }
1111
1112        if ( numberOfEffectivePixels == 0 )
1113        {
1114          actualQP = g_RCInvalidQPValue;
1115        }
1116        else
1117        {
1118          actualQP = pcCU->getQP( 0 );
1119        }
1120        m_pcRdCost->setLambda(oldLambda);
1121
1122        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1123      }
1124#endif
1125     
1126      // restore entropy coder to an initial stage
1127      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1128      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1129      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1130      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1131      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1132      m_pcBitCounter->resetBits();
1133      pppcRDSbacCoder->setBinsCoded( 0 );
1134      m_pcCuEncoder->encodeCU( pcCU );
1135
1136      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1137      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1138      {
1139        pcSlice->setNextSlice( true );
1140        break;
1141      }
1142      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1143      {
1144        pcSlice->setNextSliceSegment( true );
1145        break;
1146      }
1147      if( m_pcCfg->getUseSBACRD() )
1148      {
1149         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1150       
1151         //Store probabilties of second LCU in line into buffer
1152         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1153        {
1154          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1155        }
1156      }
1157    }
1158    // other case: encodeCU is not called
1159    else
1160    {
1161      m_pcCuEncoder->compressCU( pcCU );
1162      m_pcCuEncoder->encodeCU( pcCU );
1163      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1164      {
1165        pcSlice->setNextSlice( true );
1166        break;
1167      }
1168      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1169      {
1170        pcSlice->setNextSliceSegment( true );
1171        break;
1172      }
1173    }
1174   
1175    m_uiPicTotalBits += pcCU->getTotalBits();
1176    m_dPicRdCost     += pcCU->getTotalCost();
1177    m_uiPicDist      += pcCU->getTotalDistortion();
1178#if !RATE_CONTROL_LAMBDA_DOMAIN
1179    if(m_pcCfg->getUseRateCtrl())
1180    {
1181      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1182      m_pcRateCtrl->updataRCUnitStatus();
1183    }
1184#endif
1185  }
1186  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1187  {
1188    pcSlice->setNextSlice( true );
1189  }
1190  if( depSliceSegmentsEnabled )
1191  {
1192    if (m_pcCfg->getWaveFrontsynchro())
1193    {
1194      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1195    }
1196     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1197  }
1198  xRestoreWPparam( pcSlice );
1199#if !RATE_CONTROL_LAMBDA_DOMAIN
1200  if(m_pcCfg->getUseRateCtrl())
1201  {
1202    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1203  }
1204#endif
1205}
1206
1207/**
1208 \param  rpcPic        picture class
1209 \retval rpcBitstream  bitstream class
1210 */
1211Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1212{
1213  UInt       uiCUAddr;
1214  UInt       uiStartCUAddr;
1215  UInt       uiBoundingCUAddr;
1216  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1217
1218  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1219  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1220  // choose entropy coder
1221  {
1222    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1223    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1224  }
1225 
1226  m_pcCuEncoder->setBitCounter( NULL );
1227  m_pcBitCounter = NULL;
1228  // Appropriate substream bitstream is switched later.
1229  // for every CU
1230#if ENC_DEC_TRACE
1231  g_bJustDoIt = g_bEncDecTraceEnable;
1232#endif
1233  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1234  DTRACE_CABAC_T( "\tPOC: " );
1235  DTRACE_CABAC_V( rpcPic->getPOC() );
1236  DTRACE_CABAC_T( "\n" );
1237#if ENC_DEC_TRACE
1238  g_bJustDoIt = g_bEncDecTraceDisable;
1239#endif
1240
1241  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1242  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1243  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1244  UInt uiBitsOriginallyInSubstreams = 0;
1245  {
1246    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1247    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1248    {
1249      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1250    }
1251   
1252    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1253    {
1254      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1255    }
1256
1257    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1258    {
1259      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1260    }
1261  }
1262
1263  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1264  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1265  UInt uiTileCol      = 0;
1266  UInt uiTileStartLCU = 0;
1267  UInt uiTileLCUX     = 0;
1268  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1269  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1270                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1271                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1272  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1273  if( depSliceSegmentsEnabled )
1274  {
1275    if( pcSlice->isNextSlice()||
1276        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1277    {
1278      if(m_pcCfg->getWaveFrontsynchro())
1279      {
1280        CTXMem[1]->loadContexts(m_pcSbacCoder);
1281      }
1282      CTXMem[0]->loadContexts(m_pcSbacCoder);
1283    }
1284    else
1285    {
1286      if(m_pcCfg->getWaveFrontsynchro())
1287      {
1288        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1289        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1290        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1291        uiLin     = uiCUAddr / uiWidthInLCUs;
1292        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1293          + uiLin%iNumSubstreamsPerTile;
1294        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1295        {
1296          uiCol     = uiCUAddr % uiWidthInLCUs;
1297          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1298          if(uiCol==uiTileLCUX)
1299          {
1300            CTXMem[0]->loadContexts(m_pcSbacCoder);
1301          }
1302        }
1303      }
1304      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1305    }
1306  }
1307
1308  UInt uiEncCUOrder;
1309  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1310       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1311       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1312  {
1313    if( m_pcCfg->getUseSBACRD() )
1314    {
1315      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1316      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1317      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1318      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1319      uiCol     = uiCUAddr % uiWidthInLCUs;
1320      uiLin     = uiCUAddr / uiWidthInLCUs;
1321      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1322      {
1323        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1324        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1325        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1326                      + uiLin%iNumSubstreamsPerTile;
1327      }
1328      else
1329      {
1330        // dependent tiles => substreams are "per frame".
1331        uiSubStrm = uiLin % iNumSubstreams;
1332      }
1333
1334      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1335      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1336      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1337      {
1338        // We'll sync if the TR is available.
1339        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1340        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1341        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1342        TComDataCU *pcCUTR = NULL;
1343        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1344        {
1345          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1346        }
1347        if ( (true/*bEnforceSliceRestriction*/ &&
1348             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1349             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1350             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1351             ))
1352           )
1353        {
1354          // TR not available.
1355        }
1356        else
1357        {
1358          // TR is available, we use it.
1359          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1360        }
1361      }
1362      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1363    }
1364    // reset the entropy coder
1365    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1366        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1367        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1368        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1369    {
1370      {
1371        // We're crossing into another tile, tiles are independent.
1372        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1373        // have to perform it here.
1374        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1375        {
1376          ; // do nothing.
1377        }
1378        else
1379        {
1380          SliceType sliceType  = pcSlice->getSliceType();
1381          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1382          {
1383            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1384          }
1385          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1386          // Byte-alignment in slice_data() when new tile
1387          pcSubstreams[uiSubStrm].writeByteAlignment();
1388        }
1389      }
1390      {
1391        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1392        UInt uiAccumulatedSubstreamLength = 0;
1393        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1394        {
1395          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1396        }
1397        // add bits coded in previous dependent slices + bits coded so far
1398        // add number of emulation prevention byte count in the tile
1399        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1400      }
1401    }
1402
1403    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1404    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1405    {
1406      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1407      Int iNumCuInWidth     = saoParam->numCuInWidth;
1408      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1409      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1410      Int rx = uiCUAddr % iNumCuInWidth;
1411      Int ry = uiCUAddr / iNumCuInWidth;
1412      Int allowMergeLeft = 1;
1413      Int allowMergeUp   = 1;
1414      if (rx!=0)
1415      {
1416        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1417        {
1418          allowMergeLeft = 0;
1419        }
1420      }
1421      if (ry!=0)
1422      {
1423        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1424        {
1425          allowMergeUp = 0;
1426        }
1427      }
1428      Int addr = pcCU->getAddr();
1429      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1430      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1431      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1432      {
1433        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1434        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1435        if (allowMergeLeft)
1436        {
1437          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
1438        }
1439        else
1440        {
1441          mergeLeft = 0;
1442        }
1443        if(mergeLeft == 0)
1444        {
1445          if (allowMergeUp)
1446          {
1447            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1448          }
1449          else
1450          {
1451            mergeUp = 0;
1452          }
1453          if(mergeUp == 0)
1454          {
1455            for (Int compIdx=0;compIdx<3;compIdx++)
1456            {
1457            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1458              {
1459                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1460              }
1461            }
1462          }
1463        }
1464      }
1465    }
1466    else if (pcSlice->getSPS()->getUseSAO())
1467    {
1468      Int addr = pcCU->getAddr();
1469      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1470      for (Int cIdx=0; cIdx<3; cIdx++)
1471      {
1472        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1473        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1474        {
1475          saoLcuParam->mergeUpFlag   = 0;
1476          saoLcuParam->mergeLeftFlag = 0;
1477          saoLcuParam->subTypeIdx    = 0;
1478          saoLcuParam->typeIdx       = -1;
1479          saoLcuParam->offset[0]     = 0;
1480          saoLcuParam->offset[1]     = 0;
1481          saoLcuParam->offset[2]     = 0;
1482          saoLcuParam->offset[3]     = 0;
1483        }
1484      }
1485    }
1486#if ENC_DEC_TRACE
1487    g_bJustDoIt = g_bEncDecTraceEnable;
1488#endif
1489    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1490      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1491    {
1492      m_pcCuEncoder->encodeCU( pcCU );
1493    }
1494    else
1495    {
1496      m_pcCuEncoder->encodeCU( pcCU );
1497    }
1498#if ENC_DEC_TRACE
1499    g_bJustDoIt = g_bEncDecTraceDisable;
1500#endif   
1501    if( m_pcCfg->getUseSBACRD() )
1502    {
1503       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1504       
1505
1506       //Store probabilties of second LCU in line into buffer
1507       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1508      {
1509        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1510      }
1511    }
1512  }
1513  if( depSliceSegmentsEnabled )
1514  {
1515    if (m_pcCfg->getWaveFrontsynchro())
1516    {
1517      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1518    }
1519    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1520  }
1521#if ADAPTIVE_QP_SELECTION
1522  if( m_pcCfg->getUseAdaptQpSelect() )
1523  {
1524    m_pcTrQuant->storeSliceQpNext(pcSlice);
1525  }
1526#endif
1527  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1528  {
1529    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1530    {
1531      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1532    }
1533    else
1534    {
1535      m_pcEntropyCoder->determineCabacInitIdx();
1536    }
1537  }
1538}
1539
1540/** Determines the starting and bounding LCU address of current slice / dependent slice
1541 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1542 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1543 */
1544Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1545{
1546  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1547  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1548  UInt tileIdxIncrement;
1549  UInt tileIdx;
1550  UInt tileWidthInLcu;
1551  UInt tileHeightInLcu;
1552  UInt tileTotalCount;
1553
1554  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1555  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1556  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1557  if (bEncodeSlice) 
1558  {
1559    UInt uiCUAddrIncrement;
1560    switch (m_pcCfg->getSliceMode())
1561    {
1562    case FIXED_NUMBER_OF_LCU:
1563      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1564      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1565      break;
1566    case FIXED_NUMBER_OF_BYTES:
1567      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1568      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1569      break;
1570    case FIXED_NUMBER_OF_TILES:
1571      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1572        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1573        );
1574      uiCUAddrIncrement        = 0;
1575      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1576
1577      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1578      {
1579        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1580        {
1581          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1582          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1583          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1584        }
1585      }
1586
1587      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1588      break;
1589    default:
1590      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1591      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1592      break;
1593    } 
1594    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1595    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1596    {
1597      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1598    }
1599    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1600  }
1601  else
1602  {
1603    UInt uiCUAddrIncrement     ;
1604    switch (m_pcCfg->getSliceMode())
1605    {
1606    case FIXED_NUMBER_OF_LCU:
1607      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1608      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1609      break;
1610    case FIXED_NUMBER_OF_TILES:
1611      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1612        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1613        );
1614      uiCUAddrIncrement        = 0;
1615      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1616
1617      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1618      {
1619        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1620        {
1621          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1622          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1623          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1624        }
1625      }
1626
1627      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1628      break;
1629    default:
1630      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1631      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1632      break;
1633    } 
1634    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1635    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1636    {
1637      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1638    }
1639    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1640  }
1641
1642  Bool tileBoundary = false;
1643  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1644      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1645  {
1646    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1647    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1648    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1649    UInt tileBoundingCUAddrSlice = 0;
1650    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1651    {
1652      lcuEncAddr++;
1653      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1654    }
1655    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1656   
1657    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1658    {
1659      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1660      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1661      tileBoundary = true;
1662    }
1663  }
1664
1665  // Dependent slice
1666  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1667  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1668  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1669  if (bEncodeSlice) 
1670  {
1671    UInt uiCUAddrIncrement;
1672    switch (m_pcCfg->getSliceSegmentMode())
1673    {
1674    case FIXED_NUMBER_OF_LCU:
1675      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1676      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1677      break;
1678    case FIXED_NUMBER_OF_BYTES:
1679      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1680      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1681      break;
1682    case FIXED_NUMBER_OF_TILES:
1683      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1684        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1685        );
1686      uiCUAddrIncrement        = 0;
1687      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1688
1689      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1690      {
1691        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1692        {
1693          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1694          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1695          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1696        }
1697      }
1698      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1699      break;
1700    default:
1701      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1702      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1703      break;
1704    } 
1705    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1706    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1707    {
1708      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1709    }
1710    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1711  }
1712  else
1713  {
1714    UInt uiCUAddrIncrement;
1715    switch (m_pcCfg->getSliceSegmentMode())
1716    {
1717    case FIXED_NUMBER_OF_LCU:
1718      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1719      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1720      break;
1721    case FIXED_NUMBER_OF_TILES:
1722      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1723        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1724        );
1725      uiCUAddrIncrement        = 0;
1726      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1727
1728      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1729      {
1730        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1731        {
1732          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1733          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1734          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1735        }
1736      }
1737      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1738      break;
1739    default:
1740      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1741      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1742      break;
1743    } 
1744    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1745    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1746    {
1747      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1748    }
1749    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1750  }
1751  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1752    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1753  {
1754    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1755    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1756    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1757    UInt tileBoundingCUAddrSlice = 0;
1758    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1759    {
1760      lcuEncAddr++;
1761      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1762    }
1763    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1764
1765    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1766    {
1767      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1768      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1769      tileBoundary = true;
1770    }
1771  }
1772
1773  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1774  {
1775    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1776    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1777  }
1778
1779  //calculate real dependent slice start address
1780  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1781  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1782  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1783  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1784  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1785  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1786  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1787  {
1788    uiInternalAddress++;
1789    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1790    {
1791      uiInternalAddress=0;
1792      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1793    }
1794    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1795    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1796  }
1797  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1798 
1799  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1800  startCUAddrSliceSegment=uiRealStartAddress;
1801 
1802  //calculate real slice start address
1803  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1804  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1805  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1806  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1807  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1808  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1809  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1810  {
1811    uiInternalAddress++;
1812    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1813    {
1814      uiInternalAddress=0;
1815      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1816    }
1817    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1818    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1819  }
1820  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1821 
1822  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1823  uiStartCUAddrSlice=uiRealStartAddress;
1824 
1825  // Make a joint decision based on reconstruction and dependent slice bounds
1826  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1827  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1828
1829
1830  if (!bEncodeSlice)
1831  {
1832    // 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
1833    // first. Set the flags accordingly.
1834    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1835      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1836      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1837      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1838      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1839      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1840      || tileBoundary
1841)
1842    {
1843      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1844      {
1845        pcSlice->setNextSlice       ( true );
1846        pcSlice->setNextSliceSegment( false );
1847      }
1848      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1849      {
1850        pcSlice->setNextSlice       ( false );
1851        pcSlice->setNextSliceSegment( true );
1852      }
1853      else
1854      {
1855        pcSlice->setNextSlice       ( true );
1856        pcSlice->setNextSliceSegment( true );
1857      }
1858    }
1859    else
1860    {
1861      pcSlice->setNextSlice       ( false );
1862      pcSlice->setNextSliceSegment( false );
1863    }
1864  }
1865}
1866
1867Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1868{
1869  return 4.2005*log(lambda) + 13.7122;
1870}
1871
1872#if JCTVC_M0259_LAMBDAREFINEMENT
1873Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
1874{
1875  double tmp = beta * pow( 2.0 , deltaQP / 6 );
1876  double gamma = tmp / ( tmp + 1 );
1877  return( gamma );
1878}
1879#endif
1880//! \}
Note: See TracBrowser for help on using the repository browser.