source: SHVCSoftware/branches/HM-10.0-dev-SHM/source/Lib/TLibEncoder/TEncSlice.cpp @ 59

Last change on this file since 59 was 54, checked in by seregin, 12 years ago

port simulcast

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