source: SHVCSoftware/branches/SHM-1.1-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 503

Last change on this file since 503 was 11, checked in by seregin, 12 years ago

SET_SLICE_LAYER_ID: set layerId to the slice

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