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

Last change on this file since 297 was 296, checked in by nokia, 12 years ago

Implementation of JCTVC-M0040 "Adaptive Resolution Change"

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