source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncSlice.cpp @ 885

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

Merged HTM-10.0-dev0@871. (MV-HEVC 7 HLS)

  • 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#if H_3D_QTLPC
1460    rpcPic->setReduceBitsFlag(false);
1461#endif
1462  }
1463  if( depSliceSegmentsEnabled )
1464  {
1465    if (m_pcCfg->getWaveFrontsynchro())
1466    {
1467      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1468    }
1469    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1470  }
1471#if ADAPTIVE_QP_SELECTION
1472  if( m_pcCfg->getUseAdaptQpSelect() )
1473  {
1474    m_pcTrQuant->storeSliceQpNext(pcSlice);
1475  }
1476#endif
1477  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1478  {
1479    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1480    {
1481      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1482    }
1483    else
1484    {
1485      m_pcEntropyCoder->determineCabacInitIdx();
1486    }
1487  }
1488}
1489
1490/** Determines the starting and bounding LCU address of current slice / dependent slice
1491 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1492 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1493 */
1494Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1495{
1496  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1497  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1498  UInt tileIdxIncrement;
1499  UInt tileIdx;
1500  UInt tileWidthInLcu;
1501  UInt tileHeightInLcu;
1502  UInt tileTotalCount;
1503
1504  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1505  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1506  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1507  if (bEncodeSlice) 
1508  {
1509    UInt uiCUAddrIncrement;
1510    switch (m_pcCfg->getSliceMode())
1511    {
1512    case FIXED_NUMBER_OF_LCU:
1513      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1514      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1515      break;
1516    case FIXED_NUMBER_OF_BYTES:
1517      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1518      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1519      break;
1520    case FIXED_NUMBER_OF_TILES:
1521      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1522        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1523        );
1524      uiCUAddrIncrement        = 0;
1525      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1526
1527      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1528      {
1529        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1530        {
1531          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1532          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1533          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1534        }
1535      }
1536
1537      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1538      break;
1539    default:
1540      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1541      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1542      break;
1543    } 
1544    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1545    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1546    {
1547      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1548    }
1549    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1550  }
1551  else
1552  {
1553    UInt uiCUAddrIncrement     ;
1554    switch (m_pcCfg->getSliceMode())
1555    {
1556    case FIXED_NUMBER_OF_LCU:
1557      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1558      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1559      break;
1560    case FIXED_NUMBER_OF_TILES:
1561      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1562        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1563        );
1564      uiCUAddrIncrement        = 0;
1565      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1566
1567      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1568      {
1569        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1570        {
1571          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1572          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1573          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1574        }
1575      }
1576
1577      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1578      break;
1579    default:
1580      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1581      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1582      break;
1583    } 
1584    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1585    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1586    {
1587      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1588    }
1589    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1590  }
1591
1592  Bool tileBoundary = false;
1593  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1594      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1595  {
1596    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1597    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1598    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1599    UInt tileBoundingCUAddrSlice = 0;
1600    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1601    {
1602      lcuEncAddr++;
1603      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1604    }
1605    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1606   
1607    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1608    {
1609      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1610      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1611      tileBoundary = true;
1612    }
1613  }
1614
1615  // Dependent slice
1616  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1617  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1618  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1619  if (bEncodeSlice) 
1620  {
1621    UInt uiCUAddrIncrement;
1622    switch (m_pcCfg->getSliceSegmentMode())
1623    {
1624    case FIXED_NUMBER_OF_LCU:
1625      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1626      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1627      break;
1628    case FIXED_NUMBER_OF_BYTES:
1629      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1630      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1631      break;
1632    case FIXED_NUMBER_OF_TILES:
1633      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1634        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1635        );
1636      uiCUAddrIncrement        = 0;
1637      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1638
1639      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1640      {
1641        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1642        {
1643          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1644          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1645          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1646        }
1647      }
1648      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1649      break;
1650    default:
1651      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1652      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1653      break;
1654    } 
1655    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1656    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1657    {
1658      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1659    }
1660    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1661  }
1662  else
1663  {
1664    UInt uiCUAddrIncrement;
1665    switch (m_pcCfg->getSliceSegmentMode())
1666    {
1667    case FIXED_NUMBER_OF_LCU:
1668      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1669      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1670      break;
1671    case FIXED_NUMBER_OF_TILES:
1672      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1673        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1674        );
1675      uiCUAddrIncrement        = 0;
1676      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1677
1678      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1679      {
1680        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1681        {
1682          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1683          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1684          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1685        }
1686      }
1687      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1688      break;
1689    default:
1690      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1691      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1692      break;
1693    } 
1694    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1695    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1696    {
1697      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1698    }
1699    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1700  }
1701  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1702    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1703  {
1704    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1705    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1706    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1707    UInt tileBoundingCUAddrSlice = 0;
1708    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1709    {
1710      lcuEncAddr++;
1711      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1712    }
1713    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1714
1715    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1716    {
1717      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1718      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1719      tileBoundary = true;
1720    }
1721  }
1722
1723  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1724  {
1725    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1726    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1727  }
1728
1729  //calculate real dependent slice start address
1730  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1731  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1732  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1733  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1734  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1735  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1736  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1737  {
1738    uiInternalAddress++;
1739    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1740    {
1741      uiInternalAddress=0;
1742      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1743    }
1744    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1745    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1746  }
1747  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1748 
1749  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1750  startCUAddrSliceSegment=uiRealStartAddress;
1751 
1752  //calculate real slice start address
1753  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1754  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1755  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1756  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1757  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1758  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1759  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1760  {
1761    uiInternalAddress++;
1762    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1763    {
1764      uiInternalAddress=0;
1765      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1766    }
1767    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1768    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1769  }
1770  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1771 
1772  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1773  uiStartCUAddrSlice=uiRealStartAddress;
1774 
1775  // Make a joint decision based on reconstruction and dependent slice bounds
1776  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1777  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1778
1779
1780  if (!bEncodeSlice)
1781  {
1782    // 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
1783    // first. Set the flags accordingly.
1784    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1785      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1786      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1787      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1788      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1789      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1790      || tileBoundary
1791)
1792    {
1793      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1794      {
1795        pcSlice->setNextSlice       ( true );
1796        pcSlice->setNextSliceSegment( false );
1797      }
1798      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1799      {
1800        pcSlice->setNextSlice       ( false );
1801        pcSlice->setNextSliceSegment( true );
1802      }
1803      else
1804      {
1805        pcSlice->setNextSlice       ( true );
1806        pcSlice->setNextSliceSegment( true );
1807      }
1808    }
1809    else
1810    {
1811      pcSlice->setNextSlice       ( false );
1812      pcSlice->setNextSliceSegment( false );
1813    }
1814  }
1815}
1816
1817Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1818{
1819  return 4.2005*log(lambda) + 13.7122;
1820}
1821
1822//! \}
Note: See TracBrowser for help on using the repository browser.