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

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

merge with SHM-5.0-dev

  • Property svn:eol-style set to native
File size: 75.3 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-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;
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 % 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->getSPS()->getUseLossless())))
283#else
284    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless())))
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 % 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  if( m_pcCfg->getUseSBACRD() )
788  {
789    m_pcSbacCoder->init( m_pcBinCABAC );
790    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
791    m_pcEntropyCoder->resetEntropy      ();
792    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
793    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
794    pppcRDSbacCoder->setBinCountingEnableFlag( false );
795    pppcRDSbacCoder->setBinsCoded( 0 );
796  }
797  else
798  {
799    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
800    m_pcEntropyCoder->resetEntropy      ();
801    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
802  }
803
804  //------------------------------------------------------------------------------
805  //  Weighted Prediction parameters estimation.
806  //------------------------------------------------------------------------------
807  // calculate AC/DC values for current picture
808  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
809  {
810    xCalcACDCParamSlice(pcSlice);
811  }
812#if O0194_WEIGHTED_PREDICTION_CGS
813  else if( m_ppcTEncTop[pcSlice->getLayerId()]->getInterLayerWeightedPredFlag() )
814  {
815    // Calculate for the base layer to be used in EL as Inter layer reference
816    estimateILWpParam( pcSlice );   
817  }
818#endif
819
820  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
821
822  if ( bWp_explicit )
823  {
824    //------------------------------------------------------------------------------
825    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
826    //------------------------------------------------------------------------------
827    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
828    {
829      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
830    }
831
832    xEstimateWPParamSlice( pcSlice );
833    pcSlice->initWpScaling();
834
835    // check WP on/off
836    xCheckWPEnable( pcSlice );
837  }
838
839#if ADAPTIVE_QP_SELECTION
840  if( m_pcCfg->getUseAdaptQpSelect() )
841  {
842    m_pcTrQuant->clearSliceARLCnt();
843    if(pcSlice->getSliceType()!=I_SLICE)
844    {
845      Int qpBase = pcSlice->getSliceQpBase();
846      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
847    }
848  }
849#endif
850  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
851  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
852  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
853  Int  iNumSubstreams = 1;
854  UInt uiTilesAcross  = 0;
855
856  if( m_pcCfg->getUseSBACRD() )
857  {
858    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
859    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
860    delete[] m_pcBufferSbacCoders;
861    delete[] m_pcBufferBinCoderCABACs;
862    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
863    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
864    for (Int ui = 0; ui < uiTilesAcross; ui++)
865    {
866      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
867    }
868    for (UInt ui = 0; ui < uiTilesAcross; ui++)
869    {
870      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
871    }
872
873    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
874    {
875      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
876    }
877  }
878  //if( m_pcCfg->getUseSBACRD() )
879  {
880    delete[] m_pcBufferLowLatSbacCoders;
881    delete[] m_pcBufferLowLatBinCoderCABACs;
882    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
883    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
884    for (Int ui = 0; ui < uiTilesAcross; ui++)
885    {
886      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
887    }
888    for (UInt ui = 0; ui < uiTilesAcross; ui++)
889      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
890  }
891  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
892  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
893  UInt uiCol=0, uiLin=0, uiSubStrm=0;
894  UInt uiTileCol      = 0;
895  UInt uiTileStartLCU = 0;
896  UInt uiTileLCUX     = 0;
897  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
898  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
899  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
900  if( depSliceSegmentsEnabled )
901  {
902    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
903    {
904      if( m_pcCfg->getWaveFrontsynchro() )
905      {
906        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
907        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
908        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
909        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
910        uiLin     = uiCUAddr / uiWidthInLCUs;
911        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
912          + uiLin%iNumSubstreamsPerTile;
913        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
914        {
915          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
916          uiCol     = uiCUAddr % uiWidthInLCUs;
917          if(uiCol==uiTileStartLCU)
918          {
919            CTXMem[0]->loadContexts(m_pcSbacCoder);
920          }
921        }
922      }
923      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
924      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
925    }
926    else
927    {
928      if(m_pcCfg->getWaveFrontsynchro())
929      {
930        CTXMem[1]->loadContexts(m_pcSbacCoder);
931      }
932      CTXMem[0]->loadContexts(m_pcSbacCoder);
933    }
934  }
935  // for every CU in slice
936  UInt uiEncCUOrder;
937  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
938       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
939       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
940  {
941    // initialize CU encoder
942    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
943    pcCU->initCU( rpcPic, uiCUAddr );
944
945    // inherit from TR if necessary, select substream to use.
946    if( m_pcCfg->getUseSBACRD() )
947    {
948      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
949      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
950      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
951      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
952      uiCol     = uiCUAddr % uiWidthInLCUs;
953      uiLin     = uiCUAddr / uiWidthInLCUs;
954      if (pcSlice->getPPS()->getNumSubstreams() > 1)
955      {
956        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
957        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
958        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
959                      + uiLin%iNumSubstreamsPerTile;
960      }
961      else
962      {
963        // dependent tiles => substreams are "per frame".
964        uiSubStrm = uiLin % iNumSubstreams;
965      }
966      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
967      {
968        // We'll sync if the TR is available.
969        TComDataCU *pcCUUp = pcCU->getCUAbove();
970        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
971        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
972        TComDataCU *pcCUTR = NULL;
973        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
974        {
975          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
976        }
977        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||
978             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
979             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
980             )
981           )
982        {
983          // TR not available.
984        }
985        else
986        {
987          // TR is available, we use it.
988          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
989        }
990      }
991      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
992    }
993
994    // reset the entropy coder
995    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
996        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
997        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
998        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
999    {
1000      SliceType sliceType = pcSlice->getSliceType();
1001      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1002      {
1003        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1004      }
1005      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1006      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1007      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1008      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1009    }
1010    // if RD based on SBAC is used
1011    if( m_pcCfg->getUseSBACRD() )
1012    {
1013      // set go-on entropy coder
1014      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1015      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1016
1017      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1018
1019      Double oldLambda = m_pcRdCost->getLambda();
1020      if ( m_pcCfg->getUseRateCtrl() )
1021      {
1022        Int estQP        = pcSlice->getSliceQp();
1023        Double estLambda = -1.0;
1024        Double bpp       = -1.0;
1025
1026        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1027        {
1028          estQP = pcSlice->getSliceQp();
1029        }
1030        else
1031        {
1032          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1033          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1034          {
1035            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1036          }
1037          else
1038          {
1039            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1040            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1041          }
1042
1043#if REPN_FORMAT_IN_VPS
1044          estQP     = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, estQP );
1045#else
1046          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1047#endif
1048
1049          m_pcRdCost->setLambda(estLambda);
1050#if RDOQ_CHROMA_LAMBDA
1051          // set lambda for RDOQ
1052          Double weight=m_pcRdCost->getChromaWeight();
1053          const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) };
1054          m_pcTrQuant->setLambdas( lambdaArray );
1055#else
1056          m_pcTrQuant->setLambda( estLambda );
1057#endif
1058        }
1059
1060        m_pcRateCtrl->setRCQP( estQP );
1061        pcCU->getSlice()->setSliceQpBase( estQP );
1062      }
1063
1064      // run CU encoder
1065      m_pcCuEncoder->compressCU( pcCU );
1066
1067      // restore entropy coder to an initial stage
1068      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1069      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1070      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1071      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1072      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1073      m_pcBitCounter->resetBits();
1074      pppcRDSbacCoder->setBinsCoded( 0 );
1075      m_pcCuEncoder->encodeCU( pcCU );
1076
1077      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1078      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1079      {
1080        pcSlice->setNextSlice( true );
1081        break;
1082      }
1083      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1084      {
1085        pcSlice->setNextSliceSegment( true );
1086        break;
1087      }
1088      if( m_pcCfg->getUseSBACRD() )
1089      {
1090         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1091
1092         //Store probabilties of second LCU in line into buffer
1093         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1094        {
1095          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1096        }
1097      }
1098
1099      if ( m_pcCfg->getUseRateCtrl() )
1100      {
1101
1102        Int actualQP        = g_RCInvalidQPValue;
1103        Double actualLambda = m_pcRdCost->getLambda();
1104        Int actualBits      = pcCU->getTotalBits();
1105        Int numberOfEffectivePixels    = 0;
1106        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1107        {
1108          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1109          {
1110            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1111            break;
1112          }
1113        }
1114
1115        if ( numberOfEffectivePixels == 0 )
1116        {
1117          actualQP = g_RCInvalidQPValue;
1118        }
1119        else
1120        {
1121          actualQP = pcCU->getQP( 0 );
1122        }
1123        m_pcRdCost->setLambda(oldLambda);
1124
1125        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
1126          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1127      }
1128    }
1129    // other case: encodeCU is not called
1130    else
1131    {
1132      m_pcCuEncoder->compressCU( pcCU );
1133      m_pcCuEncoder->encodeCU( pcCU );
1134      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1135      {
1136        pcSlice->setNextSlice( true );
1137        break;
1138      }
1139      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1140      {
1141        pcSlice->setNextSliceSegment( true );
1142        break;
1143      }
1144    }
1145
1146    m_uiPicTotalBits += pcCU->getTotalBits();
1147    m_dPicRdCost     += pcCU->getTotalCost();
1148    m_uiPicDist      += pcCU->getTotalDistortion();
1149  }
1150  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1151  {
1152    pcSlice->setNextSlice( true );
1153  }
1154  if( depSliceSegmentsEnabled )
1155  {
1156    if (m_pcCfg->getWaveFrontsynchro())
1157    {
1158      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1159    }
1160     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1161  }
1162  xRestoreWPparam( pcSlice );
1163}
1164
1165/**
1166 \param  rpcPic        picture class
1167 \retval rpcBitstream  bitstream class
1168 */
1169Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1170{
1171  UInt       uiCUAddr;
1172  UInt       uiStartCUAddr;
1173  UInt       uiBoundingCUAddr;
1174  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1175
1176  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1177  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1178  // choose entropy coder
1179  {
1180    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1181    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1182  }
1183
1184  m_pcCuEncoder->setBitCounter( NULL );
1185  m_pcBitCounter = NULL;
1186  // Appropriate substream bitstream is switched later.
1187  // for every CU
1188#if ENC_DEC_TRACE
1189  g_bJustDoIt = g_bEncDecTraceEnable;
1190#endif
1191  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1192  DTRACE_CABAC_T( "\tPOC: " );
1193  DTRACE_CABAC_V( rpcPic->getPOC() );
1194  DTRACE_CABAC_T( "\n" );
1195#if ENC_DEC_TRACE
1196  g_bJustDoIt = g_bEncDecTraceDisable;
1197#endif
1198
1199  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1200  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1201  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1202  UInt uiBitsOriginallyInSubstreams = 0;
1203  {
1204    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1205    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1206    {
1207      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1208    }
1209
1210    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1211    {
1212      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1213    }
1214
1215    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1216    {
1217      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1218    }
1219  }
1220
1221  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1222  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1223  UInt uiTileCol      = 0;
1224  UInt uiTileStartLCU = 0;
1225  UInt uiTileLCUX     = 0;
1226  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1227  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1228                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1229                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1230  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1231  if( depSliceSegmentsEnabled )
1232  {
1233    if( pcSlice->isNextSlice()||
1234        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1235    {
1236      if(m_pcCfg->getWaveFrontsynchro())
1237      {
1238        CTXMem[1]->loadContexts(m_pcSbacCoder);
1239      }
1240      CTXMem[0]->loadContexts(m_pcSbacCoder);
1241    }
1242    else
1243    {
1244      if(m_pcCfg->getWaveFrontsynchro())
1245      {
1246        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1247        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1248        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1249        uiLin     = uiCUAddr / uiWidthInLCUs;
1250        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1251          + uiLin%iNumSubstreamsPerTile;
1252        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1253        {
1254          uiCol     = uiCUAddr % uiWidthInLCUs;
1255          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1256          if(uiCol==uiTileLCUX)
1257          {
1258            CTXMem[0]->loadContexts(m_pcSbacCoder);
1259          }
1260        }
1261      }
1262      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1263    }
1264  }
1265
1266  UInt uiEncCUOrder;
1267  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1268       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1269       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1270  {
1271    if( m_pcCfg->getUseSBACRD() )
1272    {
1273      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1274      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1275      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1276      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1277      uiCol     = uiCUAddr % uiWidthInLCUs;
1278      uiLin     = uiCUAddr / uiWidthInLCUs;
1279      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1280      {
1281        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1282        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1283        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1284                      + uiLin%iNumSubstreamsPerTile;
1285      }
1286      else
1287      {
1288        // dependent tiles => substreams are "per frame".
1289        uiSubStrm = uiLin % iNumSubstreams;
1290      }
1291
1292      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1293      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1294      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1295      {
1296        // We'll sync if the TR is available.
1297        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1298        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1299        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1300        TComDataCU *pcCUTR = NULL;
1301        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1302        {
1303          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1304        }
1305        if ( (true/*bEnforceSliceRestriction*/ &&
1306             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||
1307             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1308             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1309             ))
1310           )
1311        {
1312          // TR not available.
1313        }
1314        else
1315        {
1316          // TR is available, we use it.
1317          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1318        }
1319      }
1320      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1321    }
1322    // reset the entropy coder
1323    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1324        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1325        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1326        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1327    {
1328      {
1329        // We're crossing into another tile, tiles are independent.
1330        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1331        // have to perform it here.
1332        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1333        {
1334          ; // do nothing.
1335        }
1336        else
1337        {
1338          SliceType sliceType  = pcSlice->getSliceType();
1339          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1340          {
1341            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1342          }
1343          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1344          // Byte-alignment in slice_data() when new tile
1345          pcSubstreams[uiSubStrm].writeByteAlignment();
1346        }
1347      }
1348      {
1349        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1350        UInt uiAccumulatedSubstreamLength = 0;
1351        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1352        {
1353          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1354        }
1355        // add bits coded in previous dependent slices + bits coded so far
1356        // add number of emulation prevention byte count in the tile
1357        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1358      }
1359    }
1360
1361    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1362#if HM_CLEANUP_SAO
1363    if ( pcSlice->getSPS()->getUseSAO() )
1364    {
1365      if (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma())
1366      {
1367        SAOBlkParam& saoblkParam = (rpcPic->getPicSym()->getSAOBlkParam())[uiCUAddr];
1368        Bool sliceEnabled[NUM_SAO_COMPONENTS];
1369        sliceEnabled[SAO_Y] = pcSlice->getSaoEnabledFlag();
1370        sliceEnabled[SAO_Cb]= sliceEnabled[SAO_Cr]= pcSlice->getSaoEnabledFlagChroma();
1371
1372        Bool leftMergeAvail = false;
1373        Bool aboveMergeAvail= false;
1374        //merge left condition
1375        Int rx = (uiCUAddr % uiWidthInLCUs);
1376        if(rx > 0)
1377        {
1378          leftMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-1);
1379        }
1380
1381        //merge up condition
1382        Int ry = (uiCUAddr / uiWidthInLCUs);
1383        if(ry > 0)
1384        {
1385          aboveMergeAvail = rpcPic->getSAOMergeAvailability(uiCUAddr, uiCUAddr-uiWidthInLCUs);
1386        }
1387
1388        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam,sliceEnabled, leftMergeAvail, aboveMergeAvail);
1389      }
1390    }
1391#else
1392    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1393    {
1394      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1395      Int iNumCuInWidth     = saoParam->numCuInWidth;
1396      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1397      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1398      Int rx = uiCUAddr % iNumCuInWidth;
1399      Int ry = uiCUAddr / iNumCuInWidth;
1400      Int allowMergeLeft = 1;
1401      Int allowMergeUp   = 1;
1402      if (rx!=0)
1403      {
1404        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1405        {
1406          allowMergeLeft = 0;
1407        }
1408      }
1409      if (ry!=0)
1410      {
1411        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1412        {
1413          allowMergeUp = 0;
1414        }
1415      }
1416      Int addr = pcCU->getAddr();
1417      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1418      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1419      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1420      {
1421        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1422        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1423        if (allowMergeLeft)
1424        {
1425          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft);
1426        }
1427        else
1428        {
1429          mergeLeft = 0;
1430        }
1431        if(mergeLeft == 0)
1432        {
1433          if (allowMergeUp)
1434          {
1435            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1436          }
1437          else
1438          {
1439            mergeUp = 0;
1440          }
1441          if(mergeUp == 0)
1442          {
1443            for (Int compIdx=0;compIdx<3;compIdx++)
1444            {
1445            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1446              {
1447                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1448              }
1449            }
1450          }
1451        }
1452      }
1453    }
1454    else if (pcSlice->getSPS()->getUseSAO())
1455    {
1456      Int addr = pcCU->getAddr();
1457      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1458      for (Int cIdx=0; cIdx<3; cIdx++)
1459      {
1460        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1461        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1462        {
1463          saoLcuParam->mergeUpFlag   = 0;
1464          saoLcuParam->mergeLeftFlag = 0;
1465          saoLcuParam->subTypeIdx    = 0;
1466          saoLcuParam->typeIdx       = -1;
1467          saoLcuParam->offset[0]     = 0;
1468          saoLcuParam->offset[1]     = 0;
1469          saoLcuParam->offset[2]     = 0;
1470          saoLcuParam->offset[3]     = 0;
1471        }
1472      }
1473    }
1474#endif
1475
1476#if ENC_DEC_TRACE
1477    g_bJustDoIt = g_bEncDecTraceEnable;
1478#endif
1479    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1480      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1481    {
1482      m_pcCuEncoder->encodeCU( pcCU );
1483    }
1484    else
1485    {
1486      m_pcCuEncoder->encodeCU( pcCU );
1487    }
1488#if ENC_DEC_TRACE
1489    g_bJustDoIt = g_bEncDecTraceDisable;
1490#endif
1491    if( m_pcCfg->getUseSBACRD() )
1492    {
1493       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1494
1495
1496       //Store probabilties of second LCU in line into buffer
1497       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1498      {
1499        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1500      }
1501    }
1502  }
1503  if( depSliceSegmentsEnabled )
1504  {
1505    if (m_pcCfg->getWaveFrontsynchro())
1506    {
1507      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1508    }
1509    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1510  }
1511#if ADAPTIVE_QP_SELECTION
1512  if( m_pcCfg->getUseAdaptQpSelect() )
1513  {
1514    m_pcTrQuant->storeSliceQpNext(pcSlice);
1515  }
1516#endif
1517  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1518  {
1519    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1520    {
1521      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1522    }
1523    else
1524    {
1525      m_pcEntropyCoder->determineCabacInitIdx();
1526    }
1527  }
1528}
1529
1530/** Determines the starting and bounding LCU address of current slice / dependent slice
1531 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1532 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1533 */
1534Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1535{
1536  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1537  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1538  UInt tileIdxIncrement;
1539  UInt tileIdx;
1540  UInt tileWidthInLcu;
1541  UInt tileHeightInLcu;
1542  UInt tileTotalCount;
1543
1544  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1545  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1546  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1547  if (bEncodeSlice)
1548  {
1549    UInt uiCUAddrIncrement;
1550    switch (m_pcCfg->getSliceMode())
1551    {
1552    case FIXED_NUMBER_OF_LCU:
1553      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1554      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1555      break;
1556    case FIXED_NUMBER_OF_BYTES:
1557      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1558      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1559      break;
1560    case FIXED_NUMBER_OF_TILES:
1561      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1562        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1563        );
1564      uiCUAddrIncrement        = 0;
1565      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1566
1567      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1568      {
1569        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1570        {
1571          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1572          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1573          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1574        }
1575      }
1576
1577      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1578      break;
1579    default:
1580      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1581      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1582      break;
1583    }
1584    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1585    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1586    {
1587      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1588    }
1589    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1590  }
1591  else
1592  {
1593    UInt uiCUAddrIncrement     ;
1594    switch (m_pcCfg->getSliceMode())
1595    {
1596    case FIXED_NUMBER_OF_LCU:
1597      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1598      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1599      break;
1600    case FIXED_NUMBER_OF_TILES:
1601      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1602        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1603        );
1604      uiCUAddrIncrement        = 0;
1605      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1606
1607      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1608      {
1609        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1610        {
1611          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1612          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1613          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1614        }
1615      }
1616
1617      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1618      break;
1619    default:
1620      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1621      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1622      break;
1623    }
1624    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1625    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1626    {
1627      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1628    }
1629    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1630  }
1631
1632  Bool tileBoundary = false;
1633  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) &&
1634      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1635  {
1636    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1637    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1638    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1639    UInt tileBoundingCUAddrSlice = 0;
1640    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1641    {
1642      lcuEncAddr++;
1643      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1644    }
1645    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1646
1647    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1648    {
1649      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1650      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1651      tileBoundary = true;
1652    }
1653  }
1654
1655  // Dependent slice
1656  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1657  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1658  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1659  if (bEncodeSlice)
1660  {
1661    UInt uiCUAddrIncrement;
1662    switch (m_pcCfg->getSliceSegmentMode())
1663    {
1664    case FIXED_NUMBER_OF_LCU:
1665      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1666      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1667      break;
1668    case FIXED_NUMBER_OF_BYTES:
1669      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1670      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1671      break;
1672    case FIXED_NUMBER_OF_TILES:
1673      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1674        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1675        );
1676      uiCUAddrIncrement        = 0;
1677      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1678
1679      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1680      {
1681        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1682        {
1683          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1684          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1685          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1686        }
1687      }
1688      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1689      break;
1690    default:
1691      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1692      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1693      break;
1694    }
1695    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1696    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1697    {
1698      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1699    }
1700    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1701  }
1702  else
1703  {
1704    UInt uiCUAddrIncrement;
1705    switch (m_pcCfg->getSliceSegmentMode())
1706    {
1707    case FIXED_NUMBER_OF_LCU:
1708      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1709      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1710      break;
1711    case FIXED_NUMBER_OF_TILES:
1712      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1713        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1714        );
1715      uiCUAddrIncrement        = 0;
1716      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1717
1718      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1719      {
1720        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1721        {
1722          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1723          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1724          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1725        }
1726      }
1727      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1728      break;
1729    default:
1730      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1731      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1732      break;
1733    }
1734    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1735    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1736    {
1737      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1738    }
1739    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1740  }
1741  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) &&
1742    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1743  {
1744    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1745    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1746    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1747    UInt tileBoundingCUAddrSlice = 0;
1748    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1749    {
1750      lcuEncAddr++;
1751      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1752    }
1753    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1754
1755    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1756    {
1757      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1758      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1759      tileBoundary = true;
1760    }
1761  }
1762
1763  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1764  {
1765    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1766    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1767  }
1768
1769  //calculate real dependent slice start address
1770  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1771  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1772  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1773  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1774#if REPN_FORMAT_IN_VPS
1775  UInt uiWidth = pcSlice->getPicWidthInLumaSamples();
1776  UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
1777#else
1778  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1779  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1780#endif
1781  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1782  {
1783    uiInternalAddress++;
1784    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1785    {
1786      uiInternalAddress=0;
1787      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1788    }
1789    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1790    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1791  }
1792  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1793
1794  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1795  startCUAddrSliceSegment=uiRealStartAddress;
1796
1797  //calculate real slice start address
1798  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1799  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1800  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1801  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1802#if REPN_FORMAT_IN_VPS
1803  uiWidth = pcSlice->getPicWidthInLumaSamples();
1804  uiHeight = pcSlice->getPicHeightInLumaSamples();
1805#else
1806  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1807  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1808#endif
1809  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1810  {
1811    uiInternalAddress++;
1812    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1813    {
1814      uiInternalAddress=0;
1815      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1816    }
1817    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1818    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1819  }
1820  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1821
1822  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1823  uiStartCUAddrSlice=uiRealStartAddress;
1824
1825  // Make a joint decision based on reconstruction and dependent slice bounds
1826  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1827  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1828
1829
1830  if (!bEncodeSlice)
1831  {
1832    // 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
1833    // first. Set the flags accordingly.
1834    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1835      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1836      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0)
1837      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1838      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0)
1839      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1840      || tileBoundary
1841)
1842    {
1843      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1844      {
1845        pcSlice->setNextSlice       ( true );
1846        pcSlice->setNextSliceSegment( false );
1847      }
1848      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1849      {
1850        pcSlice->setNextSlice       ( false );
1851        pcSlice->setNextSliceSegment( true );
1852      }
1853      else
1854      {
1855        pcSlice->setNextSlice       ( true );
1856        pcSlice->setNextSliceSegment( true );
1857      }
1858    }
1859    else
1860    {
1861      pcSlice->setNextSlice       ( false );
1862      pcSlice->setNextSliceSegment( false );
1863    }
1864  }
1865}
1866
1867Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1868{
1869  return 4.2005*log(lambda) + 13.7122;
1870}
1871
1872#if JCTVC_M0259_LAMBDAREFINEMENT
1873Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
1874{
1875  double tmp = beta * pow( 2.0 , deltaQP / 6 );
1876  double gamma = tmp / ( tmp + 1 );
1877  return( gamma );
1878}
1879#endif
1880#if O0194_WEIGHTED_PREDICTION_CGS
1881Void TEncSlice::estimateILWpParam( TComSlice* pcSlice )
1882{
1883  xCalcACDCParamSlice(pcSlice);
1884  wpACDCParam * temp_weightACDCParam;
1885
1886  pcSlice->getWpAcDcParam(temp_weightACDCParam);
1887  g_refWeightACDCParam = (void *) temp_weightACDCParam;
1888}
1889#endif
1890//! \}
Note: See TracBrowser for help on using the repository browser.