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

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

merge SHM-4.1-dev branch

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