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

Last change on this file was 431, checked in by seregin, 11 years ago

initial porting of HM12

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