source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncSlice.cpp @ 698

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

merge with SHM-5.1-dev branch

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