source: 3DVCSoftware/branches/HTM-DEV-0.2-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 456

Last change on this file since 456 was 446, checked in by tech, 12 years ago

Added missing parts.

  • Property svn:eol-style set to native
File size: 76.1 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2013, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncSlice.cpp
35    \brief    slice encoder class
36*/
37
38#include "TEncTop.h"
39#include "TEncSlice.h"
40#include <math.h>
41
42//! \ingroup TLibEncoder
43//! \{
44
45// ====================================================================================================================
46// Constructor / destructor / create / destroy
47// ====================================================================================================================
48
49TEncSlice::TEncSlice()
50{
51  m_apcPicYuvPred = NULL;
52  m_apcPicYuvResi = NULL;
53 
54  m_pdRdPicLambda = NULL;
55  m_pdRdPicQp     = NULL;
56  m_piRdPicQp     = NULL;
57  m_pcBufferSbacCoders    = NULL;
58  m_pcBufferBinCoderCABACs  = NULL;
59  m_pcBufferLowLatSbacCoders    = NULL;
60  m_pcBufferLowLatBinCoderCABACs  = NULL;
61}
62
63TEncSlice::~TEncSlice()
64{
65  for (std::vector<TEncSbac*>::iterator i = CTXMem.begin(); i != CTXMem.end(); i++)
66  {
67    delete (*i);
68  }
69}
70
71Void TEncSlice::initCtxMem(  UInt i )               
72{   
73  for (std::vector<TEncSbac*>::iterator j = CTXMem.begin(); j != CTXMem.end(); j++)
74  {
75    delete (*j);
76  }
77  CTXMem.clear(); 
78  CTXMem.resize(i); 
79}
80
81Void TEncSlice::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
82{
83  // create prediction picture
84  if ( m_apcPicYuvPred == NULL )
85  {
86    m_apcPicYuvPred  = new TComPicYuv;
87    m_apcPicYuvPred->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
88  }
89 
90  // create residual picture
91  if( m_apcPicYuvResi == NULL )
92  {
93    m_apcPicYuvResi  = new TComPicYuv;
94    m_apcPicYuvResi->create( iWidth, iHeight, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
95  }
96}
97
98Void TEncSlice::destroy()
99{
100  // destroy prediction picture
101  if ( m_apcPicYuvPred )
102  {
103    m_apcPicYuvPred->destroy();
104    delete m_apcPicYuvPred;
105    m_apcPicYuvPred  = NULL;
106  }
107 
108  // destroy residual picture
109  if ( m_apcPicYuvResi )
110  {
111    m_apcPicYuvResi->destroy();
112    delete m_apcPicYuvResi;
113    m_apcPicYuvResi  = NULL;
114  }
115 
116  // free lambda and QP arrays
117  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
118  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
119  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
120
121  if ( m_pcBufferSbacCoders )
122  {
123    delete[] m_pcBufferSbacCoders;
124  }
125  if ( m_pcBufferBinCoderCABACs )
126  {
127    delete[] m_pcBufferBinCoderCABACs;
128  }
129  if ( m_pcBufferLowLatSbacCoders )
130    delete[] m_pcBufferLowLatSbacCoders;
131  if ( m_pcBufferLowLatBinCoderCABACs )
132    delete[] m_pcBufferLowLatBinCoderCABACs;
133}
134
135Void TEncSlice::init( TEncTop* pcEncTop )
136{
137  m_pcCfg             = pcEncTop;
138  m_pcListPic         = pcEncTop->getListPic();
139 
140  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
141  m_pcCuEncoder       = pcEncTop->getCuEncoder();
142  m_pcPredSearch      = pcEncTop->getPredSearch();
143 
144  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
145  m_pcCavlcCoder      = pcEncTop->getCavlcCoder();
146  m_pcSbacCoder       = pcEncTop->getSbacCoder();
147  m_pcBinCABAC        = pcEncTop->getBinCABAC();
148  m_pcTrQuant         = pcEncTop->getTrQuant();
149 
150  m_pcBitCounter      = pcEncTop->getBitCounter();
151  m_pcRdCost          = pcEncTop->getRdCost();
152  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
153  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
154 
155  // create lambda and QP arrays
156  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
157  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
158  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
159  m_pcRateCtrl        = pcEncTop->getRateCtrl();
160}
161
162/**
163 - non-referenced frame marking
164 - QP computation based on temporal structure
165 - lambda computation based on QP
166 - set temporal layer ID and the parameter sets
167 .
168 \param pcPic         picture class
169 \param pocLast       POC of last picture
170 \param pocCurr       current POC
171 \param iNumPicRcvd   number of received pictures
172 \param iTimeOffset   POC offset for hierarchical structure
173 \param iDepth        temporal layer depth
174 \param rpcSlice      slice header class
175 \param pSPS          SPS associated with the slice
176 \param pPPS          PPS associated with the slice
177 */
178Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS )
179{
180  Double dQP;
181  Double dLambda;
182 
183  rpcSlice = pcPic->getSlice(0);
184  rpcSlice->setSPS( pSPS );
185  rpcSlice->setPPS( pPPS );
186  rpcSlice->setSliceBits(0);
187  rpcSlice->setPic( pcPic );
188  rpcSlice->initSlice();
189  rpcSlice->setPicOutputFlag( true );
190  rpcSlice->setPOC( pocCurr );
191 
192  // depth computation based on GOP size
193  Int depth;
194  {
195    Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
196    if ( poc == 0 )
197    {
198      depth = 0;
199    }
200    else
201    {
202      Int step = m_pcCfg->getGOPSize();
203      depth    = 0;
204      for( Int i=step>>1; i>=1; i>>=1 )
205      {
206        for ( Int j=i; j<m_pcCfg->getGOPSize(); j+=step )
207        {
208          if ( j == poc )
209          {
210            i=0;
211            break;
212          }
213        }
214        step >>= 1;
215        depth++;
216      }
217    }
218  }
219 
220  // slice type
221#if H_MV
222  SliceType eSliceTypeBaseView;
223  if( pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0 )
224  {
225    eSliceTypeBaseView = I_SLICE;
226  }
227  else
228  {
229    eSliceTypeBaseView = B_SLICE;
230  }
231  SliceType eSliceType = eSliceTypeBaseView;
232  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
233  {
234    eSliceType = B_SLICE; 
235  }
236#else
237  SliceType eSliceType;
238 
239  eSliceType=B_SLICE;
240  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
241 
242  rpcSlice->setSliceType    ( eSliceType );
243#endif
244
245  // ------------------------------------------------------------------------------------------------------------------
246  // Non-referenced frame marking
247  // ------------------------------------------------------------------------------------------------------------------
248 
249  if(pocLast == 0)
250  {
251    rpcSlice->setTemporalLayerNonReferenceFlag(false);
252  }
253  else
254  {
255#if 0 // Check this! H_MV
256    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_refPic);
257#else
258    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
259#endif
260  }
261  rpcSlice->setReferenced(true);
262 
263  // ------------------------------------------------------------------------------------------------------------------
264  // QP setting
265  // ------------------------------------------------------------------------------------------------------------------
266 
267  dQP = m_pcCfg->getQP();
268  if(eSliceType!=I_SLICE)
269  {
270    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffsetY() ) && (rpcSlice->getSPS()->getUseLossless()))) 
271    {
272#if H_MV
273      dQP += m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPOffset;
274#else
275      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
276#endif
277    }
278  }
279 
280  // modify QP
281  Int* pdQPs = m_pcCfg->getdQPs();
282  if ( pdQPs )
283  {
284    dQP += pdQPs[ rpcSlice->getPOC() ];
285  }
286#if !RATE_CONTROL_LAMBDA_DOMAIN
287  if ( m_pcCfg->getUseRateCtrl())
288  {
289    dQP = m_pcRateCtrl->getFrameQP(rpcSlice->isReferenced(), rpcSlice->getPOC());
290  }
291#endif
292  // ------------------------------------------------------------------------------------------------------------------
293  // Lambda computation
294  // ------------------------------------------------------------------------------------------------------------------
295 
296  Int iQP;
297  Double dOrigQP = dQP;
298
299  // pre-compute lambda and QP values for all possible QP candidates
300  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
301  {
302    // compute QP value
303    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
304   
305    // compute lambda value
306    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
307    Int    SHIFT_QP = 12;
308    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
309#if FULL_NBIT
310    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
311#else
312    Int    bitdepth_luma_qp_scale = 0;
313#endif
314    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
315#if FULL_NBIT
316    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
317#endif
318    // Case #1: I or P-slices (key-frame)
319#if H_MV
320    Double dQPFactor;
321    if( eSliceType != I_SLICE ) 
322    {
323      dQPFactor = m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_QPFactor;
324    }
325    else
326#else
327    Double dQPFactor = m_pcCfg->getGOPEntry(iGOPid).m_QPFactor;
328    if ( eSliceType==I_SLICE )
329#endif
330    {
331      dQPFactor=0.57*dLambda_scale;
332    }
333    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
334
335    if ( depth>0 )
336    {
337#if FULL_NBIT
338        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
339#else
340        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
341#endif
342    }
343   
344    // if hadamard is used in ME process
345    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
346    {
347      dLambda *= 0.95;
348    }
349   
350    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
351
352    m_pdRdPicLambda[iDQpIdx] = dLambda;
353    m_pdRdPicQp    [iDQpIdx] = dQP;
354    m_piRdPicQp    [iDQpIdx] = iQP;
355  }
356 
357  // obtain dQP = 0 case
358  dLambda = m_pdRdPicLambda[0];
359  dQP     = m_pdRdPicQp    [0];
360  iQP     = m_piRdPicQp    [0];
361 
362  if( rpcSlice->getSliceType( ) != I_SLICE )
363  {
364#if H_MV
365    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_temporalId );
366#else
367    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
368#endif
369  }
370
371  // store lambda
372  m_pcRdCost ->setLambda( dLambda );
373
374#if H_3D_VSO
375  m_pcRdCost->setUseLambdaScaleVSO  ( (m_pcCfg->getUseVSO() ||  m_pcCfg->getForceLambdaScaleVSO()) && m_pcCfg->getIsDepth() );
376  m_pcRdCost->setLambdaVSO          ( dLambda * m_pcCfg->getLambdaScaleVSO() );
377
378  // Should be moved to TEncTop
379 
380  // SAIT_VSO_EST_A0033
381  m_pcRdCost->setDisparityCoeff( m_pcCfg->getDispCoeff() );
382
383  // LGE_WVSO_A0119
384  if( m_pcCfg->getUseWVSO() && m_pcCfg->getIsDepth() )
385  {
386    m_pcRdCost->setDWeight  ( m_pcCfg->getDWeight()   );
387    m_pcRdCost->setVSOWeight( m_pcCfg->getVSOWeight() );
388    m_pcRdCost->setVSDWeight( m_pcCfg->getVSDWeight() );
389  }
390
391#endif
392
393#if WEIGHTED_CHROMA_DISTORTION
394// for RDO
395  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
396  Double weight = 1.0;
397  Int qpc;
398  Int chromaQPOffset;
399
400  chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
401  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
402  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
403  m_pcRdCost->setCbDistortionWeight(weight);
404
405  chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
406  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
407  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
408  m_pcRdCost->setCrDistortionWeight(weight);
409#endif
410
411#if RDOQ_CHROMA_LAMBDA
412// for RDOQ
413  m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
414#else
415  m_pcTrQuant->setLambda( dLambda );
416#endif
417
418#if SAO_CHROMA_LAMBDA
419// For SAO
420  rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
421#else
422  rpcSlice   ->setLambda( dLambda );
423#endif
424 
425#if HB_LAMBDA_FOR_LDC
426  // restore original slice type
427#if H_MV
428  eSliceType = eSliceTypeBaseView;
429  if( eSliceTypeBaseView == I_SLICE && m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType != 'I' )
430  {
431    eSliceType = B_SLICE;
432  }
433#else
434  eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
435#endif
436
437  rpcSlice->setSliceType        ( eSliceType );
438#endif
439 
440  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
441  {
442    dQP = xGetQPValueAccordingToLambda( dLambda );
443    iQP = max( -pSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );   
444  }
445
446  rpcSlice->setSliceQp          ( iQP );
447#if ADAPTIVE_QP_SELECTION
448  rpcSlice->setSliceQpBase      ( iQP );
449#endif
450  rpcSlice->setSliceQpDelta     ( 0 );
451  rpcSlice->setSliceQpDeltaCb   ( 0 );
452  rpcSlice->setSliceQpDeltaCr   ( 0 );
453#if H_MV
454  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
455  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_numRefPicsActive);
456#else
457  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
458  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
459#endif
460
461#if L0386_DB_METRIC
462  if ( m_pcCfg->getDeblockingFilterMetric() )
463  {
464    rpcSlice->setDeblockingFilterOverrideFlag(true);
465    rpcSlice->setDeblockingFilterDisable(false);
466    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
467    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
468  } else
469#endif
470  if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
471  {
472    rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
473    rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
474    rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
475    rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
476    if ( !rpcSlice->getDeblockingFilterDisable())
477    {
478      if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
479      {
480#if H_MV
481        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
482        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
483        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
484        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
485#else
486        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
487        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
488        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
489        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
490#endif
491      }
492      else
493      {
494      rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
495      rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
496      rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
497      rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
498      }
499    }
500  }
501  else
502  {
503    rpcSlice->setDeblockingFilterOverrideFlag( false );
504    rpcSlice->setDeblockingFilterDisable( false );
505    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
506    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
507  }
508
509  rpcSlice->setDepth            ( depth );
510 
511#if H_MV
512  pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId );
513#else
514  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
515#endif
516  if(eSliceType==I_SLICE)
517  {
518    pcPic->setTLayer(0);
519  }
520  rpcSlice->setTLayer( pcPic->getTLayer() );
521
522  assert( m_apcPicYuvPred );
523  assert( m_apcPicYuvResi );
524 
525  pcPic->setPicYuvPred( m_apcPicYuvPred );
526  pcPic->setPicYuvResi( m_apcPicYuvResi );
527  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
528  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
529  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
530  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
531  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
532  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
533}
534
535#if RATE_CONTROL_LAMBDA_DOMAIN
536Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
537{
538  TComSlice* slice = pic->getSlice(0);
539
540  // store lambda
541  slice->setSliceQp( sliceQP );
542#if L0033_RC_BUGFIX
543  slice->setSliceQpBase ( sliceQP );
544#endif
545  m_pcRdCost ->setLambda( lambda );
546#if WEIGHTED_CHROMA_DISTORTION
547  // for RDO
548  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
549  Double weight;
550  Int qpc;
551  Int chromaQPOffset;
552
553  chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
554  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
555  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
556  m_pcRdCost->setCbDistortionWeight(weight);
557
558  chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
559  qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
560  weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
561  m_pcRdCost->setCrDistortionWeight(weight);
562#endif
563
564#if RDOQ_CHROMA_LAMBDA
565  // for RDOQ
566  m_pcTrQuant->setLambda( lambda, lambda / weight );
567#else
568  m_pcTrQuant->setLambda( lambda );
569#endif
570
571#if SAO_CHROMA_LAMBDA
572  // For SAO
573  slice   ->setLambda( lambda, lambda / weight );
574#else
575  slice   ->setLambda( lambda );
576#endif
577}
578#else
579/**
580 - lambda re-computation based on rate control QP
581 */
582Void TEncSlice::xLamdaRecalculation(Int changeQP, Int idGOP, Int depth, SliceType eSliceType, TComSPS* pcSPS, TComSlice* pcSlice)
583{
584  Int qp;
585  Double recalQP= (Double)changeQP;
586  Double origQP = (Double)recalQP;
587  Double lambda;
588
589  // pre-compute lambda and QP values for all possible QP candidates
590  for ( Int deltqQpIdx = 0; deltqQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; deltqQpIdx++ )
591  {
592    // compute QP value
593    recalQP = origQP + ((deltqQpIdx+1)>>1)*(deltqQpIdx%2 ? -1 : 1);
594
595    // compute lambda value
596    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
597    Int    SHIFT_QP = 12;
598    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
599#if FULL_NBIT
600    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth - 8);
601#else
602    Int    bitdepth_luma_qp_scale = 0;
603#endif
604    Double qp_temp = (Double) recalQP + bitdepth_luma_qp_scale - SHIFT_QP;
605#if FULL_NBIT
606    Double qp_temp_orig = (Double) recalQP - SHIFT_QP;
607#endif
608    // Case #1: I or P-slices (key-frame)
609    Double dQPFactor = m_pcCfg->getGOPEntry(idGOP).m_QPFactor;
610    if ( eSliceType==I_SLICE )
611    {
612      dQPFactor=0.57*dLambda_scale;
613    }
614    lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
615
616    if ( depth>0 )
617    {
618#if FULL_NBIT
619      lambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
620#else
621      lambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
622#endif
623    }
624
625    // if hadamard is used in ME process
626    if ( !m_pcCfg->getUseHADME() )
627    {
628      lambda *= 0.95;
629    }
630
631    qp = max( -pcSPS->getQpBDOffsetY(), min( MAX_QP, (Int) floor( recalQP + 0.5 ) ) );
632
633    m_pdRdPicLambda[deltqQpIdx] = lambda;
634    m_pdRdPicQp    [deltqQpIdx] = recalQP;
635    m_piRdPicQp    [deltqQpIdx] = qp;
636  }
637
638  // obtain dQP = 0 case
639  lambda  = m_pdRdPicLambda[0];
640  recalQP = m_pdRdPicQp    [0];
641  qp      = m_piRdPicQp    [0];
642
643  if( pcSlice->getSliceType( ) != I_SLICE )
644  {
645    lambda *= m_pcCfg->getLambdaModifier( depth );
646  }
647
648  // store lambda
649  m_pcRdCost ->setLambda( lambda );
650#if WEIGHTED_CHROMA_DISTORTION
651  // for RDO
652  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
653  Double weight = 1.0;
654  Int qpc;
655  Int chromaQPOffset;
656
657  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
658  qpc = Clip3( 0, 57, qp + chromaQPOffset);
659  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
660  m_pcRdCost->setCbDistortionWeight(weight);
661
662  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
663  qpc = Clip3( 0, 57, qp + chromaQPOffset);
664  weight = pow( 2.0, (qp-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
665  m_pcRdCost->setCrDistortionWeight(weight);
666#endif
667
668#if RDOQ_CHROMA_LAMBDA
669  // for RDOQ
670  m_pcTrQuant->setLambda( lambda, lambda / weight );   
671#else
672  m_pcTrQuant->setLambda( lambda );
673#endif
674
675#if SAO_CHROMA_LAMBDA
676  // For SAO
677  pcSlice   ->setLambda( lambda, lambda / weight ); 
678#else
679  pcSlice   ->setLambda( lambda );
680#endif
681}
682#endif
683// ====================================================================================================================
684// Public member functions
685// ====================================================================================================================
686
687Void TEncSlice::setSearchRange( TComSlice* pcSlice )
688{
689  Int iCurrPOC = pcSlice->getPOC();
690  Int iRefPOC;
691  Int iGOPSize = m_pcCfg->getGOPSize();
692  Int iOffset = (iGOPSize >> 1);
693  Int iMaxSR = m_pcCfg->getSearchRange();
694  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
695 
696  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
697  {
698    //RefPicList e = (RefPicList)iDir;
699    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
700    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
701    {
702      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
703      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
704      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
705    }
706  }
707}
708
709/**
710 - multi-loop slice encoding for different slice QP
711 .
712 \param rpcPic    picture class
713 */
714Void TEncSlice::precompressSlice( TComPic*& rpcPic )
715{
716  // if deltaQP RD is not used, simply return
717  if ( m_pcCfg->getDeltaQpRD() == 0 )
718  {
719    return;
720  }
721
722#if RATE_CONTROL_LAMBDA_DOMAIN
723  if ( m_pcCfg->getUseRateCtrl() )
724  {
725    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
726    assert(0);
727  }
728#endif
729 
730  TComSlice* pcSlice        = rpcPic->getSlice(getSliceIdx());
731  Double     dPicRdCostBest = MAX_DOUBLE;
732  UInt       uiQpIdxBest = 0;
733 
734  Double dFrameLambda;
735#if FULL_NBIT
736  Int    SHIFT_QP = 12 + 6 * (g_bitDepth - 8);
737#else
738  Int    SHIFT_QP = 12;
739#endif
740 
741  // set frame lambda
742  if (m_pcCfg->getGOPSize() > 1)
743  {
744    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
745  }
746  else
747  {
748    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
749  }
750  m_pcRdCost      ->setFrameLambda(dFrameLambda);
751 
752  // for each QP candidate
753  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
754  {
755    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
756#if ADAPTIVE_QP_SELECTION
757    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
758#endif
759    m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
760#if WEIGHTED_CHROMA_DISTORTION
761    // for RDO
762    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
763    Int iQP = m_piRdPicQp    [uiQpIdx];
764    Double weight = 1.0;
765    Int qpc;
766    Int chromaQPOffset;
767
768    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
769    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
770    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
771    m_pcRdCost->setCbDistortionWeight(weight);
772
773    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
774    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
775    weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
776    m_pcRdCost->setCrDistortionWeight(weight);
777#endif
778
779#if RDOQ_CHROMA_LAMBDA
780    // for RDOQ
781    m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
782#else
783    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
784#endif
785#if SAO_CHROMA_LAMBDA
786    // For SAO
787    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight ); 
788#else
789    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
790#endif
791   
792    // try compress
793    compressSlice   ( rpcPic );
794   
795    Double dPicRdCost;
796#if H_3D_VSO
797    Dist64 uiPicDist        = m_uiPicDist;
798#else
799    UInt64 uiPicDist        = m_uiPicDist;
800#endif
801    UInt64 uiALFBits        = 0;
802   
803    m_pcGOPEncoder->preLoopFilterPicAll( rpcPic, uiPicDist, uiALFBits );
804   
805    // compute RD cost and choose the best
806    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits + uiALFBits, uiPicDist, true, DF_SSE_FRAME);
807#if H_3D
808    // Above calculation need to be fixed for VSO, including frameLambda value.
809#endif
810   
811    if ( dPicRdCost < dPicRdCostBest )
812    {
813      uiQpIdxBest    = uiQpIdx;
814      dPicRdCostBest = dPicRdCost;
815    }
816  }
817 
818  // set best values
819  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
820#if ADAPTIVE_QP_SELECTION
821  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
822#endif
823  m_pcRdCost    ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
824#if WEIGHTED_CHROMA_DISTORTION
825  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
826  Int iQP = m_piRdPicQp    [uiQpIdxBest];
827  Double weight = 1.0;
828  Int qpc;
829  Int chromaQPOffset;
830
831  chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
832  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
833  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
834  m_pcRdCost->setCbDistortionWeight(weight);
835
836  chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
837  qpc = Clip3( 0, 57, iQP + chromaQPOffset);
838  weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
839  m_pcRdCost->setCrDistortionWeight(weight);
840#endif
841
842#if RDOQ_CHROMA_LAMBDA
843  // for RDOQ
844  m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
845#else
846  m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
847#endif
848#if SAO_CHROMA_LAMBDA
849  // For SAO
850  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight ); 
851#else
852  pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
853#endif
854}
855
856/** \param rpcPic   picture class
857 */
858Void TEncSlice::compressSlice( TComPic*& rpcPic )
859{
860  UInt  uiCUAddr;
861  UInt   uiStartCUAddr;
862  UInt   uiBoundingCUAddr;
863  rpcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
864  TEncBinCABAC* pppcRDSbacCoder = NULL;
865  TComSlice* pcSlice            = rpcPic->getSlice(getSliceIdx());
866  xDetermineStartAndBoundingCUAddr ( uiStartCUAddr, uiBoundingCUAddr, rpcPic, false );
867 
868  // initialize cost values
869  m_uiPicTotalBits  = 0;
870  m_dPicRdCost      = 0;
871  m_uiPicDist       = 0;
872 
873  // set entropy coder
874  if( m_pcCfg->getUseSBACRD() )
875  {
876    m_pcSbacCoder->init( m_pcBinCABAC );
877    m_pcEntropyCoder->setEntropyCoder   ( m_pcSbacCoder, pcSlice );
878    m_pcEntropyCoder->resetEntropy      ();
879    m_pppcRDSbacCoder[0][CI_CURR_BEST]->load(m_pcSbacCoder);
880    pppcRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
881    pppcRDSbacCoder->setBinCountingEnableFlag( false );
882    pppcRDSbacCoder->setBinsCoded( 0 );
883  }
884  else
885  {
886    m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
887    m_pcEntropyCoder->resetEntropy      ();
888    m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
889  }
890 
891  //------------------------------------------------------------------------------
892  //  Weighted Prediction parameters estimation.
893  //------------------------------------------------------------------------------
894  // calculate AC/DC values for current picture
895  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
896  {
897    xCalcACDCParamSlice(pcSlice);
898  }
899
900  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
901
902  if ( bWp_explicit )
903  {
904    //------------------------------------------------------------------------------
905    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
906    //------------------------------------------------------------------------------
907    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
908    {
909      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
910    }
911
912    xEstimateWPParamSlice( pcSlice );
913    pcSlice->initWpScaling();
914
915    // check WP on/off
916    xCheckWPEnable( pcSlice );
917  }
918
919#if ADAPTIVE_QP_SELECTION
920  if( m_pcCfg->getUseAdaptQpSelect() )
921  {
922    m_pcTrQuant->clearSliceARLCnt();
923    if(pcSlice->getSliceType()!=I_SLICE)
924    {
925      Int qpBase = pcSlice->getSliceQpBase();
926      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
927    }
928  }
929#endif
930  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
931  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
932  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
933  Int  iNumSubstreams = 1;
934  UInt uiTilesAcross  = 0;
935
936  if( m_pcCfg->getUseSBACRD() )
937  {
938    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
939    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
940    delete[] m_pcBufferSbacCoders;
941    delete[] m_pcBufferBinCoderCABACs;
942    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
943    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
944    for (Int ui = 0; ui < uiTilesAcross; ui++)
945    {
946      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
947    }
948    for (UInt ui = 0; ui < uiTilesAcross; ui++)
949    {
950      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
951    }
952
953    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
954    {
955      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
956    }
957  }
958  //if( m_pcCfg->getUseSBACRD() )
959  {
960    delete[] m_pcBufferLowLatSbacCoders;
961    delete[] m_pcBufferLowLatBinCoderCABACs;
962    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
963    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
964    for (Int ui = 0; ui < uiTilesAcross; ui++)
965    {
966      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
967    }
968    for (UInt ui = 0; ui < uiTilesAcross; ui++)
969      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
970  }
971  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
972  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
973  UInt uiCol=0, uiLin=0, uiSubStrm=0;
974  UInt uiTileCol      = 0;
975  UInt uiTileStartLCU = 0;
976  UInt uiTileLCUX     = 0;
977  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
978  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
979  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
980  if( depSliceSegmentsEnabled )
981  {
982    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
983    {
984      if( m_pcCfg->getWaveFrontsynchro() )
985      {
986        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
987        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
988        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
989        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
990        uiLin     = uiCUAddr / uiWidthInLCUs;
991        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
992          + uiLin%iNumSubstreamsPerTile;
993        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
994        {
995          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
996          uiCol     = uiCUAddr % uiWidthInLCUs;
997          if(uiCol==uiTileStartLCU)
998          {
999            CTXMem[0]->loadContexts(m_pcSbacCoder);
1000          }
1001        }
1002      }
1003      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1004      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1005    }
1006    else
1007    {
1008      if(m_pcCfg->getWaveFrontsynchro())
1009      {
1010        CTXMem[1]->loadContexts(m_pcSbacCoder);
1011      }
1012      CTXMem[0]->loadContexts(m_pcSbacCoder);
1013    }
1014  }
1015  // for every CU in slice
1016#if H_3D
1017  Int iLastPosY = -1;
1018#endif
1019  UInt uiEncCUOrder;
1020  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1021       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1022       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1023  {
1024    // initialize CU encoder
1025    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1026    pcCU->initCU( rpcPic, uiCUAddr );
1027#if H_3D_VSO
1028    if ( m_pcRdCost->getUseRenModel() )
1029    {
1030      // updated renderer model if necessary
1031      Int iCurPosX;
1032      Int iCurPosY; 
1033      pcCU->getPosInPic(0, iCurPosX, iCurPosY );
1034      if ( iCurPosY != iLastPosY )
1035      {
1036        iLastPosY = iCurPosY;         
1037        pcEncTop->setupRenModel( pcSlice->getPOC() , pcSlice->getViewIndex(), pcSlice->getIsDepth() ? 1 : 0, iCurPosY );
1038      }
1039    }
1040#endif
1041#if !RATE_CONTROL_LAMBDA_DOMAIN
1042    if(m_pcCfg->getUseRateCtrl())
1043    {
1044      if(m_pcRateCtrl->calculateUnitQP())
1045      {
1046        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
1047      }
1048    }
1049#endif
1050    // inherit from TR if necessary, select substream to use.
1051    if( m_pcCfg->getUseSBACRD() )
1052    {
1053      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1054      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1055      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1056      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1057      uiCol     = uiCUAddr % uiWidthInLCUs;
1058      uiLin     = uiCUAddr / uiWidthInLCUs;
1059      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1060      {
1061        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1062        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1063        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1064                      + uiLin%iNumSubstreamsPerTile;
1065      }
1066      else
1067      {
1068        // dependent tiles => substreams are "per frame".
1069        uiSubStrm = uiLin % iNumSubstreams;
1070      }
1071      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1072      {
1073        // We'll sync if the TR is available.
1074        TComDataCU *pcCUUp = pcCU->getCUAbove();
1075        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1076        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1077        TComDataCU *pcCUTR = NULL;
1078        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1079        {
1080          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1081        }
1082        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1083             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1084             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1085             )
1086           )
1087        {
1088          // TR not available.
1089        }
1090        else
1091        {
1092          // TR is available, we use it.
1093          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1094        }
1095      }
1096      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1097    }
1098
1099    // reset the entropy coder
1100    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1101        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1102        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1103        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1104    {
1105      SliceType sliceType = pcSlice->getSliceType();
1106      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1107      {
1108        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1109      }
1110      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1111      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1112      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1113      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1114    }
1115    // if RD based on SBAC is used
1116    if( m_pcCfg->getUseSBACRD() )
1117    {
1118      // set go-on entropy coder
1119      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1120      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1121     
1122      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1123
1124#if RATE_CONTROL_LAMBDA_DOMAIN
1125      Double oldLambda = m_pcRdCost->getLambda();
1126      if ( m_pcCfg->getUseRateCtrl() )
1127      {
1128        Int estQP        = pcSlice->getSliceQp();
1129        Double estLambda = -1.0;
1130        Double bpp       = -1.0;
1131
1132        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
1133        {
1134          estQP = pcSlice->getSliceQp();
1135        }
1136        else
1137        {
1138          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
1139          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1140          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1141          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1142
1143          m_pcRdCost->setLambda(estLambda);
1144        }
1145
1146        m_pcRateCtrl->setRCQP( estQP );
1147#if L0033_RC_BUGFIX
1148        pcCU->getSlice()->setSliceQpBase( estQP );
1149#endif
1150      }
1151#endif
1152
1153      // run CU encoder
1154      m_pcCuEncoder->compressCU( pcCU );
1155
1156#if RATE_CONTROL_LAMBDA_DOMAIN
1157      if ( m_pcCfg->getUseRateCtrl() )
1158      {
1159        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1160        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1161        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1162        Double MAD = (Double)SAD / (Double)(height * width);
1163        MAD = MAD * MAD;
1164        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1165
1166        Int actualQP        = g_RCInvalidQPValue;
1167        Double actualLambda = m_pcRdCost->getLambda();
1168        Int actualBits      = pcCU->getTotalBits();
1169        Int numberOfEffectivePixels    = 0;
1170        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1171        {
1172          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1173          {
1174            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1175            break;
1176          }
1177        }
1178
1179        if ( numberOfEffectivePixels == 0 )
1180        {
1181          actualQP = g_RCInvalidQPValue;
1182        }
1183        else
1184        {
1185          actualQP = pcCU->getQP( 0 );
1186        }
1187        m_pcRdCost->setLambda(oldLambda);
1188
1189        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1190      }
1191#endif
1192     
1193      // restore entropy coder to an initial stage
1194      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1195      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1196      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1197      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1198      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1199      m_pcBitCounter->resetBits();
1200      pppcRDSbacCoder->setBinsCoded( 0 );
1201      m_pcCuEncoder->encodeCU( pcCU );
1202
1203      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1204      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1205      {
1206        pcSlice->setNextSlice( true );
1207        break;
1208      }
1209      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1210      {
1211        pcSlice->setNextSliceSegment( true );
1212        break;
1213      }
1214      if( m_pcCfg->getUseSBACRD() )
1215      {
1216         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1217       
1218         //Store probabilties of second LCU in line into buffer
1219         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1220        {
1221          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1222        }
1223      }
1224    }
1225    // other case: encodeCU is not called
1226    else
1227    {
1228      m_pcCuEncoder->compressCU( pcCU );
1229      m_pcCuEncoder->encodeCU( pcCU );
1230      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1231      {
1232        pcSlice->setNextSlice( true );
1233        break;
1234      }
1235      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1236      {
1237        pcSlice->setNextSliceSegment( true );
1238        break;
1239      }
1240    }
1241   
1242    m_uiPicTotalBits += pcCU->getTotalBits();
1243    m_dPicRdCost     += pcCU->getTotalCost();
1244    m_uiPicDist      += pcCU->getTotalDistortion();
1245#if !RATE_CONTROL_LAMBDA_DOMAIN
1246    if(m_pcCfg->getUseRateCtrl())
1247    {
1248      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1249      m_pcRateCtrl->updataRCUnitStatus();
1250    }
1251#endif
1252  }
1253  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1254  {
1255    pcSlice->setNextSlice( true );
1256  }
1257  if( depSliceSegmentsEnabled )
1258  {
1259    if (m_pcCfg->getWaveFrontsynchro())
1260    {
1261      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1262    }
1263     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1264  }
1265  xRestoreWPparam( pcSlice );
1266#if !RATE_CONTROL_LAMBDA_DOMAIN
1267  if(m_pcCfg->getUseRateCtrl())
1268  {
1269    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1270  }
1271#endif
1272}
1273
1274/**
1275 \param  rpcPic        picture class
1276 \retval rpcBitstream  bitstream class
1277 */
1278Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1279{
1280  UInt       uiCUAddr;
1281  UInt       uiStartCUAddr;
1282  UInt       uiBoundingCUAddr;
1283  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1284
1285  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1286  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1287  // choose entropy coder
1288  {
1289    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1290    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1291  }
1292 
1293  m_pcCuEncoder->setBitCounter( NULL );
1294  m_pcBitCounter = NULL;
1295  // Appropriate substream bitstream is switched later.
1296  // for every CU
1297#if ENC_DEC_TRACE
1298  g_bJustDoIt = g_bEncDecTraceEnable;
1299#endif
1300  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1301  DTRACE_CABAC_T( "\tPOC: " );
1302  DTRACE_CABAC_V( rpcPic->getPOC() );
1303  DTRACE_CABAC_T( "\n" );
1304#if ENC_DEC_TRACE
1305  g_bJustDoIt = g_bEncDecTraceDisable;
1306#endif
1307
1308  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1309  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1310  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1311  UInt uiBitsOriginallyInSubstreams = 0;
1312  {
1313    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1314    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1315    {
1316      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1317    }
1318   
1319    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1320    {
1321      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1322    }
1323
1324    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1325    {
1326      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1327    }
1328  }
1329
1330  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1331  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1332  UInt uiTileCol      = 0;
1333  UInt uiTileStartLCU = 0;
1334  UInt uiTileLCUX     = 0;
1335  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1336  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1337                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1338                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1339  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1340  if( depSliceSegmentsEnabled )
1341  {
1342    if( pcSlice->isNextSlice()||
1343        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1344    {
1345      if(m_pcCfg->getWaveFrontsynchro())
1346      {
1347        CTXMem[1]->loadContexts(m_pcSbacCoder);
1348      }
1349      CTXMem[0]->loadContexts(m_pcSbacCoder);
1350    }
1351    else
1352    {
1353      if(m_pcCfg->getWaveFrontsynchro())
1354      {
1355        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1356        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1357        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1358        uiLin     = uiCUAddr / uiWidthInLCUs;
1359        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1360          + uiLin%iNumSubstreamsPerTile;
1361        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1362        {
1363          uiCol     = uiCUAddr % uiWidthInLCUs;
1364          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1365          if(uiCol==uiTileLCUX)
1366          {
1367            CTXMem[0]->loadContexts(m_pcSbacCoder);
1368          }
1369        }
1370      }
1371      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1372    }
1373  }
1374
1375  UInt uiEncCUOrder;
1376  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1377       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1378       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1379  {
1380    if( m_pcCfg->getUseSBACRD() )
1381    {
1382      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1383      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1384      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1385      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1386      uiCol     = uiCUAddr % uiWidthInLCUs;
1387      uiLin     = uiCUAddr / uiWidthInLCUs;
1388      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1389      {
1390        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1391        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1392        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1393                      + uiLin%iNumSubstreamsPerTile;
1394      }
1395      else
1396      {
1397        // dependent tiles => substreams are "per frame".
1398        uiSubStrm = uiLin % iNumSubstreams;
1399      }
1400
1401      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1402      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1403      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1404      {
1405        // We'll sync if the TR is available.
1406        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1407        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1408        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1409        TComDataCU *pcCUTR = NULL;
1410        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1411        {
1412          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1413        }
1414        if ( (true/*bEnforceSliceRestriction*/ &&
1415             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) || 
1416             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1417             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1418             ))
1419           )
1420        {
1421          // TR not available.
1422        }
1423        else
1424        {
1425          // TR is available, we use it.
1426          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1427        }
1428      }
1429      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1430    }
1431    // reset the entropy coder
1432    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1433        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1434        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1435        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1436    {
1437      {
1438        // We're crossing into another tile, tiles are independent.
1439        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1440        // have to perform it here.
1441        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1442        {
1443          ; // do nothing.
1444        }
1445        else
1446        {
1447          SliceType sliceType  = pcSlice->getSliceType();
1448          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1449          {
1450            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1451          }
1452          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1453          // Byte-alignment in slice_data() when new tile
1454          pcSubstreams[uiSubStrm].writeByteAlignment();
1455        }
1456      }
1457      {
1458        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1459        UInt uiAccumulatedSubstreamLength = 0;
1460        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1461        {
1462          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1463        }
1464        // add bits coded in previous dependent slices + bits coded so far
1465        // add number of emulation prevention byte count in the tile
1466        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1467      }
1468    }
1469
1470    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );   
1471    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1472    {
1473      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1474      Int iNumCuInWidth     = saoParam->numCuInWidth;
1475      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1476      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1477      Int rx = uiCUAddr % iNumCuInWidth;
1478      Int ry = uiCUAddr / iNumCuInWidth;
1479      Int allowMergeLeft = 1;
1480      Int allowMergeUp   = 1;
1481      if (rx!=0)
1482      {
1483        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1484        {
1485          allowMergeLeft = 0;
1486        }
1487      }
1488      if (ry!=0)
1489      {
1490        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1491        {
1492          allowMergeUp = 0;
1493        }
1494      }
1495      Int addr = pcCU->getAddr();
1496      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1497      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1498      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1499      {
1500        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1501        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1502        if (allowMergeLeft)
1503        {
1504          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft); 
1505        }
1506        else
1507        {
1508          mergeLeft = 0;
1509        }
1510        if(mergeLeft == 0)
1511        {
1512          if (allowMergeUp)
1513          {
1514            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1515          }
1516          else
1517          {
1518            mergeUp = 0;
1519          }
1520          if(mergeUp == 0)
1521          {
1522            for (Int compIdx=0;compIdx<3;compIdx++)
1523            {
1524            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1525              {
1526                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1527              }
1528            }
1529          }
1530        }
1531      }
1532    }
1533    else if (pcSlice->getSPS()->getUseSAO())
1534    {
1535      Int addr = pcCU->getAddr();
1536      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1537      for (Int cIdx=0; cIdx<3; cIdx++)
1538      {
1539        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1540        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1541        {
1542          saoLcuParam->mergeUpFlag   = 0;
1543          saoLcuParam->mergeLeftFlag = 0;
1544          saoLcuParam->subTypeIdx    = 0;
1545          saoLcuParam->typeIdx       = -1;
1546          saoLcuParam->offset[0]     = 0;
1547          saoLcuParam->offset[1]     = 0;
1548          saoLcuParam->offset[2]     = 0;
1549          saoLcuParam->offset[3]     = 0;
1550        }
1551      }
1552    }
1553#if ENC_DEC_TRACE
1554    g_bJustDoIt = g_bEncDecTraceEnable;
1555#endif
1556    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1557      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1558    {
1559      m_pcCuEncoder->encodeCU( pcCU );
1560    }
1561    else
1562    {
1563      m_pcCuEncoder->encodeCU( pcCU );
1564    }
1565#if ENC_DEC_TRACE
1566    g_bJustDoIt = g_bEncDecTraceDisable;
1567#endif   
1568    if( m_pcCfg->getUseSBACRD() )
1569    {
1570       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1571       
1572
1573       //Store probabilties of second LCU in line into buffer
1574       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1575      {
1576        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1577      }
1578    }
1579  }
1580  if( depSliceSegmentsEnabled )
1581  {
1582    if (m_pcCfg->getWaveFrontsynchro())
1583    {
1584      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1585    }
1586    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1587  }
1588#if ADAPTIVE_QP_SELECTION
1589  if( m_pcCfg->getUseAdaptQpSelect() )
1590  {
1591    m_pcTrQuant->storeSliceQpNext(pcSlice);
1592  }
1593#endif
1594  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1595  {
1596    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1597    {
1598      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1599    }
1600    else
1601    {
1602      m_pcEntropyCoder->determineCabacInitIdx();
1603    }
1604  }
1605}
1606
1607/** Determines the starting and bounding LCU address of current slice / dependent slice
1608 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1609 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1610 */
1611Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1612{
1613  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1614  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1615  UInt tileIdxIncrement;
1616  UInt tileIdx;
1617  UInt tileWidthInLcu;
1618  UInt tileHeightInLcu;
1619  UInt tileTotalCount;
1620
1621  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1622  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1623  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1624  if (bEncodeSlice) 
1625  {
1626    UInt uiCUAddrIncrement;
1627    switch (m_pcCfg->getSliceMode())
1628    {
1629    case FIXED_NUMBER_OF_LCU:
1630      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1631      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1632      break;
1633    case FIXED_NUMBER_OF_BYTES:
1634      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1635      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1636      break;
1637    case FIXED_NUMBER_OF_TILES:
1638      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1639        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1640        );
1641      uiCUAddrIncrement        = 0;
1642      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1643
1644      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1645      {
1646        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1647        {
1648          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1649          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1650          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1651        }
1652      }
1653
1654      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1655      break;
1656    default:
1657      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1658      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1659      break;
1660    } 
1661    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1662    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1663    {
1664      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1665    }
1666    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1667  }
1668  else
1669  {
1670    UInt uiCUAddrIncrement     ;
1671    switch (m_pcCfg->getSliceMode())
1672    {
1673    case FIXED_NUMBER_OF_LCU:
1674      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1675      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1676      break;
1677    case FIXED_NUMBER_OF_TILES:
1678      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1679        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1680        );
1681      uiCUAddrIncrement        = 0;
1682      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1683
1684      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1685      {
1686        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1687        {
1688          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1689          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1690          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1691        }
1692      }
1693
1694      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1695      break;
1696    default:
1697      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1698      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1699      break;
1700    } 
1701    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1702    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1703    {
1704      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1705    }
1706    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1707  }
1708
1709  Bool tileBoundary = false;
1710  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) && 
1711      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1712  {
1713    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1714    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1715    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1716    UInt tileBoundingCUAddrSlice = 0;
1717    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1718    {
1719      lcuEncAddr++;
1720      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1721    }
1722    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1723   
1724    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1725    {
1726      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1727      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1728      tileBoundary = true;
1729    }
1730  }
1731
1732  // Dependent slice
1733  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1734  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1735  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1736  if (bEncodeSlice) 
1737  {
1738    UInt uiCUAddrIncrement;
1739    switch (m_pcCfg->getSliceSegmentMode())
1740    {
1741    case FIXED_NUMBER_OF_LCU:
1742      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1743      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1744      break;
1745    case FIXED_NUMBER_OF_BYTES:
1746      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1747      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1748      break;
1749    case FIXED_NUMBER_OF_TILES:
1750      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1751        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1752        );
1753      uiCUAddrIncrement        = 0;
1754      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1755
1756      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1757      {
1758        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1759        {
1760          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1761          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1762          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1763        }
1764      }
1765      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1766      break;
1767    default:
1768      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1769      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1770      break;
1771    } 
1772    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1773    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1774    {
1775      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1776    }
1777    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1778  }
1779  else
1780  {
1781    UInt uiCUAddrIncrement;
1782    switch (m_pcCfg->getSliceSegmentMode())
1783    {
1784    case FIXED_NUMBER_OF_LCU:
1785      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1786      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1787      break;
1788    case FIXED_NUMBER_OF_TILES:
1789      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1790        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1791        );
1792      uiCUAddrIncrement        = 0;
1793      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1794
1795      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1796      {
1797        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1798        {
1799          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1800          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1801          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1802        }
1803      }
1804      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1805      break;
1806    default:
1807      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1808      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1809      break;
1810    } 
1811    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1812    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1813    {
1814      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1815    }
1816    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1817  }
1818  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) && 
1819    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1820  {
1821    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1822    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1823    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1824    UInt tileBoundingCUAddrSlice = 0;
1825    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1826    {
1827      lcuEncAddr++;
1828      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1829    }
1830    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1831
1832    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1833    {
1834      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1835      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1836      tileBoundary = true;
1837    }
1838  }
1839
1840  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1841  {
1842    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1843    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1844  }
1845
1846  //calculate real dependent slice start address
1847  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1848  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1849  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1850  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1851  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1852  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1853  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1854  {
1855    uiInternalAddress++;
1856    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1857    {
1858      uiInternalAddress=0;
1859      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1860    }
1861    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1862    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1863  }
1864  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1865 
1866  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
1867  startCUAddrSliceSegment=uiRealStartAddress;
1868 
1869  //calculate real slice start address
1870  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
1871  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
1872  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1873  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1874  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1875  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1876  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1877  {
1878    uiInternalAddress++;
1879    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1880    {
1881      uiInternalAddress=0;
1882      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1883    }
1884    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1885    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1886  }
1887  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
1888 
1889  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
1890  uiStartCUAddrSlice=uiRealStartAddress;
1891 
1892  // Make a joint decision based on reconstruction and dependent slice bounds
1893  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
1894  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
1895
1896
1897  if (!bEncodeSlice)
1898  {
1899    // 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
1900    // first. Set the flags accordingly.
1901    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1902      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1903      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
1904      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
1905      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
1906      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
1907      || tileBoundary
1908)
1909    {
1910      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1911      {
1912        pcSlice->setNextSlice       ( true );
1913        pcSlice->setNextSliceSegment( false );
1914      }
1915      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
1916      {
1917        pcSlice->setNextSlice       ( false );
1918        pcSlice->setNextSliceSegment( true );
1919      }
1920      else
1921      {
1922        pcSlice->setNextSlice       ( true );
1923        pcSlice->setNextSliceSegment( true );
1924      }
1925    }
1926    else
1927    {
1928      pcSlice->setNextSlice       ( false );
1929      pcSlice->setNextSliceSegment( false );
1930    }
1931  }
1932}
1933
1934Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1935{
1936  return 4.2005*log(lambda) + 13.7122;
1937}
1938
1939//! \}
Note: See TracBrowser for help on using the repository browser.