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

Last change on this file since 504 was 504, checked in by zhang, 11 years ago

Merge Dev2.a to Dev2 and simulation results updated

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