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

Last change on this file since 468 was 468, checked in by lg, 11 years ago

1.IC and full pel depth coding are integrated and is guarded by Macro H_3D_IC.

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