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

Last change on this file since 880 was 880, checked in by seregin, 11 years ago

port rev 4061 from RExt to solve WPP problem related to ticket #35, macro is WPP_FIX

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