source: 3DVCSoftware/branches/HTM-DEV-0.3-dev0/source/Lib/TLibEncoder/TEncSlice.cpp @ 498

Last change on this file since 498 was 498, checked in by tech, 12 years ago

Further fixes and new nonctc cfg files.

  • Property svn:eol-style set to native
File size: 76.2 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
374#if H_3D_VSO
375  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->getIsDepth() );
376  m_pcRdCost->setLambdaVSO          ( dLambda * m_pcCfg->getLambdaScaleVSO() );
377
378  // Should be moved to TEncTop
379 
380  // SAIT_VSO_EST_A0033
381  m_pcRdCost->setDisparityCoeff( m_pcCfg->getDispCoeff() );
382
383  // LGE_WVSO_A0119
384  if( m_pcCfg->getUseWVSO() && m_pcCfg->getIsDepth() )
385  {
386    m_pcRdCost->setDWeight  ( m_pcCfg->getDWeight()   );
387    m_pcRdCost->setVSOWeight( m_pcCfg->getVSOWeight() );
388    m_pcRdCost->setVSDWeight( m_pcCfg->getVSDWeight() );
389  }
390
391#endif
392
393#if WEIGHTED_CHROMA_DISTORTION
394// for RDO
395  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
396  Double weight = 1.0;
397  Int qpc;
398  Int chromaQPOffset;
399
400  chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
401  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
402  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
403  m_pcRdCost->setCbDistortionWeight(weight);
404
405  chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
406  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
407  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
408  m_pcRdCost->setCrDistortionWeight(weight);
409#endif
410
411#if RDOQ_CHROMA_LAMBDA
412// for RDOQ
413  m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
414#else
415  m_pcTrQuant->setLambda( dLambda );
416#endif
417
418#if SAO_CHROMA_LAMBDA
419// For SAO
420  rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
421#else
422  rpcSlice   ->setLambda( dLambda );
423#endif
424 
425#if HB_LAMBDA_FOR_LDC
426  // restore original slice type
427#if H_MV
428  eSliceType = eSliceTypeBaseView;
429  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
430  {
431    eSliceType = B_SLICE;
432  }
433#else
434  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
435#endif
436
437  rpcSlice->setSliceType        ( eSliceType );
438#endif
439 
440  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
441  {
442    dQP = xGetQPValueAccordingToLambda( dLambda );
443    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );   
444  }
445
446  rpcSlice->setSliceQp          ( iQP );
447#if ADAPTIVE_QP_SELECTION
448  rpcSlice->setSliceQpBase      ( iQP );
449#endif
450  rpcSlice->setSliceQpDelta     ( 0 );
451  rpcSlice->setSliceQpDeltaCb   ( 0 );
452  rpcSlice->setSliceQpDeltaCr   ( 0 );
453#if H_MV
454  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
455  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
456#else
457  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
458  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
459#endif
460
461#if L0386_DB_METRIC
462  if ( m_pcCfg->getDeblockingFilterMetric() )
463  {
464    rpcSlice->setDeblockingFilterOverrideFlag(true);
465    rpcSlice->setDeblockingFilterDisable(false);
466    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
467    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
468  } else
469#endif
470  if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
471  {
472    rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
473    rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
474    rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
475    rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
476    if ( !rpcSlice->getDeblockingFilterDisable())
477    {
478      if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
479      {
480#if H_MV
481        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
482        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
483        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
484        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
485#else
486        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
487        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
488        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
489        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
490#endif
491      }
492      else
493      {
494      rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
495      rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
496      rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
497      rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
498      }
499    }
500  }
501  else
502  {
503    rpcSlice->setDeblockingFilterOverrideFlag( false );
504    rpcSlice->setDeblockingFilterDisable( false );
505    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
506    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
507  }
508
509  rpcSlice->setDepth            ( depth );
510 
511#if H_MV
512  pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId );
513#else
514  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
515#endif
516  if(eSliceType==I_SLICE)
517  {
518    pcPic->setTLayer(0);
519  }
520  rpcSlice->setTLayer( pcPic->getTLayer() );
521
522  assert( m_apcPicYuvPred );
523  assert( m_apcPicYuvResi );
524 
525  pcPic->setPicYuvPred( m_apcPicYuvPred );
526  pcPic->setPicYuvResi( m_apcPicYuvResi );
527  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
528  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
529  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
530  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
531  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
532  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
533}
534
535#if RATE_CONTROL_LAMBDA_DOMAIN
536Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
537{
538  TComSlice* slice = pic->getSlice(0);
539
540  // store lambda
541  slice->setSliceQp( sliceQP );
542#if L0033_RC_BUGFIX
543  slice->setSliceQpBase ( sliceQP );
544#endif
545  m_pcRdCost ->setLambda( lambda );
546#if WEIGHTED_CHROMA_DISTORTION
547  // for RDO
548  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
549  Double weight;
550  Int qpc;
551  Int chromaQPOffset;
552
553  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
554  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
555  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
556  m_pcRdCost->setCbDistortionWeight(weight);
557
558  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
559  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
560  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
561  m_pcRdCost->setCrDistortionWeight(weight);
562#endif
563
564#if RDOQ_CHROMA_LAMBDA
565  // for RDOQ
566  m_pcTrQuant->setLambda( lambda, lambda / weight );
567#else
568  m_pcTrQuant->setLambda( lambda );
569#endif
570
571#if SAO_CHROMA_LAMBDA
572  // For SAO
573  slice   ->setLambda( lambda, lambda / weight );
574#else
575  slice   ->setLambda( lambda );
576#endif
577}
578#else
579/**
580 - lambda re-computation based on rate control QP
581 */
582Void TEncSlice::xLamdaRecalculation(Int changeQP, Int idGOP, Int depth, SliceType eSliceType, TComSPS* pcSPS, TComSlice* pcSlice)
583{
584  Int qp;
585  Double recalQP= (Double)changeQP;
586  Double origQP = (Double)recalQP;
587  Double lambda;
588
589  // pre-compute lambda and QP values for all possible QP candidates
590  for ( Int deltqQpIdx = 0; deltqQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; deltqQpIdx++ )
591  {
592    // compute QP value
593    recalQP = origQP + ((deltqQpIdx+1)>>1)*(deltqQpIdx%2 ? -1 : 1);
594
595    // compute lambda value
596    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
597    Int    SHIFT_QP = 12;
598    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
599#if FULL_NBIT
600    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
601#else
602    Int    bitdepth_luma_qp_scale = 0;
603#endif
604    Double qp_temp = (Double) recalQP + bitdepth_luma_qp_scale - SHIFT_QP;
605#if FULL_NBIT
606    Double qp_temp_orig = (Double) recalQP - SHIFT_QP;
607#endif
608    // Case #1: I or P-slices (key-frame)
609    Double dQPFactor = m_pcCfg->getGOPEntry(idGOP).m_QPFactor;
610    if ( eSliceType==I_SLICE )
611    {
612      dQPFactor=0.57*dLambda_scale;
613    }
614    lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
615
616    if ( depth>0 )
617    {
618#if FULL_NBIT
619      lambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
620#else
621      lambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
622#endif
623    }
624
625    // if hadamard is used in ME process
626    if ( !m_pcCfg->getUseHADME() )
627    {
628      lambda *= 0.95;
629    }
630
631    qp = max( -pcSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( recalQP + 0.5 ) ) );
632
633    m_pdRdPicLambda[deltqQpIdx] = lambda;
634    m_pdRdPicQp    [deltqQpIdx] = recalQP;
635    m_piRdPicQp    [deltqQpIdx] = qp;
636  }
637
638  // obtain dQP = 0 case
639  lambda  = m_pdRdPicLambda[0];
640  recalQP = m_pdRdPicQp    [0];
641  qp      = m_piRdPicQp    [0];
642
643  if( pcSlice->getSliceType( ) != I_SLICE )
644  {
645    lambda *= m_pcCfg->getLambdaModifier( depth );
646  }
647
648  // store lambda
649  m_pcRdCost ->setLambda( lambda );
650#if WEIGHTED_CHROMA_DISTORTION
651  // for RDO
652  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
653  Double weight = 1.0;
654  Int qpc;
655  Int chromaQPOffset;
656
657  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
658  qpc = Clip3( 0, 57, qp + chromaQPOffset);
659  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
660  m_pcRdCost->setCbDistortionWeight(weight);
661
662  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
663  qpc = Clip3( 0, 57, qp + chromaQPOffset);
664  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
665  m_pcRdCost->setCrDistortionWeight(weight);
666#endif
667
668#if RDOQ_CHROMA_LAMBDA
669  // for RDOQ
670  m_pcTrQuant->setLambda( lambda, lambda / weight );   
671#else
672  m_pcTrQuant->setLambda( lambda );
673#endif
674
675#if SAO_CHROMA_LAMBDA
676  // For SAO
677  pcSlice   ->setLambda( lambda, lambda / weight ); 
678#else
679  pcSlice   ->setLambda( lambda );
680#endif
681}
682#endif
683// ====================================================================================================================
684// Public member functions
685// ====================================================================================================================
686
687Void TEncSlice::setSearchRange( TComSlice* pcSlice )
688{
689  Int iCurrPOC = pcSlice->getPOC();
690  Int iRefPOC;
691  Int iGOPSize = m_pcCfg->getGOPSize();
692  Int iOffset = (iGOPSize >> 1);
693  Int iMaxSR = m_pcCfg->getSearchRange();
694  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
695 
696  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
697  {
698    //RefPicList e = (RefPicList)iDir;
699    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
700    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
701    {
702      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
703      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
704      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
705    }
706  }
707}
708
709/**
710 - multi-loop slice encoding for different slice QP
711 .
712 \param rpcPic    picture class
713 */
714Void TEncSlice::precompressSlice( TComPic*& rpcPic )
715{
716  // if deltaQP RD is not used, simply return
717  if ( m_pcCfg->getDeltaQpRD() == 0 )
718  {
719    return;
720  }
721
722#if RATE_CONTROL_LAMBDA_DOMAIN
723  if ( m_pcCfg->getUseRateCtrl() )
724  {
725    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
726    assert(0);
727  }
728#endif
729 
730  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
731  Double     dPicRdCostBest = MAX_DOUBLE;
732  UInt       uiQpIdxBest = 0;
733 
734  Double dFrameLambda;
735#if FULL_NBIT
736  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
737#else
738  Int    SHIFT_QP = 12;
739#endif
740 
741  // set frame lambda
742  if (m_pcCfg->getGOPSize() > 1)
743  {
744    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
745  }
746  else
747  {
748    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
749  }
750  m_pcRdCost      ->setFrameLambda(dFrameLambda);
751 
752  // for each QP candidate
753  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
754  {
755    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
756#if ADAPTIVE_QP_SELECTION
757    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
758#endif
759    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
760#if WEIGHTED_CHROMA_DISTORTION
761    // for RDO
762    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
763    Int iQP = m_piRdPicQp    [uiQpIdx];
764    Double weight = 1.0;
765    Int qpc;
766    Int chromaQPOffset;
767
768    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
769    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
770    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
771    m_pcRdCost->setCbDistortionWeight(weight);
772
773    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
774    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
775    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
776    m_pcRdCost->setCrDistortionWeight(weight);
777#endif
778
779#if RDOQ_CHROMA_LAMBDA
780    // for RDOQ
781    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
782#else
783    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
784#endif
785#if SAO_CHROMA_LAMBDA
786    // For SAO
787    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
788#else
789    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
790#endif
791   
792    // try compress
793    compressSlice   ( rpcPic );
794   
795    Double dPicRdCost;
796#if H_3D_VSO
797    Dist64 uiPicDist        = m_uiPicDist;
798#else
799    UInt64 uiPicDist        = m_uiPicDist;
800#endif
801    UInt64 uiALFBits        = 0;
802   
803    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
804   
805    // compute RD cost and choose the best
806    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
807#if H_3D
808    // Above calculation need to be fixed for VSO, including frameLambda value.
809#endif
810   
811    if ( dPicRdCost < dPicRdCostBest )
812    {
813      uiQpIdxBest    = uiQpIdx;
814      dPicRdCostBest = dPicRdCost;
815    }
816  }
817 
818  // set best values
819  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
820#if ADAPTIVE_QP_SELECTION
821  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
822#endif
823  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
824#if WEIGHTED_CHROMA_DISTORTION
825  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
826  Int iQP = m_piRdPicQp    [uiQpIdxBest];
827  Double weight = 1.0;
828  Int qpc;
829  Int chromaQPOffset;
830
831  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
832  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
833  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
834  m_pcRdCost->setCbDistortionWeight(weight);
835
836  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
837  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
838  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
839  m_pcRdCost->setCrDistortionWeight(weight);
840#endif
841
842#if RDOQ_CHROMA_LAMBDA
843  // for RDOQ
844  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
845#else
846  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
847#endif
848#if SAO_CHROMA_LAMBDA
849  // For SAO
850  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
851#else
852  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
853#endif
854}
855
856/** \param rpcPic   picture class
857 */
858Void TEncSlice::compressSlice( TComPic*& rpcPic )
859{
860  UInt  uiCUAddr;
861  UInt   uiStartCUAddr;
862  UInt   uiBoundingCUAddr;
863  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
864  TEncBinCABAC* pppcRDSbacCoder = NULL;
865  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
866  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
867 
868  // initialize cost values
869  m_uiPicTotalBits  = 0;
870  m_dPicRdCost      = 0;
871  m_uiPicDist       = 0;
872 
873  // set entropy coder
874  if( m_pcCfg->getUseSBACRD() )
875  {
876    m_pcSbacCoder->init( m_pcBinCABAC );
877    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
878    m_pcEntropyCoder->resetEntropy      ();
879    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
880    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
881    pppcRDSbacCoder->setBinCountingEnableFlag( false );
882    pppcRDSbacCoder->setBinsCoded( 0 );
883  }
884  else
885  {
886    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
887    m_pcEntropyCoder->resetEntropy      ();
888    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
889  }
890 
891  //------------------------------------------------------------------------------
892  //  Weighted Prediction parameters estimation.
893  //------------------------------------------------------------------------------
894  // calculate AC/DC values for current picture
895  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
896  {
897    xCalcACDCParamSlice(pcSlice);
898  }
899
900  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
901
902  if ( bWp_explicit )
903  {
904    //------------------------------------------------------------------------------
905    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
906    //------------------------------------------------------------------------------
907    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
908    {
909      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
910    }
911
912    xEstimateWPParamSlice( pcSlice );
913    pcSlice->initWpScaling();
914
915    // check WP on/off
916    xCheckWPEnable( pcSlice );
917  }
918
919#if ADAPTIVE_QP_SELECTION
920  if( m_pcCfg->getUseAdaptQpSelect() )
921  {
922    m_pcTrQuant->clearSliceARLCnt();
923    if(pcSlice->getSliceType()!=I_SLICE)
924    {
925      Int qpBase = pcSlice->getSliceQpBase();
926      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
927    }
928  }
929#endif
930  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
931  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
932  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
933  Int  iNumSubstreams = 1;
934  UInt uiTilesAcross  = 0;
935
936  if( m_pcCfg->getUseSBACRD() )
937  {
938    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
939    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
940    delete[] m_pcBufferSbacCoders;
941    delete[] m_pcBufferBinCoderCABACs;
942    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
943    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
944    for (Int ui = 0; ui < uiTilesAcross; ui++)
945    {
946      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
947    }
948    for (UInt ui = 0; ui < uiTilesAcross; ui++)
949    {
950      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
951    }
952
953    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
954    {
955      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
956    }
957  }
958  //if( m_pcCfg->getUseSBACRD() )
959  {
960    delete[] m_pcBufferLowLatSbacCoders;
961    delete[] m_pcBufferLowLatBinCoderCABACs;
962    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
963    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
964    for (Int ui = 0; ui < uiTilesAcross; ui++)
965    {
966      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
967    }
968    for (UInt ui = 0; ui < uiTilesAcross; ui++)
969      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
970  }
971  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
972  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
973  UInt uiCol=0, uiLin=0, uiSubStrm=0;
974  UInt uiTileCol      = 0;
975  UInt uiTileStartLCU = 0;
976  UInt uiTileLCUX     = 0;
977  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
978  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
979  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
980  if( depSliceSegmentsEnabled )
981  {
982    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
983    {
984      if( m_pcCfg->getWaveFrontsynchro() )
985      {
986        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
987        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
988        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
989        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
990        uiLin     = uiCUAddr / uiWidthInLCUs;
991        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
992          + uiLin%iNumSubstreamsPerTile;
993        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
994        {
995          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
996          uiCol     = uiCUAddr % uiWidthInLCUs;
997          if(uiCol==uiTileStartLCU)
998          {
999            CTXMem[0]->loadContexts(m_pcSbacCoder);
1000          }
1001        }
1002      }
1003      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1004      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1005    }
1006    else
1007    {
1008      if(m_pcCfg->getWaveFrontsynchro())
1009      {
1010        CTXMem[1]->loadContexts(m_pcSbacCoder);
1011      }
1012      CTXMem[0]->loadContexts(m_pcSbacCoder);
1013    }
1014  }
1015  // for every CU in slice
1016#if H_3D
1017  Int iLastPosY = -1;
1018#endif
1019  UInt uiEncCUOrder;
1020  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1021       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1022       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1023  {
1024    // initialize CU encoder
1025    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1026    pcCU->initCU( rpcPic, uiCUAddr );
1027#if H_3D_VSO
1028    if ( m_pcRdCost->getUseRenModel() )
1029    {
1030      // updated renderer model if necessary
1031      Int iCurPosX;
1032      Int iCurPosY; 
1033      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
1034      if ( iCurPosY != iLastPosY )
1035      {
1036        iLastPosY = iCurPosY;         
1037        pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY );
1038      }
1039    }
1040#endif
1041#if !RATE_CONTROL_LAMBDA_DOMAIN
1042    if(m_pcCfg->getUseRateCtrl())
1043    {
1044      if(m_pcRateCtrl->calculateUnitQP())
1045      {
1046        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
1047      }
1048    }
1049#endif
1050    // inherit from TR if necessary, select substream to use.
1051    if( m_pcCfg->getUseSBACRD() )
1052    {
1053      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1054      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1055      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1056      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1057      uiCol     = uiCUAddr % uiWidthInLCUs;
1058      uiLin     = uiCUAddr / uiWidthInLCUs;
1059      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1060      {
1061        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1062        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1063        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1064                      + uiLin%iNumSubstreamsPerTile;
1065      }
1066      else
1067      {
1068        // dependent tiles => substreams are "per frame".
1069        uiSubStrm = uiLin % iNumSubstreams;
1070      }
1071      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1072      {
1073        // We'll sync if the TR is available.
1074        TComDataCU *pcCUUp = pcCU->getCUAbove();
1075        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1076        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1077        TComDataCU *pcCUTR = NULL;
1078        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1079        {
1080          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1081        }
1082        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1083             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1084             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1085             )
1086           )
1087        {
1088          // TR not available.
1089        }
1090        else
1091        {
1092          // TR is available, we use it.
1093          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1094        }
1095      }
1096      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1097    }
1098
1099    // reset the entropy coder
1100    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1101        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1102        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1103        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1104    {
1105      SliceType sliceType = pcSlice->getSliceType();
1106      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1107      {
1108        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1109      }
1110      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1111      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1112      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1113      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1114    }
1115    // if RD based on SBAC is used
1116    if( m_pcCfg->getUseSBACRD() )
1117    {
1118      // set go-on entropy coder
1119      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1120      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1121     
1122      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1123
1124#if RATE_CONTROL_LAMBDA_DOMAIN
1125      Double oldLambda = m_pcRdCost->getLambda();
1126      if ( m_pcCfg->getUseRateCtrl() )
1127      {
1128        Int estQP        = pcSlice->getSliceQp();
1129        Double estLambda = -1.0;
1130        Double bpp       = -1.0;
1131
1132        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
1133        {
1134          estQP = pcSlice->getSliceQp();
1135        }
1136        else
1137        {
1138          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
1139          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1140          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1141          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1142
1143          m_pcRdCost->setLambda(estLambda);
1144        }
1145
1146        m_pcRateCtrl->setRCQP( estQP );
1147#if L0033_RC_BUGFIX
1148        pcCU->getSlice()->setSliceQpBase( estQP );
1149#endif
1150      }
1151#endif
1152
1153      // run CU encoder
1154      m_pcCuEncoder->compressCU( pcCU );
1155
1156#if RATE_CONTROL_LAMBDA_DOMAIN
1157      if ( m_pcCfg->getUseRateCtrl() )
1158      {
1159        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1160        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1161        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1162        Double MAD = (Double)SAD / (Double)(height * width);
1163        MAD = MAD * MAD;
1164        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1165
1166        Int actualQP        = g_RCInvalidQPValue;
1167        Double actualLambda = m_pcRdCost->getLambda();
1168        Int actualBits      = pcCU->getTotalBits();
1169        Int numberOfEffectivePixels    = 0;
1170        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1171        {
1172          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1173          {
1174            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1175            break;
1176          }
1177        }
1178
1179        if ( numberOfEffectivePixels == 0 )
1180        {
1181          actualQP = g_RCInvalidQPValue;
1182        }
1183        else
1184        {
1185          actualQP = pcCU->getQP( 0 );
1186        }
1187        m_pcRdCost->setLambda(oldLambda);
1188
1189        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1190      }
1191#endif
1192     
1193      // restore entropy coder to an initial stage
1194      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1195      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1196      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1197      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1198      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1199      m_pcBitCounter->resetBits();
1200      pppcRDSbacCoder->setBinsCoded( 0 );
1201      m_pcCuEncoder->encodeCU( pcCU );
1202
1203      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1204      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1205      {
1206        pcSlice->setNextSlice( true );
1207        break;
1208      }
1209      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1210      {
1211        pcSlice->setNextSliceSegment( true );
1212        break;
1213      }
1214      if( m_pcCfg->getUseSBACRD() )
1215      {
1216         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1217       
1218         //Store probabilties of second LCU in line into buffer
1219         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1220        {
1221          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1222        }
1223      }
1224    }
1225    // other case: encodeCU is not called
1226    else
1227    {
1228      m_pcCuEncoder->compressCU( pcCU );
1229      m_pcCuEncoder->encodeCU( pcCU );
1230      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1231      {
1232        pcSlice->setNextSlice( true );
1233        break;
1234      }
1235      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1236      {
1237        pcSlice->setNextSliceSegment( true );
1238        break;
1239      }
1240    }
1241   
1242    m_uiPicTotalBits += pcCU->getTotalBits();
1243    m_dPicRdCost     += pcCU->getTotalCost();
1244    m_uiPicDist      += pcCU->getTotalDistortion();
1245#if !RATE_CONTROL_LAMBDA_DOMAIN
1246    if(m_pcCfg->getUseRateCtrl())
1247    {
1248      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1249      m_pcRateCtrl->updataRCUnitStatus();
1250    }
1251#endif
1252  }
1253  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1254  {
1255    pcSlice->setNextSlice( true );
1256  }
1257  if( depSliceSegmentsEnabled )
1258  {
1259    if (m_pcCfg->getWaveFrontsynchro())
1260    {
1261      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1262    }
1263     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1264  }
1265  xRestoreWPparam( pcSlice );
1266#if !RATE_CONTROL_LAMBDA_DOMAIN
1267  if(m_pcCfg->getUseRateCtrl())
1268  {
1269    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1270  }
1271#endif
1272}
1273
1274/**
1275 \param  rpcPic        picture class
1276 \retval rpcBitstream  bitstream class
1277 */
1278Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1279{
1280  UInt       uiCUAddr;
1281  UInt       uiStartCUAddr;
1282  UInt       uiBoundingCUAddr;
1283  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1284
1285  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1286  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1287  // choose entropy coder
1288  {
1289    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1290    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1291  }
1292 
1293  m_pcCuEncoder->setBitCounter( NULL );
1294  m_pcBitCounter = NULL;
1295  // Appropriate substream bitstream is switched later.
1296  // for every CU
1297#if ENC_DEC_TRACE
1298  g_bJustDoIt = g_bEncDecTraceEnable;
1299#endif
1300  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1301  DTRACE_CABAC_T( "\tPOC: " );
1302  DTRACE_CABAC_V( rpcPic->getPOC() );
1303#if H_MV
1304  DTRACE_CABAC_T( "\tLayer: " );
1305  DTRACE_CABAC_V( rpcPic->getLayerId()  );
1306#endif
1307  DTRACE_CABAC_T( "\n" );
1308#if ENC_DEC_TRACE
1309  g_bJustDoIt = g_bEncDecTraceDisable;
1310#endif
1311
1312  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1313  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1314  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1315  UInt uiBitsOriginallyInSubstreams = 0;
1316  {
1317    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1318    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1319    {
1320      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1321    }
1322   
1323    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1324    {
1325      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1326    }
1327
1328    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1329    {
1330      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1331    }
1332  }
1333
1334  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1335  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1336  UInt uiTileCol      = 0;
1337  UInt uiTileStartLCU = 0;
1338  UInt uiTileLCUX     = 0;
1339  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1340  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1341                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1342                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1343  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1344  if( depSliceSegmentsEnabled )
1345  {
1346    if( pcSlice->isNextSlice()||
1347        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1348    {
1349      if(m_pcCfg->getWaveFrontsynchro())
1350      {
1351        CTXMem[1]->loadContexts(m_pcSbacCoder);
1352      }
1353      CTXMem[0]->loadContexts(m_pcSbacCoder);
1354    }
1355    else
1356    {
1357      if(m_pcCfg->getWaveFrontsynchro())
1358      {
1359        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1360        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1361        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1362        uiLin     = uiCUAddr / uiWidthInLCUs;
1363        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1364          + uiLin%iNumSubstreamsPerTile;
1365        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1366        {
1367          uiCol     = uiCUAddr % uiWidthInLCUs;
1368          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1369          if(uiCol==uiTileLCUX)
1370          {
1371            CTXMem[0]->loadContexts(m_pcSbacCoder);
1372          }
1373        }
1374      }
1375      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1376    }
1377  }
1378
1379  UInt uiEncCUOrder;
1380  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1381       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1382       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1383  {
1384    if( m_pcCfg->getUseSBACRD() )
1385    {
1386      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1387      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1388      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1389      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1390      uiCol     = uiCUAddr % uiWidthInLCUs;
1391      uiLin     = uiCUAddr / uiWidthInLCUs;
1392      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1393      {
1394        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1395        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1396        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1397                      + uiLin%iNumSubstreamsPerTile;
1398      }
1399      else
1400      {
1401        // dependent tiles => substreams are "per frame".
1402        uiSubStrm = uiLin % iNumSubstreams;
1403      }
1404
1405      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1406      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1407      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1408      {
1409        // We'll sync if the TR is available.
1410        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1411        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1412        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1413        TComDataCU *pcCUTR = NULL;
1414        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1415        {
1416          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1417        }
1418        if ( (true/*bEnforceSliceRestriction*/ &&
1419             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1420             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1421             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1422             ))
1423           )
1424        {
1425          // TR not available.
1426        }
1427        else
1428        {
1429          // TR is available, we use it.
1430          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1431        }
1432      }
1433      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1434    }
1435    // reset the entropy coder
1436    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1437        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1438        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1439        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1440    {
1441      {
1442        // We're crossing into another tile, tiles are independent.
1443        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1444        // have to perform it here.
1445        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1446        {
1447          ; // do nothing.
1448        }
1449        else
1450        {
1451          SliceType sliceType  = pcSlice->getSliceType();
1452          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1453          {
1454            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1455          }
1456          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1457          // Byte-alignment in slice_data() when new tile
1458          pcSubstreams[uiSubStrm].writeByteAlignment();
1459        }
1460      }
1461      {
1462        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1463        UInt uiAccumulatedSubstreamLength = 0;
1464        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1465        {
1466          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1467        }
1468        // add bits coded in previous dependent slices + bits coded so far
1469        // add number of emulation prevention byte count in the tile
1470        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1471      }
1472    }
1473
1474    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1475    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1476    {
1477      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1478      Int iNumCuInWidth     = saoParam->numCuInWidth;
1479      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1480      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1481      Int rx = uiCUAddr % iNumCuInWidth;
1482      Int ry = uiCUAddr / iNumCuInWidth;
1483      Int allowMergeLeft = 1;
1484      Int allowMergeUp   = 1;
1485      if (rx!=0)
1486      {
1487        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1488        {
1489          allowMergeLeft = 0;
1490        }
1491      }
1492      if (ry!=0)
1493      {
1494        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1495        {
1496          allowMergeUp = 0;
1497        }
1498      }
1499      Int addr = pcCU->getAddr();
1500      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1501      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1502      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1503      {
1504        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1505        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1506        if (allowMergeLeft)
1507        {
1508          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
1509        }
1510        else
1511        {
1512          mergeLeft = 0;
1513        }
1514        if(mergeLeft == 0)
1515        {
1516          if (allowMergeUp)
1517          {
1518            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1519          }
1520          else
1521          {
1522            mergeUp = 0;
1523          }
1524          if(mergeUp == 0)
1525          {
1526            for (Int compIdx=0;compIdx<3;compIdx++)
1527            {
1528            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1529              {
1530                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1531              }
1532            }
1533          }
1534        }
1535      }
1536    }
1537    else if (pcSlice->getSPS()->getUseSAO())
1538    {
1539      Int addr = pcCU->getAddr();
1540      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1541      for (Int cIdx=0; cIdx<3; cIdx++)
1542      {
1543        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1544        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1545        {
1546          saoLcuParam->mergeUpFlag   = 0;
1547          saoLcuParam->mergeLeftFlag = 0;
1548          saoLcuParam->subTypeIdx    = 0;
1549          saoLcuParam->typeIdx       = -1;
1550          saoLcuParam->offset[0]     = 0;
1551          saoLcuParam->offset[1]     = 0;
1552          saoLcuParam->offset[2]     = 0;
1553          saoLcuParam->offset[3]     = 0;
1554        }
1555      }
1556    }
1557#if ENC_DEC_TRACE
1558    g_bJustDoIt = g_bEncDecTraceEnable;
1559#endif
1560    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1561      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1562    {
1563      m_pcCuEncoder->encodeCU( pcCU );
1564    }
1565    else
1566    {
1567      m_pcCuEncoder->encodeCU( pcCU );
1568    }
1569#if ENC_DEC_TRACE
1570    g_bJustDoIt = g_bEncDecTraceDisable;
1571#endif   
1572    if( m_pcCfg->getUseSBACRD() )
1573    {
1574       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1575       
1576
1577       //Store probabilties of second LCU in line into buffer
1578       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1579      {
1580        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1581      }
1582    }
1583  }
1584  if( depSliceSegmentsEnabled )
1585  {
1586    if (m_pcCfg->getWaveFrontsynchro())
1587    {
1588      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1589    }
1590    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1591  }
1592#if ADAPTIVE_QP_SELECTION
1593  if( m_pcCfg->getUseAdaptQpSelect() )
1594  {
1595    m_pcTrQuant->storeSliceQpNext(pcSlice);
1596  }
1597#endif
1598  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1599  {
1600    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1601    {
1602      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1603    }
1604    else
1605    {
1606      m_pcEntropyCoder->determineCabacInitIdx();
1607    }
1608  }
1609}
1610
1611/** Determines the starting and bounding LCU address of current slice / dependent slice
1612 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1613 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1614 */
1615Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1616{
1617  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1618  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1619  UInt tileIdxIncrement;
1620  UInt tileIdx;
1621  UInt tileWidthInLcu;
1622  UInt tileHeightInLcu;
1623  UInt tileTotalCount;
1624
1625  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1626  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1627  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1628  if (bEncodeSlice) 
1629  {
1630    UInt uiCUAddrIncrement;
1631    switch (m_pcCfg->getSliceMode())
1632    {
1633    case FIXED_NUMBER_OF_LCU:
1634      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1635      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1636      break;
1637    case FIXED_NUMBER_OF_BYTES:
1638      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1639      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1640      break;
1641    case FIXED_NUMBER_OF_TILES:
1642      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1643        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1644        );
1645      uiCUAddrIncrement        = 0;
1646      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1647
1648      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1649      {
1650        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1651        {
1652          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1653          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1654          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1655        }
1656      }
1657
1658      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1659      break;
1660    default:
1661      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1662      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1663      break;
1664    } 
1665    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1666    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1667    {
1668      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1669    }
1670    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1671  }
1672  else
1673  {
1674    UInt uiCUAddrIncrement     ;
1675    switch (m_pcCfg->getSliceMode())
1676    {
1677    case FIXED_NUMBER_OF_LCU:
1678      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1679      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1680      break;
1681    case FIXED_NUMBER_OF_TILES:
1682      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1683        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1684        );
1685      uiCUAddrIncrement        = 0;
1686      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1687
1688      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1689      {
1690        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1691        {
1692          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1693          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1694          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1695        }
1696      }
1697
1698      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1699      break;
1700    default:
1701      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1702      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1703      break;
1704    } 
1705    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1706    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1707    {
1708      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1709    }
1710    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1711  }
1712
1713  Bool tileBoundary = false;
1714  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1715      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1716  {
1717    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1718    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1719    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1720    UInt tileBoundingCUAddrSlice = 0;
1721    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1722    {
1723      lcuEncAddr++;
1724      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1725    }
1726    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1727   
1728    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1729    {
1730      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1731      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1732      tileBoundary = true;
1733    }
1734  }
1735
1736  // Dependent slice
1737  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1738  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1739  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1740  if (bEncodeSlice) 
1741  {
1742    UInt uiCUAddrIncrement;
1743    switch (m_pcCfg->getSliceSegmentMode())
1744    {
1745    case FIXED_NUMBER_OF_LCU:
1746      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1747      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1748      break;
1749    case FIXED_NUMBER_OF_BYTES:
1750      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1751      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1752      break;
1753    case FIXED_NUMBER_OF_TILES:
1754      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1755        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1756        );
1757      uiCUAddrIncrement        = 0;
1758      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1759
1760      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1761      {
1762        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1763        {
1764          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1765          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1766          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1767        }
1768      }
1769      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1770      break;
1771    default:
1772      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1773      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1774      break;
1775    } 
1776    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1777    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1778    {
1779      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1780    }
1781    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1782  }
1783  else
1784  {
1785    UInt uiCUAddrIncrement;
1786    switch (m_pcCfg->getSliceSegmentMode())
1787    {
1788    case FIXED_NUMBER_OF_LCU:
1789      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1790      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1791      break;
1792    case FIXED_NUMBER_OF_TILES:
1793      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1794        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1795        );
1796      uiCUAddrIncrement        = 0;
1797      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1798
1799      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1800      {
1801        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1802        {
1803          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1804          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1805          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1806        }
1807      }
1808      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1809      break;
1810    default:
1811      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1812      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1813      break;
1814    } 
1815    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1816    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1817    {
1818      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1819    }
1820    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1821  }
1822  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1823    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1824  {
1825    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1826    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1827    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1828    UInt tileBoundingCUAddrSlice = 0;
1829    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1830    {
1831      lcuEncAddr++;
1832      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1833    }
1834    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1835
1836    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1837    {
1838      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1839      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1840      tileBoundary = true;
1841    }
1842  }
1843
1844  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1845  {
1846    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1847    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1848  }
1849
1850  //calculate real dependent slice start address
1851  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1852  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1853  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1854  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1855  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1856  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1857  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1858  {
1859    uiInternalAddress++;
1860    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1861    {
1862      uiInternalAddress=0;
1863      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1864    }
1865    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1866    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1867  }
1868  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1869 
1870  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1871  startCUAddrSliceSegment=uiRealStartAddress;
1872 
1873  //calculate real slice start address
1874  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1875  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1876  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1877  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1878  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1879  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1880  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1881  {
1882    uiInternalAddress++;
1883    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1884    {
1885      uiInternalAddress=0;
1886      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1887    }
1888    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1889    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1890  }
1891  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1892 
1893  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1894  uiStartCUAddrSlice=uiRealStartAddress;
1895 
1896  // Make a joint decision based on reconstruction and dependent slice bounds
1897  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1898  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1899
1900
1901  if (!bEncodeSlice)
1902  {
1903    // 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
1904    // first. Set the flags accordingly.
1905    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1906      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1907      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1908      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1909      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1910      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1911      || tileBoundary
1912)
1913    {
1914      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1915      {
1916        pcSlice->setNextSlice       ( true );
1917        pcSlice->setNextSliceSegment( false );
1918      }
1919      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1920      {
1921        pcSlice->setNextSlice       ( false );
1922        pcSlice->setNextSliceSegment( true );
1923      }
1924      else
1925      {
1926        pcSlice->setNextSlice       ( true );
1927        pcSlice->setNextSliceSegment( true );
1928      }
1929    }
1930    else
1931    {
1932      pcSlice->setNextSlice       ( false );
1933      pcSlice->setNextSliceSegment( false );
1934    }
1935  }
1936}
1937
1938Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1939{
1940  return 4.2005*log(lambda) + 13.7122;
1941}
1942
1943//! \}
Note: See TracBrowser for help on using the repository browser.