source: 3DVCSoftware/branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncSlice.cpp @ 479

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