source: SHVCSoftware/branches/SHM-3.1-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 427

Last change on this file since 427 was 401, checked in by sony, 11 years ago

TEMP_SCALABILITY_FIX: encoder fix to handle temporal scalability configuration

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