source: SHVCSoftware/branches/SHM-4.0-dev/source/Lib/TLibEncoder/TEncSlice.cpp @ 475

Last change on this file since 475 was 475, checked in by nokia, 11 years ago

Integrate auxiliary picture layers (JCTVC-O0041)

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