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

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

merge with SHM-5.0-dev branch

  • Property svn:eol-style set to native
File size: 71.1 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2014, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncSlice.cpp
35    \brief    slice encoder class
36*/
37
38#include "TEncTop.h"
39#include "TEncSlice.h"
40#include <math.h>
41
42//! \ingroup TLibEncoder
43//! \{
44
45// ====================================================================================================================
46// Constructor / destructor / create / destroy
47// ====================================================================================================================
48
49TEncSlice::TEncSlice()
50{
51  m_apcPicYuvPred = NULL;
52  m_apcPicYuvResi = NULL;
53
54  m_pdRdPicLambda = NULL;
55  m_pdRdPicQp     = NULL;
56  m_piRdPicQp     = NULL;
57  m_pcBufferSbacCoders    = NULL;
58  m_pcBufferBinCoderCABACs  = NULL;
59  m_pcBufferLowLatSbacCoders    = NULL;
60  m_pcBufferLowLatBinCoderCABACs  = NULL;
61}
62
63TEncSlice::~TEncSlice()
64{
65  for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
66  {
67    delete (*i);
68  }
69}
70
71Void TEncSlice::initCtxMem(  UInt i )
72{
73  for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
74  {
75    delete (*j);
76  }
77  CTXMem.clear();
78  CTXMem.resize(i);
79}
80
81#if AUXILIARY_PICTURES
82Void TEncSlice::create( Int iWidth, Int iHeight, ChromaFormat chromaFormat, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
83{
84  // create prediction picture
85  if ( m_apcPicYuvPred == NULL )
86  {
87    m_apcPicYuvPred  = new TComPicYuv;
88    m_apcPicYuvPred->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
89  }
90
91  // create residual picture
92  if( m_apcPicYuvResi == NULL )
93  {
94    m_apcPicYuvResi  = new TComPicYuv;
95    m_apcPicYuvResi->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
96  }
97}
98#else
99Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
100{
101  // create prediction picture
102  if ( m_apcPicYuvPred == NULL )
103  {
104    m_apcPicYuvPred  = new TComPicYuv;
105    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
106  }
107
108  // create residual picture
109  if( m_apcPicYuvResi == NULL )
110  {
111    m_apcPicYuvResi  = new TComPicYuv;
112    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
113  }
114}
115#endif
116
117Void TEncSlice::destroy()
118{
119  // destroy prediction picture
120  if ( m_apcPicYuvPred )
121  {
122    m_apcPicYuvPred->destroy();
123    delete m_apcPicYuvPred;
124    m_apcPicYuvPred  = NULL;
125  }
126
127  // destroy residual picture
128  if ( m_apcPicYuvResi )
129  {
130    m_apcPicYuvResi->destroy();
131    delete m_apcPicYuvResi;
132    m_apcPicYuvResi  = NULL;
133  }
134
135  // free lambda and QP arrays
136  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
137  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
138  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
139
140  if ( m_pcBufferSbacCoders )
141  {
142    delete[] m_pcBufferSbacCoders;
143  }
144  if ( m_pcBufferBinCoderCABACs )
145  {
146    delete[] m_pcBufferBinCoderCABACs;
147  }
148  if ( m_pcBufferLowLatSbacCoders )
149    delete[] m_pcBufferLowLatSbacCoders;
150  if ( m_pcBufferLowLatBinCoderCABACs )
151    delete[] m_pcBufferLowLatBinCoderCABACs;
152}
153
154Void TEncSlice::init( TEncTop* pcEncTop )
155{
156  m_pcCfg             = pcEncTop;
157  m_pcListPic         = pcEncTop->getListPic();
158#if SVC_EXTENSION
159  m_ppcTEncTop        = pcEncTop->getLayerEnc();
160#endif
161  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
162  m_pcCuEncoder       = pcEncTop->getCuEncoder();
163  m_pcPredSearch      = pcEncTop->getPredSearch();
164
165  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
166  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
167  m_pcSbacCoder       = pcEncTop->getSbacCoder();
168  m_pcBinCABAC        = pcEncTop->getBinCABAC();
169  m_pcTrQuant         = pcEncTop->getTrQuant();
170
171  m_pcBitCounter      = pcEncTop->getBitCounter();
172  m_pcRdCost          = pcEncTop->getRdCost();
173  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
174  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
175
176  // create lambda and QP arrays
177  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
178  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
179  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
180  m_pcRateCtrl        = pcEncTop->getRateCtrl();
181}
182
183/**
184 - non-referenced frame marking
185 - QP computation based on temporal structure
186 - lambda computation based on QP
187 - set temporal layer ID and the parameter sets
188 .
189 \param pcPic         picture class
190 \param pocLast       POC of last picture
191 \param pocCurr       current POC
192 \param iNumPicRcvd   number of received pictures
193 \param iTimeOffset   POC offset for hierarchical structure
194 \param iDepth        temporal layer depth
195 \param rpcSlice      slice header class
196 \param pSPS          SPS associated with the slice
197 \param pPPS          PPS associated with the slice
198 */
199#if SVC_EXTENSION
200//\param vps          VPS associated with the slice
201Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, TComVPS *vps, Bool isField )
202#else
203Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, Bool isField )
204#endif
205{
206  Double dQP;
207  Double dLambda;
208
209  rpcSlice = pcPic->getSlice(0);
210  rpcSlice->setSPS( pSPS );
211  rpcSlice->setPPS( pPPS );
212  rpcSlice->setSliceBits(0);
213  rpcSlice->setPic( pcPic );
214#if SVC_EXTENSION
215  UInt layerId = pcPic->getLayerId();
216  rpcSlice->setVPS( vps );
217  rpcSlice->initSlice( layerId );
218#else
219  rpcSlice->initSlice();
220#endif
221  rpcSlice->setPicOutputFlag( true );
222  rpcSlice->setPOC( pocCurr );
223
224  // depth computation based on GOP size
225  Int depth;
226  {
227    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  }
251
252  // slice type
253  SliceType eSliceType;
254
255  eSliceType=B_SLICE;
256  eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
257
258  rpcSlice->setSliceType    ( eSliceType );
259
260  // ------------------------------------------------------------------------------------------------------------------
261  // Non-referenced frame marking
262  // ------------------------------------------------------------------------------------------------------------------
263
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);
273
274  // ------------------------------------------------------------------------------------------------------------------
275  // QP setting
276  // ------------------------------------------------------------------------------------------------------------------
277
278  dQP = m_pcCfg->getQP();
279  if(eSliceType!=I_SLICE)
280  {
281#if REPN_FORMAT_IN_VPS
282    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getQpBDOffsetY() ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
283#else
284    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
285#endif
286    {
287      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
288    }
289  }
290
291  // modify QP
292  Int* pdQPs = m_pcCfg->getdQPs();
293  if ( pdQPs )
294  {
295    dQP += pdQPs[ rpcSlice->getPOC() ];
296  }
297  // ------------------------------------------------------------------------------------------------------------------
298  // Lambda computation
299  // ------------------------------------------------------------------------------------------------------------------
300
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);
309
310    // compute lambda value
311    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
312    Int    SHIFT_QP = 12;
313
314    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) );
315
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    }
341
342    // if hadamard is used in ME process
343    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
344    {
345      dLambda *= 0.95;
346    }
347
348#if REPN_FORMAT_IN_VPS
349    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
350#else
351    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
352#endif
353
354    m_pdRdPicLambda[iDQpIdx] = dLambda;
355    m_pdRdPicQp    [iDQpIdx] = dQP;
356    m_piRdPicQp    [iDQpIdx] = iQP;
357  }
358
359  // obtain dQP = 0 case
360  dLambda = m_pdRdPicLambda[0];
361  dQP     = m_pdRdPicQp    [0];
362  iQP     = m_piRdPicQp    [0];
363
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
370  if( rpcSlice->getLayerId() > 0 && m_ppcTEncTop[layerId]->getNumActiveRefLayers() && depth >= 3 && m_pcCfg->getGOPSize() == ( 1 << depth ) )
371  {
372    Int nCurLayer = rpcSlice->getLayerId();
373    Double gamma = xCalEnhLambdaFactor( m_ppcTEncTop[nCurLayer-1]->getQP() - m_ppcTEncTop[nCurLayer]->getQP() ,
374      1.0 * m_ppcTEncTop[nCurLayer]->getSourceWidth() * m_ppcTEncTop[nCurLayer]->getSourceHeight()
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.
384  Double weight[2] = { 1.0, 1.0 };
385  Int qpc;
386  Int chromaQPOffset;
387
388  chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
389  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
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]);
392
393  chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
394  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
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
398#if JCTVC_M0259_LAMBDAREFINEMENT
399  if( rpcSlice->getLayerId() > 0 && m_ppcTEncTop[layerId]->getNumActiveRefLayers() && m_pcCfg->getGOPSize() >= 8 && rpcSlice->isIntra() == false && depth == 0 )
400  {
401    dLambda *= 1.1;
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]);
408  }
409#endif
410
411  const Double lambdaArray[3] = {dLambda, (dLambda / weight[0]), (dLambda / weight[1])};
412 
413#if RDOQ_CHROMA_LAMBDA
414// for RDOQ
415  m_pcTrQuant->setLambdas( lambdaArray );
416#else
417  m_pcTrQuant->setLambda( dLambda );
418#endif
419
420// For SAO
421  rpcSlice->setLambdas( lambdaArray );
422
423#if HB_LAMBDA_FOR_LDC
424  // restore original slice type
425  eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
426
427#if SVC_EXTENSION
428  if( m_pcCfg->getLayerId() > 0 && m_pcCfg->getNumActiveRefLayers() > 0 )
429  {
430    eSliceType=B_SLICE;
431  }
432#endif
433  rpcSlice->setSliceType        ( eSliceType );
434#endif
435
436  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
437  {
438    dQP = xGetQPValueAccordingToLambda( dLambda );
439#if REPN_FORMAT_IN_VPS
440    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
441#else
442    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
443#endif
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);
455
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 );
496
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 );
506
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()        );
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
520  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
521
522#if SVC_EXTENSION
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.
550  Double weight[2] = { 1.0, 1.0 };
551  Int qpc;
552  Int chromaQPOffset;
553
554  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
555  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
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]);
558
559  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
560  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
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]);
563
564  const Double lambdaArray[3] = {lambda, (lambda / weight[0]), (lambda / weight[1])};
565
566#if RDOQ_CHROMA_LAMBDA
567  // for RDOQ
568  m_pcTrQuant->setLambdas( lambdaArray );
569#else
570  m_pcTrQuant->setLambda( lambda );
571#endif
572
573  // For SAO
574  slice->setLambdas( lambdaArray );
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;
588
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  }
620
621  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
622  Double     dPicRdCostBest = MAX_DOUBLE;
623  UInt       uiQpIdxBest = 0;
624
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
631
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);
642
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];
654    Double weight[2] = { 1.0, 1.0 };
655    Int qpc;
656    Int chromaQPOffset;
657
658    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
659    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
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]);
662
663    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
664    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
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]);
667
668    const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdx], (m_pdRdPicLambda[uiQpIdx] / weight[0]), (m_pdRdPicLambda[uiQpIdx] / weight[1])};
669#if RDOQ_CHROMA_LAMBDA
670    // for RDOQ
671    m_pcTrQuant->setLambdas( lambdaArray );
672#else
673    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
674#endif
675    // For SAO
676    pcSlice->setLambdas( lambdaArray );
677
678    // try compress
679    compressSlice   ( rpcPic );
680
681    Double dPicRdCost;
682    UInt64 uiPicDist        = m_uiPicDist;
683    UInt64 uiALFBits        = 0;
684
685    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
686
687    // compute RD cost and choose the best
688    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
689
690    if ( dPicRdCost < dPicRdCostBest )
691    {
692      uiQpIdxBest    = uiQpIdx;
693      dPicRdCostBest = dPicRdCost;
694    }
695  }
696
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];
705  Double weight[2] = { 1.0, 1.0 };
706  Int qpc;
707  Int chromaQPOffset;
708
709  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
710  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
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]);
713
714  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
715  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
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]);
718
719  const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdxBest], (m_pdRdPicLambda[uiQpIdxBest] / weight[0]), (m_pdRdPicLambda[uiQpIdxBest] / weight[1])};
720#if RDOQ_CHROMA_LAMBDA
721  // for RDOQ
722  m_pcTrQuant->setLambdas( lambdaArray );
723#else
724  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
725#endif
726  // For SAO
727  pcSlice->setLambdas( lambdaArray );
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;
745  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
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
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
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() );
760#endif
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 );
780
781  // initialize cost values
782  m_uiPicTotalBits  = 0;
783  m_dPicRdCost      = 0;
784  m_uiPicDist       = 0;
785
786  // set entropy coder
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 
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  }
803#if O0194_WEIGHTED_PREDICTION_CGS
804  else if( m_ppcTEncTop[pcSlice->getLayerId()]->getInterLayerWeightedPredFlag() )
805  {
806    // Calculate for the base layer to be used in EL as Inter layer reference
807    estimateILWpParam( pcSlice );   
808  }
809#endif
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
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++)
854  {
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  }
861
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]);
865  }
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++)
872  {
873    m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
874  }
875  for (UInt ui = 0; ui < uiTilesAcross; ui++)
876    m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
877
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();
896        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
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.
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)
940    {
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)  )
959      {
960        pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
961      }
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      )
967      {
968        // TR not available.
969      }
970      else
971      {
972        // TR is available, we use it.
973        ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
974      }
975    }
976    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
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    }
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() )
1003    {
1004      Int estQP        = pcSlice->getSliceQp();
1005      Double estLambda = -1.0;
1006      Double bpp       = -1.0;
1007
1008      if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1009      {
1010        estQP = pcSlice->getSliceQp();
1011      }
1012      else
1013      {
1014        bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1015        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1016        {
1017          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1018        }
1019        else
1020        {
1021          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1022          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1023        }
1024
1025#if REPN_FORMAT_IN_VPS
1026          estQP     = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, estQP );
1027#else
1028          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1029#endif
1030
1031          m_pcRdCost->setLambda(estLambda);
1032#if RDOQ_CHROMA_LAMBDA
1033          // set lambda for RDOQ
1034          Double weight=m_pcRdCost->getChromaWeight();
1035          const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) };
1036          m_pcTrQuant->setLambdas( lambdaArray );
1037#else
1038          m_pcTrQuant->setLambda( estLambda );
1039#endif
1040      }
1041
1042      m_pcRateCtrl->setRCQP( estQP );
1043      pcCU->getSlice()->setSliceQpBase( estQP );
1044    }
1045
1046    // run CU encoder
1047    m_pcCuEncoder->compressCU( pcCU );
1048
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 );
1058
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    }
1070
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    }
1077
1078    if ( m_pcCfg->getUseRateCtrl() )
1079    {
1080
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 ) ) )
1088        {
1089          numberOfEffectivePixels = numberOfEffectivePixels + 16;
1090          break;
1091        }
1092      }
1093
1094      if ( numberOfEffectivePixels == 0 )
1095      {
1096        actualQP = g_RCInvalidQPValue;
1097      }
1098      else
1099      {
1100        actualQP = pcCU->getQP( 0 );
1101      }
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() );
1106    }
1107
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  }
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  }
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  }
1156
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    }
1182
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  {
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)
1251    {
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)  )
1273      {
1274        pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1275      }
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      )
1282      {
1283        // TR not available.
1284      }
1285      else
1286      {
1287        // TR is available, we use it.
1288        pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1289      }
1290    }
1291    m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1292
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
1332    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
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
1358        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam,sliceEnabled, leftMergeAvail, aboveMergeAvail);
1359      }
1360    }
1361
1362#if ENC_DEC_TRACE
1363    g_bJustDoIt = g_bEncDecTraceEnable;
1364#endif
1365    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1366      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1367    {
1368      m_pcCuEncoder->encodeCU( pcCU );
1369    }
1370    else
1371    {
1372      m_pcCuEncoder->encodeCU( pcCU );
1373    }
1374#if ENC_DEC_TRACE
1375    g_bJustDoIt = g_bEncDecTraceDisable;
1376#endif
1377    pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1378    //Store probabilties of second LCU in line into buffer
1379    if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1380    {
1381      m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1382    }
1383  }
1384  if( depSliceSegmentsEnabled )
1385  {
1386    if (m_pcCfg->getWaveFrontsynchro())
1387    {
1388      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1389    }
1390    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1391  }
1392#if ADAPTIVE_QP_SELECTION
1393  if( m_pcCfg->getUseAdaptQpSelect() )
1394  {
1395    m_pcTrQuant->storeSliceQpNext(pcSlice);
1396  }
1397#endif
1398  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1399  {
1400    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1401    {
1402      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1403    }
1404    else
1405    {
1406      m_pcEntropyCoder->determineCabacInitIdx();
1407    }
1408  }
1409}
1410
1411/** Determines the starting and bounding LCU address of current slice / dependent slice
1412 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1413 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1414 */
1415Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1416{
1417  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1418  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1419  UInt tileIdxIncrement;
1420  UInt tileIdx;
1421  UInt tileWidthInLcu;
1422  UInt tileHeightInLcu;
1423  UInt tileTotalCount;
1424
1425  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1426  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1427  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1428  if (bEncodeSlice)
1429  {
1430    UInt uiCUAddrIncrement;
1431    switch (m_pcCfg->getSliceMode())
1432    {
1433    case FIXED_NUMBER_OF_LCU:
1434      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1435      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1436      break;
1437    case FIXED_NUMBER_OF_BYTES:
1438      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1439      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1440      break;
1441    case FIXED_NUMBER_OF_TILES:
1442      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1443        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1444        );
1445      uiCUAddrIncrement        = 0;
1446      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1447
1448      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1449      {
1450        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1451        {
1452          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1453          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1454          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1455        }
1456      }
1457
1458      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1459      break;
1460    default:
1461      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1462      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1463      break;
1464    }
1465    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1466    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1467    {
1468      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1469    }
1470    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1471  }
1472  else
1473  {
1474    UInt uiCUAddrIncrement     ;
1475    switch (m_pcCfg->getSliceMode())
1476    {
1477    case FIXED_NUMBER_OF_LCU:
1478      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1479      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1480      break;
1481    case FIXED_NUMBER_OF_TILES:
1482      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1483        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1484        );
1485      uiCUAddrIncrement        = 0;
1486      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1487
1488      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1489      {
1490        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1491        {
1492          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1493          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1494          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1495        }
1496      }
1497
1498      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1499      break;
1500    default:
1501      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1502      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1503      break;
1504    }
1505    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1506    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1507    {
1508      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1509    }
1510    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1511  }
1512
1513  Bool tileBoundary = false;
1514  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) &&
1515      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1516  {
1517    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1518    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1519    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1520    UInt tileBoundingCUAddrSlice = 0;
1521    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1522    {
1523      lcuEncAddr++;
1524      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1525    }
1526    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1527
1528    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1529    {
1530      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1531      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1532      tileBoundary = true;
1533    }
1534  }
1535
1536  // Dependent slice
1537  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1538  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1539  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1540  if (bEncodeSlice)
1541  {
1542    UInt uiCUAddrIncrement;
1543    switch (m_pcCfg->getSliceSegmentMode())
1544    {
1545    case FIXED_NUMBER_OF_LCU:
1546      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1547      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1548      break;
1549    case FIXED_NUMBER_OF_BYTES:
1550      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1551      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1552      break;
1553    case FIXED_NUMBER_OF_TILES:
1554      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1555        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1556        );
1557      uiCUAddrIncrement        = 0;
1558      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1559
1560      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1561      {
1562        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1563        {
1564          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1565          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1566          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1567        }
1568      }
1569      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1570      break;
1571    default:
1572      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1573      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1574      break;
1575    }
1576    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1577    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1578    {
1579      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1580    }
1581    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1582  }
1583  else
1584  {
1585    UInt uiCUAddrIncrement;
1586    switch (m_pcCfg->getSliceSegmentMode())
1587    {
1588    case FIXED_NUMBER_OF_LCU:
1589      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1590      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1591      break;
1592    case FIXED_NUMBER_OF_TILES:
1593      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1594        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1595        );
1596      uiCUAddrIncrement        = 0;
1597      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1598
1599      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1600      {
1601        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1602        {
1603          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1604          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1605          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1606        }
1607      }
1608      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1609      break;
1610    default:
1611      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1612      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1613      break;
1614    }
1615    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1616    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1617    {
1618      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1619    }
1620    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1621  }
1622  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) &&
1623    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1624  {
1625    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1626    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1627    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1628    UInt tileBoundingCUAddrSlice = 0;
1629    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1630    {
1631      lcuEncAddr++;
1632      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1633    }
1634    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1635
1636    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1637    {
1638      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1639      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1640      tileBoundary = true;
1641    }
1642  }
1643
1644  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1645  {
1646    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1647    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1648  }
1649
1650  //calculate real dependent slice start address
1651  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1652  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1653  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1654  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1655#if REPN_FORMAT_IN_VPS
1656  UInt uiWidth = pcSlice->getPicWidthInLumaSamples();
1657  UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
1658#else
1659  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1660  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1661#endif
1662  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1663  {
1664    uiInternalAddress++;
1665    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1666    {
1667      uiInternalAddress=0;
1668      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1669    }
1670    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1671    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1672  }
1673  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1674
1675  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1676  startCUAddrSliceSegment=uiRealStartAddress;
1677
1678  //calculate real slice start address
1679  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1680  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1681  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1682  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1683#if REPN_FORMAT_IN_VPS
1684  uiWidth = pcSlice->getPicWidthInLumaSamples();
1685  uiHeight = pcSlice->getPicHeightInLumaSamples();
1686#else
1687  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1688  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1689#endif
1690  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1691  {
1692    uiInternalAddress++;
1693    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1694    {
1695      uiInternalAddress=0;
1696      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1697    }
1698    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1699    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1700  }
1701  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1702
1703  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1704  uiStartCUAddrSlice=uiRealStartAddress;
1705
1706  // Make a joint decision based on reconstruction and dependent slice bounds
1707  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1708  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1709
1710
1711  if (!bEncodeSlice)
1712  {
1713    // 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
1714    // first. Set the flags accordingly.
1715    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1716      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1717      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0)
1718      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1719      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0)
1720      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1721      || tileBoundary
1722)
1723    {
1724      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1725      {
1726        pcSlice->setNextSlice       ( true );
1727        pcSlice->setNextSliceSegment( false );
1728      }
1729      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1730      {
1731        pcSlice->setNextSlice       ( false );
1732        pcSlice->setNextSliceSegment( true );
1733      }
1734      else
1735      {
1736        pcSlice->setNextSlice       ( true );
1737        pcSlice->setNextSliceSegment( true );
1738      }
1739    }
1740    else
1741    {
1742      pcSlice->setNextSlice       ( false );
1743      pcSlice->setNextSliceSegment( false );
1744    }
1745  }
1746}
1747
1748Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1749{
1750  return 4.2005*log(lambda) + 13.7122;
1751}
1752
1753#if SVC_EXTENSION
1754#if JCTVC_M0259_LAMBDAREFINEMENT
1755Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
1756{
1757  double tmp = beta * pow( 2.0 , deltaQP / 6 );
1758  double gamma = tmp / ( tmp + 1 );
1759  return( gamma );
1760}
1761#endif
1762#if O0194_WEIGHTED_PREDICTION_CGS
1763Void TEncSlice::estimateILWpParam( TComSlice* pcSlice )
1764{
1765  xCalcACDCParamSlice(pcSlice);
1766  wpACDCParam * temp_weightACDCParam;
1767
1768  pcSlice->getWpAcDcParam(temp_weightACDCParam);
1769  g_refWeightACDCParam = (void *) temp_weightACDCParam;
1770}
1771#endif
1772#endif //SVC_EXTENSION
1773//! \}
Note: See TracBrowser for help on using the repository browser.