source: 3DVCSoftware/branches/HTM-13.0-MV-draft-2/source/Lib/TLibEncoder/TEncSlice.cpp

Last change on this file was 1128, checked in by tech, 10 years ago

Removed 3D-HEVC related code.

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