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

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

Integrated following changes:

  • H_MV_FIX1071, fix of encoder side reference list construction on IRAP pictures, same as in HM11.
  • H_3D_VSO_FIX_BORDRE_EXTENSION, fixed uninitialized borders for org-yuvs in VSO
  • H_MV_ENC_DEC_TRAC, added cu/pu level trace ( only enabled when ENC_DEC_TRACE is enabled)
  • Property svn:eol-style set to native
File size: 77.5 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2013, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncSlice.cpp
35    \brief    slice encoder class
36*/
37
38#include "TEncTop.h"
39#include "TEncSlice.h"
40#include <math.h>
41
42//! \ingroup TLibEncoder
43//! \{
44
45// ====================================================================================================================
46// Constructor / destructor / create / destroy
47// ====================================================================================================================
48
49TEncSlice::TEncSlice()
50{
51  m_apcPicYuvPred = NULL;
52  m_apcPicYuvResi = NULL;
53 
54  m_pdRdPicLambda = NULL;
55  m_pdRdPicQp     = NULL;
56  m_piRdPicQp     = NULL;
57  m_pcBufferSbacCoders    = NULL;
58  m_pcBufferBinCoderCABACs  = NULL;
59  m_pcBufferLowLatSbacCoders    = NULL;
60  m_pcBufferLowLatBinCoderCABACs  = NULL;
61}
62
63TEncSlice::~TEncSlice()
64{
65  for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
66  {
67    delete (*i);
68  }
69}
70
71Void TEncSlice::initCtxMem(  UInt i )               
72{   
73  for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
74  {
75    delete (*j);
76  }
77  CTXMem.clear(); 
78  CTXMem.resize(i); 
79}
80
81Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
82{
83  // create prediction picture
84  if ( m_apcPicYuvPred == NULL )
85  {
86    m_apcPicYuvPred  = new TComPicYuv;
87    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
88  }
89 
90  // create residual picture
91  if( m_apcPicYuvResi == NULL )
92  {
93    m_apcPicYuvResi  = new TComPicYuv;
94    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
95  }
96}
97
98Void TEncSlice::destroy()
99{
100  // destroy prediction picture
101  if ( m_apcPicYuvPred )
102  {
103    m_apcPicYuvPred->destroy();
104    delete m_apcPicYuvPred;
105    m_apcPicYuvPred  = NULL;
106  }
107 
108  // destroy residual picture
109  if ( m_apcPicYuvResi )
110  {
111    m_apcPicYuvResi->destroy();
112    delete m_apcPicYuvResi;
113    m_apcPicYuvResi  = NULL;
114  }
115 
116  // free lambda and QP arrays
117  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
118  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
119  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
120
121  if ( m_pcBufferSbacCoders )
122  {
123    delete[] m_pcBufferSbacCoders;
124  }
125  if ( m_pcBufferBinCoderCABACs )
126  {
127    delete[] m_pcBufferBinCoderCABACs;
128  }
129  if ( m_pcBufferLowLatSbacCoders )
130    delete[] m_pcBufferLowLatSbacCoders;
131  if ( m_pcBufferLowLatBinCoderCABACs )
132    delete[] m_pcBufferLowLatBinCoderCABACs;
133}
134
135Void TEncSlice::init( TEncTop* pcEncTop )
136{
137  m_pcCfg             = pcEncTop;
138  m_pcListPic         = pcEncTop->getListPic();
139 
140  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
141  m_pcCuEncoder       = pcEncTop->getCuEncoder();
142  m_pcPredSearch      = pcEncTop->getPredSearch();
143 
144  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
145  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
146  m_pcSbacCoder       = pcEncTop->getSbacCoder();
147  m_pcBinCABAC        = pcEncTop->getBinCABAC();
148  m_pcTrQuant         = pcEncTop->getTrQuant();
149 
150  m_pcBitCounter      = pcEncTop->getBitCounter();
151  m_pcRdCost          = pcEncTop->getRdCost();
152  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
153  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
154 
155  // create lambda and QP arrays
156  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
157  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
158  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
159  m_pcRateCtrl        = pcEncTop->getRateCtrl();
160}
161
162/**
163 - non-referenced frame marking
164 - QP computation based on temporal structure
165 - lambda computation based on QP
166 - set temporal layer ID and the parameter sets
167 .
168 \param pcPic         picture class
169 \param pocLast       POC of last picture
170 \param pocCurr       current POC
171 \param iNumPicRcvd   number of received pictures
172 \param iTimeOffset   POC offset for hierarchical structure
173 \param iDepth        temporal layer depth
174 \param rpcSlice      slice header class
175 \param pSPS          SPS associated with the slice
176 \param pPPS          PPS associated with the slice
177 */
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#if H_MV_ENC_DEC_TRAC
1335  DTRACE_CABAC_T( " Layer: " );
1336  DTRACE_CABAC_V( rpcPic->getLayerId() );
1337#endif
1338  DTRACE_CABAC_T( "\n" );
1339#if ENC_DEC_TRACE
1340  g_bJustDoIt = g_bEncDecTraceDisable;
1341#endif
1342
1343  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1344  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1345  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1346  UInt uiBitsOriginallyInSubstreams = 0;
1347  {
1348    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1349    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1350    {
1351      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1352    }
1353   
1354    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1355    {
1356      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1357    }
1358
1359    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1360    {
1361      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1362    }
1363  }
1364
1365  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1366  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1367  UInt uiTileCol      = 0;
1368  UInt uiTileStartLCU = 0;
1369  UInt uiTileLCUX     = 0;
1370  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1371  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1372                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1373                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1374  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1375  if( depSliceSegmentsEnabled )
1376  {
1377    if( pcSlice->isNextSlice()||
1378        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1379    {
1380      if(m_pcCfg->getWaveFrontsynchro())
1381      {
1382        CTXMem[1]->loadContexts(m_pcSbacCoder);
1383      }
1384      CTXMem[0]->loadContexts(m_pcSbacCoder);
1385    }
1386    else
1387    {
1388      if(m_pcCfg->getWaveFrontsynchro())
1389      {
1390        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1391        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1392        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1393        uiLin     = uiCUAddr / uiWidthInLCUs;
1394        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1395          + uiLin%iNumSubstreamsPerTile;
1396        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1397        {
1398          uiCol     = uiCUAddr % uiWidthInLCUs;
1399          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1400          if(uiCol==uiTileLCUX)
1401          {
1402            CTXMem[0]->loadContexts(m_pcSbacCoder);
1403          }
1404        }
1405      }
1406      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1407    }
1408  }
1409
1410  UInt uiEncCUOrder;
1411  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1412       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1413       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1414  {
1415    if( m_pcCfg->getUseSBACRD() )
1416    {
1417      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1418      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1419      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1420      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1421      uiCol     = uiCUAddr % uiWidthInLCUs;
1422      uiLin     = uiCUAddr / uiWidthInLCUs;
1423      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1424      {
1425        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1426        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1427        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1428                      + uiLin%iNumSubstreamsPerTile;
1429      }
1430      else
1431      {
1432        // dependent tiles => substreams are "per frame".
1433        uiSubStrm = uiLin % iNumSubstreams;
1434      }
1435
1436      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1437      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1438      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1439      {
1440        // We'll sync if the TR is available.
1441        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1442        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1443        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1444        TComDataCU *pcCUTR = NULL;
1445        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1446        {
1447          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1448        }
1449        if ( (true/*bEnforceSliceRestriction*/ &&
1450             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1451             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1452             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1453             ))
1454           )
1455        {
1456          // TR not available.
1457        }
1458        else
1459        {
1460          // TR is available, we use it.
1461          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1462        }
1463      }
1464      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1465    }
1466    // reset the entropy coder
1467    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1468        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1469        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1470        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1471    {
1472      {
1473        // We're crossing into another tile, tiles are independent.
1474        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1475        // have to perform it here.
1476        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1477        {
1478          ; // do nothing.
1479        }
1480        else
1481        {
1482          SliceType sliceType  = pcSlice->getSliceType();
1483          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1484          {
1485            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1486          }
1487          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1488          // Byte-alignment in slice_data() when new tile
1489          pcSubstreams[uiSubStrm].writeByteAlignment();
1490        }
1491      }
1492      {
1493        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1494        UInt uiAccumulatedSubstreamLength = 0;
1495        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1496        {
1497          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1498        }
1499        // add bits coded in previous dependent slices + bits coded so far
1500        // add number of emulation prevention byte count in the tile
1501        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1502      }
1503    }
1504
1505    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1506    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1507    {
1508      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1509      Int iNumCuInWidth     = saoParam->numCuInWidth;
1510      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1511      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1512      Int rx = uiCUAddr % iNumCuInWidth;
1513      Int ry = uiCUAddr / iNumCuInWidth;
1514      Int allowMergeLeft = 1;
1515      Int allowMergeUp   = 1;
1516      if (rx!=0)
1517      {
1518        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1519        {
1520          allowMergeLeft = 0;
1521        }
1522      }
1523      if (ry!=0)
1524      {
1525        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1526        {
1527          allowMergeUp = 0;
1528        }
1529      }
1530      Int addr = pcCU->getAddr();
1531      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1532      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1533      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1534      {
1535        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1536        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1537        if (allowMergeLeft)
1538        {
1539          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
1540        }
1541        else
1542        {
1543          mergeLeft = 0;
1544        }
1545        if(mergeLeft == 0)
1546        {
1547          if (allowMergeUp)
1548          {
1549            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1550          }
1551          else
1552          {
1553            mergeUp = 0;
1554          }
1555          if(mergeUp == 0)
1556          {
1557            for (Int compIdx=0;compIdx<3;compIdx++)
1558            {
1559            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1560              {
1561                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1562              }
1563            }
1564          }
1565        }
1566      }
1567    }
1568    else if (pcSlice->getSPS()->getUseSAO())
1569    {
1570      Int addr = pcCU->getAddr();
1571      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1572      for (Int cIdx=0; cIdx<3; cIdx++)
1573      {
1574        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1575        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1576        {
1577          saoLcuParam->mergeUpFlag   = 0;
1578          saoLcuParam->mergeLeftFlag = 0;
1579          saoLcuParam->subTypeIdx    = 0;
1580          saoLcuParam->typeIdx       = -1;
1581          saoLcuParam->offset[0]     = 0;
1582          saoLcuParam->offset[1]     = 0;
1583          saoLcuParam->offset[2]     = 0;
1584          saoLcuParam->offset[3]     = 0;
1585        }
1586      }
1587    }
1588#if ENC_DEC_TRACE
1589    g_bJustDoIt = g_bEncDecTraceEnable;
1590#endif
1591    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1592      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1593    {
1594      m_pcCuEncoder->encodeCU( pcCU );
1595    }
1596    else
1597    {
1598      m_pcCuEncoder->encodeCU( pcCU );
1599    }
1600#if ENC_DEC_TRACE
1601    g_bJustDoIt = g_bEncDecTraceDisable;
1602#endif   
1603    if( m_pcCfg->getUseSBACRD() )
1604    {
1605       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1606       
1607
1608       //Store probabilties of second LCU in line into buffer
1609       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1610      {
1611        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1612      }
1613    }
1614  }
1615  if( depSliceSegmentsEnabled )
1616  {
1617    if (m_pcCfg->getWaveFrontsynchro())
1618    {
1619      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1620    }
1621    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1622  }
1623#if ADAPTIVE_QP_SELECTION
1624  if( m_pcCfg->getUseAdaptQpSelect() )
1625  {
1626    m_pcTrQuant->storeSliceQpNext(pcSlice);
1627  }
1628#endif
1629  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1630  {
1631    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1632    {
1633      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1634    }
1635    else
1636    {
1637      m_pcEntropyCoder->determineCabacInitIdx();
1638    }
1639  }
1640}
1641
1642/** Determines the starting and bounding LCU address of current slice / dependent slice
1643 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1644 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1645 */
1646Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1647{
1648  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1649  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1650  UInt tileIdxIncrement;
1651  UInt tileIdx;
1652  UInt tileWidthInLcu;
1653  UInt tileHeightInLcu;
1654  UInt tileTotalCount;
1655
1656  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1657  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1658  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1659  if (bEncodeSlice) 
1660  {
1661    UInt uiCUAddrIncrement;
1662    switch (m_pcCfg->getSliceMode())
1663    {
1664    case FIXED_NUMBER_OF_LCU:
1665      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1666      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1667      break;
1668    case FIXED_NUMBER_OF_BYTES:
1669      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1670      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1671      break;
1672    case FIXED_NUMBER_OF_TILES:
1673      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1674        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1675        );
1676      uiCUAddrIncrement        = 0;
1677      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1678
1679      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1680      {
1681        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1682        {
1683          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1684          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1685          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1686        }
1687      }
1688
1689      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1690      break;
1691    default:
1692      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1693      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1694      break;
1695    } 
1696    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1697    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1698    {
1699      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1700    }
1701    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1702  }
1703  else
1704  {
1705    UInt uiCUAddrIncrement     ;
1706    switch (m_pcCfg->getSliceMode())
1707    {
1708    case FIXED_NUMBER_OF_LCU:
1709      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1710      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1711      break;
1712    case FIXED_NUMBER_OF_TILES:
1713      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1714        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1715        );
1716      uiCUAddrIncrement        = 0;
1717      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1718
1719      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1720      {
1721        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1722        {
1723          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1724          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1725          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1726        }
1727      }
1728
1729      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1730      break;
1731    default:
1732      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1733      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1734      break;
1735    } 
1736    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1737    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1738    {
1739      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1740    }
1741    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1742  }
1743
1744  Bool tileBoundary = false;
1745  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1746      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1747  {
1748    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1749    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1750    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1751    UInt tileBoundingCUAddrSlice = 0;
1752    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1753    {
1754      lcuEncAddr++;
1755      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1756    }
1757    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1758   
1759    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1760    {
1761      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1762      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1763      tileBoundary = true;
1764    }
1765  }
1766
1767  // Dependent slice
1768  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1769  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1770  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1771  if (bEncodeSlice) 
1772  {
1773    UInt uiCUAddrIncrement;
1774    switch (m_pcCfg->getSliceSegmentMode())
1775    {
1776    case FIXED_NUMBER_OF_LCU:
1777      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1778      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1779      break;
1780    case FIXED_NUMBER_OF_BYTES:
1781      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1782      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1783      break;
1784    case FIXED_NUMBER_OF_TILES:
1785      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1786        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1787        );
1788      uiCUAddrIncrement        = 0;
1789      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1790
1791      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1792      {
1793        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1794        {
1795          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1796          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1797          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1798        }
1799      }
1800      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1801      break;
1802    default:
1803      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1804      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1805      break;
1806    } 
1807    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1808    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1809    {
1810      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1811    }
1812    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1813  }
1814  else
1815  {
1816    UInt uiCUAddrIncrement;
1817    switch (m_pcCfg->getSliceSegmentMode())
1818    {
1819    case FIXED_NUMBER_OF_LCU:
1820      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1821      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1822      break;
1823    case FIXED_NUMBER_OF_TILES:
1824      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1825        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1826        );
1827      uiCUAddrIncrement        = 0;
1828      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1829
1830      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1831      {
1832        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1833        {
1834          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1835          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1836          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1837        }
1838      }
1839      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1840      break;
1841    default:
1842      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1843      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1844      break;
1845    } 
1846    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1847    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1848    {
1849      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1850    }
1851    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1852  }
1853  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1854    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1855  {
1856    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1857    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1858    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1859    UInt tileBoundingCUAddrSlice = 0;
1860    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1861    {
1862      lcuEncAddr++;
1863      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1864    }
1865    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1866
1867    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1868    {
1869      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1870      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1871      tileBoundary = true;
1872    }
1873  }
1874
1875  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1876  {
1877    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1878    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1879  }
1880
1881  //calculate real dependent slice start address
1882  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1883  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1884  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1885  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1886  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1887  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1888  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1889  {
1890    uiInternalAddress++;
1891    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1892    {
1893      uiInternalAddress=0;
1894      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1895    }
1896    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1897    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1898  }
1899  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1900 
1901  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1902  startCUAddrSliceSegment=uiRealStartAddress;
1903 
1904  //calculate real slice start address
1905  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1906  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1907  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1908  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1909  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1910  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1911  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1912  {
1913    uiInternalAddress++;
1914    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1915    {
1916      uiInternalAddress=0;
1917      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1918    }
1919    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1920    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1921  }
1922  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1923 
1924  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1925  uiStartCUAddrSlice=uiRealStartAddress;
1926 
1927  // Make a joint decision based on reconstruction and dependent slice bounds
1928  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1929  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1930
1931
1932  if (!bEncodeSlice)
1933  {
1934    // 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
1935    // first. Set the flags accordingly.
1936    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1937      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1938      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1939      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1940      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1941      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1942      || tileBoundary
1943)
1944    {
1945      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1946      {
1947        pcSlice->setNextSlice       ( true );
1948        pcSlice->setNextSliceSegment( false );
1949      }
1950      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1951      {
1952        pcSlice->setNextSlice       ( false );
1953        pcSlice->setNextSliceSegment( true );
1954      }
1955      else
1956      {
1957        pcSlice->setNextSlice       ( true );
1958        pcSlice->setNextSliceSegment( true );
1959      }
1960    }
1961    else
1962    {
1963      pcSlice->setNextSlice       ( false );
1964      pcSlice->setNextSliceSegment( false );
1965    }
1966  }
1967}
1968
1969Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1970{
1971  return 4.2005*log(lambda) + 13.7122;
1972}
1973
1974//! \}
Note: See TracBrowser for help on using the repository browser.