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

Last change on this file since 757 was 493, checked in by seregin, 11 years ago

fix ILP WP parameters derivation to be from the BL reference layer

  • Property svn:eol-style set to native
File size: 82.3 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    estimateILWpParam( pcSlice );   
953  }
954#endif
955
956  Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
957
958  if ( bWp_explicit )
959  {
960    //------------------------------------------------------------------------------
961    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
962    //------------------------------------------------------------------------------
963    if ( pcSlice->getSliceMode()==2 || pcSlice->getSliceSegmentMode()==2 )
964    {
965      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
966    }
967
968    xEstimateWPParamSlice( pcSlice );
969    pcSlice->initWpScaling();
970
971    // check WP on/off
972    xCheckWPEnable( pcSlice );
973  }
974
975#if ADAPTIVE_QP_SELECTION
976  if( m_pcCfg->getUseAdaptQpSelect() )
977  {
978    m_pcTrQuant->clearSliceARLCnt();
979    if(pcSlice->getSliceType()!=I_SLICE)
980    {
981      Int qpBase = pcSlice->getSliceQpBase();
982      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
983    }
984  }
985#endif
986  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
987  TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
988  TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
989  Int  iNumSubstreams = 1;
990  UInt uiTilesAcross  = 0;
991
992  if( m_pcCfg->getUseSBACRD() )
993  {
994    iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
995    uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
996    delete[] m_pcBufferSbacCoders;
997    delete[] m_pcBufferBinCoderCABACs;
998    m_pcBufferSbacCoders     = new TEncSbac    [uiTilesAcross];
999    m_pcBufferBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
1000    for (Int ui = 0; ui < uiTilesAcross; ui++)
1001    {
1002      m_pcBufferSbacCoders[ui].init( &m_pcBufferBinCoderCABACs[ui] );
1003    }
1004    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1005    {
1006      m_pcBufferSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
1007    }
1008
1009    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) //init all sbac coders for RD optimization
1010    {
1011      ppppcRDSbacCoders[ui][0][CI_CURR_BEST]->load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
1012    }
1013  }
1014  //if( m_pcCfg->getUseSBACRD() )
1015  {
1016    delete[] m_pcBufferLowLatSbacCoders;
1017    delete[] m_pcBufferLowLatBinCoderCABACs;
1018    m_pcBufferLowLatSbacCoders     = new TEncSbac    [uiTilesAcross];
1019    m_pcBufferLowLatBinCoderCABACs = new TEncBinCABAC[uiTilesAcross];
1020    for (Int ui = 0; ui < uiTilesAcross; ui++)
1021    {
1022      m_pcBufferLowLatSbacCoders[ui].init( &m_pcBufferLowLatBinCoderCABACs[ui] );
1023    }
1024    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1025      m_pcBufferLowLatSbacCoders[ui].load(m_pppcRDSbacCoder[0][CI_CURR_BEST]);  //init. state
1026  }
1027  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1028  //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
1029  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1030  UInt uiTileCol      = 0;
1031  UInt uiTileStartLCU = 0;
1032  UInt uiTileLCUX     = 0;
1033
1034  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1035  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
1036  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1037  if( depSliceSegmentsEnabled )
1038  {
1039    if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
1040    {
1041      if( m_pcCfg->getWaveFrontsynchro() )
1042      {
1043        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1044        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1045        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1046        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
1047        uiLin     = uiCUAddr / uiWidthInLCUs;
1048        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap(uiCUAddr))*iNumSubstreamsPerTile
1049          + uiLin%iNumSubstreamsPerTile;
1050        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1051        {
1052          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1053          uiCol     = uiCUAddr % uiWidthInLCUs;
1054          if(uiCol==uiTileStartLCU)
1055          {
1056            CTXMem[0]->loadContexts(m_pcSbacCoder);
1057          }
1058        }
1059      }
1060      m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1061      ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
1062    }
1063    else
1064    {
1065      if(m_pcCfg->getWaveFrontsynchro())
1066      {
1067        CTXMem[1]->loadContexts(m_pcSbacCoder);
1068      }
1069      CTXMem[0]->loadContexts(m_pcSbacCoder);
1070    }
1071  }
1072  // for every CU in slice
1073  UInt uiEncCUOrder;
1074  for( uiEncCUOrder = uiStartCUAddr/rpcPic->getNumPartInCU();
1075       uiEncCUOrder < (uiBoundingCUAddr+(rpcPic->getNumPartInCU()-1))/rpcPic->getNumPartInCU();
1076       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1077  {
1078    // initialize CU encoder
1079    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1080    pcCU->initCU( rpcPic, uiCUAddr );
1081
1082#if !RATE_CONTROL_LAMBDA_DOMAIN
1083    if(m_pcCfg->getUseRateCtrl())
1084    {
1085      if(m_pcRateCtrl->calculateUnitQP())
1086      {
1087        xLamdaRecalculation(m_pcRateCtrl->getUnitQP(), m_pcRateCtrl->getGOPId(), pcSlice->getDepth(), pcSlice->getSliceType(), pcSlice->getSPS(), pcSlice );
1088      }
1089    }
1090#endif
1091    // inherit from TR if necessary, select substream to use.
1092    if( m_pcCfg->getUseSBACRD() )
1093    {
1094      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1095      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1096      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1097      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1098      uiCol     = uiCUAddr % uiWidthInLCUs;
1099      uiLin     = uiCUAddr / uiWidthInLCUs;
1100      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1101      {
1102        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1103        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1104        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1105                      + uiLin%iNumSubstreamsPerTile;
1106      }
1107      else
1108      {
1109        // dependent tiles => substreams are "per frame".
1110        uiSubStrm = uiLin % iNumSubstreams;
1111      }
1112      if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1113      {
1114        // We'll sync if the TR is available.
1115        TComDataCU *pcCUUp = pcCU->getCUAbove();
1116        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1117        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1118        TComDataCU *pcCUTR = NULL;
1119        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1120        {
1121          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1122        }
1123        if ( ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||
1124             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1125             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1126             )
1127           )
1128        {
1129          // TR not available.
1130        }
1131        else
1132        {
1133          // TR is available, we use it.
1134          ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1135        }
1136      }
1137      m_pppcRDSbacCoder[0][CI_CURR_BEST]->load( ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST] ); //this load is used to simplify the code
1138    }
1139
1140    // reset the entropy coder
1141    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1142        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1143        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1144        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1145    {
1146      SliceType sliceType = pcSlice->getSliceType();
1147      if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1148      {
1149        sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1150      }
1151      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp(), false );
1152      m_pcEntropyCoder->setEntropyCoder     ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1153      m_pcEntropyCoder->updateContextTables ( sliceType, pcSlice->getSliceQp() );
1154      m_pcEntropyCoder->setEntropyCoder     ( m_pcSbacCoder, pcSlice );
1155    }
1156    // if RD based on SBAC is used
1157    if( m_pcCfg->getUseSBACRD() )
1158    {
1159      // set go-on entropy coder
1160      m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
1161      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1162
1163      ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
1164
1165#if RATE_CONTROL_LAMBDA_DOMAIN
1166      Double oldLambda = m_pcRdCost->getLambda();
1167      if ( m_pcCfg->getUseRateCtrl() )
1168      {
1169        Int estQP        = pcSlice->getSliceQp();
1170        Double estLambda = -1.0;
1171        Double bpp       = -1.0;
1172
1173#if M0036_RC_IMPROVEMENT
1174        if ( ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
1175#else
1176        if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE || !m_pcCfg->getLCULevelRC() )
1177#endif
1178        {
1179          estQP = pcSlice->getSliceQp();
1180        }
1181        else
1182        {
1183#if RATE_CONTROL_INTRA
1184          bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
1185          if ( rpcPic->getSlice( 0 )->getSliceType() == I_SLICE)
1186          {
1187            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
1188          }
1189          else
1190          {
1191            estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1192            estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1193          }
1194#else
1195          bpp       = m_pcRateCtrl->getRCPic()->getLCUTargetBpp();
1196          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
1197          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
1198#endif
1199
1200#if REPN_FORMAT_IN_VPS
1201          estQP     = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, estQP );
1202#else
1203          estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, estQP );
1204#endif
1205
1206          m_pcRdCost->setLambda(estLambda);
1207#if M0036_RC_IMPROVEMENT
1208#if RDOQ_CHROMA_LAMBDA
1209          // set lambda for RDOQ
1210          Double weight=m_pcRdCost->getChromaWeight();
1211          m_pcTrQuant->setLambda( estLambda, estLambda / weight );
1212#else
1213          m_pcTrQuant->setLambda( estLambda );
1214#endif
1215#endif
1216        }
1217
1218        m_pcRateCtrl->setRCQP( estQP );
1219        pcCU->getSlice()->setSliceQpBase( estQP );
1220      }
1221#endif
1222
1223      // run CU encoder
1224      m_pcCuEncoder->compressCU( pcCU );
1225
1226#if !TICKET_1090_FIX
1227#if RATE_CONTROL_LAMBDA_DOMAIN
1228      if ( m_pcCfg->getUseRateCtrl() )
1229      {
1230#if !M0036_RC_IMPROVEMENT
1231        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1232#if REPN_FORMAT_IN_VPS
1233        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1234        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->>getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1235#else
1236        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1237        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1238#endif
1239        Double MAD = (Double)SAD / (Double)(height * width);
1240        MAD = MAD * MAD;
1241        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1242#endif
1243
1244        Int actualQP        = g_RCInvalidQPValue;
1245        Double actualLambda = m_pcRdCost->getLambda();
1246        Int actualBits      = pcCU->getTotalBits();
1247        Int numberOfEffectivePixels    = 0;
1248        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1249        {
1250          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1251          {
1252            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1253            break;
1254          }
1255        }
1256
1257        if ( numberOfEffectivePixels == 0 )
1258        {
1259          actualQP = g_RCInvalidQPValue;
1260        }
1261        else
1262        {
1263          actualQP = pcCU->getQP( 0 );
1264        }
1265        m_pcRdCost->setLambda(oldLambda);
1266#if RATE_CONTROL_INTRA
1267        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
1268          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1269#else
1270        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1271#endif
1272      }
1273#endif
1274#endif
1275
1276      // restore entropy coder to an initial stage
1277      m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
1278      m_pcEntropyCoder->setBitstream( &pcBitCounters[uiSubStrm] );
1279      m_pcCuEncoder->setBitCounter( &pcBitCounters[uiSubStrm] );
1280      m_pcBitCounter = &pcBitCounters[uiSubStrm];
1281      pppcRDSbacCoder->setBinCountingEnableFlag( true );
1282      m_pcBitCounter->resetBits();
1283      pppcRDSbacCoder->setBinsCoded( 0 );
1284      m_pcCuEncoder->encodeCU( pcCU );
1285
1286      pppcRDSbacCoder->setBinCountingEnableFlag( false );
1287      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits() + m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1288      {
1289        pcSlice->setNextSlice( true );
1290        break;
1291      }
1292      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+m_pcEntropyCoder->getNumberOfWrittenBits() > (m_pcCfg->getSliceSegmentArgument() << 3) &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1293      {
1294        pcSlice->setNextSliceSegment( true );
1295        break;
1296      }
1297      if( m_pcCfg->getUseSBACRD() )
1298      {
1299         ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
1300
1301         //Store probabilties of second LCU in line into buffer
1302         if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
1303        {
1304          m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
1305        }
1306      }
1307
1308#if TICKET_1090_FIX
1309#if RATE_CONTROL_LAMBDA_DOMAIN
1310      if ( m_pcCfg->getUseRateCtrl() )
1311      {
1312#if !M0036_RC_IMPROVEMENT
1313        UInt SAD    = m_pcCuEncoder->getLCUPredictionSAD();
1314#if REPN_FORMAT_IN_VPS
1315        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1316        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1317#else
1318        Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - uiCUAddr / rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUHeight() );
1319        Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - uiCUAddr % rpcPic->getFrameWidthInCU() * pcSlice->getSPS()->getMaxCUWidth() );
1320#endif
1321        Double MAD = (Double)SAD / (Double)(height * width);
1322        MAD = MAD * MAD;
1323        ( m_pcRateCtrl->getRCPic()->getLCU(uiCUAddr) ).m_MAD = MAD;
1324#endif
1325
1326        Int actualQP        = g_RCInvalidQPValue;
1327        Double actualLambda = m_pcRdCost->getLambda();
1328        Int actualBits      = pcCU->getTotalBits();
1329        Int numberOfEffectivePixels    = 0;
1330        for ( Int idx = 0; idx < rpcPic->getNumPartInCU(); idx++ )
1331        {
1332          if ( pcCU->getPredictionMode( idx ) != MODE_NONE && ( !pcCU->isSkipped( idx ) ) )
1333          {
1334            numberOfEffectivePixels = numberOfEffectivePixels + 16;
1335            break;
1336          }
1337        }
1338
1339        if ( numberOfEffectivePixels == 0 )
1340        {
1341          actualQP = g_RCInvalidQPValue;
1342        }
1343        else
1344        {
1345          actualQP = pcCU->getQP( 0 );
1346        }
1347        m_pcRdCost->setLambda(oldLambda);
1348
1349#if RATE_CONTROL_INTRA
1350        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
1351          pcCU->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1352#else
1353        m_pcRateCtrl->getRCPic()->updateAfterLCU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda, m_pcCfg->getLCULevelRC() );
1354#endif
1355      }
1356#endif
1357#endif
1358    }
1359    // other case: encodeCU is not called
1360    else
1361    {
1362      m_pcCuEncoder->compressCU( pcCU );
1363      m_pcCuEncoder->encodeCU( pcCU );
1364      if (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_BYTES && ( ( pcSlice->getSliceBits()+ m_pcEntropyCoder->getNumberOfWrittenBits() ) ) > m_pcCfg->getSliceArgument()<<3)
1365      {
1366        pcSlice->setNextSlice( true );
1367        break;
1368      }
1369      if (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+ m_pcEntropyCoder->getNumberOfWrittenBits()> m_pcCfg->getSliceSegmentArgument()<<3 &&pcSlice->getSliceCurEndCUAddr()!=pcSlice->getSliceSegmentCurEndCUAddr())
1370      {
1371        pcSlice->setNextSliceSegment( true );
1372        break;
1373      }
1374    }
1375
1376    m_uiPicTotalBits += pcCU->getTotalBits();
1377    m_dPicRdCost     += pcCU->getTotalCost();
1378    m_uiPicDist      += pcCU->getTotalDistortion();
1379#if !RATE_CONTROL_LAMBDA_DOMAIN
1380    if(m_pcCfg->getUseRateCtrl())
1381    {
1382      m_pcRateCtrl->updateLCUData(pcCU, pcCU->getTotalBits(), pcCU->getQP(0));
1383      m_pcRateCtrl->updataRCUnitStatus();
1384    }
1385#endif
1386  }
1387  if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
1388  {
1389    pcSlice->setNextSlice( true );
1390  }
1391  if( depSliceSegmentsEnabled )
1392  {
1393    if (m_pcCfg->getWaveFrontsynchro())
1394    {
1395      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1396    }
1397     CTXMem[0]->loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1398  }
1399  xRestoreWPparam( pcSlice );
1400#if !RATE_CONTROL_LAMBDA_DOMAIN
1401  if(m_pcCfg->getUseRateCtrl())
1402  {
1403    m_pcRateCtrl->updateFrameData(m_uiPicTotalBits);
1404  }
1405#endif
1406}
1407
1408/**
1409 \param  rpcPic        picture class
1410 \retval rpcBitstream  bitstream class
1411 */
1412Void TEncSlice::encodeSlice   ( TComPic*& rpcPic, TComOutputBitstream* pcSubstreams )
1413{
1414  UInt       uiCUAddr;
1415  UInt       uiStartCUAddr;
1416  UInt       uiBoundingCUAddr;
1417  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1418
1419  uiStartCUAddr=pcSlice->getSliceSegmentCurStartCUAddr();
1420  uiBoundingCUAddr=pcSlice->getSliceSegmentCurEndCUAddr();
1421  // choose entropy coder
1422  {
1423    m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1424    m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1425  }
1426
1427  m_pcCuEncoder->setBitCounter( NULL );
1428  m_pcBitCounter = NULL;
1429  // Appropriate substream bitstream is switched later.
1430  // for every CU
1431#if ENC_DEC_TRACE
1432  g_bJustDoIt = g_bEncDecTraceEnable;
1433#endif
1434  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1435  DTRACE_CABAC_T( "\tPOC: " );
1436  DTRACE_CABAC_V( rpcPic->getPOC() );
1437  DTRACE_CABAC_T( "\n" );
1438#if ENC_DEC_TRACE
1439  g_bJustDoIt = g_bEncDecTraceDisable;
1440#endif
1441
1442  TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
1443  TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
1444  Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1445  UInt uiBitsOriginallyInSubstreams = 0;
1446  {
1447    UInt uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
1448    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1449    {
1450      m_pcBufferSbacCoders[ui].load(m_pcSbacCoder); //init. state
1451    }
1452
1453    for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1454    {
1455      uiBitsOriginallyInSubstreams += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1456    }
1457
1458    for (UInt ui = 0; ui < uiTilesAcross; ui++)
1459    {
1460      m_pcBufferLowLatSbacCoders[ui].load(m_pcSbacCoder);  //init. state
1461    }
1462  }
1463
1464  UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
1465  UInt uiCol=0, uiLin=0, uiSubStrm=0;
1466  UInt uiTileCol      = 0;
1467  UInt uiTileStartLCU = 0;
1468  UInt uiTileLCUX     = 0;
1469  Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1470  uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());  /* for tiles, uiStartCUAddr is NOT the real raster scan address, it is actually
1471                                                                                               an encoding order index, so we need to convert the index (uiStartCUAddr)
1472                                                                                               into the real raster scan address (uiCUAddr) via the CUOrderMap */
1473  uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1474  if( depSliceSegmentsEnabled )
1475  {
1476    if( pcSlice->isNextSlice()||
1477        uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
1478    {
1479      if(m_pcCfg->getWaveFrontsynchro())
1480      {
1481        CTXMem[1]->loadContexts(m_pcSbacCoder);
1482      }
1483      CTXMem[0]->loadContexts(m_pcSbacCoder);
1484    }
1485    else
1486    {
1487      if(m_pcCfg->getWaveFrontsynchro())
1488      {
1489        uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
1490        m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
1491        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1492        uiLin     = uiCUAddr / uiWidthInLCUs;
1493        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(rpcPic->getPicSym()->getCUOrderMap( uiCUAddr))*iNumSubstreamsPerTile
1494          + uiLin%iNumSubstreamsPerTile;
1495        if ( (uiCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
1496        {
1497          uiCol     = uiCUAddr % uiWidthInLCUs;
1498          uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1499          if(uiCol==uiTileLCUX)
1500          {
1501            CTXMem[0]->loadContexts(m_pcSbacCoder);
1502          }
1503        }
1504      }
1505      pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
1506    }
1507  }
1508
1509  UInt uiEncCUOrder;
1510  for( uiEncCUOrder = uiStartCUAddr /rpcPic->getNumPartInCU();
1511       uiEncCUOrder < (uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1512       uiCUAddr = rpcPic->getPicSym()->getCUOrderMap(++uiEncCUOrder) )
1513  {
1514    if( m_pcCfg->getUseSBACRD() )
1515    {
1516      uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
1517      uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
1518      uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
1519      //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
1520      uiCol     = uiCUAddr % uiWidthInLCUs;
1521      uiLin     = uiCUAddr / uiWidthInLCUs;
1522      if (pcSlice->getPPS()->getNumSubstreams() > 1)
1523      {
1524        // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
1525        Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
1526        uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)*iNumSubstreamsPerTile
1527                      + uiLin%iNumSubstreamsPerTile;
1528      }
1529      else
1530      {
1531        // dependent tiles => substreams are "per frame".
1532        uiSubStrm = uiLin % iNumSubstreams;
1533      }
1534
1535      m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1536      // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
1537      if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
1538      {
1539        // We'll sync if the TR is available.
1540        TComDataCU *pcCUUp = rpcPic->getCU( uiCUAddr )->getCUAbove();
1541        UInt uiWidthInCU = rpcPic->getFrameWidthInCU();
1542        UInt uiMaxParts = 1<<(pcSlice->getSPS()->getMaxCUDepth()<<1);
1543        TComDataCU *pcCUTR = NULL;
1544        if ( pcCUUp && ((uiCUAddr%uiWidthInCU+1) < uiWidthInCU)  )
1545        {
1546          pcCUTR = rpcPic->getCU( uiCUAddr - uiWidthInCU + 1 );
1547        }
1548        if ( (true/*bEnforceSliceRestriction*/ &&
1549             ((pcCUTR==NULL) || (pcCUTR->getSlice()==NULL) ||
1550             (pcCUTR->getSCUAddr()+uiMaxParts-1 < pcSlice->getSliceCurStartCUAddr()) ||
1551             ((rpcPic->getPicSym()->getTileIdxMap( pcCUTR->getAddr() ) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr)))
1552             ))
1553           )
1554        {
1555          // TR not available.
1556        }
1557        else
1558        {
1559          // TR is available, we use it.
1560          pcSbacCoders[uiSubStrm].loadContexts( &m_pcBufferSbacCoders[uiTileCol] );
1561        }
1562      }
1563      m_pcSbacCoder->load(&pcSbacCoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to m_pcSbacCoder)
1564    }
1565    // reset the entropy coder
1566    if( uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr() &&                                   // must be first CU of tile
1567        uiCUAddr!=0 &&                                                                                                                                    // cannot be first CU of picture
1568        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceSegmentCurStartCUAddr())/rpcPic->getNumPartInCU() &&
1569        uiCUAddr!=rpcPic->getPicSym()->getPicSCUAddr(rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getSliceCurStartCUAddr())/rpcPic->getNumPartInCU())     // cannot be first CU of slice
1570    {
1571      {
1572        // We're crossing into another tile, tiles are independent.
1573        // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
1574        // have to perform it here.
1575        if (pcSlice->getPPS()->getNumSubstreams() > 1)
1576        {
1577          ; // do nothing.
1578        }
1579        else
1580        {
1581          SliceType sliceType  = pcSlice->getSliceType();
1582          if (!pcSlice->isIntra() && pcSlice->getPPS()->getCabacInitPresentFlag() && pcSlice->getPPS()->getEncCABACTableIdx()!=I_SLICE)
1583          {
1584            sliceType = (SliceType) pcSlice->getPPS()->getEncCABACTableIdx();
1585          }
1586          m_pcEntropyCoder->updateContextTables( sliceType, pcSlice->getSliceQp() );
1587          // Byte-alignment in slice_data() when new tile
1588          pcSubstreams[uiSubStrm].writeByteAlignment();
1589        }
1590      }
1591      {
1592        UInt numStartCodeEmulations = pcSubstreams[uiSubStrm].countStartCodeEmulations();
1593        UInt uiAccumulatedSubstreamLength = 0;
1594        for (Int iSubstrmIdx=0; iSubstrmIdx < iNumSubstreams; iSubstrmIdx++)
1595        {
1596          uiAccumulatedSubstreamLength += pcSubstreams[iSubstrmIdx].getNumberOfWrittenBits();
1597        }
1598        // add bits coded in previous dependent slices + bits coded so far
1599        // add number of emulation prevention byte count in the tile
1600        pcSlice->addTileLocation( ((pcSlice->getTileOffstForMultES() + uiAccumulatedSubstreamLength - uiBitsOriginallyInSubstreams) >> 3) + numStartCodeEmulations );
1601      }
1602    }
1603
1604    TComDataCU*& pcCU = rpcPic->getCU( uiCUAddr );
1605    if ( pcSlice->getSPS()->getUseSAO() && (pcSlice->getSaoEnabledFlag()||pcSlice->getSaoEnabledFlagChroma()) )
1606    {
1607      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1608      Int iNumCuInWidth     = saoParam->numCuInWidth;
1609      Int iCUAddrInSlice    = uiCUAddr - rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceCurStartCUAddr()/rpcPic->getNumPartInCU());
1610      Int iCUAddrUpInSlice  = iCUAddrInSlice - iNumCuInWidth;
1611      Int rx = uiCUAddr % iNumCuInWidth;
1612      Int ry = uiCUAddr / iNumCuInWidth;
1613      Int allowMergeLeft = 1;
1614      Int allowMergeUp   = 1;
1615      if (rx!=0)
1616      {
1617        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-1) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1618        {
1619          allowMergeLeft = 0;
1620        }
1621      }
1622      if (ry!=0)
1623      {
1624        if (rpcPic->getPicSym()->getTileIdxMap(uiCUAddr-iNumCuInWidth) != rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))
1625        {
1626          allowMergeUp = 0;
1627        }
1628      }
1629      Int addr = pcCU->getAddr();
1630      allowMergeLeft = allowMergeLeft && (rx>0) && (iCUAddrInSlice!=0);
1631      allowMergeUp = allowMergeUp && (ry>0) && (iCUAddrUpInSlice>=0);
1632      if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
1633      {
1634        Int mergeLeft = saoParam->saoLcuParam[0][addr].mergeLeftFlag;
1635        Int mergeUp = saoParam->saoLcuParam[0][addr].mergeUpFlag;
1636        if (allowMergeLeft)
1637        {
1638          m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeLeft);
1639        }
1640        else
1641        {
1642          mergeLeft = 0;
1643        }
1644        if(mergeLeft == 0)
1645        {
1646          if (allowMergeUp)
1647          {
1648            m_pcEntropyCoder->m_pcEntropyCoderIf->codeSaoMerge(mergeUp);
1649          }
1650          else
1651          {
1652            mergeUp = 0;
1653          }
1654          if(mergeUp == 0)
1655          {
1656            for (Int compIdx=0;compIdx<3;compIdx++)
1657            {
1658            if( (compIdx == 0 && saoParam->bSaoFlag[0]) || (compIdx > 0 && saoParam->bSaoFlag[1]))
1659              {
1660                m_pcEntropyCoder->encodeSaoOffset(&saoParam->saoLcuParam[compIdx][addr], compIdx);
1661              }
1662            }
1663          }
1664        }
1665      }
1666    }
1667    else if (pcSlice->getSPS()->getUseSAO())
1668    {
1669      Int addr = pcCU->getAddr();
1670      SAOParam *saoParam = pcSlice->getPic()->getPicSym()->getSaoParam();
1671      for (Int cIdx=0; cIdx<3; cIdx++)
1672      {
1673        SaoLcuParam *saoLcuParam = &(saoParam->saoLcuParam[cIdx][addr]);
1674        if ( ((cIdx == 0) && !pcSlice->getSaoEnabledFlag()) || ((cIdx == 1 || cIdx == 2) && !pcSlice->getSaoEnabledFlagChroma()))
1675        {
1676          saoLcuParam->mergeUpFlag   = 0;
1677          saoLcuParam->mergeLeftFlag = 0;
1678          saoLcuParam->subTypeIdx    = 0;
1679          saoLcuParam->typeIdx       = -1;
1680          saoLcuParam->offset[0]     = 0;
1681          saoLcuParam->offset[1]     = 0;
1682          saoLcuParam->offset[2]     = 0;
1683          saoLcuParam->offset[3]     = 0;
1684        }
1685      }
1686    }
1687#if ENC_DEC_TRACE
1688    g_bJustDoIt = g_bEncDecTraceEnable;
1689#endif
1690    if ( (m_pcCfg->getSliceMode()!=0 || m_pcCfg->getSliceSegmentMode()!=0) &&
1691      uiCUAddr == rpcPic->getPicSym()->getCUOrderMap((uiBoundingCUAddr+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU()-1) )
1692    {
1693      m_pcCuEncoder->encodeCU( pcCU );
1694    }
1695    else
1696    {
1697      m_pcCuEncoder->encodeCU( pcCU );
1698    }
1699#if ENC_DEC_TRACE
1700    g_bJustDoIt = g_bEncDecTraceDisable;
1701#endif
1702    if( m_pcCfg->getUseSBACRD() )
1703    {
1704       pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
1705
1706
1707       //Store probabilties of second LCU in line into buffer
1708       if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
1709      {
1710        m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
1711      }
1712    }
1713  }
1714  if( depSliceSegmentsEnabled )
1715  {
1716    if (m_pcCfg->getWaveFrontsynchro())
1717    {
1718      CTXMem[1]->loadContexts( &m_pcBufferSbacCoders[uiTileCol] );//ctx 2.LCU
1719    }
1720    CTXMem[0]->loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1721  }
1722#if ADAPTIVE_QP_SELECTION
1723  if( m_pcCfg->getUseAdaptQpSelect() )
1724  {
1725    m_pcTrQuant->storeSliceQpNext(pcSlice);
1726  }
1727#endif
1728  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1729  {
1730    if  (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1731    {
1732      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1733    }
1734    else
1735    {
1736      m_pcEntropyCoder->determineCabacInitIdx();
1737    }
1738  }
1739}
1740
1741/** Determines the starting and bounding LCU address of current slice / dependent slice
1742 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1743 * \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address
1744 */
1745Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice )
1746{
1747  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx());
1748  UInt uiStartCUAddrSlice, uiBoundingCUAddrSlice;
1749  UInt tileIdxIncrement;
1750  UInt tileIdx;
1751  UInt tileWidthInLcu;
1752  UInt tileHeightInLcu;
1753  UInt tileTotalCount;
1754
1755  uiStartCUAddrSlice        = pcSlice->getSliceCurStartCUAddr();
1756  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame();
1757  uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame;
1758  if (bEncodeSlice)
1759  {
1760    UInt uiCUAddrIncrement;
1761    switch (m_pcCfg->getSliceMode())
1762    {
1763    case FIXED_NUMBER_OF_LCU:
1764      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1765      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1766      break;
1767    case FIXED_NUMBER_OF_BYTES:
1768      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1769      uiBoundingCUAddrSlice    = pcSlice->getSliceCurEndCUAddr();
1770      break;
1771    case FIXED_NUMBER_OF_TILES:
1772      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1773        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1774        );
1775      uiCUAddrIncrement        = 0;
1776      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1777
1778      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1779      {
1780        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1781        {
1782          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1783          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1784          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1785        }
1786      }
1787
1788      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1789      break;
1790    default:
1791      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1792      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1793      break;
1794    }
1795    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1796    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1797    {
1798      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1799    }
1800    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1801  }
1802  else
1803  {
1804    UInt uiCUAddrIncrement     ;
1805    switch (m_pcCfg->getSliceMode())
1806    {
1807    case FIXED_NUMBER_OF_LCU:
1808      uiCUAddrIncrement        = m_pcCfg->getSliceArgument();
1809      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1810      break;
1811    case FIXED_NUMBER_OF_TILES:
1812      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1813        rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/rpcPic->getNumPartInCU())
1814        );
1815      uiCUAddrIncrement        = 0;
1816      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1817
1818      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceArgument(); tileIdxIncrement++)
1819      {
1820        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1821        {
1822          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1823          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1824          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1825        }
1826      }
1827
1828      uiBoundingCUAddrSlice    = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU()) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1829      break;
1830    default:
1831      uiCUAddrIncrement        = rpcPic->getNumCUsInFrame();
1832      uiBoundingCUAddrSlice    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1833      break;
1834    }
1835    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1836    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1837    {
1838      uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1839    }
1840    pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1841  }
1842
1843  Bool tileBoundary = false;
1844  if ((m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_BYTES) &&
1845      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1846  {
1847    UInt lcuEncAddr = (uiStartCUAddrSlice+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1848    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1849    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1850    UInt tileBoundingCUAddrSlice = 0;
1851    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1852    {
1853      lcuEncAddr++;
1854      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1855    }
1856    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1857
1858    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice)
1859    {
1860      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice;
1861      pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice );
1862      tileBoundary = true;
1863    }
1864  }
1865
1866  // Dependent slice
1867  UInt startCUAddrSliceSegment, boundingCUAddrSliceSegment;
1868  startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr();
1869  boundingCUAddrSliceSegment = uiNumberOfCUsInFrame;
1870  if (bEncodeSlice)
1871  {
1872    UInt uiCUAddrIncrement;
1873    switch (m_pcCfg->getSliceSegmentMode())
1874    {
1875    case FIXED_NUMBER_OF_LCU:
1876      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1877      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1878      break;
1879    case FIXED_NUMBER_OF_BYTES:
1880      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1881      boundingCUAddrSliceSegment    = pcSlice->getSliceSegmentCurEndCUAddr();
1882      break;
1883    case FIXED_NUMBER_OF_TILES:
1884      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1885        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1886        );
1887      uiCUAddrIncrement        = 0;
1888      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1889
1890      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1891      {
1892        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1893        {
1894          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1895          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1896          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1897        }
1898      }
1899      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1900      break;
1901    default:
1902      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1903      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1904      break;
1905    }
1906    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1907    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1908    {
1909      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1910    }
1911    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1912  }
1913  else
1914  {
1915    UInt uiCUAddrIncrement;
1916    switch (m_pcCfg->getSliceSegmentMode())
1917    {
1918    case FIXED_NUMBER_OF_LCU:
1919      uiCUAddrIncrement               = m_pcCfg->getSliceSegmentArgument();
1920      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1921      break;
1922    case FIXED_NUMBER_OF_TILES:
1923      tileIdx                = rpcPic->getPicSym()->getTileIdxMap(
1924        rpcPic->getPicSym()->getCUOrderMap(pcSlice->getSliceSegmentCurStartCUAddr()/rpcPic->getNumPartInCU())
1925        );
1926      uiCUAddrIncrement        = 0;
1927      tileTotalCount         = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1);
1928
1929      for(tileIdxIncrement = 0; tileIdxIncrement < m_pcCfg->getSliceSegmentArgument(); tileIdxIncrement++)
1930      {
1931        if((tileIdx + tileIdxIncrement) < tileTotalCount)
1932        {
1933          tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth();
1934          tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight();
1935          uiCUAddrIncrement += (tileWidthInLcu * tileHeightInLcu * rpcPic->getNumPartInCU());
1936        }
1937      }
1938      boundingCUAddrSliceSegment    = ((startCUAddrSliceSegment + uiCUAddrIncrement) < uiNumberOfCUsInFrame*rpcPic->getNumPartInCU() ) ? (startCUAddrSliceSegment + uiCUAddrIncrement) : uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1939      break;
1940    default:
1941      uiCUAddrIncrement               = rpcPic->getNumCUsInFrame();
1942      boundingCUAddrSliceSegment    = uiNumberOfCUsInFrame*rpcPic->getNumPartInCU();
1943      break;
1944    }
1945    // WPP: if a slice segment does not start at the beginning of a CTB row, it must end within the same CTB row
1946    if (pcSlice->getPPS()->getNumSubstreams() > 1 && (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()) != 0))
1947    {
1948      boundingCUAddrSliceSegment = min(boundingCUAddrSliceSegment, startCUAddrSliceSegment - (startCUAddrSliceSegment % (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU())) + (rpcPic->getFrameWidthInCU()*rpcPic->getNumPartInCU()));
1949    }
1950    pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1951  }
1952  if ((m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_LCU || m_pcCfg->getSliceSegmentMode() == FIXED_NUMBER_OF_BYTES) &&
1953    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1954  {
1955    UInt lcuEncAddr = (startCUAddrSliceSegment+rpcPic->getNumPartInCU()-1)/rpcPic->getNumPartInCU();
1956    UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1957    UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr);
1958    UInt tileBoundingCUAddrSlice = 0;
1959    while (lcuEncAddr < uiNumberOfCUsInFrame && rpcPic->getPicSym()->getTileIdxMap(lcuAddr) == startTileIdx)
1960    {
1961      lcuEncAddr++;
1962      lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddr);
1963    }
1964    tileBoundingCUAddrSlice = lcuEncAddr*rpcPic->getNumPartInCU();
1965
1966    if (tileBoundingCUAddrSlice < boundingCUAddrSliceSegment)
1967    {
1968      boundingCUAddrSliceSegment = tileBoundingCUAddrSlice;
1969      pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment );
1970      tileBoundary = true;
1971    }
1972  }
1973
1974  if(boundingCUAddrSliceSegment>uiBoundingCUAddrSlice)
1975  {
1976    boundingCUAddrSliceSegment = uiBoundingCUAddrSlice;
1977    pcSlice->setSliceSegmentCurEndCUAddr(uiBoundingCUAddrSlice);
1978  }
1979
1980  //calculate real dependent slice start address
1981  UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) % rpcPic->getNumPartInCU();
1982  UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()) / rpcPic->getNumPartInCU();
1983  UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1984  UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1985#if REPN_FORMAT_IN_VPS
1986  UInt uiWidth = pcSlice->getPicWidthInLumaSamples();
1987  UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
1988#else
1989  UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1990  UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1991#endif
1992  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
1993  {
1994    uiInternalAddress++;
1995    if(uiInternalAddress>=rpcPic->getNumPartInCU())
1996    {
1997      uiInternalAddress=0;
1998      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1999    }
2000    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2001    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2002  }
2003  UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
2004
2005  pcSlice->setSliceSegmentCurStartCUAddr(uiRealStartAddress);
2006  startCUAddrSliceSegment=uiRealStartAddress;
2007
2008  //calculate real slice start address
2009  uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) % rpcPic->getNumPartInCU();
2010  uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceCurStartCUAddr()) / rpcPic->getNumPartInCU();
2011  uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2012  uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2013#if REPN_FORMAT_IN_VPS
2014  uiWidth = pcSlice->getPicWidthInLumaSamples();
2015  uiHeight = pcSlice->getPicHeightInLumaSamples();
2016#else
2017  uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
2018  uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
2019#endif
2020  while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight))
2021  {
2022    uiInternalAddress++;
2023    if(uiInternalAddress>=rpcPic->getNumPartInCU())
2024    {
2025      uiInternalAddress=0;
2026      uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
2027    }
2028    uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2029    uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2030  }
2031  uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*rpcPic->getNumPartInCU()+uiInternalAddress);
2032
2033  pcSlice->setSliceCurStartCUAddr(uiRealStartAddress);
2034  uiStartCUAddrSlice=uiRealStartAddress;
2035
2036  // Make a joint decision based on reconstruction and dependent slice bounds
2037  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   );
2038  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment);
2039
2040
2041  if (!bEncodeSlice)
2042  {
2043    // 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
2044    // first. Set the flags accordingly.
2045    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2046      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2047      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0)
2048      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU)
2049      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0)
2050      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0)
2051      || tileBoundary
2052)
2053    {
2054      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment)
2055      {
2056        pcSlice->setNextSlice       ( true );
2057        pcSlice->setNextSliceSegment( false );
2058      }
2059      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment)
2060      {
2061        pcSlice->setNextSlice       ( false );
2062        pcSlice->setNextSliceSegment( true );
2063      }
2064      else
2065      {
2066        pcSlice->setNextSlice       ( true );
2067        pcSlice->setNextSliceSegment( true );
2068      }
2069    }
2070    else
2071    {
2072      pcSlice->setNextSlice       ( false );
2073      pcSlice->setNextSliceSegment( false );
2074    }
2075  }
2076}
2077
2078Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
2079{
2080  return 4.2005*log(lambda) + 13.7122;
2081}
2082
2083#if JCTVC_M0259_LAMBDAREFINEMENT
2084Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
2085{
2086  double tmp = beta * pow( 2.0 , deltaQP / 6 );
2087  double gamma = tmp / ( tmp + 1 );
2088  return( gamma );
2089}
2090#endif
2091#if O0194_WEIGHTED_PREDICTION_CGS
2092Void TEncSlice::estimateILWpParam( TComSlice* pcSlice )
2093{
2094  xCalcACDCParamSlice(pcSlice);
2095  wpACDCParam * temp_weightACDCParam;
2096
2097  pcSlice->getWpAcDcParam(temp_weightACDCParam);
2098  g_refWeightACDCParam = (void *) temp_weightACDCParam;
2099}
2100#endif
2101//! \}
Note: See TracBrowser for help on using the repository browser.