source: 3DVCSoftware/branches/HTM-DEV-0.1-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 362

Last change on this file since 362 was 362, checked in by tech, 11 years ago

Update to HM-10.1.

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