source: 3DVCSoftware/branches/HTM-8.2-dev2-Samsung/source/Lib/TLibEncoder/TEncSlice.cpp @ 696

Last change on this file since 696 was 696, checked in by samsung-htm, 11 years ago

Integration of F0150: MPI candidate in depth merge mode list construction

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