source: 3DVCSoftware/branches/HTM-10.2-dev3-MediaTek/source/Lib/TLibEncoder/TEncSlice.cpp @ 902

Last change on this file since 902 was 902, checked in by mediatek-htm, 10 years ago

Integration of low-latency IC encoding as proposed in JCT3V-H0086.
The MACRO is "MTK_LOW_LATENCY_IC_ENCODING_H0086"
The configuration files are modified by adding one additional control parameter "IlluCompLowLatencyEnc" which is set to 0 for CTC.

By Yi-Wen Chen (yiwen.chen@…)

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