source: SHVCSoftware/branches/SHM-2.0-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 171

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

set VPS for a slice and derive NumDirectRefLayers

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