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

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

Merged branch/9.2-dev0@722.

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