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

Last change on this file since 915 was 883, checked in by seregin, 10 years ago

fix compiler warning

  • Property svn:eol-style set to native
File size: 85.2 KB
RevLine 
[313]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
[494]4 * granted under this license.
[313]5 *
[595]6 * Copyright (c) 2010-2014, ITU/ISO/IEC
[313]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;
[494]53
[313]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
[494]71Void TEncSlice::initCtxMem(  UInt i )
72{
[313]73  for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
74  {
75    delete (*j);
76  }
[494]77  CTXMem.clear();
78  CTXMem.resize(i);
[313]79}
80
[494]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
[313]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  }
[494]107
[313]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}
[494]115#endif
[313]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  }
[494]126
[313]127  // destroy residual picture
128  if ( m_apcPicYuvResi )
129  {
130    m_apcPicYuvResi->destroy();
131    delete m_apcPicYuvResi;
132    m_apcPicYuvResi  = NULL;
133  }
[494]134
[313]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();
[494]160#endif
[313]161  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
162  m_pcCuEncoder       = pcEncTop->getCuEncoder();
163  m_pcPredSearch      = pcEncTop->getPredSearch();
[494]164
[313]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();
[494]170
[313]171  m_pcBitCounter      = pcEncTop->getBitCounter();
172  m_pcRdCost          = pcEncTop->getRdCost();
173  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
174  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
[494]175
[313]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
[442]201Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, TComVPS *vps, Bool isField )
[313]202#else
[442]203Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, Bool isField )
[313]204#endif
205{
206  Double dQP;
207  Double dLambda;
[494]208
[313]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 );
[494]223
[313]224  // depth computation based on GOP size
225  Int depth;
226  {
[713]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
[313]238    Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
[713]239#endif
[313]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    }
[713]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
[313]272  }
[713]273#endif
274#endif
275  }
[494]276
[313]277  // slice type
278  SliceType eSliceType;
[494]279
[313]280  eSliceType=B_SLICE;
[713]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  {
[595]292  eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
[713]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
[494]300
[313]301  rpcSlice->setSliceType    ( eSliceType );
[494]302
[313]303  // ------------------------------------------------------------------------------------------------------------------
304  // Non-referenced frame marking
305  // ------------------------------------------------------------------------------------------------------------------
[494]306
[313]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);
[494]316
[313]317  // ------------------------------------------------------------------------------------------------------------------
318  // QP setting
319  // ------------------------------------------------------------------------------------------------------------------
[494]320
[313]321  dQP = m_pcCfg->getQP();
322  if(eSliceType!=I_SLICE)
323  {
[442]324#if REPN_FORMAT_IN_VPS
[595]325    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getQpBDOffsetY() ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
[442]326#else
[595]327    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
[442]328#endif
[313]329    {
330      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
331    }
332  }
[494]333
[313]334  // modify QP
335  Int* pdQPs = m_pcCfg->getdQPs();
336  if ( pdQPs )
337  {
338    dQP += pdQPs[ rpcSlice->getPOC() ];
339  }
340  // ------------------------------------------------------------------------------------------------------------------
341  // Lambda computation
342  // ------------------------------------------------------------------------------------------------------------------
[494]343
[313]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);
[494]352
[313]353    // compute lambda value
354    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
355    Int    SHIFT_QP = 12;
[442]356
357    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) );
358
[313]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    }
[494]384
[313]385    // if hadamard is used in ME process
386    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
387    {
388      dLambda *= 0.95;
389    }
[494]390
[442]391#if REPN_FORMAT_IN_VPS
392    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
393#else
[313]394    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
[442]395#endif
[313]396
397    m_pdRdPicLambda[iDQpIdx] = dLambda;
398    m_pdRdPicQp    [iDQpIdx] = dQP;
399    m_piRdPicQp    [iDQpIdx] = iQP;
400  }
[494]401
[313]402  // obtain dQP = 0 case
403  dLambda = m_pdRdPicLambda[0];
404  dQP     = m_pdRdPicQp    [0];
405  iQP     = m_piRdPicQp    [0];
[494]406
[313]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
[345]413  if( rpcSlice->getLayerId() > 0 && m_ppcTEncTop[layerId]->getNumActiveRefLayers() && depth >= 3 && m_pcCfg->getGOPSize() == ( 1 << depth ) )
[313]414  {
415    Int nCurLayer = rpcSlice->getLayerId();
416    Double gamma = xCalEnhLambdaFactor( m_ppcTEncTop[nCurLayer-1]->getQP() - m_ppcTEncTop[nCurLayer]->getQP() ,
[494]417      1.0 * m_ppcTEncTop[nCurLayer]->getSourceWidth() * m_ppcTEncTop[nCurLayer]->getSourceHeight()
[313]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.
[540]427  Double weight[2] = { 1.0, 1.0 };
[313]428  Int qpc;
429  Int chromaQPOffset;
430
431  chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
432  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
[540]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]);
[313]435
436  chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
437  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
[540]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
[313]441#if JCTVC_M0259_LAMBDAREFINEMENT
[345]442  if( rpcSlice->getLayerId() > 0 && m_ppcTEncTop[layerId]->getNumActiveRefLayers() && m_pcCfg->getGOPSize() >= 8 && rpcSlice->isIntra() == false && depth == 0 )
[313]443  {
444    dLambda *= 1.1;
[540]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]);
[313]451  }
452#endif
453
[540]454  const Double lambdaArray[3] = {dLambda, (dLambda / weight[0]), (dLambda / weight[1])};
455 
[494]456#if RDOQ_CHROMA_LAMBDA
[313]457// for RDOQ
[540]458  m_pcTrQuant->setLambdas( lambdaArray );
[313]459#else
460  m_pcTrQuant->setLambda( dLambda );
461#endif
462
463// For SAO
[540]464  rpcSlice->setLambdas( lambdaArray );
[494]465
[313]466#if HB_LAMBDA_FOR_LDC
467  // restore original slice type
[713]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  {
[595]481  eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
[713]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
[494]489
[442]490#if SVC_EXTENSION
[540]491  if( m_pcCfg->getLayerId() > 0 && m_pcCfg->getNumActiveRefLayers() > 0 )
[313]492  {
493    eSliceType=B_SLICE;
494  }
495#endif
496  rpcSlice->setSliceType        ( eSliceType );
497#endif
[494]498
[313]499  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
500  {
501    dQP = xGetQPValueAccordingToLambda( dLambda );
[442]502#if REPN_FORMAT_IN_VPS
[494]503    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
[442]504#else
[494]505    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
[442]506#endif
[313]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);
[494]518
[313]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 );
[494]559
[313]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 );
[494]569
[313]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()        );
[540]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
[313]583  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
584
[442]585#if SVC_EXTENSION
[313]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 );
[713]609#if ADAPTIVE_QP_SELECTION
[313]610  slice->setSliceQpBase ( sliceQP );
[713]611#endif
[313]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.
[540]615  Double weight[2] = { 1.0, 1.0 };
[313]616  Int qpc;
617  Int chromaQPOffset;
618
619  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
620  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
[540]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]);
[313]623
624  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
625  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
[540]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]);
[313]628
[540]629  const Double lambdaArray[3] = {lambda, (lambda / weight[0]), (lambda / weight[1])};
[313]630
[494]631#if RDOQ_CHROMA_LAMBDA
[313]632  // for RDOQ
[540]633  m_pcTrQuant->setLambdas( lambdaArray );
[313]634#else
635  m_pcTrQuant->setLambda( lambda );
636#endif
637
638  // For SAO
[540]639  slice->setLambdas( lambdaArray );
[313]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;
[494]653
[313]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  }
[494]685
[313]686  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
687  Double     dPicRdCostBest = MAX_DOUBLE;
688  UInt       uiQpIdxBest = 0;
[494]689
[313]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
[494]696
[313]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);
[494]707
[313]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];
[540]719    Double weight[2] = { 1.0, 1.0 };
[313]720    Int qpc;
721    Int chromaQPOffset;
722
723    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
724    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
[540]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]);
[313]727
728    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
729    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
[540]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]);
[313]732
[540]733    const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdx], (m_pdRdPicLambda[uiQpIdx] / weight[0]), (m_pdRdPicLambda[uiQpIdx] / weight[1])};
[494]734#if RDOQ_CHROMA_LAMBDA
[313]735    // for RDOQ
[540]736    m_pcTrQuant->setLambdas( lambdaArray );
[313]737#else
738    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
739#endif
740    // For SAO
[540]741    pcSlice->setLambdas( lambdaArray );
[494]742
[313]743    // try compress
744    compressSlice   ( rpcPic );
[494]745
[313]746    Double dPicRdCost;
747    UInt64 uiPicDist        = m_uiPicDist;
748    UInt64 uiALFBits        = 0;
[494]749
[313]750    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
[494]751
[313]752    // compute RD cost and choose the best
753    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
[494]754
[313]755    if ( dPicRdCost < dPicRdCostBest )
756    {
757      uiQpIdxBest    = uiQpIdx;
758      dPicRdCostBest = dPicRdCost;
759    }
760  }
[494]761
[313]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];
[540]770  Double weight[2] = { 1.0, 1.0 };
[313]771  Int qpc;
772  Int chromaQPOffset;
773
774  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
775  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
[540]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]);
[313]778
779  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
780  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
[540]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]);
[313]783
[540]784  const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdxBest], (m_pdRdPicLambda[uiQpIdxBest] / weight[0]), (m_pdRdPicLambda[uiQpIdxBest] / weight[1])};
[494]785#if RDOQ_CHROMA_LAMBDA
786  // for RDOQ
[540]787  m_pcTrQuant->setLambdas( lambdaArray );
[313]788#else
789  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
790#endif
791  // For SAO
[540]792  pcSlice->setLambdas( lambdaArray );
[313]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;
[494]810  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
[313]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
[442]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
[313]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() );
[442]825#endif
[313]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{
[880]838#if !WPP_FIX
[313]839  UInt  uiCUAddr;
[880]840#endif
[313]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 );
[494]847
[313]848  // initialize cost values
849  m_uiPicTotalBits  = 0;
850  m_dPicRdCost      = 0;
851  m_uiPicDist       = 0;
[494]852
[313]853  // set entropy coder
[595]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 
[313]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  }
[494]870#if O0194_WEIGHTED_PREDICTION_CGS
[588]871  else if( m_ppcTEncTop[pcSlice->getLayerId()]->getInterLayerWeightedPredFlag() )
[494]872  {
873    // Calculate for the base layer to be used in EL as Inter layer reference
874    estimateILWpParam( pcSlice );   
875  }
876#endif
[313]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();
[880]911#if WPP_FIX
912  const Int  iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
913  const UInt uiTilesAcross  = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
914#else
[313]915  Int  iNumSubstreams = 1;
916  UInt uiTilesAcross  = 0;
917
[595]918  iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
919  uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
[880]920#endif
[595]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++)
[313]926  {
[595]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  }
[313]933
[595]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]);
[313]937  }
[595]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++)
[313]944  {
[595]945    m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
[313]946  }
[595]947  for (UInt ui = 0; ui < uiTilesAcross; ui++)
948    m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
949
[313]950  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
951  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
[880]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
[313]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();
[880]967#endif
[313]968  if( depSliceSegmentsEnabled )
969  {
970    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
971    {
[880]972#if WPP_FIX
973      UInt uiSubStrm=0;
974#endif
[313]975      if( m_pcCfg->getWaveFrontsynchro() )
976      {
[880]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
[313]987        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
988        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
989        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
[494]990        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
[313]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        }
[880]1003#endif
[313]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.
[595]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();
[880]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
[595]1038    uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1039    //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1040    uiCol     = uiCUAddr % uiWidthInLCUs;
1041    uiLin     = uiCUAddr / uiWidthInLCUs;
1042    if (pcSlice->getPPS()->getNumSubstreams() > 1)
[313]1043    {
[595]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())
[880]1055#endif
[595]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)  )
[313]1063      {
[595]1064        pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
[313]1065      }
[595]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      )
[313]1071      {
[595]1072        // TR not available.
[313]1073      }
[595]1074      else
[313]1075      {
[595]1076        // TR is available, we use it.
1077        ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
[313]1078      }
1079    }
[595]1080    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
[313]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    }
[595]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() )
[313]1107    {
[595]1108      Int estQP        = pcSlice->getSliceQp();
1109      Double estLambda = -1.0;
1110      Double bpp       = -1.0;
[494]1111
[595]1112      if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
[313]1113      {
[595]1114        estQP = pcSlice->getSliceQp();
1115      }
1116      else
1117      {
1118        bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1119        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
[313]1120        {
[595]1121          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
[313]1122        }
1123        else
1124        {
[595]1125          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1126          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1127        }
[313]1128
[442]1129#if REPN_FORMAT_IN_VPS
1130          estQP     = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, estQP );
1131#else
[313]1132          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
[442]1133#endif
[313]1134
1135          m_pcRdCost->setLambda(estLambda);
1136#if RDOQ_CHROMA_LAMBDA
1137          // set lambda for RDOQ
1138          Double weight=m_pcRdCost->getChromaWeight();
[540]1139          const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) };
1140          m_pcTrQuant->setLambdas( lambdaArray );
[313]1141#else
1142          m_pcTrQuant->setLambda( estLambda );
1143#endif
1144      }
1145
[595]1146      m_pcRateCtrl->setRCQP( estQP );
[713]1147#if ADAPTIVE_QP_SELECTION
[595]1148      pcCU->getSlice()->setSliceQpBase( estQP );
[713]1149#endif
[595]1150    }
[313]1151
[595]1152    // run CU encoder
1153    m_pcCuEncoder->compressCU( pcCU );
[313]1154
[595]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 );
[494]1164
[595]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    }
[313]1176
[595]1177    ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1178    //Store probabilties of second LCU in line into buffer
[880]1179#if WPP_FIX
1180    if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (iNumSubstreams > 1)) && m_pcCfg->getWaveFrontsynchro()) 
1181#else
[595]1182    if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
[880]1183#endif
[595]1184    {
1185      m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1186    }
[313]1187
[595]1188    if ( m_pcCfg->getUseRateCtrl() )
1189    {
[313]1190
[595]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 ) ) )
[313]1198        {
[595]1199          numberOfEffectivePixels = numberOfEffectivePixels + 16;
1200          break;
[313]1201        }
[595]1202      }
[313]1203
[595]1204      if ( numberOfEffectivePixels == 0 )
[313]1205      {
[595]1206        actualQP = g_RCInvalidQPValue;
[313]1207      }
[595]1208      else
[313]1209      {
[595]1210        actualQP = pcCU->getQP( 0 );
[313]1211      }
[595]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() );
[313]1216    }
[494]1217
[313]1218    m_uiPicTotalBits += pcCU->getTotalBits();
1219    m_dPicRdCost     += pcCU->getTotalCost();
1220    m_uiPicDist      += pcCU->getTotalDistortion();
1221  }
[880]1222#if WPP_FIX
1223  if ((iNumSubstreams > 1) && !depSliceSegmentsEnabled)
1224#else
[313]1225  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
[880]1226#endif
[313]1227  {
1228    pcSlice->setNextSlice( true );
1229  }
[595]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  }
[313]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  }
[494]1270
[313]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
[880]1288#if WPP_FIX
1289  const Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams(); 
1290#else
[313]1291  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
[880]1292#endif
[313]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    }
[494]1300
[313]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();
[883]1313#if WPP_FIX
1314  UInt uiCol=0, uiSubStrm=0;
1315#else
[313]1316  UInt uiCol=0, uiLin=0, uiSubStrm=0;
[883]1317#endif
[313]1318  UInt uiTileCol      = 0;
1319  UInt uiTileStartLCU = 0;
1320  UInt uiTileLCUX     = 0;
1321  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1322  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1323                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1324                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
[880]1325#if WPP_FIX
1326  UInt currentTileIdx=rpcPic->getPicSym()->getTileIdxMap(uiCUAddr); 
1327  TComTile *pCurrentTile=rpcPic->getPicSym()->getTComTile(currentTileIdx); 
1328  uiTileStartLCU = pCurrentTile->getFirstCUAddr(); 
1329#else
[313]1330  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
[880]1331#endif
[313]1332  if( depSliceSegmentsEnabled )
1333  {
[880]1334#if WPP_FIX
1335    if( pcSlice->isNextSlice()|| uiCUAddr == uiTileStartLCU)
1336#else
[313]1337    if( pcSlice->isNextSlice()||
1338        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
[880]1339#endif
[313]1340    {
1341      if(m_pcCfg->getWaveFrontsynchro())
1342      {
1343        CTXMem[1]->loadContexts(m_pcSbacCoder);
1344      }
1345      CTXMem[0]->loadContexts(m_pcSbacCoder);
1346    }
1347    else
1348    {
1349      if(m_pcCfg->getWaveFrontsynchro())
1350      {
[880]1351#if WPP_FIX
1352        uiTileCol = currentTileIdx % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1353#else
[313]1354        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
[880]1355#endif
[313]1356        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
[880]1357#if WPP_FIX
1358        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
1359        uiSubStrm=rpcPic->getSubstreamForLCUAddr(uiCUAddr, true, pcSlice); 
1360        if ( pCurrentTile->getTileWidth() < 2) 
1361        { 
1362          CTXMem[0]->loadContexts(m_pcSbacCoder); 
1363        } 
1364#else
[313]1365        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1366        uiLin     = uiCUAddr / uiWidthInLCUs;
1367        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1368          + uiLin%iNumSubstreamsPerTile;
1369        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1370        {
1371          uiCol     = uiCUAddr % uiWidthInLCUs;
1372          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1373          if(uiCol==uiTileLCUX)
1374          {
1375            CTXMem[0]->loadContexts(m_pcSbacCoder);
1376          }
1377        }
[880]1378#endif
[313]1379      }
1380      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1381    }
1382  }
1383
1384  UInt uiEncCUOrder;
1385  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1386       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1387       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1388  {
[595]1389    uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1390    uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1391    uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1392    //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1393    uiCol     = uiCUAddr % uiWidthInLCUs;
[880]1394#if WPP_FIX
1395    uiSubStrm=rpcPic->getSubstreamForLCUAddr(uiCUAddr, true, pcSlice);
1396#else
[883]1397    uiLin     = uiCUAddr / uiWidthInLCUs;
[595]1398    if (pcSlice->getPPS()->getNumSubstreams() > 1)
[313]1399    {
[595]1400      // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1401      Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1402      uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1403          + uiLin%iNumSubstreamsPerTile;
1404    }
1405    else
1406    {
1407      // dependent tiles => substreams are "per frame".
1408      uiSubStrm = uiLin % iNumSubstreams;
1409    }
[880]1410#endif
[595]1411
1412    m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1413    // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
[880]1414#if WPP_FIX
1415    if (((iNumSubstreams > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1416#else
[595]1417    if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
[880]1418#endif
[595]1419    {
1420      // We'll sync if the TR is available.
1421      TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1422      UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1423      UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1424      TComDataCU *pcCUTR = NULL;
1425      if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
[313]1426      {
[595]1427        pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
[313]1428      }
[595]1429      if ( (true/*bEnforceSliceRestriction*/ &&
1430          ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||
1431              (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1432              ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1433          ))
1434      )
[313]1435      {
[595]1436        // TR not available.
[313]1437      }
[595]1438      else
[313]1439      {
[595]1440        // TR is available, we use it.
1441        pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
[313]1442      }
1443    }
[595]1444    m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1445
[313]1446    // reset the entropy coder
1447    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1448        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1449        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1450        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1451    {
1452      {
1453        // We're crossing into another tile, tiles are independent.
1454        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1455        // have to perform it here.
[880]1456#if WPP_FIX
1457        if (iNumSubstreams <= 1)
1458#else
[313]1459        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1460        {
1461          ; // do nothing.
1462        }
1463        else
[880]1464#endif
[313]1465        {
1466          SliceType sliceType  = pcSlice->getSliceType();
1467          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1468          {
1469            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1470          }
1471          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1472          // Byte-alignment in slice_data() when new tile
1473          pcSubstreams[uiSubStrm].writeByteAlignment();
1474        }
1475      }
1476      {
1477        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1478        UInt uiAccumulatedSubstreamLength = 0;
1479        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1480        {
1481          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1482        }
1483        // add bits coded in previous dependent slices + bits coded so far
1484        // add number of emulation prevention byte count in the tile
1485        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1486      }
1487    }
1488
[494]1489    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
[540]1490    if ( pcSlice->getSPS()->getUseSAO() )
1491    {
1492      if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
1493      {
1494        SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[uiCUAddr];
1495        Bool sliceEnabled[NUM_SAO_COMPONENTS];
1496        sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag();
1497        sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma();
1498
1499        Bool leftMergeAvail = false;
1500        Bool aboveMergeAvail= false;
1501        //merge left condition
1502        Int rx = (uiCUAddr % uiWidthInLCUs);
1503        if(rx > 0)
1504        {
1505          leftMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-1);
1506        }
1507
1508        //merge up condition
1509        Int ry = (uiCUAddr / uiWidthInLCUs);
1510        if(ry > 0)
1511        {
1512          aboveMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-uiWidthInLCUs);
1513        }
1514
[644]1515#if SVC_EXTENSION
1516        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, m_ppcTEncTop[pcSlice->getLayerId()]->getSAO()->getSaoMaxOffsetQVal(), sliceEnabled, leftMergeAvail, aboveMergeAvail);
1517#else
[540]1518        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam,sliceEnabled, leftMergeAvail, aboveMergeAvail);
[644]1519#endif
[540]1520      }
1521    }
1522
[313]1523#if ENC_DEC_TRACE
1524    g_bJustDoIt = g_bEncDecTraceEnable;
1525#endif
1526    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1527      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1528    {
1529      m_pcCuEncoder->encodeCU( pcCU );
1530    }
1531    else
1532    {
1533      m_pcCuEncoder->encodeCU( pcCU );
1534    }
1535#if ENC_DEC_TRACE
1536    g_bJustDoIt = g_bEncDecTraceDisable;
[494]1537#endif
[595]1538    pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1539    //Store probabilties of second LCU in line into buffer
[880]1540#if WPP_FIX
1541    if ( (depSliceSegmentsEnabled || (iNumSubstreams > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1542#else
[595]1543    if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
[880]1544#endif
[313]1545    {
[595]1546      m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
[313]1547    }
1548  }
1549  if( depSliceSegmentsEnabled )
1550  {
1551    if (m_pcCfg->getWaveFrontsynchro())
1552    {
1553      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1554    }
1555    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1556  }
1557#if ADAPTIVE_QP_SELECTION
1558  if( m_pcCfg->getUseAdaptQpSelect() )
1559  {
1560    m_pcTrQuant->storeSliceQpNext(pcSlice);
1561  }
1562#endif
1563  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1564  {
1565    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1566    {
1567      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1568    }
1569    else
1570    {
1571      m_pcEntropyCoder->determineCabacInitIdx();
1572    }
1573  }
1574}
1575
[880]1576#if WPP_FIX
1577Void TEncSlice::calculateBoundingCUAddrForSlice(UInt &uiStartCUAddrSlice, UInt &uiBoundingCUAddrSlice, Bool &bReachedTileBoundary, TComPic*& rpcPic, Bool bEncodeSlice, Int sliceMode, Int sliceArgument, UInt uiSliceCurEndCUAddr) 
1578{ 
1579  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx()); 
1580  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame(); 
1581  const UInt scaleCUAddr = rpcPic->getNumPartInCU(); // due to fine granularity slices all addresses are scaled.
1582  uiBoundingCUAddrSlice=0; 
1583  bReachedTileBoundary=false; 
1584
1585  switch (sliceMode) 
1586  { 
1587  case FIXED_NUMBER_OF_LCU: 
1588    { 
1589      UInt uiCUAddrIncrement    = sliceArgument; 
1590      uiBoundingCUAddrSlice     = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*scaleCUAddr) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*scaleCUAddr; 
1591    } 
1592    break; 
1593  case FIXED_NUMBER_OF_BYTES: 
1594    if (bEncodeSlice) 
1595      uiBoundingCUAddrSlice     = uiSliceCurEndCUAddr; 
1596    else 
1597      uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame*scaleCUAddr; 
1598    break; 
1599  case FIXED_NUMBER_OF_TILES: 
1600    { 
1601      UInt tileIdx              = rpcPic->getPicSym()->getTileIdxMap( rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/scaleCUAddr) ); 
1602      UInt uiCUAddrIncrement    = 0; 
1603      UInt tileTotalCount       = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1); 
1604
1605      for(UInt tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++) 
1606      { 
1607        if((tileIdx + tileIdxIncrement) < tileTotalCount) 
1608        { 
1609          UInt tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth(); 
1610          UInt tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight(); 
1611          uiCUAddrIncrement    += (tileWidthInLcu * tileHeightInLcu * scaleCUAddr); 
1612        } 
1613      } 
1614
1615      uiBoundingCUAddrSlice     = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*scaleCUAddr) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*scaleCUAddr; 
1616    } 
1617    break; 
1618  default: 
1619    uiBoundingCUAddrSlice       = uiNumberOfCUsInFrame*scaleCUAddr; 
1620    break; 
1621  } 
1622
1623  // Adjust for tiles and wavefronts.
1624  if ((sliceMode == FIXED_NUMBER_OF_LCU || sliceMode == FIXED_NUMBER_OF_BYTES) && 
1625    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0)) 
1626  { 
1627    const UInt lcuEncAddrStart = (uiStartCUAddrSlice+scaleCUAddr-1)/scaleCUAddr; 
1628    const UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddrStart); 
1629    const UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr); 
1630    const Bool bWavefrontsEnabled = m_pcCfg->getWaveFrontsynchro(); 
1631
1632    TComTile *pStartingTile = rpcPic->getPicSym()->getTComTile(startTileIdx); 
1633    const UInt uiTileStartLCUEncAddr      = rpcPic->getPicSym()->getInverseCUOrderMap(pStartingTile->getFirstCUAddr()); 
1634    const UInt uiTileStartWidth           = pStartingTile->getTileWidth(); 
1635    const UInt uiTileStartHeight          = pStartingTile->getTileHeight(); 
1636    const UInt uiTileLastLCUEncAddr_excl  = uiTileStartLCUEncAddr + uiTileStartWidth*uiTileStartHeight; 
1637    const UInt tileBoundingCUAddrSlice    = uiTileLastLCUEncAddr_excl * scaleCUAddr; 
1638
1639    const UInt lcuColumnOfStartingTile=((lcuEncAddrStart-uiTileStartLCUEncAddr)%uiTileStartWidth); 
1640    if (bWavefrontsEnabled && lcuColumnOfStartingTile!=0) 
1641    { 
1642      // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1643      const UInt numberOfLCUsToEndOfRow=uiTileStartWidth-lcuColumnOfStartingTile; 
1644      const UInt wavefrontTileBoundingCUAddrSlice = (lcuEncAddrStart+numberOfLCUsToEndOfRow)*scaleCUAddr; 
1645      if (wavefrontTileBoundingCUAddrSlice < uiBoundingCUAddrSlice) 
1646      { 
1647        uiBoundingCUAddrSlice = wavefrontTileBoundingCUAddrSlice; 
1648      } 
1649    } 
1650
1651    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice) 
1652    { 
1653      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice; 
1654      bReachedTileBoundary = true; 
1655    } 
1656  } 
1657  else if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*scaleCUAddr) != 0)) 
1658  { 
1659    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1660    uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*scaleCUAddr)) + (rpcPic->getFrameWidthInCU()*scaleCUAddr)); 
1661  } 
1662
1663  //calculate real slice start address (fine granularity slices)
1664  { 
1665    UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(uiStartCUAddrSlice) % scaleCUAddr; 
1666    UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(uiStartCUAddrSlice) / scaleCUAddr; 
1667    UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; 
1668    UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; 
1669#if REPN_FORMAT_IN_VPS
1670    UInt uiWidth = pcSlice->getPicWidthInLumaSamples();
1671    UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
1672#else
1673    UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples(); 
1674    UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples(); 
1675#endif
1676    while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight)) 
1677    { 
1678      uiInternalAddress++; 
1679      if(uiInternalAddress>=scaleCUAddr) 
1680      { 
1681        uiInternalAddress=0; 
1682        uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1); 
1683      } 
1684      uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; 
1685      uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; 
1686    } 
1687    UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*scaleCUAddr+uiInternalAddress); 
1688
1689    uiStartCUAddrSlice=uiRealStartAddress; 
1690  } 
1691} 
1692
1693/** Determines the starting and bounding LCU address of current slice / dependent slice
1694* \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1695* \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1696*/ 
1697Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice ) 
1698{ 
1699  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx()); 
1700
1701  // Non-dependent slice
1702  UInt uiStartCUAddrSlice   = pcSlice->getSliceCurStartCUAddr(); 
1703  Bool bTileBoundarySlice   = false; 
1704  UInt uiBoundingCUAddrSlice; 
1705  calculateBoundingCUAddrForSlice(uiStartCUAddrSlice, uiBoundingCUAddrSlice, bTileBoundarySlice, rpcPic, bEncodeSlice, m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument(), pcSlice->getSliceCurEndCUAddr()); 
1706  pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice ); 
1707  pcSlice->setSliceCurStartCUAddr(uiStartCUAddrSlice); 
1708
1709  // Dependent slice
1710  UInt startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr(); 
1711  Bool bTileBoundarySliceSegment  = false; 
1712  UInt boundingCUAddrSliceSegment; 
1713  calculateBoundingCUAddrForSlice(startCUAddrSliceSegment, boundingCUAddrSliceSegment, bTileBoundarySliceSegment, rpcPic, bEncodeSlice, m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument(), pcSlice->getSliceSegmentCurEndCUAddr()); 
1714  pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment ); 
1715  pcSlice->setSliceSegmentCurStartCUAddr(startCUAddrSliceSegment); 
1716
1717  // Make a joint decision based on reconstruction and dependent slice bounds
1718  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   ); 
1719  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment); 
1720
1721
1722  if (!bEncodeSlice) 
1723  { 
1724    // 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
1725    // first. Set the flags accordingly.
1726    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU) 
1727      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU) 
1728      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1729      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU) 
1730      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1731      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0) 
1732      || bTileBoundarySlice || bTileBoundarySliceSegment ) 
1733    { 
1734      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment) 
1735      { 
1736        pcSlice->setNextSlice       ( true ); 
1737        pcSlice->setNextSliceSegment( false ); 
1738      } 
1739      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment) 
1740      { 
1741        pcSlice->setNextSlice       ( false ); 
1742        pcSlice->setNextSliceSegment( true ); 
1743      } 
1744      else 
1745      { 
1746        pcSlice->setNextSlice       ( true ); 
1747        pcSlice->setNextSliceSegment( true ); 
1748      } 
1749    } 
1750    else 
1751    { 
1752      pcSlice->setNextSlice       ( false ); 
1753      pcSlice->setNextSliceSegment( false ); 
1754    } 
1755  } 
1756} 
1757#else
[313]1758/** Determines the starting and bounding LCU address of current slice / dependent slice
1759 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1760 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1761 */
1762Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1763{
1764  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1765  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1766  UInt tileIdxIncrement;
1767  UInt tileIdx;
1768  UInt tileWidthInLcu;
1769  UInt tileHeightInLcu;
1770  UInt tileTotalCount;
1771
1772  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1773  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1774  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
[494]1775  if (bEncodeSlice)
[313]1776  {
1777    UInt uiCUAddrIncrement;
1778    switch (m_pcCfg->getSliceMode())
1779    {
1780    case FIXED_NUMBER_OF_LCU:
1781      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1782      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1783      break;
1784    case FIXED_NUMBER_OF_BYTES:
1785      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1786      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1787      break;
1788    case FIXED_NUMBER_OF_TILES:
1789      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1790        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1791        );
1792      uiCUAddrIncrement        = 0;
1793      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1794
1795      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1796      {
1797        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1798        {
1799          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1800          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1801          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1802        }
1803      }
1804
1805      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1806      break;
1807    default:
1808      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1809      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1810      break;
[494]1811    }
[313]1812    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1813    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1814    {
1815      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1816    }
1817    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1818  }
1819  else
1820  {
1821    UInt uiCUAddrIncrement     ;
1822    switch (m_pcCfg->getSliceMode())
1823    {
1824    case FIXED_NUMBER_OF_LCU:
1825      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1826      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1827      break;
1828    case FIXED_NUMBER_OF_TILES:
1829      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1830        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1831        );
1832      uiCUAddrIncrement        = 0;
1833      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1834
1835      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1836      {
1837        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1838        {
1839          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1840          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1841          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1842        }
1843      }
1844
1845      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1846      break;
1847    default:
1848      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1849      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1850      break;
[494]1851    }
[313]1852    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1853    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1854    {
1855      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1856    }
1857    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1858  }
1859
1860  Bool tileBoundary = false;
[494]1861  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) &&
[313]1862      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1863  {
1864    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1865    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1866    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1867    UInt tileBoundingCUAddrSlice = 0;
1868    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1869    {
1870      lcuEncAddr++;
1871      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1872    }
1873    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
[494]1874
[313]1875    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1876    {
1877      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1878      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1879      tileBoundary = true;
1880    }
1881  }
1882
1883  // Dependent slice
1884  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1885  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1886  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
[494]1887  if (bEncodeSlice)
[313]1888  {
1889    UInt uiCUAddrIncrement;
1890    switch (m_pcCfg->getSliceSegmentMode())
1891    {
1892    case FIXED_NUMBER_OF_LCU:
1893      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1894      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1895      break;
1896    case FIXED_NUMBER_OF_BYTES:
1897      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1898      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1899      break;
1900    case FIXED_NUMBER_OF_TILES:
1901      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1902        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1903        );
1904      uiCUAddrIncrement        = 0;
1905      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1906
1907      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1908      {
1909        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1910        {
1911          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1912          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1913          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1914        }
1915      }
1916      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1917      break;
1918    default:
1919      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1920      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1921      break;
[494]1922    }
[313]1923    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1924    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1925    {
1926      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1927    }
1928    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1929  }
1930  else
1931  {
1932    UInt uiCUAddrIncrement;
1933    switch (m_pcCfg->getSliceSegmentMode())
1934    {
1935    case FIXED_NUMBER_OF_LCU:
1936      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1937      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1938      break;
1939    case FIXED_NUMBER_OF_TILES:
1940      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1941        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1942        );
1943      uiCUAddrIncrement        = 0;
1944      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1945
1946      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1947      {
1948        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1949        {
1950          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1951          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1952          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1953        }
1954      }
1955      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1956      break;
1957    default:
1958      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1959      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1960      break;
[494]1961    }
[313]1962    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1963    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1964    {
1965      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1966    }
1967    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1968  }
[494]1969  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) &&
[313]1970    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1971  {
1972    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1973    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1974    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1975    UInt tileBoundingCUAddrSlice = 0;
1976    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1977    {
1978      lcuEncAddr++;
1979      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1980    }
1981    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1982
1983    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1984    {
1985      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1986      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1987      tileBoundary = true;
1988    }
1989  }
1990
1991  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1992  {
1993    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1994    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1995  }
1996
1997  //calculate real dependent slice start address
1998  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1999  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
2000  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2001  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
[442]2002#if REPN_FORMAT_IN_VPS
2003  UInt uiWidth = pcSlice->getPicWidthInLumaSamples();
2004  UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
2005#else
[313]2006  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
2007  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
[442]2008#endif
[313]2009  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
2010  {
2011    uiInternalAddress++;
2012    if(uiInternalAddress>=rpcPic->getNumPartInCU())
2013    {
2014      uiInternalAddress=0;
2015      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
2016    }
2017    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2018    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2019  }
2020  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
[494]2021
[313]2022  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
2023  startCUAddrSliceSegment=uiRealStartAddress;
[494]2024
[313]2025  //calculate real slice start address
2026  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
2027  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
2028  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2029  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
[442]2030#if REPN_FORMAT_IN_VPS
2031  uiWidth = pcSlice->getPicWidthInLumaSamples();
2032  uiHeight = pcSlice->getPicHeightInLumaSamples();
2033#else
[313]2034  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
2035  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
[442]2036#endif
[313]2037  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
2038  {
2039    uiInternalAddress++;
2040    if(uiInternalAddress>=rpcPic->getNumPartInCU())
2041    {
2042      uiInternalAddress=0;
2043      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
2044    }
2045    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2046    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2047  }
2048  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
[494]2049
[313]2050  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
2051  uiStartCUAddrSlice=uiRealStartAddress;
[494]2052
[313]2053  // Make a joint decision based on reconstruction and dependent slice bounds
2054  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
2055  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
2056
2057
2058  if (!bEncodeSlice)
2059  {
2060    // 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
2061    // first. Set the flags accordingly.
2062    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2063      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
[494]2064      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0)
[313]2065      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
[494]2066      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0)
[313]2067      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
2068      || tileBoundary
2069)
2070    {
2071      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
2072      {
2073        pcSlice->setNextSlice       ( true );
2074        pcSlice->setNextSliceSegment( false );
2075      }
2076      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
2077      {
2078        pcSlice->setNextSlice       ( false );
2079        pcSlice->setNextSliceSegment( true );
2080      }
2081      else
2082      {
2083        pcSlice->setNextSlice       ( true );
2084        pcSlice->setNextSliceSegment( true );
2085      }
2086    }
2087    else
2088    {
2089      pcSlice->setNextSlice       ( false );
2090      pcSlice->setNextSliceSegment( false );
2091    }
2092  }
2093}
[880]2094#endif
[313]2095
2096Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
2097{
2098  return 4.2005*log(lambda) + 13.7122;
2099}
2100
[595]2101#if SVC_EXTENSION
[313]2102#if JCTVC_M0259_LAMBDAREFINEMENT
2103Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
2104{
2105  double tmp = beta * pow( 2.0 , deltaQP / 6 );
2106  double gamma = tmp / ( tmp + 1 );
2107  return( gamma );
2108}
2109#endif
[494]2110#if O0194_WEIGHTED_PREDICTION_CGS
2111Void TEncSlice::estimateILWpParam( TComSlice* pcSlice )
2112{
2113  xCalcACDCParamSlice(pcSlice);
2114  wpACDCParam * temp_weightACDCParam;
2115
2116  pcSlice->getWpAcDcParam(temp_weightACDCParam);
2117  g_refWeightACDCParam = (void *) temp_weightACDCParam;
2118}
2119#endif
[595]2120#endif //SVC_EXTENSION
[313]2121//! \}
Note: See TracBrowser for help on using the repository browser.