source: SHVCSoftware/branches/HM-10.0-dev-SHM/source/Lib/TLibEncoder/TEncSlice.cpp @ 51

Last change on this file since 51 was 51, checked in by suehring, 12 years ago

import HM 10.0 (HEVCSoftware/trunk rev. 3352)

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