source: 3DVCSoftware/branches/HTM-DEV-0.1-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 365

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

Further minor cleanups.

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