source: 3DVCSoftware/branches/HTM-10.0rc1-dev0/source/Lib/TLibEncoder/TEncSlice.cpp @ 841

Last change on this file since 841 was 841, checked in by tech, 10 years ago

Further fixes.

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