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

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

Integrated 3D encoder control, camera parameters, renderer and MV fixes.

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