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

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

Integrated DoNBDV provided by Mediatek and applied clean ups.

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