source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncSlice.cpp @ 191

Last change on this file since 191 was 191, checked in by seregin, 12 years ago

unix2dos for *.cpp and *.h

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