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

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

Macro removal part H_MV5.

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