source: 3DVCSoftware/branches/HTM-8.2-dev0-KWU/source/Lib/TLibEncoder/TEncSlice.cpp @ 637

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

Clean up and revised according to the guideline.

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