source: 3DVCSoftware/branches/HTM-8.1-dev0-Cleanup/source/Lib/TLibEncoder/TEncSlice.cpp @ 684

Last change on this file since 684 was 651, checked in by tech, 11 years ago

Update to HM 12.0.

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