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

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

Further fixes.

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