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

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

-minor non-normative fix of IC

  • Property svn:eol-style set to native
File size: 76.6 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() &&
939       !( ( pcSlice->getSliceType() == P_SLICE && pcSlice->getPPS()->getUseWP() ) || ( pcSlice->getSliceType() == B_SLICE && pcSlice->getPPS()->getWPBiPred() ) )
940     )
941  {
942    pcSlice ->xSetApplyIC();
943    if ( pcSlice->getApplyIC() )
944    {
945      pcSlice->setIcSkipParseFlag( pcSlice->getPOC() % m_pcCfg->getIntraPeriod() != 0 );
946    }
947  }
948#endif
949  if( m_pcCfg->getUseSBACRD() )
950  {
951    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
952    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
953    delete[] m_pcBufferSbacCoders;
954    delete[] m_pcBufferBinCoderCABACs;
955    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
956    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
957    for (Int ui = 0; ui < uiTilesAcross; ui++)
958    {
959      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
960    }
961    for (UInt ui = 0; ui < uiTilesAcross; ui++)
962    {
963      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
964    }
965
966    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
967    {
968      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
969    }
970  }
971  //if( m_pcCfg->getUseSBACRD() )
972  {
973    delete[] m_pcBufferLowLatSbacCoders;
974    delete[] m_pcBufferLowLatBinCoderCABACs;
975    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
976    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
977    for (Int ui = 0; ui < uiTilesAcross; ui++)
978    {
979      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
980    }
981    for (UInt ui = 0; ui < uiTilesAcross; ui++)
982      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
983  }
984  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
985  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
986  UInt uiCol=0, uiLin=0, uiSubStrm=0;
987  UInt uiTileCol      = 0;
988  UInt uiTileStartLCU = 0;
989  UInt uiTileLCUX     = 0;
990  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
991  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
992  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
993  if( depSliceSegmentsEnabled )
994  {
995    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
996    {
997      if( m_pcCfg->getWaveFrontsynchro() )
998      {
999        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1000        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1001        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1002        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
1003        uiLin     = uiCUAddr / uiWidthInLCUs;
1004        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
1005          + uiLin%iNumSubstreamsPerTile;
1006        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1007        {
1008          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1009          uiCol     = uiCUAddr % uiWidthInLCUs;
1010          if(uiCol==uiTileStartLCU)
1011          {
1012            CTXMem[0]->loadContexts(m_pcSbacCoder);
1013          }
1014        }
1015      }
1016      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1017      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1018    }
1019    else
1020    {
1021      if(m_pcCfg->getWaveFrontsynchro())
1022      {
1023        CTXMem[1]->loadContexts(m_pcSbacCoder);
1024      }
1025      CTXMem[0]->loadContexts(m_pcSbacCoder);
1026    }
1027  }
1028  // for every CU in slice
1029#if H_3D
1030  Int iLastPosY = -1;
1031#endif
1032  UInt uiEncCUOrder;
1033  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1034       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1035       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1036  {
1037    // initialize CU encoder
1038    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1039    pcCU->initCU( rpcPic, uiCUAddr );
1040#if H_3D_VSO
1041    if ( m_pcRdCost->getUseRenModel() )
1042    {
1043      // updated renderer model if necessary
1044      Int iCurPosX;
1045      Int iCurPosY; 
1046      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
1047      if ( iCurPosY != iLastPosY )
1048      {
1049        iLastPosY = iCurPosY;         
1050        pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY );
1051      }
1052    }
1053#endif
1054#if !RATE_CONTROL_LAMBDA_DOMAIN
1055    if(m_pcCfg->getUseRateCtrl())
1056    {
1057      if(m_pcRateCtrl->calculateUnitQP())
1058      {
1059        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
1060      }
1061    }
1062#endif
1063    // inherit from TR if necessary, select substream to use.
1064    if( m_pcCfg->getUseSBACRD() )
1065    {
1066      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1067      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1068      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1069      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1070      uiCol     = uiCUAddr % uiWidthInLCUs;
1071      uiLin     = uiCUAddr / uiWidthInLCUs;
1072      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1073      {
1074        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1075        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1076        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1077                      + uiLin%iNumSubstreamsPerTile;
1078      }
1079      else
1080      {
1081        // dependent tiles => substreams are "per frame".
1082        uiSubStrm = uiLin % iNumSubstreams;
1083      }
1084      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1085      {
1086        // We'll sync if the TR is available.
1087        TComDataCU *pcCUUp = pcCU->getCUAbove();
1088        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1089        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1090        TComDataCU *pcCUTR = NULL;
1091        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1092        {
1093          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1094        }
1095        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1096             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1097             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1098             )
1099           )
1100        {
1101          // TR not available.
1102        }
1103        else
1104        {
1105          // TR is available, we use it.
1106          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1107        }
1108      }
1109      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1110    }
1111
1112    // reset the entropy coder
1113    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1114        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1115        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1116        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1117    {
1118      SliceType sliceType = pcSlice->getSliceType();
1119      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1120      {
1121        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1122      }
1123      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1124      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1125      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1126      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1127    }
1128    // if RD based on SBAC is used
1129    if( m_pcCfg->getUseSBACRD() )
1130    {
1131      // set go-on entropy coder
1132      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1133      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1134     
1135      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1136
1137#if RATE_CONTROL_LAMBDA_DOMAIN
1138      Double oldLambda = m_pcRdCost->getLambda();
1139      if ( m_pcCfg->getUseRateCtrl() )
1140      {
1141        Int estQP        = pcSlice->getSliceQp();
1142        Double estLambda = -1.0;
1143        Double bpp       = -1.0;
1144
1145        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
1146        {
1147          estQP = pcSlice->getSliceQp();
1148        }
1149        else
1150        {
1151          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
1152          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1153          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1154          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1155
1156          m_pcRdCost->setLambda(estLambda);
1157        }
1158
1159        m_pcRateCtrl->setRCQP( estQP );
1160#if L0033_RC_BUGFIX
1161        pcCU->getSlice()->setSliceQpBase( estQP );
1162#endif
1163      }
1164#endif
1165
1166      // run CU encoder
1167      m_pcCuEncoder->compressCU( pcCU );
1168
1169#if RATE_CONTROL_LAMBDA_DOMAIN
1170      if ( m_pcCfg->getUseRateCtrl() )
1171      {
1172        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1173        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1174        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1175        Double MAD = (Double)SAD / (Double)(height * width);
1176        MAD = MAD * MAD;
1177        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1178
1179        Int actualQP        = g_RCInvalidQPValue;
1180        Double actualLambda = m_pcRdCost->getLambda();
1181        Int actualBits      = pcCU->getTotalBits();
1182        Int numberOfEffectivePixels    = 0;
1183        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1184        {
1185          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1186          {
1187            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1188            break;
1189          }
1190        }
1191
1192        if ( numberOfEffectivePixels == 0 )
1193        {
1194          actualQP = g_RCInvalidQPValue;
1195        }
1196        else
1197        {
1198          actualQP = pcCU->getQP( 0 );
1199        }
1200        m_pcRdCost->setLambda(oldLambda);
1201
1202        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1203      }
1204#endif
1205     
1206      // restore entropy coder to an initial stage
1207      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1208      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1209      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1210      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1211      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1212      m_pcBitCounter->resetBits();
1213      pppcRDSbacCoder->setBinsCoded( 0 );
1214      m_pcCuEncoder->encodeCU( pcCU );
1215
1216      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1217      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1218      {
1219        pcSlice->setNextSlice( true );
1220        break;
1221      }
1222      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1223      {
1224        pcSlice->setNextSliceSegment( true );
1225        break;
1226      }
1227      if( m_pcCfg->getUseSBACRD() )
1228      {
1229         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1230       
1231         //Store probabilties of second LCU in line into buffer
1232         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1233        {
1234          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1235        }
1236      }
1237    }
1238    // other case: encodeCU is not called
1239    else
1240    {
1241      m_pcCuEncoder->compressCU( pcCU );
1242      m_pcCuEncoder->encodeCU( pcCU );
1243      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1244      {
1245        pcSlice->setNextSlice( true );
1246        break;
1247      }
1248      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1249      {
1250        pcSlice->setNextSliceSegment( true );
1251        break;
1252      }
1253    }
1254   
1255    m_uiPicTotalBits += pcCU->getTotalBits();
1256    m_dPicRdCost     += pcCU->getTotalCost();
1257    m_uiPicDist      += pcCU->getTotalDistortion();
1258#if !RATE_CONTROL_LAMBDA_DOMAIN
1259    if(m_pcCfg->getUseRateCtrl())
1260    {
1261      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1262      m_pcRateCtrl->updataRCUnitStatus();
1263    }
1264#endif
1265  }
1266  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1267  {
1268    pcSlice->setNextSlice( true );
1269  }
1270  if( depSliceSegmentsEnabled )
1271  {
1272    if (m_pcCfg->getWaveFrontsynchro())
1273    {
1274      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1275    }
1276     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1277  }
1278  xRestoreWPparam( pcSlice );
1279#if !RATE_CONTROL_LAMBDA_DOMAIN
1280  if(m_pcCfg->getUseRateCtrl())
1281  {
1282    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1283  }
1284#endif
1285}
1286
1287/**
1288 \param  rpcPic        picture class
1289 \retval rpcBitstream  bitstream class
1290 */
1291Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1292{
1293  UInt       uiCUAddr;
1294  UInt       uiStartCUAddr;
1295  UInt       uiBoundingCUAddr;
1296  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1297
1298  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1299  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1300  // choose entropy coder
1301  {
1302    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1303    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1304  }
1305 
1306  m_pcCuEncoder->setBitCounter( NULL );
1307  m_pcBitCounter = NULL;
1308  // Appropriate substream bitstream is switched later.
1309  // for every CU
1310#if ENC_DEC_TRACE
1311  g_bJustDoIt = g_bEncDecTraceEnable;
1312#endif
1313  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1314  DTRACE_CABAC_T( "\tPOC: " );
1315  DTRACE_CABAC_V( rpcPic->getPOC() );
1316  DTRACE_CABAC_T( "\n" );
1317#if ENC_DEC_TRACE
1318  g_bJustDoIt = g_bEncDecTraceDisable;
1319#endif
1320
1321  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1322  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1323  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1324  UInt uiBitsOriginallyInSubstreams = 0;
1325  {
1326    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1327    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1328    {
1329      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1330    }
1331   
1332    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1333    {
1334      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1335    }
1336
1337    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1338    {
1339      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1340    }
1341  }
1342
1343  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1344  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1345  UInt uiTileCol      = 0;
1346  UInt uiTileStartLCU = 0;
1347  UInt uiTileLCUX     = 0;
1348  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1349  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1350                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1351                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1352  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1353  if( depSliceSegmentsEnabled )
1354  {
1355    if( pcSlice->isNextSlice()||
1356        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1357    {
1358      if(m_pcCfg->getWaveFrontsynchro())
1359      {
1360        CTXMem[1]->loadContexts(m_pcSbacCoder);
1361      }
1362      CTXMem[0]->loadContexts(m_pcSbacCoder);
1363    }
1364    else
1365    {
1366      if(m_pcCfg->getWaveFrontsynchro())
1367      {
1368        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1369        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1370        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1371        uiLin     = uiCUAddr / uiWidthInLCUs;
1372        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1373          + uiLin%iNumSubstreamsPerTile;
1374        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1375        {
1376          uiCol     = uiCUAddr % uiWidthInLCUs;
1377          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1378          if(uiCol==uiTileLCUX)
1379          {
1380            CTXMem[0]->loadContexts(m_pcSbacCoder);
1381          }
1382        }
1383      }
1384      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1385    }
1386  }
1387
1388  UInt uiEncCUOrder;
1389  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1390       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1391       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1392  {
1393    if( m_pcCfg->getUseSBACRD() )
1394    {
1395      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1396      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1397      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1398      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1399      uiCol     = uiCUAddr % uiWidthInLCUs;
1400      uiLin     = uiCUAddr / uiWidthInLCUs;
1401      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1402      {
1403        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1404        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1405        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1406                      + uiLin%iNumSubstreamsPerTile;
1407      }
1408      else
1409      {
1410        // dependent tiles => substreams are "per frame".
1411        uiSubStrm = uiLin % iNumSubstreams;
1412      }
1413
1414      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1415      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1416      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1417      {
1418        // We'll sync if the TR is available.
1419        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1420        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1421        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1422        TComDataCU *pcCUTR = NULL;
1423        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1424        {
1425          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1426        }
1427        if ( (true/*bEnforceSliceRestriction*/ &&
1428             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1429             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1430             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1431             ))
1432           )
1433        {
1434          // TR not available.
1435        }
1436        else
1437        {
1438          // TR is available, we use it.
1439          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1440        }
1441      }
1442      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1443    }
1444    // reset the entropy coder
1445    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1446        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1447        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1448        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1449    {
1450      {
1451        // We're crossing into another tile, tiles are independent.
1452        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1453        // have to perform it here.
1454        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1455        {
1456          ; // do nothing.
1457        }
1458        else
1459        {
1460          SliceType sliceType  = pcSlice->getSliceType();
1461          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1462          {
1463            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1464          }
1465          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1466          // Byte-alignment in slice_data() when new tile
1467          pcSubstreams[uiSubStrm].writeByteAlignment();
1468        }
1469      }
1470      {
1471        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1472        UInt uiAccumulatedSubstreamLength = 0;
1473        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1474        {
1475          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1476        }
1477        // add bits coded in previous dependent slices + bits coded so far
1478        // add number of emulation prevention byte count in the tile
1479        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1480      }
1481    }
1482
1483    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1484    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1485    {
1486      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1487      Int iNumCuInWidth     = saoParam->numCuInWidth;
1488      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1489      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1490      Int rx = uiCUAddr % iNumCuInWidth;
1491      Int ry = uiCUAddr / iNumCuInWidth;
1492      Int allowMergeLeft = 1;
1493      Int allowMergeUp   = 1;
1494      if (rx!=0)
1495      {
1496        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1497        {
1498          allowMergeLeft = 0;
1499        }
1500      }
1501      if (ry!=0)
1502      {
1503        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1504        {
1505          allowMergeUp = 0;
1506        }
1507      }
1508      Int addr = pcCU->getAddr();
1509      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1510      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1511      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1512      {
1513        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1514        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1515        if (allowMergeLeft)
1516        {
1517          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
1518        }
1519        else
1520        {
1521          mergeLeft = 0;
1522        }
1523        if(mergeLeft == 0)
1524        {
1525          if (allowMergeUp)
1526          {
1527            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1528          }
1529          else
1530          {
1531            mergeUp = 0;
1532          }
1533          if(mergeUp == 0)
1534          {
1535            for (Int compIdx=0;compIdx<3;compIdx++)
1536            {
1537            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1538              {
1539                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1540              }
1541            }
1542          }
1543        }
1544      }
1545    }
1546    else if (pcSlice->getSPS()->getUseSAO())
1547    {
1548      Int addr = pcCU->getAddr();
1549      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1550      for (Int cIdx=0; cIdx<3; cIdx++)
1551      {
1552        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1553        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1554        {
1555          saoLcuParam->mergeUpFlag   = 0;
1556          saoLcuParam->mergeLeftFlag = 0;
1557          saoLcuParam->subTypeIdx    = 0;
1558          saoLcuParam->typeIdx       = -1;
1559          saoLcuParam->offset[0]     = 0;
1560          saoLcuParam->offset[1]     = 0;
1561          saoLcuParam->offset[2]     = 0;
1562          saoLcuParam->offset[3]     = 0;
1563        }
1564      }
1565    }
1566#if ENC_DEC_TRACE
1567    g_bJustDoIt = g_bEncDecTraceEnable;
1568#endif
1569    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1570      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1571    {
1572      m_pcCuEncoder->encodeCU( pcCU );
1573    }
1574    else
1575    {
1576      m_pcCuEncoder->encodeCU( pcCU );
1577    }
1578#if ENC_DEC_TRACE
1579    g_bJustDoIt = g_bEncDecTraceDisable;
1580#endif   
1581    if( m_pcCfg->getUseSBACRD() )
1582    {
1583       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1584       
1585
1586       //Store probabilties of second LCU in line into buffer
1587       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1588      {
1589        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1590      }
1591    }
1592  }
1593  if( depSliceSegmentsEnabled )
1594  {
1595    if (m_pcCfg->getWaveFrontsynchro())
1596    {
1597      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1598    }
1599    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1600  }
1601#if ADAPTIVE_QP_SELECTION
1602  if( m_pcCfg->getUseAdaptQpSelect() )
1603  {
1604    m_pcTrQuant->storeSliceQpNext(pcSlice);
1605  }
1606#endif
1607  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1608  {
1609    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1610    {
1611      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1612    }
1613    else
1614    {
1615      m_pcEntropyCoder->determineCabacInitIdx();
1616    }
1617  }
1618}
1619
1620/** Determines the starting and bounding LCU address of current slice / dependent slice
1621 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1622 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1623 */
1624Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1625{
1626  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1627  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1628  UInt tileIdxIncrement;
1629  UInt tileIdx;
1630  UInt tileWidthInLcu;
1631  UInt tileHeightInLcu;
1632  UInt tileTotalCount;
1633
1634  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1635  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1636  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1637  if (bEncodeSlice) 
1638  {
1639    UInt uiCUAddrIncrement;
1640    switch (m_pcCfg->getSliceMode())
1641    {
1642    case FIXED_NUMBER_OF_LCU:
1643      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1644      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1645      break;
1646    case FIXED_NUMBER_OF_BYTES:
1647      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1648      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1649      break;
1650    case FIXED_NUMBER_OF_TILES:
1651      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1652        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1653        );
1654      uiCUAddrIncrement        = 0;
1655      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1656
1657      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1658      {
1659        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1660        {
1661          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1662          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1663          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1664        }
1665      }
1666
1667      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1668      break;
1669    default:
1670      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1671      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1672      break;
1673    } 
1674    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1675    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1676    {
1677      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1678    }
1679    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1680  }
1681  else
1682  {
1683    UInt uiCUAddrIncrement     ;
1684    switch (m_pcCfg->getSliceMode())
1685    {
1686    case FIXED_NUMBER_OF_LCU:
1687      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1688      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1689      break;
1690    case FIXED_NUMBER_OF_TILES:
1691      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1692        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1693        );
1694      uiCUAddrIncrement        = 0;
1695      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1696
1697      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1698      {
1699        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1700        {
1701          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1702          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1703          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1704        }
1705      }
1706
1707      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1708      break;
1709    default:
1710      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1711      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1712      break;
1713    } 
1714    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1715    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1716    {
1717      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1718    }
1719    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1720  }
1721
1722  Bool tileBoundary = false;
1723  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1724      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1725  {
1726    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1727    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1728    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1729    UInt tileBoundingCUAddrSlice = 0;
1730    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1731    {
1732      lcuEncAddr++;
1733      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1734    }
1735    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1736   
1737    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1738    {
1739      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1740      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1741      tileBoundary = true;
1742    }
1743  }
1744
1745  // Dependent slice
1746  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1747  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1748  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1749  if (bEncodeSlice) 
1750  {
1751    UInt uiCUAddrIncrement;
1752    switch (m_pcCfg->getSliceSegmentMode())
1753    {
1754    case FIXED_NUMBER_OF_LCU:
1755      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1756      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1757      break;
1758    case FIXED_NUMBER_OF_BYTES:
1759      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1760      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1761      break;
1762    case FIXED_NUMBER_OF_TILES:
1763      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1764        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1765        );
1766      uiCUAddrIncrement        = 0;
1767      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1768
1769      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1770      {
1771        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1772        {
1773          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1774          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1775          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1776        }
1777      }
1778      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1779      break;
1780    default:
1781      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1782      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1783      break;
1784    } 
1785    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1786    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1787    {
1788      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1789    }
1790    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1791  }
1792  else
1793  {
1794    UInt uiCUAddrIncrement;
1795    switch (m_pcCfg->getSliceSegmentMode())
1796    {
1797    case FIXED_NUMBER_OF_LCU:
1798      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1799      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1800      break;
1801    case FIXED_NUMBER_OF_TILES:
1802      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1803        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1804        );
1805      uiCUAddrIncrement        = 0;
1806      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1807
1808      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1809      {
1810        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1811        {
1812          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1813          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1814          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1815        }
1816      }
1817      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1818      break;
1819    default:
1820      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1821      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1822      break;
1823    } 
1824    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1825    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1826    {
1827      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1828    }
1829    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1830  }
1831  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1832    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1833  {
1834    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1835    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1836    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1837    UInt tileBoundingCUAddrSlice = 0;
1838    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1839    {
1840      lcuEncAddr++;
1841      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1842    }
1843    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1844
1845    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1846    {
1847      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1848      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1849      tileBoundary = true;
1850    }
1851  }
1852
1853  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1854  {
1855    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1856    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1857  }
1858
1859  //calculate real dependent slice start address
1860  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1861  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1862  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1863  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1864  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1865  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1866  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1867  {
1868    uiInternalAddress++;
1869    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1870    {
1871      uiInternalAddress=0;
1872      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1873    }
1874    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1875    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1876  }
1877  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1878 
1879  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1880  startCUAddrSliceSegment=uiRealStartAddress;
1881 
1882  //calculate real slice start address
1883  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1884  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1885  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1886  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1887  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1888  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1889  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1890  {
1891    uiInternalAddress++;
1892    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1893    {
1894      uiInternalAddress=0;
1895      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1896    }
1897    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1898    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1899  }
1900  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1901 
1902  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1903  uiStartCUAddrSlice=uiRealStartAddress;
1904 
1905  // Make a joint decision based on reconstruction and dependent slice bounds
1906  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1907  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1908
1909
1910  if (!bEncodeSlice)
1911  {
1912    // 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
1913    // first. Set the flags accordingly.
1914    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1915      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1916      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1917      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1918      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1919      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1920      || tileBoundary
1921)
1922    {
1923      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1924      {
1925        pcSlice->setNextSlice       ( true );
1926        pcSlice->setNextSliceSegment( false );
1927      }
1928      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1929      {
1930        pcSlice->setNextSlice       ( false );
1931        pcSlice->setNextSliceSegment( true );
1932      }
1933      else
1934      {
1935        pcSlice->setNextSlice       ( true );
1936        pcSlice->setNextSliceSegment( true );
1937      }
1938    }
1939    else
1940    {
1941      pcSlice->setNextSlice       ( false );
1942      pcSlice->setNextSliceSegment( false );
1943    }
1944  }
1945}
1946
1947Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1948{
1949  return 4.2005*log(lambda) + 13.7122;
1950}
1951
1952//! \}
Note: See TracBrowser for help on using the repository browser.