source: SHVCSoftware/branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 258

Last change on this file since 258 was 258, checked in by qualcomm, 11 years ago

Generic initialization of ActiveNumILRRefIdx and InterLayerPredLayerIdc.

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