source: SHVCSoftware/branches/0.1.1-bugfix/source/Lib/TLibEncoder/TEncSlice.cpp

Last change on this file was 2, checked in by seregin, 12 years ago

Initial import by Vadim Seregin <vseregin@…>

File size: 70.6 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2012, 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#if DEPENDENT_SLICES
66  for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
67  {
68    delete (*i);
69  }
70#endif
71}
72
73#if DEPENDENT_SLICES
74Void TEncSlice::initCtxMem(  UInt i )               
75{   
76  for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
77  {
78    delete (*j);
79  }
80  CTXMem.clear(); 
81  CTXMem.resize(i); 
82}
83#endif
84
85Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
86{
87  // create prediction picture
88  if ( m_apcPicYuvPred == NULL )
89  {
90    m_apcPicYuvPred  = new TComPicYuv;
91    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
92  }
93 
94  // create residual picture
95  if( m_apcPicYuvResi == NULL )
96  {
97    m_apcPicYuvResi  = new TComPicYuv;
98    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
99  }
100}
101
102Void TEncSlice::destroy()
103{
104  // destroy prediction picture
105  if ( m_apcPicYuvPred )
106  {
107    m_apcPicYuvPred->destroy();
108    delete m_apcPicYuvPred;
109    m_apcPicYuvPred  = NULL;
110  }
111 
112  // destroy residual picture
113  if ( m_apcPicYuvResi )
114  {
115    m_apcPicYuvResi->destroy();
116    delete m_apcPicYuvResi;
117    m_apcPicYuvResi  = NULL;
118  }
119 
120  // free lambda and QP arrays
121  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
122  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
123  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
124
125  if ( m_pcBufferSbacCoders )
126  {
127    delete[] m_pcBufferSbacCoders;
128  }
129  if ( m_pcBufferBinCoderCABACs )
130  {
131    delete[] m_pcBufferBinCoderCABACs;
132  }
133  if ( m_pcBufferLowLatSbacCoders )
134    delete[] m_pcBufferLowLatSbacCoders;
135  if ( m_pcBufferLowLatBinCoderCABACs )
136    delete[] m_pcBufferLowLatBinCoderCABACs;
137}
138
139Void TEncSlice::init( TEncTop* pcEncTop )
140{
141  m_pcCfg             = pcEncTop;
142  m_pcListPic         = pcEncTop->getListPic();
143#if SVC_EXTENSION
144  m_ppcTEncTop        = pcEncTop->getLayerEnc();
145#endif 
146  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
147  m_pcCuEncoder       = pcEncTop->getCuEncoder();
148  m_pcPredSearch      = pcEncTop->getPredSearch();
149 
150  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
151  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
152  m_pcSbacCoder       = pcEncTop->getSbacCoder();
153  m_pcBinCABAC        = pcEncTop->getBinCABAC();
154  m_pcTrQuant         = pcEncTop->getTrQuant();
155 
156  m_pcBitCounter      = pcEncTop->getBitCounter();
157  m_pcRdCost          = pcEncTop->getRdCost();
158  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
159  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
160 
161  // create lambda and QP arrays
162  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
163  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
164  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
165  m_pcRateCtrl        = pcEncTop->getRateCtrl();
166}
167
168/**
169 - non-referenced frame marking
170 - QP computation based on temporal structure
171 - lambda computation based on QP
172 - set temporal layer ID and the parameter sets
173 .
174 \param pcPic         picture class
175 \param iPOCLast      POC of last picture
176 \param uiPOCCurr     current POC
177 \param iNumPicRcvd   number of received pictures
178 \param iTimeOffset   POC offset for hierarchical structure
179 \param iDepth        temporal layer depth
180 \param rpcSlice      slice header class
181 \param pSPS          SPS associated with the slice
182 \param pPPS          PPS associated with the slice
183 */
184Void TEncSlice::initEncSlice( TComPic* pcPic, Int iPOCLast, UInt uiPOCCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
185{
186  Double dQP;
187  Double dLambda;
188 
189  rpcSlice = pcPic->getSlice(0);
190  rpcSlice->setSPS( pSPS );
191  rpcSlice->setPPS( pPPS );
192  rpcSlice->setSliceBits(0);
193  rpcSlice->setPic( pcPic );
194  rpcSlice->initSlice();
195  rpcSlice->setPicOutputFlag( true );
196  rpcSlice->setPOC( uiPOCCurr );
197 
198#if SVC_EXTENSION
199  rpcSlice->setLayerId( pcPic->getLayerId());
200#endif
201
202  // depth computation based on GOP size
203  int iDepth;
204  {
205    Int i, j;
206    Int iPOC = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
207    if ( iPOC == 0 )
208    {
209      iDepth = 0;
210    }
211    else
212    {
213      Int iStep = m_pcCfg->getGOPSize();
214      iDepth    = 0;
215      for( i=iStep>>1; i>=1; i>>=1 )
216      {
217        for ( j=i; j<m_pcCfg->getGOPSize(); j+=iStep )
218        {
219          if ( j == iPOC )
220          {
221            i=0;
222            break;
223          }
224        }
225        iStep>>=1;
226        iDepth++;
227      }
228    }
229  }
230 
231  // slice type
232  SliceType eSliceType;
233 
234  eSliceType=B_SLICE;
235  eSliceType = (iPOCLast == 0 || uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
236 
237  rpcSlice->setSliceType    ( eSliceType );
238 
239  // ------------------------------------------------------------------------------------------------------------------
240  // Non-referenced frame marking
241  // ------------------------------------------------------------------------------------------------------------------
242 
243#if TEMPORAL_LAYER_NON_REFERENCE
244  if(iPOCLast == 0)
245  {
246    rpcSlice->setTemporalLayerNonReferenceFlag(false);
247  }
248  else
249  {
250    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
251  }
252  rpcSlice->setReferenced(true);
253#else
254  rpcSlice->setReferenced(m_pcCfg->getGOPEntry(iGOPid).m_refPic);
255#endif
256#if !REMOVE_NAL_REF_FLAG
257  rpcSlice->setNalRefFlag(m_pcCfg->getGOPEntry(iGOPid).m_refPic);
258#endif
259#if !TEMPORAL_LAYER_NON_REFERENCE
260  if(eSliceType==I_SLICE)
261  {
262    rpcSlice->setReferenced(true);
263  }
264#endif
265 
266  // ------------------------------------------------------------------------------------------------------------------
267  // QP setting
268  // ------------------------------------------------------------------------------------------------------------------
269 
270  dQP = m_pcCfg->getQP();
271  if(eSliceType!=I_SLICE)
272  {
273    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless()))) 
274    {
275      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
276    }
277  }
278 
279  // modify QP
280  Int* pdQPs = m_pcCfg->getdQPs();
281  if ( pdQPs )
282  {
283    dQP += pdQPs[ rpcSlice->getPOC() ];
284  }
285  if ( m_pcCfg->getUseRateCtrl())
286  {
287    dQP = m_pcRateCtrl->getFrameQP(rpcSlice->isReferenced(), rpcSlice->getPOC());
288  }
289  // ------------------------------------------------------------------------------------------------------------------
290  // Lambda computation
291  // ------------------------------------------------------------------------------------------------------------------
292 
293  Int iQP;
294  Double dOrigQP = dQP;
295
296  // pre-compute lambda and QP values for all possible QP candidates
297  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
298  {
299    // compute QP value
300    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
301   
302    // compute lambda value
303    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
304    Int    SHIFT_QP = 12;
305    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
306#if FULL_NBIT
307    Int    bitdepth_luma_qp_scale = 6 * (g_uiBitDepth - 8);
308#else
309    Int    bitdepth_luma_qp_scale = 0;
310#endif
311    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
312#if FULL_NBIT
313    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
314#endif
315    // Case #1: I or P-slices (key-frame)
316    Double dQPFactor = m_pcCfg->getGOPEntry(iGOPid).m_QPFactor;
317    if ( eSliceType==I_SLICE )
318    {
319      dQPFactor=0.57*dLambda_scale;
320    }
321    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
322
323    if ( iDepth>0 )
324    {
325#if FULL_NBIT
326        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
327#else
328        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
329#endif
330    }
331   
332    // if hadamard is used in ME process
333    if ( !m_pcCfg->getUseHADME() )
334    {
335      dLambda *= 0.95;
336    }
337   
338    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
339
340    m_pdRdPicLambda[iDQpIdx] = dLambda;
341    m_pdRdPicQp    [iDQpIdx] = dQP;
342    m_piRdPicQp    [iDQpIdx] = iQP;
343  }
344 
345  // obtain dQP = 0 case
346  dLambda = m_pdRdPicLambda[0];
347  dQP     = m_pdRdPicQp    [0];
348  iQP     = m_piRdPicQp    [0];
349 
350  if( rpcSlice->getSliceType( ) != I_SLICE )
351  {
352    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
353  }
354
355  // store lambda
356  m_pcRdCost ->setLambda( dLambda );
357#if WEIGHTED_CHROMA_DISTORTION
358// for RDO
359  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
360  Double weight = 1.0;
361  if(iQP >= 0)
362  {
363    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
364  }
365  m_pcRdCost ->setChromaDistortionWeight( weight );     
366#endif
367
368#if RDOQ_CHROMA_LAMBDA
369// for RDOQ
370  m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
371#else
372  m_pcTrQuant->setLambda( dLambda );
373#endif
374
375#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
376// For ALF or SAO
377  rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
378#else
379  rpcSlice   ->setLambda( dLambda );
380#endif
381 
382#if HB_LAMBDA_FOR_LDC
383  // restore original slice type
384  eSliceType = (iPOCLast == 0 || uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
385#if REF_IDX_FRAMEWORK
386  if(m_pcCfg->getLayerId() > 0)
387  {
388    eSliceType=B_SLICE;
389  }
390#endif
391  rpcSlice->setSliceType        ( eSliceType );
392#endif
393 
394#if RECALCULATE_QP_ACCORDING_LAMBDA
395  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
396  {
397    dQP = xGetQPValueAccordingToLambda( dLambda );
398    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );   
399  }
400#endif
401
402  rpcSlice->setSliceQp          ( iQP );
403#if ADAPTIVE_QP_SELECTION
404  rpcSlice->setSliceQpBase      ( iQP );
405#endif
406  rpcSlice->setSliceQpDelta     ( 0 );
407#if CHROMA_QP_EXTENSION
408  rpcSlice->setSliceQpDeltaCb   ( 0 );
409  rpcSlice->setSliceQpDeltaCr   ( 0 );
410#endif
411  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
412  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
413 
414  if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
415  {
416    rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
417    rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
418    rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
419    rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
420    if ( !rpcSlice->getDeblockingFilterDisable())
421    {
422      rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
423      rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
424      rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
425      rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
426    }
427  }
428
429  rpcSlice->setDepth            ( iDepth );
430 
431  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
432  if(eSliceType==I_SLICE)
433  {
434    pcPic->setTLayer(0);
435  }
436  rpcSlice->setTLayer( pcPic->getTLayer() );
437
438  assert( m_apcPicYuvPred );
439  assert( m_apcPicYuvResi );
440 
441  pcPic->setPicYuvPred( m_apcPicYuvPred );
442  pcPic->setPicYuvResi( m_apcPicYuvResi );
443  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
444  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
445  rpcSlice->setDependentSliceMode     ( m_pcCfg->getDependentSliceMode()     );
446  rpcSlice->setDependentSliceArgument ( m_pcCfg->getDependentSliceArgument() );
447  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
448  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
449}
450
451
452/**
453 - lambda re-computation based on rate control QP
454 */
455Void TEncSlice::xLamdaRecalculation(Int changeQP, Int idGOP, Int depth, SliceType eSliceType, TComSPS* pcSPS, TComSlice* pcSlice)
456{
457  Int qp;
458  Double recalQP= (Double)changeQP;
459  Double origQP = (Double)recalQP;
460  Double lambda;
461
462  // pre-compute lambda and QP values for all possible QP candidates
463  for ( Int deltqQpIdx = 0; deltqQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; deltqQpIdx++ )
464  {
465    // compute QP value
466    recalQP = origQP + ((deltqQpIdx+1)>>1)*(deltqQpIdx%2 ? -1 : 1);
467
468    // compute lambda value
469    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
470    Int    SHIFT_QP = 12;
471    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
472#if FULL_NBIT
473    Int    bitdepth_luma_qp_scale = 6 * (g_uiBitDepth - 8);
474#else
475    Int    bitdepth_luma_qp_scale = 0;
476#endif
477    Double qp_temp = (Double) recalQP + bitdepth_luma_qp_scale - SHIFT_QP;
478#if FULL_NBIT
479    Double qp_temp_orig = (Double) recalQP - SHIFT_QP;
480#endif
481    // Case #1: I or P-slices (key-frame)
482    Double dQPFactor = m_pcCfg->getGOPEntry(idGOP).m_QPFactor;
483    if ( eSliceType==I_SLICE )
484    {
485      dQPFactor=0.57*dLambda_scale;
486    }
487    lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
488
489    if ( depth>0 )
490    {
491#if FULL_NBIT
492      lambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
493#else
494      lambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
495#endif
496    }
497
498    // if hadamard is used in ME process
499    if ( !m_pcCfg->getUseHADME() )
500    {
501      lambda *= 0.95;
502    }
503
504    qp = max( -pcSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( recalQP + 0.5 ) ) );
505
506    m_pdRdPicLambda[deltqQpIdx] = lambda;
507    m_pdRdPicQp    [deltqQpIdx] = recalQP;
508    m_piRdPicQp    [deltqQpIdx] = qp;
509  }
510
511  // obtain dQP = 0 case
512  lambda  = m_pdRdPicLambda[0];
513  recalQP = m_pdRdPicQp    [0];
514  qp      = m_piRdPicQp    [0];
515
516  if( pcSlice->getSliceType( ) != I_SLICE )
517  {
518    lambda *= m_pcCfg->getLambdaModifier( depth );
519  }
520
521  // store lambda
522  m_pcRdCost ->setLambda( lambda );
523#if WEIGHTED_CHROMA_DISTORTION
524  // for RDO
525  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
526  Double weight = 1.0;
527  if(qp >= 0)
528  {
529    weight = pow( 2.0, (qp-g_aucChromaScale[qp])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
530  }
531  m_pcRdCost ->setChromaDistortionWeight( weight );     
532#endif
533
534#if RDOQ_CHROMA_LAMBDA
535  // for RDOQ
536  m_pcTrQuant->setLambda( lambda, lambda / weight );   
537#else
538  m_pcTrQuant->setLambda( lambda );
539#endif
540
541#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
542  // For ALF or SAO
543  pcSlice   ->setLambda( lambda, lambda / weight ); 
544#else
545  pcSlice   ->setLambda( lambda );
546#endif
547}
548// ====================================================================================================================
549// Public member functions
550// ====================================================================================================================
551
552Void TEncSlice::setSearchRange( TComSlice* pcSlice )
553{
554  Int iCurrPOC = pcSlice->getPOC();
555  Int iRefPOC;
556  Int iGOPSize = m_pcCfg->getGOPSize();
557  Int iOffset = (iGOPSize >> 1);
558  Int iMaxSR = m_pcCfg->getSearchRange();
559  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
560 
561  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
562  {
563    //RefPicList e = (RefPicList)iDir;
564    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
565    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
566    {
567      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
568      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
569      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
570    }
571  }
572}
573
574/**
575 - multi-loop slice encoding for different slice QP
576 .
577 \param rpcPic    picture class
578 */
579Void TEncSlice::precompressSlice( TComPic*& rpcPic )
580{
581  // if deltaQP RD is not used, simply return
582  if ( m_pcCfg->getDeltaQpRD() == 0 )
583  {
584    return;
585  }
586 
587  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
588  Double     dPicRdCostBest = MAX_DOUBLE;
589  UInt       uiQpIdxBest = 0;
590 
591  Double dFrameLambda;
592#if FULL_NBIT
593  Int    SHIFT_QP = 12 + 6 * (g_uiBitDepth - 8);
594#else
595  Int    SHIFT_QP = 12;
596#endif
597 
598  // set frame lambda
599  if (m_pcCfg->getGOPSize() > 1)
600  {
601    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
602  }
603  else
604  {
605    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
606  }
607  m_pcRdCost      ->setFrameLambda(dFrameLambda);
608 
609  // for each QP candidate
610  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
611  {
612    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
613#if ADAPTIVE_QP_SELECTION
614    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
615#endif
616    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
617#if WEIGHTED_CHROMA_DISTORTION
618    // for RDO
619    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
620    int iQP = m_piRdPicQp    [uiQpIdx];
621    Double weight = 1.0;
622    if(iQP >= 0)
623    {
624      weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
625    }
626    m_pcRdCost    ->setChromaDistortionWeight( weight );     
627#endif
628
629#if RDOQ_CHROMA_LAMBDA
630    // for RDOQ
631    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
632#else
633    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
634#endif
635#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
636    // For ALF or SAO
637    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
638#else
639    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
640#endif
641   
642    // try compress
643    compressSlice   ( rpcPic );
644   
645    Double dPicRdCost;
646    UInt64 uiPicDist        = m_uiPicDist;
647    UInt64 uiALFBits        = 0;
648   
649    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
650   
651    // compute RD cost and choose the best
652    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
653   
654    if ( dPicRdCost < dPicRdCostBest )
655    {
656      uiQpIdxBest    = uiQpIdx;
657      dPicRdCostBest = dPicRdCost;
658    }
659  }
660 
661  // set best values
662  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
663#if ADAPTIVE_QP_SELECTION
664  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
665#endif
666  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
667#if WEIGHTED_CHROMA_DISTORTION
668  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
669  int iQP = m_piRdPicQp    [uiQpIdxBest];
670  Double weight = 1.0;
671  if(iQP >= 0)
672  {
673    weight = pow( 2.0, (iQP-g_aucChromaScale[iQP])/3.0 );  // takes into account of the chroma qp mapping without chroma qp Offset
674  }
675  m_pcRdCost ->setChromaDistortionWeight( weight );     
676#endif
677
678#if RDOQ_CHROMA_LAMBDA
679  // for RDOQ
680  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
681#else
682  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
683#endif
684#if ALF_CHROMA_LAMBDA || SAO_CHROMA_LAMBDA
685  // For ALF or SAO
686  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
687#else
688  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
689#endif
690}
691
692/** \param rpcPic   picture class
693 */
694Void TEncSlice::compressSlice( TComPic*& rpcPic )
695{
696  UInt  uiCUAddr;
697  UInt   uiStartCUAddr;
698  UInt   uiBoundingCUAddr;
699  rpcPic->getSlice(getSliceIdx())->setDependentSliceCounter(0);
700  TEncBinCABAC* pppcRDSbacCoder = NULL;
701  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
702  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
703 
704  // initialize cost values
705  m_uiPicTotalBits  = 0;
706  m_dPicRdCost      = 0;
707  m_uiPicDist       = 0;
708 
709  // set entropy coder
710  if( m_pcCfg->getUseSBACRD() )
711  {
712    m_pcSbacCoder->init( m_pcBinCABAC );
713    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
714    m_pcEntropyCoder->resetEntropy      ();
715    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
716    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
717    pppcRDSbacCoder->setBinCountingEnableFlag( false );
718    pppcRDSbacCoder->setBinsCoded( 0 );
719  }
720  else
721  {
722    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
723    m_pcEntropyCoder->resetEntropy      ();
724    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
725  }
726 
727  //------------------------------------------------------------------------------
728  //  Weighted Prediction parameters estimation.
729  //------------------------------------------------------------------------------
730  // calculate AC/DC values for current picture
731  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
732  {
733    xCalcACDCParamSlice(pcSlice);
734  }
735
736  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
737
738  if ( bWp_explicit )
739  {
740    //------------------------------------------------------------------------------
741    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
742    //------------------------------------------------------------------------------
743    if ( pcSlice->getSliceMode()==2 || pcSlice->getDependentSliceMode()==2 )
744    {
745      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
746    }
747
748    xEstimateWPParamSlice( pcSlice );
749    pcSlice->initWpScaling();
750
751    // check WP on/off
752    xCheckWPEnable( pcSlice );
753  }
754
755#if ADAPTIVE_QP_SELECTION
756  if( m_pcCfg->getUseAdaptQpSelect() )
757  {
758    m_pcTrQuant->clearSliceARLCnt();
759    if(pcSlice->getSliceType()!=I_SLICE)
760    {
761      Int qpBase = pcSlice->getSliceQpBase();
762      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
763    }
764  }
765#endif
766  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
767  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
768  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
769  Int  iNumSubstreams = 1;
770  UInt uiTilesAcross  = 0;
771
772  if( m_pcCfg->getUseSBACRD() )
773  {
774    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
775    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
776    delete[] m_pcBufferSbacCoders;
777    delete[] m_pcBufferBinCoderCABACs;
778    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
779    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
780    for (int ui = 0; ui < uiTilesAcross; ui++)
781    {
782      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
783    }
784    for (UInt ui = 0; ui < uiTilesAcross; ui++)
785    {
786      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
787    }
788
789    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
790    {
791      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
792    }
793  }
794  //if( m_pcCfg->getUseSBACRD() )
795  {
796    delete[] m_pcBufferLowLatSbacCoders;
797    delete[] m_pcBufferLowLatBinCoderCABACs;
798    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
799    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
800    for (int ui = 0; ui < uiTilesAcross; ui++)
801    {
802      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
803    }
804    for (UInt ui = 0; ui < uiTilesAcross; ui++)
805      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
806  }
807  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
808  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
809  UInt uiCol=0, uiLin=0, uiSubStrm=0;
810  UInt uiTileCol      = 0;
811  UInt uiTileStartLCU = 0;
812  UInt uiTileLCUX     = 0;
813
814#if INTRA_BL
815  m_pcCuEncoder->setBaseRecPic( rpcPic->getLayerId() > 0 ? rpcPic->getFullPelBaseRec() : NULL);
816#endif
817
818
819#if DEPENDENT_SLICES
820  Bool bAllowDependence = false;
821#if TILES_WPP_ENTROPYSLICES_FLAGS
822  if( pcSlice->getPPS()->getDependentSliceEnabledFlag()&&(!pcSlice->getPPS()->getEntropySliceEnabledFlag()) )
823#else
824  if( pcSlice->getPPS()->getDependentSliceEnabledFlag()&&(!pcSlice->getPPS()->getCabacIndependentFlag()) )
825#endif
826  {
827    bAllowDependence = true;
828  }
829  if( bAllowDependence )
830  {
831    if(pcSlice->getDependentSliceCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())
832    {
833      if( m_pcCfg->getWaveFrontsynchro() )
834      {
835        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
836      }
837      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
838      if (pcSlice->getPPS()->getNumSubstreams() > 1)
839      {
840        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
841        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
842        uiLin     = uiCUAddr / uiWidthInLCUs;
843        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
844          + uiLin%iNumSubstreamsPerTile;
845      }
846      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
847    }
848    else
849    {
850      if(m_pcCfg->getWaveFrontsynchro())
851      {
852        CTXMem[1]->loadContexts(m_pcSbacCoder);
853      }
854      CTXMem[0]->loadContexts(m_pcSbacCoder);
855    }
856  }
857#endif
858  // for every CU in slice
859  UInt uiEncCUOrder;
860  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
861  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
862       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
863       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
864  {
865    // initialize CU encoder
866    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
867    pcCU->initCU( rpcPic, uiCUAddr );
868#if SVC_EXTENSION
869    pcCU->setLayerId(m_pcCfg->getLayerId());
870#endif
871
872    if(m_pcCfg->getUseRateCtrl())
873    {
874      if(m_pcRateCtrl->calculateUnitQP())
875      {
876        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
877      }
878    }
879    // inherit from TR if necessary, select substream to use.
880    if( m_pcCfg->getUseSBACRD() )
881    {
882      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
883      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
884      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
885      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
886      uiCol     = uiCUAddr % uiWidthInLCUs;
887      uiLin     = uiCUAddr / uiWidthInLCUs;
888      if (pcSlice->getPPS()->getNumSubstreams() > 1)
889      {
890        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
891        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
892        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
893                      + uiLin%iNumSubstreamsPerTile;
894      }
895      else
896      {
897        // dependent tiles => substreams are "per frame".
898        uiSubStrm = uiLin % iNumSubstreams;
899      }
900#if DEPENDENT_SLICES
901      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || bAllowDependence ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
902#else
903      if ( pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX) )
904#endif
905      {
906        // We'll sync if the TR is available.
907        TComDataCU *pcCUUp = pcCU->getCUAbove();
908        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
909        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
910        TComDataCU *pcCUTR = NULL;
911        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
912        {
913          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
914        }
915        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
916             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
917             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
918             )||
919             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
920             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getDependentSliceCurStartCUAddr()) ||
921             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
922             )
923           )
924        {
925#if DEPENDENT_SLICES
926          if ( (uiCUAddr != 0) && (pcCUTR->getSCUAddr()+uiMaxParts-1 >= pcSlice->getSliceCurStartCUAddr())  && bAllowDependence)
927          {
928            ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
929          }
930#endif
931          // TR not available.
932        }
933        else
934        {
935          // TR is available, we use it.
936          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
937        }
938      }
939      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
940    }
941
942    // reset the entropy coder
943    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
944        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
945#if DEPENDENT_SLICES
946        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getDependentSliceCurStartCUAddr())/rpcPic->getNumPartInCU() &&
947#endif
948        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
949    {
950      SliceType sliceType = pcSlice->getSliceType();
951      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
952      {
953        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
954      }
955      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
956      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
957      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
958      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
959    }
960    // if RD based on SBAC is used
961    if( m_pcCfg->getUseSBACRD() )
962    {
963      // set go-on entropy coder
964      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
965      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
966     
967      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
968      // run CU encoder
969      m_pcCuEncoder->compressCU( pcCU );
970     
971      // restore entropy coder to an initial stage
972      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
973      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
974      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
975      m_pcBitCounter = &pcBitCounters[uiSubStrm];
976      pppcRDSbacCoder->setBinCountingEnableFlag( true );
977      m_pcBitCounter->resetBits();
978      pppcRDSbacCoder->setBinsCoded( 0 );
979      m_pcCuEncoder->encodeCU( pcCU );
980
981      pppcRDSbacCoder->setBinCountingEnableFlag( false );
982      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
983      {
984        pcSlice->setNextSlice( true );
985        break;
986      }
987      if (m_pcCfg->getDependentSliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE && pcSlice->getDependentSliceCounter()+pppcRDSbacCoder->getBinsCoded() > m_pcCfg->getDependentSliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getDependentSliceCurEndCUAddr())
988      {
989        pcSlice->setNextDependentSlice( true );
990        break;
991      }
992      if( m_pcCfg->getUseSBACRD() )
993      {
994         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
995       
996         //Store probabilties of second LCU in line into buffer
997#if DEPENDENT_SLICES
998         if ( ( uiCol == uiTileLCUX+1) && (bAllowDependence || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
999#else
1000        if (pcSlice->getPPS()->getNumSubstreams() > 1 && uiCol == uiTileLCUX+1)
1001#endif
1002        {
1003          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1004        }
1005      }
1006    }
1007    // other case: encodeCU is not called
1008    else
1009    {
1010      m_pcCuEncoder->compressCU( pcCU );
1011      m_pcCuEncoder->encodeCU( pcCU );
1012      if (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1013      {
1014        pcSlice->setNextSlice( true );
1015        break;
1016      }
1017      if (m_pcCfg->getDependentSliceMode()==SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE && pcSlice->getDependentSliceCounter()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getDependentSliceArgument()&&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getDependentSliceCurEndCUAddr())
1018      {
1019        pcSlice->setNextDependentSlice( true );
1020        break;
1021      }
1022    }
1023   
1024    m_uiPicTotalBits += pcCU->getTotalBits();
1025    m_dPicRdCost     += pcCU->getTotalCost();
1026    m_uiPicDist      += pcCU->getTotalDistortion();
1027    if(m_pcCfg->getUseRateCtrl())
1028    {
1029      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1030      m_pcRateCtrl->updataRCUnitStatus();
1031    }
1032  }
1033#if DEPENDENT_SLICES
1034  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !bAllowDependence)
1035#else
1036  if (pcSlice->getPPS()->getNumSubstreams() > 1)
1037#endif
1038  {
1039    pcSlice->setNextSlice( true );
1040  }
1041#if DEPENDENT_SLICES
1042  if( bAllowDependence )
1043  {
1044    if (m_pcCfg->getWaveFrontsynchro())
1045    {
1046      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1047    }
1048     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1049  }
1050#endif
1051  xRestoreWPparam( pcSlice );
1052  if(m_pcCfg->getUseRateCtrl())
1053  {
1054    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1055  }
1056}
1057
1058/**
1059 \param  rpcPic        picture class
1060 \retval rpcBitstream  bitstream class
1061 */
1062Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcBitstream, TComOutputBitstream* pcSubstreams )
1063{
1064  UInt       uiCUAddr;
1065  UInt       uiStartCUAddr;
1066  UInt       uiBoundingCUAddr;
1067  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1068
1069  uiStartCUAddr=pcSlice->getDependentSliceCurStartCUAddr();
1070  uiBoundingCUAddr=pcSlice->getDependentSliceCurEndCUAddr();
1071  // choose entropy coder
1072  {
1073    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1074    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1075  }
1076 
1077  m_pcCuEncoder->setBitCounter( NULL );
1078  m_pcBitCounter = NULL;
1079  // Appropriate substream bitstream is switched later.
1080  // for every CU
1081#if ENC_DEC_TRACE
1082  g_bJustDoIt = g_bEncDecTraceEnable;
1083#endif
1084  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1085  DTRACE_CABAC_T( "\tPOC: " );
1086  DTRACE_CABAC_V( rpcPic->getPOC() );
1087  DTRACE_CABAC_T( "\n" );
1088#if ENC_DEC_TRACE
1089  g_bJustDoIt = g_bEncDecTraceDisable;
1090#endif
1091
1092  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1093  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1094  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1095  UInt uiBitsOriginallyInSubstreams = 0;
1096  {
1097    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1098    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1099    {
1100      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1101    }
1102   
1103    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1104    {
1105      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1106    }
1107
1108    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1109    {
1110      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1111    }
1112  }
1113
1114  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1115  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1116  UInt uiTileCol      = 0;
1117  UInt uiTileStartLCU = 0;
1118  UInt uiTileLCUX     = 0;
1119#if DEPENDENT_SLICES
1120  Bool bAllowDependence = false;
1121#if TILES_WPP_ENTROPYSLICES_FLAGS
1122  if( pcSlice->getPPS()->getDependentSliceEnabledFlag()&&(!pcSlice->getPPS()->getEntropySliceEnabledFlag()) )
1123#else
1124  if( pcSlice->getPPS()->getDependentSliceEnabledFlag()&&(!pcSlice->getPPS()->getCabacIndependentFlag()) )
1125#endif
1126  {
1127    bAllowDependence = true;
1128  }
1129  if( bAllowDependence )
1130  {
1131    if(pcSlice->isNextSlice())
1132    {
1133      if(m_pcCfg->getWaveFrontsynchro())
1134      {
1135        CTXMem[1]->loadContexts(m_pcSbacCoder);
1136      }
1137      CTXMem[0]->loadContexts(m_pcSbacCoder);
1138    }
1139    else
1140    {
1141      if(m_pcCfg->getWaveFrontsynchro())
1142      {
1143        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1144      }
1145      if(pcSlice->getPPS()->getNumSubstreams() > 1)
1146      {
1147        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1148        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
1149        uiLin     = uiCUAddr / uiWidthInLCUs;
1150        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1151          + uiLin%iNumSubstreamsPerTile;
1152      }
1153      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1154    }
1155  }
1156#endif
1157
1158  UInt uiEncCUOrder;
1159  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /*for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1160                                                                                              an encoding order index, so we need to convert the index (uiStartCUAddr)
1161                                                                                              into the real raster scan address (uiCUAddr) via the CUOrderMap*/
1162  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1163       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1164       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1165  {
1166    if( m_pcCfg->getUseSBACRD() )
1167    {
1168      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1169      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1170      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1171      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1172      uiCol     = uiCUAddr % uiWidthInLCUs;
1173      uiLin     = uiCUAddr / uiWidthInLCUs;
1174      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1175      {
1176        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1177        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1178        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1179                      + uiLin%iNumSubstreamsPerTile;
1180      }
1181      else
1182      {
1183        // dependent tiles => substreams are "per frame".
1184        uiSubStrm = uiLin % iNumSubstreams;
1185      }
1186
1187      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1188      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1189#if DEPENDENT_SLICES
1190      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || bAllowDependence) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1191#else
1192      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX))
1193#endif
1194      {
1195        // We'll sync if the TR is available.
1196        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1197        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1198        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1199        TComDataCU *pcCUTR = NULL;
1200        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1201        {
1202          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1203        }
1204        if ( (true/*bEnforceSliceRestriction*/ &&
1205             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1206             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1207             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1208             ))||
1209             (true/*bEnforceDependentSliceRestriction*/ &&
1210             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1211             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getDependentSliceCurStartCUAddr()) ||
1212             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1213             ))
1214           )
1215        {
1216#if DEPENDENT_SLICES
1217          if ( (uiCUAddr != 0) && ( pcCUTR->getSCUAddr()+uiMaxParts-1 >= pcSlice->getSliceCurStartCUAddr() ) && bAllowDependence)
1218          {
1219            pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1220          }
1221#endif
1222          // TR not available.
1223        }
1224        else
1225        {
1226          // TR is available, we use it.
1227          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1228        }
1229      }
1230      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1231    }
1232    // reset the entropy coder
1233    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1234        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1235#if DEPENDENT_SLICES
1236        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getDependentSliceCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1237#endif
1238        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1239    {
1240      {
1241        // We're crossing into another tile, tiles are independent.
1242        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1243        // have to perform it here.
1244        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1245        {
1246          ; // do nothing.
1247        }
1248        else
1249        {
1250          SliceType sliceType  = pcSlice->getSliceType();
1251          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1252          {
1253            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1254          }
1255          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1256#if BYTE_ALIGNMENT
1257          // Byte-alignment in slice_data() when new tile
1258          pcSubstreams[uiSubStrm].writeByteAlignment();
1259#else
1260          pcSubstreams[uiSubStrm].write( 1, 1 );
1261          pcSubstreams[uiSubStrm].writeAlignZero();
1262#endif
1263        }
1264      }
1265      {
1266          UInt uiCounter = 0;
1267          vector<uint8_t>& rbsp   = pcSubstreams[uiSubStrm].getFIFO();
1268          for (vector<uint8_t>::iterator it = rbsp.begin(); it != rbsp.end();)
1269          {
1270            /* 1) find the next emulated 00 00 {00,01,02,03}
1271             * 2a) if not found, write all remaining bytes out, stop.
1272             * 2b) otherwise, write all non-emulated bytes out
1273             * 3) insert emulation_prevention_three_byte
1274             */
1275            vector<uint8_t>::iterator found = it;
1276            do
1277            {
1278              /* NB, end()-1, prevents finding a trailing two byte sequence */
1279              found = search_n(found, rbsp.end()-1, 2, 0);
1280              found++;
1281              /* if not found, found == end, otherwise found = second zero byte */
1282              if (found == rbsp.end())
1283              {
1284                break;
1285              }
1286              if (*(++found) <= 3)
1287              {
1288                break;
1289              }
1290            } while (true);
1291            it = found;
1292            if (found != rbsp.end())
1293            {
1294              it++;
1295              uiCounter++;
1296            }
1297          }
1298       
1299        UInt uiAccumulatedSubstreamLength = 0;
1300        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1301        {
1302          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1303        }
1304        // add bits coded in previous dependent slices + bits coded so far
1305        // add number of emulation prevention byte count in the tile
1306        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + uiCounter );
1307      }
1308    }
1309
1310    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1311#if !SAO_LUM_CHROMA_ONOFF_FLAGS
1312    if ( pcSlice->getSPS()->getUseSAO() && pcSlice->getSaoEnabledFlag() )
1313#else
1314    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1315#endif
1316    {
1317#if REMOVE_APS
1318      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1319#else
1320      SAOParam *saoParam = pcSlice->getAPS()->getSaoParam();
1321#endif
1322      Int iNumCuInWidth     = saoParam->numCuInWidth;
1323      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1324      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1325      Int rx = uiCUAddr % iNumCuInWidth;
1326      Int ry = uiCUAddr / iNumCuInWidth;
1327      Int allowMergeLeft = 1;
1328      Int allowMergeUp   = 1;
1329      if (rx!=0)
1330      {
1331        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1332        {
1333          allowMergeLeft = 0;
1334        }
1335      }
1336      if (ry!=0)
1337      {
1338        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1339        {
1340          allowMergeUp = 0;
1341        }
1342      }
1343      Int addr = pcCU->getAddr();
1344#if SAO_SINGLE_MERGE
1345      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1346      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1347#if SAO_TYPE_SHARING
1348      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1349#else
1350      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] || saoParam->bSaoFlag[2])
1351#endif
1352      {
1353        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1354        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1355        if (allowMergeLeft)
1356        {
1357#if SAO_MERGE_ONE_CTX
1358          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
1359#else
1360          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMergeLeft(mergeLeft, 0); 
1361#endif
1362        }
1363        else
1364        {
1365          mergeLeft = 0;
1366        }
1367        if(mergeLeft == 0)
1368        {
1369          if (allowMergeUp)
1370          {
1371#if SAO_MERGE_ONE_CTX
1372            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1373#else
1374            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMergeUp(mergeUp);
1375#endif
1376          }
1377          else
1378          {
1379            mergeUp = 0;
1380          }
1381          if(mergeUp == 0)
1382          {
1383            for (Int compIdx=0;compIdx<3;compIdx++)
1384            {
1385#if SAO_TYPE_SHARING
1386            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1387#else
1388            if( saoParam->bSaoFlag[compIdx])
1389#endif
1390              {
1391#if SAO_TYPE_SHARING
1392                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1393#else
1394                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr]);
1395#endif
1396              }
1397            }
1398          }
1399        }
1400      }
1401#else
1402      m_pcEntropyCoder->encodeSaoUnitInterleaving(0, saoParam->bSaoFlag[0], rx, ry, &(saoParam->saoLcuParam[0][addr]), iCUAddrInSlice, iCUAddrUpInSlice, allowMergeLeft, allowMergeUp);
1403      m_pcEntropyCoder->encodeSaoUnitInterleaving(1, saoParam->bSaoFlag[1], rx, ry, &(saoParam->saoLcuParam[1][addr]), iCUAddrInSlice, iCUAddrUpInSlice, allowMergeLeft, allowMergeUp);
1404      m_pcEntropyCoder->encodeSaoUnitInterleaving(2, saoParam->bSaoFlag[2], rx, ry, &(saoParam->saoLcuParam[2][addr]), iCUAddrInSlice, iCUAddrUpInSlice, allowMergeLeft, allowMergeUp);
1405#endif
1406    }
1407#if ENC_DEC_TRACE
1408    g_bJustDoIt = g_bEncDecTraceEnable;
1409#endif
1410#if !REMOVE_ALF
1411    if( pcSlice->getSPS()->getUseALF())
1412    {
1413      for(Int compIdx=0; compIdx< 3; compIdx++)
1414      {
1415        if(pcSlice->getAlfEnabledFlag(compIdx))
1416        {
1417          m_pcEntropyCoder->encodeAlfCtrlFlag(compIdx, pcCU->getAlfLCUEnabled(compIdx)?1:0);
1418        }
1419      }
1420    }
1421#endif
1422    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getDependentSliceMode()!=0) &&
1423      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1424    {
1425      m_pcCuEncoder->encodeCU( pcCU, true );
1426    }
1427    else
1428    {
1429      m_pcCuEncoder->encodeCU( pcCU );
1430    }
1431#if ENC_DEC_TRACE
1432    g_bJustDoIt = g_bEncDecTraceDisable;
1433#endif   
1434    if( m_pcCfg->getUseSBACRD() )
1435    {
1436       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1437       
1438
1439       //Store probabilties of second LCU in line into buffer
1440#if DEPENDENT_SLICES
1441       if ( (bAllowDependence || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1442#else
1443      if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiCol == uiTileLCUX+1))
1444#endif
1445      {
1446        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1447      }
1448    }
1449  }
1450#if DEPENDENT_SLICES
1451  if( bAllowDependence )
1452  {
1453    if (m_pcCfg->getWaveFrontsynchro())
1454    {
1455      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1456    }
1457    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1458  }
1459#endif
1460#if ADAPTIVE_QP_SELECTION
1461  if( m_pcCfg->getUseAdaptQpSelect() )
1462  {
1463    m_pcTrQuant->storeSliceQpNext(pcSlice);
1464  }
1465#endif
1466  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1467  {
1468    if  (pcSlice->getPPS()->getDependentSliceEnabledFlag())
1469    {
1470      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1471    }
1472    else
1473    {
1474      m_pcEntropyCoder->determineCabacInitIdx();
1475    }
1476  }
1477}
1478
1479/** Determines the starting and bounding LCU address of current slice / dependent slice
1480 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1481 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1482 */
1483Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& uiStartCUAddr, UInt& uiBoundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1484{
1485  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1486  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1487  UInt tileIdxIncrement;
1488  UInt tileIdx;
1489  UInt tileWidthInLcu;
1490  UInt tileHeightInLcu;
1491  UInt tileTotalCount;
1492
1493  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1494  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1495  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1496  if (bEncodeSlice) 
1497  {
1498    UInt uiCUAddrIncrement;
1499    switch (m_pcCfg->getSliceMode())
1500    {
1501    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1502      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1503      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1504      break;
1505    case AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE:
1506      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1507      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1508      break;
1509    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1510      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1511        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1512        );
1513      uiCUAddrIncrement        = 0;
1514      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1515
1516      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1517      {
1518        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1519        {
1520          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1521          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1522#if REMOVE_FGS
1523          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1524#else
1525          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1526#endif
1527        }
1528      }
1529
1530      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1531      break;
1532    default:
1533      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1534      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1535      break;
1536    } 
1537    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1538  }
1539  else
1540  {
1541    UInt uiCUAddrIncrement     ;
1542    switch (m_pcCfg->getSliceMode())
1543    {
1544    case AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE:
1545      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1546      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1547      break;
1548    case AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE:
1549      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1550        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1551        );
1552      uiCUAddrIncrement        = 0;
1553      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1554
1555      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1556      {
1557        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1558        {
1559          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1560          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1561#if REMOVE_FGS
1562          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1563#else
1564          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1565#endif
1566        }
1567      }
1568
1569      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1570      break;
1571    default:
1572      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1573      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1574      break;
1575    } 
1576    // set the slice end address to the end of the SCU row if the slice does not start at the beginning of an SCU row
1577    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1578    {
1579      uiBoundingCUAddrSlice = uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU());
1580    }
1581    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1582  }
1583
1584  Bool tileBoundary = false;
1585  if ((m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE || m_pcCfg->getSliceMode() == AD_HOC_SLICES_FIXED_NUMBER_OF_BYTES_IN_SLICE) && 
1586      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1587  {
1588    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1589    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1590    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1591    UInt tileBoundingCUAddrSlice = 0;
1592    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1593    {
1594      lcuEncAddr++;
1595      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1596    }
1597    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1598   
1599    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1600    {
1601      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1602      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1603      tileBoundary = true;
1604    }
1605  }
1606
1607  // Dependent slice
1608  UInt uiStartCUAddrDependentSlice, uiBoundingCUAddrDependentSlice;
1609  uiStartCUAddrDependentSlice    = pcSlice->getDependentSliceCurStartCUAddr();
1610  uiBoundingCUAddrDependentSlice = uiNumberOfCUsInFrame;
1611  if (bEncodeSlice) 
1612  {
1613    UInt uiCUAddrIncrement;
1614    switch (m_pcCfg->getDependentSliceMode())
1615    {
1616    case SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE:
1617      uiCUAddrIncrement               = m_pcCfg->getDependentSliceArgument();
1618      uiBoundingCUAddrDependentSlice    = ((uiStartCUAddrDependentSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrDependentSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1619      break;
1620    case SHARP_MULTIPLE_CONSTRAINT_BASED_DEPENDENT_SLICE:
1621      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1622      uiBoundingCUAddrDependentSlice    = pcSlice->getDependentSliceCurEndCUAddr();
1623      break;
1624#if DEPENDENT_SLICES
1625    case FIXED_NUMBER_OF_TILES_IN_DEPENDENT_SLICE:
1626      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1627        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getDependentSliceCurStartCUAddr()/rpcPic->getNumPartInCU())
1628        );
1629      uiCUAddrIncrement        = 0;
1630      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1631
1632      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getDependentSliceArgument(); tileIdxIncrement++)
1633      {
1634        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1635        {
1636          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1637          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1638#if REMOVE_FGS
1639          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1640#else
1641          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1642#endif
1643        }
1644      }
1645      uiBoundingCUAddrDependentSlice    = ((uiStartCUAddrDependentSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrDependentSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1646      break;
1647#endif
1648    default:
1649      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1650      uiBoundingCUAddrDependentSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1651      break;
1652    } 
1653    pcSlice->setDependentSliceCurEndCUAddr( uiBoundingCUAddrDependentSlice );
1654  }
1655  else
1656  {
1657    UInt uiCUAddrIncrement;
1658    switch (m_pcCfg->getDependentSliceMode())
1659    {
1660    case SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE:
1661      uiCUAddrIncrement               = m_pcCfg->getDependentSliceArgument();
1662      uiBoundingCUAddrDependentSlice    = ((uiStartCUAddrDependentSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrDependentSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1663      break;
1664#if DEPENDENT_SLICES
1665    case FIXED_NUMBER_OF_TILES_IN_DEPENDENT_SLICE:
1666      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1667        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getDependentSliceCurStartCUAddr()/rpcPic->getNumPartInCU())
1668        );
1669      uiCUAddrIncrement        = 0;
1670      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1671
1672      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getDependentSliceArgument(); tileIdxIncrement++)
1673      {
1674        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1675        {
1676          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1677          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1678#if REMOVE_FGS
1679          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1680#else
1681          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU()) >> (m_pcCfg->getSliceGranularity() << 1);
1682#endif
1683        }
1684      }
1685      uiBoundingCUAddrDependentSlice    = ((uiStartCUAddrDependentSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (uiStartCUAddrDependentSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1686      break;
1687#endif
1688    default:
1689      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1690      uiBoundingCUAddrDependentSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1691      break;
1692    } 
1693    pcSlice->setDependentSliceCurEndCUAddr( uiBoundingCUAddrDependentSlice );
1694  }
1695  if(uiBoundingCUAddrDependentSlice>uiBoundingCUAddrSlice)
1696  {
1697    uiBoundingCUAddrDependentSlice = uiBoundingCUAddrSlice;
1698    pcSlice->setDependentSliceCurEndCUAddr(uiBoundingCUAddrSlice);
1699  }
1700  //calculate real dependent slice start address
1701  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1702  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getDependentSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1703  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1704  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1705  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1706  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1707  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1708  {
1709    uiInternalAddress++;
1710    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1711    {
1712      uiInternalAddress=0;
1713      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1714    }
1715    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1716    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1717  }
1718  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1719 
1720  pcSlice->setDependentSliceCurStartCUAddr(uiRealStartAddress);
1721  uiStartCUAddrDependentSlice=uiRealStartAddress;
1722 
1723  //calculate real slice start address
1724  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1725  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1726  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1727  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1728  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1729  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1730  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1731  {
1732    uiInternalAddress++;
1733    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1734    {
1735      uiInternalAddress=0;
1736      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1737    }
1738    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1739    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1740  }
1741  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1742 
1743  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1744  uiStartCUAddrSlice=uiRealStartAddress;
1745 
1746  // Make a joint decision based on reconstruction and dependent slice bounds
1747  uiStartCUAddr    = max(uiStartCUAddrSlice   , uiStartCUAddrDependentSlice   );
1748  uiBoundingCUAddr = min(uiBoundingCUAddrSlice, uiBoundingCUAddrDependentSlice);
1749
1750
1751  if (!bEncodeSlice)
1752  {
1753    // 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
1754    // first. Set the flags accordingly.
1755    if ( (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getDependentSliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE)
1756      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getDependentSliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE)
1757      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE && m_pcCfg->getDependentSliceMode()==0) 
1758      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getDependentSliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_DEPENDENT_SLICE)
1759      || (m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_TILES_IN_SLICE && m_pcCfg->getDependentSliceMode()==0) 
1760#if DEPENDENT_SLICES
1761      || (m_pcCfg->getDependentSliceMode()==FIXED_NUMBER_OF_TILES_IN_DEPENDENT_SLICE && m_pcCfg->getSliceMode()==0)
1762#endif
1763      || tileBoundary
1764)
1765    {
1766      if (uiBoundingCUAddrSlice < uiBoundingCUAddrDependentSlice)
1767      {
1768        pcSlice->setNextSlice       ( true );
1769        pcSlice->setNextDependentSlice( false );
1770      }
1771      else if (uiBoundingCUAddrSlice > uiBoundingCUAddrDependentSlice)
1772      {
1773        pcSlice->setNextSlice       ( false );
1774        pcSlice->setNextDependentSlice( true );
1775      }
1776      else
1777      {
1778        pcSlice->setNextSlice       ( true );
1779        pcSlice->setNextDependentSlice( true );
1780      }
1781    }
1782    else
1783    {
1784      pcSlice->setNextSlice       ( false );
1785      pcSlice->setNextDependentSlice( false );
1786    }
1787  }
1788}
1789
1790#if RECALCULATE_QP_ACCORDING_LAMBDA
1791Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1792{
1793  return 4.2005*log(lambda) + 13.7122;
1794}
1795#endif
1796
1797//! \}
Note: See TracBrowser for help on using the repository browser.