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

Last change on this file since 1165 was 1128, checked in by seregin, 9 years ago

macro cleanup: HIGHER_LAYER_IRAP_SKIP_FLAG, HIGHER_LAYER_IRAP_SKIP_FLAG (keep it for encoder only)

  • Property svn:eol-style set to native
File size: 50.3 KB
RevLine 
[313]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
[494]4 * granted under this license.
[313]5 *
[595]6 * Copyright (c) 2010-2014, ITU/ISO/IEC
[313]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;
[494]53
[313]54  m_pdRdPicLambda = NULL;
55  m_pdRdPicQp     = NULL;
56  m_piRdPicQp     = NULL;
57}
58
59TEncSlice::~TEncSlice()
60{
61}
62
[494]63Void TEncSlice::create( Int iWidth, Int iHeight, ChromaFormat chromaFormat, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
64{
65  // create prediction picture
66  if ( m_apcPicYuvPred == NULL )
67  {
68    m_apcPicYuvPred  = new TComPicYuv;
69    m_apcPicYuvPred->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
70  }
71
72  // create residual picture
73  if( m_apcPicYuvResi == NULL )
74  {
75    m_apcPicYuvResi  = new TComPicYuv;
76    m_apcPicYuvResi->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
77  }
78}
79
[313]80Void TEncSlice::destroy()
81{
82  // destroy prediction picture
83  if ( m_apcPicYuvPred )
84  {
85    m_apcPicYuvPred->destroy();
86    delete m_apcPicYuvPred;
87    m_apcPicYuvPred  = NULL;
88  }
[494]89
[313]90  // destroy residual picture
91  if ( m_apcPicYuvResi )
92  {
93    m_apcPicYuvResi->destroy();
94    delete m_apcPicYuvResi;
95    m_apcPicYuvResi  = NULL;
96  }
[494]97
[313]98  // free lambda and QP arrays
99  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
100  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
101  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
102}
103
104Void TEncSlice::init( TEncTop* pcEncTop )
105{
106  m_pcCfg             = pcEncTop;
107  m_pcListPic         = pcEncTop->getListPic();
108#if SVC_EXTENSION
109  m_ppcTEncTop        = pcEncTop->getLayerEnc();
[494]110#endif
[313]111  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
112  m_pcCuEncoder       = pcEncTop->getCuEncoder();
113  m_pcPredSearch      = pcEncTop->getPredSearch();
[494]114
[313]115  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
116  m_pcSbacCoder       = pcEncTop->getSbacCoder();
117  m_pcBinCABAC        = pcEncTop->getBinCABAC();
118  m_pcTrQuant         = pcEncTop->getTrQuant();
[494]119
[313]120  m_pcRdCost          = pcEncTop->getRdCost();
121  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
122  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
[494]123
[313]124  // create lambda and QP arrays
125  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
126  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
127  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
128  m_pcRateCtrl        = pcEncTop->getRateCtrl();
129}
130
[1029]131
132
133Void
134#if JCTVC_M0259_LAMBDAREFINEMENT
135TEncSlice::setUpLambda(TComSlice* slice, Double dLambda, Int iQP, Int depth)
136#else
137TEncSlice::setUpLambda(TComSlice* slice, const Double dLambda, Int iQP)
138#endif
139{
140#if JCTVC_M0259_LAMBDAREFINEMENT
[1065]141  Int layerIdx = slice->getLayerIdx();
142
143  if( slice->getLayerId() > 0 && m_ppcTEncTop[layerIdx]->getNumActiveRefLayers() && depth >= 3 && m_pcCfg->getGOPSize() == ( 1 << depth ) )
[1029]144  {
[1062]145    UInt prevLayerIdx = 0; 
[1065]146    if( m_ppcTEncTop[layerIdx]->getNumActiveRefLayers() > 0 )
[1062]147    {
148      prevLayerIdx = m_ppcTEncTop[layerIdx]->getPredLayerIdx( m_ppcTEncTop[layerIdx]->getNumActiveRefLayers() - 1);
149    }
[1065]150
[1057]151    Double gamma = xCalEnhLambdaFactor( m_ppcTEncTop[prevLayerIdx]->getQP() - m_ppcTEncTop[layerIdx]->getQP() ,
[1065]152                                        1.0 * m_ppcTEncTop[layerIdx]->getSourceWidth() * m_ppcTEncTop[layerIdx]->getSourceHeight()
153                                        / m_ppcTEncTop[prevLayerIdx]->getSourceWidth() / m_ppcTEncTop[prevLayerIdx]->getSourceHeight() );
154
[1029]155    dLambda *= gamma;
156  }
157#endif
158
159  // store lambda
160  m_pcRdCost ->setLambda( dLambda );
161
162  // for RDO
163  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
164  Double dLambdas[MAX_NUM_COMPONENT] = { dLambda };
165  for(UInt compIdx=1; compIdx<MAX_NUM_COMPONENT; compIdx++)
166  {
167    const ComponentID compID=ComponentID(compIdx);
168    Int chromaQPOffset = slice->getPPS()->getQpOffset(compID) + slice->getSliceChromaQpDelta(compID);
169    Int qpc=(iQP + chromaQPOffset < 0) ? iQP : getScaledChromaQP(iQP + chromaQPOffset, m_pcCfg->getChromaFormatIdc());
170    Double tmpWeight = pow( 2.0, (iQP-qpc)/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
171
172#if JCTVC_M0259_LAMBDAREFINEMENT
[1057]173    if( slice->getLayerId() > 0 && m_ppcTEncTop[slice->getLayerIdx()]->getNumActiveRefLayers() && m_pcCfg->getGOPSize() >= 8 && slice->isIntra() == false && depth == 0 )
[1029]174    {
175      dLambdas[0] = dLambda * 1.1;
176      m_pcRdCost->setLambda( dLambdas[0] );
177
178      m_pcRdCost->setDistortionWeight(compID, tmpWeight * 1.15);
179      dLambdas[compIdx] = dLambdas[0] / tmpWeight / 1.15;
180    }
181    else
182    {
183#endif
184    m_pcRdCost->setDistortionWeight(compID, tmpWeight);
185    dLambdas[compIdx]=dLambda/tmpWeight;
186#if JCTVC_M0259_LAMBDAREFINEMENT
187    }
188#endif
189  }
190
191#if RDOQ_CHROMA_LAMBDA
192// for RDOQ
193  m_pcTrQuant->setLambdas( dLambdas );
194#else
195  m_pcTrQuant->setLambda( dLambda );
196#endif
197
198// For SAO
199  slice   ->setLambdas( dLambdas );
200}
201
202
203
[313]204/**
205 - non-referenced frame marking
206 - QP computation based on temporal structure
207 - lambda computation based on QP
208 - set temporal layer ID and the parameter sets
209 .
210 \param pcPic         picture class
[1029]211 \param pocLast      POC of last picture
212 \param pocCurr     current POC
[313]213 \param iNumPicRcvd   number of received pictures
214 \param iTimeOffset   POC offset for hierarchical structure
215 \param iDepth        temporal layer depth
216 \param rpcSlice      slice header class
217 \param pSPS          SPS associated with the slice
218 \param pPPS          PPS associated with the slice
219 */
220#if SVC_EXTENSION
221//\param vps          VPS associated with the slice
[442]222Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, TComVPS *vps, Bool isField )
[313]223#else
[442]224Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, TComSPS* pSPS, TComPPS *pPPS, Bool isField )
[313]225#endif
226{
227  Double dQP;
228  Double dLambda;
[494]229
[313]230  rpcSlice = pcPic->getSlice(0);
231  rpcSlice->setSPS( pSPS );
232  rpcSlice->setPPS( pPPS );
233  rpcSlice->setSliceBits(0);
234  rpcSlice->setPic( pcPic );
235#if SVC_EXTENSION
236  UInt layerId = pcPic->getLayerId();
237  rpcSlice->setVPS( vps );
238  rpcSlice->initSlice( layerId );
239#else
240  rpcSlice->initSlice();
241#endif
242  rpcSlice->setPicOutputFlag( true );
243  rpcSlice->setPOC( pocCurr );
[494]244
[313]245  // depth computation based on GOP size
246  Int depth;
247  {
[713]248    Int poc = rpcSlice->getPOC();
249    if(isField)
250    {
[1029]251      poc = (poc/2) % (m_pcCfg->getGOPSize()/2);
[713]252    }
253    else
254    {
[1029]255      poc = poc % m_pcCfg->getGOPSize();   
[713]256    }
[1029]257
[313]258    if ( poc == 0 )
259    {
260      depth = 0;
261    }
262    else
263    {
264      Int step = m_pcCfg->getGOPSize();
265      depth    = 0;
266      for( Int i=step>>1; i>=1; i>>=1 )
267      {
268        for ( Int j=i; j<m_pcCfg->getGOPSize(); j+=step )
269        {
270          if ( j == poc )
271          {
272            i=0;
273            break;
274          }
275        }
276        step >>= 1;
277        depth++;
278      }
279    }
[1029]280
[713]281#if HARMONIZE_GOP_FIRST_FIELD_COUPLE
282    if(poc != 0)
283    {
284#endif
[1029]285      if (isField && ((rpcSlice->getPOC() % 2) == 1))
286      {
287        depth ++;
288      }
289#if HARMONIZE_GOP_FIRST_FIELD_COUPLE
[713]290    }
291#endif
292  }
[494]293
[313]294  // slice type
295  SliceType eSliceType;
[494]296
[313]297  eSliceType=B_SLICE;
[713]298#if EFFICIENT_FIELD_IRAP
299  if(!(isField && pocLast == 1))
300  {
301#endif // EFFICIENT_FIELD_IRAP
302#if ALLOW_RECOVERY_POINT_AS_RAP
[1029]303    if(m_pcCfg->getDecodingRefreshType() == 3)
304    {
305      eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0             || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
306    }
307    else
308    {
[713]309#endif
[1029]310      eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
311#if ALLOW_RECOVERY_POINT_AS_RAP
312    }
313#endif
[713]314#if EFFICIENT_FIELD_IRAP
315  }
316#endif
[494]317
[313]318  rpcSlice->setSliceType    ( eSliceType );
[494]319
[313]320  // ------------------------------------------------------------------------------------------------------------------
321  // Non-referenced frame marking
322  // ------------------------------------------------------------------------------------------------------------------
[494]323
[313]324  if(pocLast == 0)
325  {
326    rpcSlice->setTemporalLayerNonReferenceFlag(false);
327  }
328  else
329  {
330    rpcSlice->setTemporalLayerNonReferenceFlag(!m_pcCfg->getGOPEntry(iGOPid).m_refPic);
331  }
332  rpcSlice->setReferenced(true);
[494]333
[313]334  // ------------------------------------------------------------------------------------------------------------------
335  // QP setting
336  // ------------------------------------------------------------------------------------------------------------------
[494]337
[313]338  dQP = m_pcCfg->getQP();
339  if(eSliceType!=I_SLICE)
340  {
[442]341#if REPN_FORMAT_IN_VPS
[595]342    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getQpBDOffsetY() ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
[442]343#else
[1029]344    if (!(( m_pcCfg->getMaxDeltaQP() == 0 ) && (dQP == -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA) ) && (rpcSlice->getPPS()->getTransquantBypassEnableFlag())))
[442]345#endif
[313]346    {
347      dQP += m_pcCfg->getGOPEntry(iGOPid).m_QPOffset;
348    }
349  }
[494]350
[313]351  // modify QP
352  Int* pdQPs = m_pcCfg->getdQPs();
353  if ( pdQPs )
354  {
355    dQP += pdQPs[ rpcSlice->getPOC() ];
356  }
[1029]357
358  if (m_pcCfg->getCostMode()==COST_LOSSLESS_CODING)
359  {
360    dQP=LOSSLESS_AND_MIXED_LOSSLESS_RD_COST_TEST_QP;
361    m_pcCfg->setDeltaQpRD(0);
362  }
363
[313]364  // ------------------------------------------------------------------------------------------------------------------
365  // Lambda computation
366  // ------------------------------------------------------------------------------------------------------------------
[494]367
[313]368  Int iQP;
369  Double dOrigQP = dQP;
370
371  // pre-compute lambda and QP values for all possible QP candidates
372  for ( Int iDQpIdx = 0; iDQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; iDQpIdx++ )
373  {
374    // compute QP value
375    dQP = dOrigQP + ((iDQpIdx+1)>>1)*(iDQpIdx%2 ? -1 : 1);
[494]376
[313]377    // compute lambda value
378    Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
379    Int    SHIFT_QP = 12;
[442]380
381    Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) );
382
[313]383#if FULL_NBIT
[1029]384    Int    bitdepth_luma_qp_scale = 6 * (g_bitDepth[CHANNEL_TYPE_LUMA] - 8);
[313]385#else
386    Int    bitdepth_luma_qp_scale = 0;
387#endif
388    Double qp_temp = (Double) dQP + bitdepth_luma_qp_scale - SHIFT_QP;
389#if FULL_NBIT
390    Double qp_temp_orig = (Double) dQP - SHIFT_QP;
391#endif
392    // Case #1: I or P-slices (key-frame)
393    Double dQPFactor = m_pcCfg->getGOPEntry(iGOPid).m_QPFactor;
394    if ( eSliceType==I_SLICE )
395    {
396      dQPFactor=0.57*dLambda_scale;
397    }
398    dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
399
400    if ( depth>0 )
401    {
402#if FULL_NBIT
403        dLambda *= Clip3( 2.00, 4.00, (qp_temp_orig / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
404#else
405        dLambda *= Clip3( 2.00, 4.00, (qp_temp / 6.0) ); // (j == B_SLICE && p_cur_frm->layer != 0 )
406#endif
407    }
[494]408
[313]409    // if hadamard is used in ME process
410    if ( !m_pcCfg->getUseHADME() && rpcSlice->getSliceType( ) != I_SLICE )
411    {
412      dLambda *= 0.95;
413    }
[494]414
[442]415#if REPN_FORMAT_IN_VPS
416    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
417#else
[1029]418    iQP = max( -pSPS->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
[442]419#endif
[313]420
421    m_pdRdPicLambda[iDQpIdx] = dLambda;
422    m_pdRdPicQp    [iDQpIdx] = dQP;
423    m_piRdPicQp    [iDQpIdx] = iQP;
424  }
[494]425
[313]426  // obtain dQP = 0 case
427  dLambda = m_pdRdPicLambda[0];
428  dQP     = m_pdRdPicQp    [0];
429  iQP     = m_piRdPicQp    [0];
[494]430
[313]431  if( rpcSlice->getSliceType( ) != I_SLICE )
432  {
433    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
434  }
435
436#if JCTVC_M0259_LAMBDAREFINEMENT
[1029]437  setUpLambda(rpcSlice, dLambda, iQP, depth);
[313]438#else
[1029]439  setUpLambda(rpcSlice, dLambda, iQP);
[313]440#endif
441#if HB_LAMBDA_FOR_LDC
442  // restore original slice type
[1029]443
[713]444#if EFFICIENT_FIELD_IRAP
445  if(!(isField && pocLast == 1))
446  {
447#endif // EFFICIENT_FIELD_IRAP
448#if ALLOW_RECOVERY_POINT_AS_RAP
[1029]449    if(m_pcCfg->getDecodingRefreshType() == 3)
450    {
451      eSliceType = (pocLast == 0 || (pocCurr)                     % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
452    }
453    else
454    {
[713]455#endif
[1029]456      eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
457#if ALLOW_RECOVERY_POINT_AS_RAP
458    }
459#endif
[713]460#if EFFICIENT_FIELD_IRAP
461  }
462#endif // EFFICIENT_FIELD_IRAP
[494]463
[442]464#if SVC_EXTENSION
[540]465  if( m_pcCfg->getLayerId() > 0 && m_pcCfg->getNumActiveRefLayers() > 0 )
[313]466  {
467    eSliceType=B_SLICE;
468  }
469#endif
470  rpcSlice->setSliceType        ( eSliceType );
471#endif
[494]472
[313]473  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
474  {
475    dQP = xGetQPValueAccordingToLambda( dLambda );
[442]476#if REPN_FORMAT_IN_VPS
[494]477    iQP = max( -rpcSlice->getQpBDOffsetY(), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
[442]478#else
[1029]479    iQP = max( -pSPS->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
[442]480#endif
[313]481  }
482
[1029]483  rpcSlice->setSliceQp           ( iQP );
[313]484#if ADAPTIVE_QP_SELECTION
[1029]485  rpcSlice->setSliceQpBase       ( iQP );
[313]486#endif
[1029]487  rpcSlice->setSliceQpDelta      ( 0 );
488  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
489  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
490  rpcSlice->setUseChromaQpAdj( pPPS->getChromaQpAdjTableSize() > 0 );
[313]491  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
492  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
[494]493
[313]494  if ( m_pcCfg->getDeblockingFilterMetric() )
495  {
496    rpcSlice->setDeblockingFilterOverrideFlag(true);
497    rpcSlice->setDeblockingFilterDisable(false);
498    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
499    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
[1029]500  }
501  else if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
[313]502  {
503    rpcSlice->getPPS()->setDeblockingFilterOverrideEnabledFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
504    rpcSlice->setDeblockingFilterOverrideFlag( !m_pcCfg->getLoopFilterOffsetInPPS() );
505    rpcSlice->getPPS()->setPicDisableDeblockingFilterFlag( m_pcCfg->getLoopFilterDisable() );
506    rpcSlice->setDeblockingFilterDisable( m_pcCfg->getLoopFilterDisable() );
507    if ( !rpcSlice->getDeblockingFilterDisable())
508    {
509      if ( !m_pcCfg->getLoopFilterOffsetInPPS() && eSliceType!=I_SLICE)
510      {
511        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset() );
512        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
513        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
514        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
515      }
516      else
517      {
[1029]518        rpcSlice->getPPS()->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
519        rpcSlice->getPPS()->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
520        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
521        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
[313]522      }
523    }
524  }
525  else
526  {
527    rpcSlice->setDeblockingFilterOverrideFlag( false );
528    rpcSlice->setDeblockingFilterDisable( false );
529    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
530    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
531  }
532
533  rpcSlice->setDepth            ( depth );
[494]534
[313]535  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
536  if(eSliceType==I_SLICE)
537  {
538    pcPic->setTLayer(0);
539  }
540  rpcSlice->setTLayer( pcPic->getTLayer() );
541
542  assert( m_apcPicYuvPred );
543  assert( m_apcPicYuvResi );
[494]544
[313]545  pcPic->setPicYuvPred( m_apcPicYuvPred );
546  pcPic->setPicYuvResi( m_apcPicYuvResi );
547  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
548  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
549  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
550  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
551  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
[1128]552
[540]553#if HIGHER_LAYER_IRAP_SKIP_FLAG
[1128]554  if( m_pcCfg->getSkipPictureAtArcSwitch() && m_pcCfg->getAdaptiveResolutionChange() > 0 && rpcSlice->getLayerId() == 1 && rpcSlice->getPOC() == m_pcCfg->getAdaptiveResolutionChange() )
[540]555  {
556    rpcSlice->setMaxNumMergeCand        ( 1 );
557  }
558#endif
[1128]559
[313]560  xStoreWPparam( pPPS->getUseWP(), pPPS->getWPBiPred() );
561
[442]562#if SVC_EXTENSION
[313]563  if( layerId > 0 )
564  {
565    if( rpcSlice->getNumILRRefIdx() > 0 )
566    {
[1057]567      rpcSlice->setActiveNumILRRefIdx( m_ppcTEncTop[rpcSlice->getVPS()->getLayerIdxInVps(layerId)]->getNumActiveRefLayers() );
[313]568      for( Int i = 0; i < rpcSlice->getActiveNumILRRefIdx(); i++ )
569      {
[1057]570        rpcSlice->setInterLayerPredLayerIdc( m_ppcTEncTop[rpcSlice->getVPS()->getLayerIdxInVps(layerId)]->getPredLayerIdx(i), i );
[313]571      }
572      rpcSlice->setInterLayerPredEnabledFlag(1);
573    }
[1057]574    rpcSlice->setMFMEnabledFlag(m_ppcTEncTop[rpcSlice->getVPS()->getLayerIdxInVps(layerId)]->getMFMEnabledFlag());
[313]575  }
576
577#endif
578}
579
580Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
581{
582  TComSlice* slice = pic->getSlice(0);
583
584  // store lambda
585  slice->setSliceQp( sliceQP );
[713]586#if ADAPTIVE_QP_SELECTION
[313]587  slice->setSliceQpBase ( sliceQP );
[713]588#endif
[1029]589  setUpLambda(slice, lambda, sliceQP);
590}
[313]591
592// ====================================================================================================================
593// Public member functions
594// ====================================================================================================================
595
596Void TEncSlice::setSearchRange( TComSlice* pcSlice )
597{
598  Int iCurrPOC = pcSlice->getPOC();
599  Int iRefPOC;
600  Int iGOPSize = m_pcCfg->getGOPSize();
601  Int iOffset = (iGOPSize >> 1);
602  Int iMaxSR = m_pcCfg->getSearchRange();
603  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
[494]604
[313]605  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
606  {
607    //RefPicList e = (RefPicList)iDir;
608    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
609    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
610    {
611      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
612      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
613      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
614    }
615  }
616}
617
618/**
619 - multi-loop slice encoding for different slice QP
620 .
621 \param rpcPic    picture class
622 */
[1029]623Void TEncSlice::precompressSlice( TComPic* pcPic )
[313]624{
625  // if deltaQP RD is not used, simply return
626  if ( m_pcCfg->getDeltaQpRD() == 0 )
627  {
628    return;
629  }
630
631  if ( m_pcCfg->getUseRateCtrl() )
632  {
633    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
634    assert(0);
635  }
[494]636
[1029]637  TComSlice* pcSlice        = pcPic->getSlice(getSliceIdx());
[313]638  Double     dPicRdCostBest = MAX_DOUBLE;
639  UInt       uiQpIdxBest = 0;
[494]640
[313]641  Double dFrameLambda;
642#if FULL_NBIT
[1029]643  Int    SHIFT_QP = 12 + 6 * (g_bitDepth[CHANNEL_TYPE_LUMA] - 8);
[313]644#else
645  Int    SHIFT_QP = 12;
646#endif
[494]647
[313]648  // set frame lambda
649  if (m_pcCfg->getGOPSize() > 1)
650  {
651    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
652  }
653  else
654  {
655    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
656  }
657  m_pcRdCost      ->setFrameLambda(dFrameLambda);
[494]658
[1029]659  const UInt initialSliceQp=pcSlice->getSliceQp();
[313]660  // for each QP candidate
661  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
662  {
663    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
664#if ADAPTIVE_QP_SELECTION
665    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
666#endif
[1029]667    setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdx], m_piRdPicQp    [uiQpIdx]);
[313]668
669    // try compress
[1029]670    compressSlice   ( pcPic );
[494]671
[313]672    Double dPicRdCost;
673    UInt64 uiPicDist        = m_uiPicDist;
[1029]674    // TODO: will this work if multiple slices are being used? There may not be any reconstruction data yet.
675    //       Will this also be ideal if a byte-restriction is placed on the slice?
676    //         - what if the last CTU was sometimes included, sometimes not, and that had all the distortion?
677    m_pcGOPEncoder->preLoopFilterPicAll( pcPic, uiPicDist );
[494]678
[313]679    // compute RD cost and choose the best
[1029]680    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits, uiPicDist, true, DF_SSE_FRAME);
[494]681
[313]682    if ( dPicRdCost < dPicRdCostBest )
683    {
684      uiQpIdxBest    = uiQpIdx;
685      dPicRdCostBest = dPicRdCost;
686    }
687  }
[494]688
[1029]689  if (pcSlice->getDependentSliceSegmentFlag() && initialSliceQp!=m_piRdPicQp[uiQpIdxBest] )
690  {
691    // TODO: this won't work with dependent slices: they do not have their own QP.
692    fprintf(stderr,"ERROR - attempt to change QP for a dependent slice-segment, having already coded the slice\n");
693    assert(pcSlice->getDependentSliceSegmentFlag()==false || initialSliceQp==m_piRdPicQp[uiQpIdxBest]);
694  }
[313]695  // set best values
696  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
697#if ADAPTIVE_QP_SELECTION
698  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
699#endif
[1029]700  setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdxBest], m_piRdPicQp    [uiQpIdxBest]);
[313]701}
702
[1029]703Void TEncSlice::calCostSliceI(TComPic* pcPic)
[313]704{
[1029]705  UInt    ctuRsAddr;
706  UInt    startCtuTsAddr;
707  UInt    boundingCtuTsAddr;
708  Int     iSumHad, shift = g_bitDepth[CHANNEL_TYPE_LUMA]-8, offset = (shift>0)?(1<<(shift-1)):0;;
[313]709  Double  iSumHadSlice = 0;
710
[1029]711  pcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
712  TComSlice* pcSlice            = pcPic->getSlice(getSliceIdx());
713  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic, false );
[313]714
[1029]715  UInt ctuTsAddr;
716  ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
717  for( ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(++ctuTsAddr) )
[313]718  {
719    // initialize CU encoder
[1029]720    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
721    pCtu->initCtu( pcPic, ctuRsAddr );
[313]722
[442]723#if REPN_FORMAT_IN_VPS
[1029]724    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - ctuRsAddr / pcPic->getFrameWidthInCtus() * pcSlice->getSPS()->getMaxCUHeight() );
725    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getPicWidthInLumaSamples() - ctuRsAddr % pcPic->getFrameWidthInCtus() * pcSlice->getSPS()->getMaxCUWidth() );
[442]726#else
[1029]727    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - ctuRsAddr / pcPic->getFrameWidthInCtus() * pcSlice->getSPS()->getMaxCUHeight() );
728    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - ctuRsAddr % pcPic->getFrameWidthInCtus() * pcSlice->getSPS()->getMaxCUWidth() );
[442]729#endif
[313]730
[1029]731    iSumHad = m_pcCuEncoder->updateCtuDataISlice(pCtu, width, height);
[313]732
[1029]733    (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra=(iSumHad+offset)>>shift;
734    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra;
[313]735
736  }
737  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
738}
739
[1029]740/** \param rpcPic   picture class
741 */
742Void TEncSlice::compressSlice( TComPic* pcPic )
[313]743{
[1029]744  UInt   startCtuTsAddr;
745  UInt   boundingCtuTsAddr;
746  TComSlice* pcSlice            = pcPic->getSlice(getSliceIdx());
747  pcSlice->setSliceSegmentBits(0);
748  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic, false );
[494]749
[1029]750  // initialize cost values - these are used by precompressSlice (they should be parameters).
[313]751  m_uiPicTotalBits  = 0;
[1029]752  m_dPicRdCost      = 0; // NOTE: This is a write-only variable!
[313]753  m_uiPicDist       = 0;
[494]754
[1029]755  m_pcEntropyCoder->setEntropyCoder   ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
[595]756  m_pcEntropyCoder->resetEntropy      ();
[1029]757
758  TEncBinCABAC* pRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
759  pRDSbacCoder->setBinCountingEnableFlag( false );
760  pRDSbacCoder->setBinsCoded( 0 );
761
762  TComBitCounter  tempBitCounter;
763  const UInt      frameWidthInCtus = pcPic->getPicSym()->getFrameWidthInCtus();
764
[313]765  //------------------------------------------------------------------------------
766  //  Weighted Prediction parameters estimation.
767  //------------------------------------------------------------------------------
768  // calculate AC/DC values for current picture
769  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
770  {
771    xCalcACDCParamSlice(pcSlice);
772  }
[494]773#if O0194_WEIGHTED_PREDICTION_CGS
[1057]774  else if( m_ppcTEncTop[pcSlice->getLayerIdx()]->getInterLayerWeightedPredFlag() )
[494]775  {
776    // Calculate for the base layer to be used in EL as Inter layer reference
777    estimateILWpParam( pcSlice );   
778  }
779#endif
[313]780
[1029]781  const Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
[313]782
783  if ( bWp_explicit )
784  {
785    //------------------------------------------------------------------------------
786    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
787    //------------------------------------------------------------------------------
[1029]788    if ( pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES || pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES )
[313]789    {
790      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
791    }
792
793    xEstimateWPParamSlice( pcSlice );
794    pcSlice->initWpScaling();
795
796    // check WP on/off
797    xCheckWPEnable( pcSlice );
798  }
799
800#if ADAPTIVE_QP_SELECTION
[1029]801  if( m_pcCfg->getUseAdaptQpSelect() && !(pcSlice->getDependentSliceSegmentFlag()))
[313]802  {
[1029]803    // TODO: this won't work with dependent slices: they do not have their own QP. Check fix to mask clause execution with && !(pcSlice->getDependentSliceSegmentFlag())
[313]804    m_pcTrQuant->clearSliceARLCnt();
805    if(pcSlice->getSliceType()!=I_SLICE)
806    {
807      Int qpBase = pcSlice->getSliceQpBase();
808      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
809    }
810  }
811#endif
812
813
[595]814
[1029]815  // Adjust initial state if this is the start of a dependent slice.
[313]816  {
[1029]817    const UInt      ctuRsAddr               = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
818    const UInt      currentTileIdx          = pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
819    const TComTile *pCurrentTile            = pcPic->getPicSym()->getTComTile(currentTileIdx);
820    const UInt      firstCtuRsAddrOfTile    = pCurrentTile->getFirstCtuRsAddr();
821    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
[313]822    {
[1029]823      // This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used.
824      if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getWaveFrontsynchro() )
[313]825      {
[1029]826        m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_lastSliceSegmentEndContextState );
[313]827      }
828    }
829  }
[1029]830
831  // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
832
833  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
[313]834  {
[1029]835    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
836    // initialize CTU encoder
837    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
838    pCtu->initCtu( pcPic, ctuRsAddr );
[313]839
[1029]840    // update CABAC state
841    const UInt firstCtuRsAddrOfTile = pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr))->getFirstCtuRsAddr();
842    const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;
843    const UInt ctuXPosInCtus  = ctuRsAddr % frameWidthInCtus;
844   
845    if (ctuRsAddr == firstCtuRsAddrOfTile)
[313]846    {
[1029]847      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy();
[595]848    }
[1029]849    else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getWaveFrontsynchro())
[595]850    {
[1029]851      // reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile).
852      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy();
853      // Sync if the Top-Right is available.
854      TComDataCU *pCtuUp = pCtu->getCtuAbove();
855      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
[313]856      {
[1029]857        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
858        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
859        {
860          // Top-Right is available, we use it.
861          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_entropyCodingSyncContextState );
862        }
[313]863      }
864    }
865
[1029]866    // set go-on entropy coder (used for all trial encodings - the cu encoder and encoder search also have a copy of the same pointer)
[595]867    m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
[1029]868    m_pcEntropyCoder->setBitstream( &tempBitCounter );
869    tempBitCounter.resetBits();
870    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); // this copy is not strictly necessary here, but indicates that the GoOnSbacCoder
871                                                                     // is reset to a known state before every decision process.
[595]872
873    ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
874
875    Double oldLambda = m_pcRdCost->getLambda();
876    if ( m_pcCfg->getUseRateCtrl() )
[313]877    {
[595]878      Int estQP        = pcSlice->getSliceQp();
879      Double estLambda = -1.0;
880      Double bpp       = -1.0;
[494]881
[1029]882      if ( ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
[313]883      {
[595]884        estQP = pcSlice->getSliceQp();
885      }
886      else
887      {
888        bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
[1029]889        if ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE)
[313]890        {
[595]891          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
[313]892        }
893        else
894        {
[595]895          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
896          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
897        }
[313]898
[442]899#if REPN_FORMAT_IN_VPS
[1029]900        estQP     = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, estQP );
[442]901#else
[1029]902        estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP );
[442]903#endif
[313]904
[1029]905        m_pcRdCost->setLambda(estLambda);
906
[313]907#if RDOQ_CHROMA_LAMBDA
[1029]908        // set lambda for RDOQ
909        const Double chromaLambda = estLambda / m_pcRdCost->getChromaWeight();
910        const Double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda };
911        m_pcTrQuant->setLambdas( lambdaArray );
[313]912#else
[1029]913        m_pcTrQuant->setLambda( estLambda );
[313]914#endif
915      }
916
[595]917      m_pcRateCtrl->setRCQP( estQP );
[713]918#if ADAPTIVE_QP_SELECTION
[1029]919      pCtu->getSlice()->setSliceQpBase( estQP );
[713]920#endif
[595]921    }
[313]922
[1029]923    // run CTU trial encoder
924    m_pcCuEncoder->compressCtu( pCtu );
[313]925
[1029]926
927    // All CTU decisions have now been made. Restore entropy coder to an initial stage, ready to make a true encode,
928    // which will result in the state of the contexts being correct. It will also count up the number of bits coded,
929    // which is used if there is a limit of the number of bytes per slice-segment.
930
[595]931    m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
[1029]932    m_pcEntropyCoder->setBitstream( &tempBitCounter );
933    pRDSbacCoder->setBinCountingEnableFlag( true );
934    m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetBits();
935    pRDSbacCoder->setBinsCoded( 0 );
[494]936
[1029]937    // encode CTU and calculate the true bit counters.
938    m_pcCuEncoder->encodeCtu( pCtu );
939
940
941    pRDSbacCoder->setBinCountingEnableFlag( false );
942
943    const Int numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();
944
945    // Calculate if this CTU puts us over slice bit size.
946    // cannot terminate if current slice/slice-segment would be 0 Ctu in size,
947    const UInt validEndOfSliceCtuTsAddr = ctuTsAddr + (ctuTsAddr == startCtuTsAddr ? 1 : 0);
948    // Set slice end parameter
949    if(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceBits()+numberOfWrittenBits > (pcSlice->getSliceArgument()<<3))
[595]950    {
[1029]951      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
952      pcSlice->setSliceCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
953      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
[595]954    }
[1029]955    else if(pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+numberOfWrittenBits > (pcSlice->getSliceSegmentArgument()<<3))
[595]956    {
[1029]957      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
958      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
[595]959    }
[313]960
[1029]961    if (boundingCtuTsAddr <= ctuTsAddr)
962      break;
963
964    pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) );
965    pcSlice->setSliceSegmentBits(pcSlice->getSliceSegmentBits()+numberOfWrittenBits);
966
967    // Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled.
968    if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getWaveFrontsynchro())
[595]969    {
[1029]970      m_entropyCodingSyncContextState.loadContexts(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
[595]971    }
[313]972
[1029]973
[595]974    if ( m_pcCfg->getUseRateCtrl() )
975    {
976      Int actualQP        = g_RCInvalidQPValue;
977      Double actualLambda = m_pcRdCost->getLambda();
[1029]978      Int actualBits      = pCtu->getTotalBits();
[595]979      Int numberOfEffectivePixels    = 0;
[1029]980      for ( Int idx = 0; idx < pcPic->getNumPartitionsInCtu(); idx++ )
[595]981      {
[1029]982        if ( pCtu->getPredictionMode( idx ) != NUMBER_OF_PREDICTION_MODES && ( !pCtu->isSkipped( idx ) ) )
[313]983        {
[595]984          numberOfEffectivePixels = numberOfEffectivePixels + 16;
985          break;
[313]986        }
[595]987      }
[313]988
[595]989      if ( numberOfEffectivePixels == 0 )
[313]990      {
[595]991        actualQP = g_RCInvalidQPValue;
[313]992      }
[595]993      else
[313]994      {
[1029]995        actualQP = pCtu->getQP( 0 );
[313]996      }
[595]997      m_pcRdCost->setLambda(oldLambda);
[1029]998      m_pcRateCtrl->getRCPic()->updateAfterCTU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
999                                                pCtu->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
[313]1000    }
[494]1001
[1029]1002    m_uiPicTotalBits += pCtu->getTotalBits();
1003    m_dPicRdCost     += pCtu->getTotalCost();
1004    m_uiPicDist      += pCtu->getTotalDistortion();
[313]1005  }
[1029]1006
1007  // store context state at the end of this slice-segment, in case the next slice is a dependent slice and continues using the CABAC contexts.
1008  if( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() )
[313]1009  {
[1029]1010    m_lastSliceSegmentEndContextState.loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
[313]1011  }
1012  xRestoreWPparam( pcSlice );
[1029]1013
1014  // stop use of temporary bit counter object.
1015  m_pppcRDSbacCoder[0][CI_CURR_BEST]->setBitstream(NULL);
1016  m_pcRDGoOnSbacCoder->setBitstream(NULL); // stop use of tempBitCounter.
[313]1017}
1018
1019/**
1020 \param  rpcPic        picture class
1021 \retval rpcBitstream  bitstream class
1022 */
[1029]1023Void TEncSlice::encodeSlice   ( TComPic* pcPic, TComOutputBitstream* pcSubstreams, UInt &numBinsCoded )
[313]1024{
[1029]1025  TComSlice* pcSlice                 = pcPic->getSlice(getSliceIdx());
[313]1026
[1029]1027  const UInt startCtuTsAddr          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1028  const UInt boundingCtuTsAddr       = pcSlice->getSliceSegmentCurEndCtuTsAddr();
[494]1029
[1029]1030  const UInt frameWidthInCtus        = pcPic->getPicSym()->getFrameWidthInCtus();
1031  const Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1032  const Bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
1033
1034  // initialise entropy coder for the slice
1035  m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1036  m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1037  m_pcEntropyCoder->resetEntropy      ();
1038
1039  numBinsCoded = 0;
1040  m_pcBinCABAC->setBinCountingEnableFlag( true );
1041  m_pcBinCABAC->setBinsCoded(0);
1042
[313]1043#if ENC_DEC_TRACE
1044  g_bJustDoIt = g_bEncDecTraceEnable;
1045#endif
1046  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1047  DTRACE_CABAC_T( "\tPOC: " );
[1029]1048  DTRACE_CABAC_V( pcPic->getPOC() );
[313]1049  DTRACE_CABAC_T( "\n" );
1050#if ENC_DEC_TRACE
1051  g_bJustDoIt = g_bEncDecTraceDisable;
1052#endif
1053
[1029]1054
1055  if (depSliceSegmentsEnabled)
[313]1056  {
[1029]1057    // modify initial contexts with previous slice segment if this is a dependent slice.
1058    const UInt ctuRsAddr        = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr );
1059    const UInt currentTileIdx=pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
1060    const TComTile *pCurrentTile=pcPic->getPicSym()->getTComTile(currentTileIdx);
1061    const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr();
[494]1062
[1029]1063    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
[313]1064    {
[1029]1065      if( pCurrentTile->getTileWidthInCtus() >= 2 || !wavefrontsEnabled )
[313]1066      {
[1029]1067        m_pcSbacCoder->loadContexts(&m_lastSliceSegmentEndContextState);
[313]1068      }
1069    }
1070  }
1071
[1029]1072  // for every CTU in the slice segment...
1073
1074  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
[313]1075  {
[1029]1076    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
1077    const TComTile &currentTile = *(pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr)));
1078    const UInt firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
1079    const UInt tileXPosInCtus       = firstCtuRsAddrOfTile % frameWidthInCtus;
1080    const UInt tileYPosInCtus       = firstCtuRsAddrOfTile / frameWidthInCtus;
1081    const UInt ctuXPosInCtus        = ctuRsAddr % frameWidthInCtus;
1082    const UInt ctuYPosInCtus        = ctuRsAddr / frameWidthInCtus;
1083    const UInt uiSubStrm=pcPic->getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice);
1084    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
[595]1085
1086    m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
[1029]1087
1088    // set up CABAC contexts' state for this CTU
1089    if (ctuRsAddr == firstCtuRsAddrOfTile)
[595]1090    {
[1029]1091      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
[313]1092      {
[1029]1093        m_pcEntropyCoder->resetEntropy();
[313]1094      }
1095    }
[1029]1096    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
[313]1097    {
[1029]1098      // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line.
1099      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
[313]1100      {
[1029]1101        m_pcEntropyCoder->resetEntropy();
[313]1102      }
[1029]1103      TComDataCU *pCtuUp = pCtu->getCtuAbove();
1104      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
[313]1105      {
[1029]1106        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
1107        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
[313]1108        {
[1029]1109          // Top-right is available, so use it.
1110          m_pcSbacCoder->loadContexts( &m_entropyCodingSyncContextState );
[313]1111        }
1112      }
1113    }
1114
[1029]1115
[540]1116    if ( pcSlice->getSPS()->getUseSAO() )
1117    {
[1029]1118      Bool bIsSAOSliceEnabled = false;
1119      Bool sliceEnabled[MAX_NUM_COMPONENT];
1120      for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
[540]1121      {
[1029]1122        ComponentID compId=ComponentID(comp);
1123        sliceEnabled[compId] = pcSlice->getSaoEnabledFlag(toChannelType(compId)) && (comp < pcPic->getNumberValidComponents());
1124        if (sliceEnabled[compId]) bIsSAOSliceEnabled=true;
1125      }
1126      if (bIsSAOSliceEnabled)
1127      {
1128        SAOBlkParam& saoblkParam = (pcPic->getPicSym()->getSAOBlkParam())[ctuRsAddr];
[540]1129
1130        Bool leftMergeAvail = false;
1131        Bool aboveMergeAvail= false;
1132        //merge left condition
[1029]1133        Int rx = (ctuRsAddr % frameWidthInCtus);
[540]1134        if(rx > 0)
1135        {
[1029]1136          leftMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-1);
[540]1137        }
1138
1139        //merge up condition
[1029]1140        Int ry = (ctuRsAddr / frameWidthInCtus);
[540]1141        if(ry > 0)
1142        {
[1029]1143          aboveMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-frameWidthInCtus);
[540]1144        }
1145
[644]1146#if SVC_EXTENSION
[1057]1147        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, m_ppcTEncTop[pcSlice->getLayerIdx()]->getSAO()->getSaoMaxOffsetQVal(), sliceEnabled, leftMergeAvail, aboveMergeAvail);
[644]1148#else
[1029]1149        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, sliceEnabled, leftMergeAvail, aboveMergeAvail);
[644]1150#endif
[540]1151      }
1152    }
1153
[313]1154#if ENC_DEC_TRACE
1155    g_bJustDoIt = g_bEncDecTraceEnable;
1156#endif
[1029]1157      m_pcCuEncoder->encodeCtu( pCtu );
[313]1158#if ENC_DEC_TRACE
1159    g_bJustDoIt = g_bEncDecTraceDisable;
[494]1160#endif
[1029]1161
1162    //Store probabilities of second CTU in line into buffer
1163    if ( ctuXPosInCtus == tileXPosInCtus+1 && wavefrontsEnabled)
[313]1164    {
[1029]1165      m_entropyCodingSyncContextState.loadContexts( m_pcSbacCoder );
[313]1166    }
[1029]1167
1168    // terminate the sub-stream, if required (end of slice-segment, end of tile, end of wavefront-CTU-row):
1169    if (ctuTsAddr+1 == boundingCtuTsAddr ||
1170         (  ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus() &&
1171          ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled)
1172         )
1173       )
1174    {
1175      m_pcEntropyCoder->encodeTerminatingBit(1);
1176      m_pcEntropyCoder->encodeSliceFinish();
1177      // Byte-alignment in slice_data() when new tile
1178      pcSubstreams[uiSubStrm].writeByteAlignment();
1179
1180      // write sub-stream size
1181      if (ctuTsAddr+1 != boundingCtuTsAddr)
1182      {
1183        pcSlice->addSubstreamSize( (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations() );
1184      }
1185    }
1186  } // CTU-loop
1187
[313]1188  if( depSliceSegmentsEnabled )
1189  {
[1029]1190    m_lastSliceSegmentEndContextState.loadContexts( m_pcSbacCoder );//ctx end of dep.slice
[313]1191  }
[1029]1192
[313]1193#if ADAPTIVE_QP_SELECTION
1194  if( m_pcCfg->getUseAdaptQpSelect() )
1195  {
1196    m_pcTrQuant->storeSliceQpNext(pcSlice);
1197  }
1198#endif
[1029]1199
[313]1200  if (pcSlice->getPPS()->getCabacInitPresentFlag())
1201  {
[1029]1202    if (pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
[313]1203    {
1204      pcSlice->getPPS()->setEncCABACTableIdx( pcSlice->getSliceType() );
1205    }
1206    else
1207    {
1208      m_pcEntropyCoder->determineCabacInitIdx();
1209    }
1210  }
[1029]1211  numBinsCoded = m_pcBinCABAC->getBinsCoded();
[313]1212}
1213
[1029]1214Void TEncSlice::calculateBoundingCtuTsAddrForSlice(UInt &startCtuTSAddrSlice, UInt &boundingCtuTSAddrSlice, Bool &haveReachedTileBoundary,
1215                                                   TComPic* pcPic, const Bool encodingSlice, const Int sliceMode, const Int sliceArgument, const UInt sliceCurEndCtuTSAddr)
[313]1216{
[1029]1217  TComSlice* pcSlice = pcPic->getSlice(getSliceIdx());
1218  const UInt numberOfCtusInFrame = pcPic->getNumberOfCtusInFrame();
1219  boundingCtuTSAddrSlice=0;
1220  haveReachedTileBoundary=false;
[313]1221
[1029]1222  switch (sliceMode)
[313]1223  {
[1029]1224    case FIXED_NUMBER_OF_CTU:
1225      {
1226        UInt ctuAddrIncrement    = sliceArgument;
1227        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
1228      }
[313]1229      break;
1230    case FIXED_NUMBER_OF_BYTES:
[1029]1231      if (encodingSlice)
1232        boundingCtuTSAddrSlice  = sliceCurEndCtuTSAddr;
1233      else
1234        boundingCtuTSAddrSlice  = numberOfCtusInFrame;
[313]1235      break;
1236    case FIXED_NUMBER_OF_TILES:
[1029]1237      {
1238        const UInt tileIdx        = pcPic->getPicSym()->getTileIdxMap( pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice) );
1239        const UInt tileTotalCount = (pcPic->getPicSym()->getNumTileColumnsMinus1()+1) * (pcPic->getPicSym()->getNumTileRowsMinus1()+1);
1240        UInt ctuAddrIncrement   = 0;
[313]1241
[1029]1242        for(UInt tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++)
[313]1243        {
[1029]1244          if((tileIdx + tileIdxIncrement) < tileTotalCount)
1245          {
1246            UInt tileWidthInCtus   = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidthInCtus();
1247            UInt tileHeightInCtus  = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeightInCtus();
1248            ctuAddrIncrement    += (tileWidthInCtus * tileHeightInCtus);
1249          }
[313]1250        }
1251
[1029]1252        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
[313]1253      }
1254      break;
1255    default:
[1029]1256      boundingCtuTSAddrSlice    = numberOfCtusInFrame;
[313]1257      break;
1258  }
1259
[1029]1260  // Adjust for tiles and wavefronts.
1261  if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) &&
[313]1262      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1263  {
[1029]1264    const UInt ctuRSAddr                  = pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice);
1265    const UInt startTileIdx               = pcPic->getPicSym()->getTileIdxMap(ctuRSAddr);
1266    const Bool wavefrontsAreEnabled       = m_pcCfg->getWaveFrontsynchro();
[494]1267
[1029]1268    const TComTile *pStartingTile         = pcPic->getPicSym()->getTComTile(startTileIdx);
1269    const UInt tileStartTsAddr            = pcPic->getPicSym()->getCtuRsToTsAddrMap(pStartingTile->getFirstCtuRsAddr());
1270    const UInt tileStartWidth             = pStartingTile->getTileWidthInCtus();
1271    const UInt tileStartHeight            = pStartingTile->getTileHeightInCtus();
1272    const UInt tileLastTsAddr_excl        = tileStartTsAddr + tileStartWidth*tileStartHeight;
1273    const UInt tileBoundingCtuTsAddrSlice = tileLastTsAddr_excl;
[313]1274
[1029]1275    const UInt ctuColumnOfStartingTile    = ((startCtuTSAddrSlice-tileStartTsAddr)%tileStartWidth);
1276    if (wavefrontsAreEnabled && ctuColumnOfStartingTile!=0)
[313]1277    {
[1029]1278      // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1279      const UInt numberOfCTUsToEndOfRow            = tileStartWidth - ctuColumnOfStartingTile;
1280      const UInt wavefrontTileBoundingCtuAddrSlice = startCtuTSAddrSlice + numberOfCTUsToEndOfRow;
1281      if (wavefrontTileBoundingCtuAddrSlice < boundingCtuTSAddrSlice)
[313]1282      {
[1029]1283        boundingCtuTSAddrSlice = wavefrontTileBoundingCtuAddrSlice;
[313]1284      }
[494]1285    }
[313]1286
[1029]1287    if (tileBoundingCtuTsAddrSlice < boundingCtuTSAddrSlice)
[313]1288    {
[1029]1289      boundingCtuTSAddrSlice = tileBoundingCtuTsAddrSlice;
1290      haveReachedTileBoundary = true;
[313]1291    }
1292  }
[1029]1293  else if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) && pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() && ((startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) != 0))
[313]1294  {
[1029]1295    // Adjust for wavefronts (no tiles).
1296    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1297    boundingCtuTSAddrSlice = min(boundingCtuTSAddrSlice, startCtuTSAddrSlice - (startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) + (pcPic->getFrameWidthInCtus()));
[313]1298  }
[1029]1299}
[313]1300
[1029]1301/** Determines the starting and bounding CTU address of current slice / dependent slice
1302 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1303 * \returns Updates startCtuTsAddr, boundingCtuTsAddr with appropriate CTU address
1304 */
1305Void TEncSlice::xDetermineStartAndBoundingCtuTsAddr  ( UInt& startCtuTsAddr, UInt& boundingCtuTsAddr, TComPic* pcPic, const Bool encodingSlice )
1306{
1307  TComSlice* pcSlice                 = pcPic->getSlice(getSliceIdx());
[313]1308
[1029]1309  // Non-dependent slice
1310  UInt startCtuTsAddrSlice           = pcSlice->getSliceCurStartCtuTsAddr();
1311  Bool haveReachedTileBoundarySlice  = false;
1312  UInt boundingCtuTsAddrSlice;
1313  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSlice, boundingCtuTsAddrSlice, haveReachedTileBoundarySlice, pcPic,
1314                                     encodingSlice, m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument(), pcSlice->getSliceCurEndCtuTsAddr());
1315  pcSlice->setSliceCurEndCtuTsAddr(   boundingCtuTsAddrSlice );
1316  pcSlice->setSliceCurStartCtuTsAddr( startCtuTsAddrSlice    );
[494]1317
[1029]1318  // Dependent slice
1319  UInt startCtuTsAddrSliceSegment          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1320  Bool haveReachedTileBoundarySliceSegment = false;
1321  UInt boundingCtuTsAddrSliceSegment;
1322  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSliceSegment, boundingCtuTsAddrSliceSegment, haveReachedTileBoundarySliceSegment, pcPic,
1323                                     encodingSlice, m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument(), pcSlice->getSliceSegmentCurEndCtuTsAddr());
1324  if (boundingCtuTsAddrSliceSegment>boundingCtuTsAddrSlice)
[313]1325  {
[1029]1326    boundingCtuTsAddrSliceSegment = boundingCtuTsAddrSlice;
[313]1327  }
[1029]1328  pcSlice->setSliceSegmentCurEndCtuTsAddr( boundingCtuTsAddrSliceSegment );
1329  pcSlice->setSliceSegmentCurStartCtuTsAddr(startCtuTsAddrSliceSegment);
[494]1330
[313]1331  // Make a joint decision based on reconstruction and dependent slice bounds
[1029]1332  startCtuTsAddr    = max(startCtuTsAddrSlice   , startCtuTsAddrSliceSegment   );
1333  boundingCtuTsAddr = boundingCtuTsAddrSliceSegment;
[313]1334}
1335
1336Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1337{
1338  return 4.2005*log(lambda) + 13.7122;
1339}
1340
[595]1341#if SVC_EXTENSION
[313]1342#if JCTVC_M0259_LAMBDAREFINEMENT
1343Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
1344{
1345  double tmp = beta * pow( 2.0 , deltaQP / 6 );
1346  double gamma = tmp / ( tmp + 1 );
1347  return( gamma );
1348}
1349#endif
[494]1350#if O0194_WEIGHTED_PREDICTION_CGS
1351Void TEncSlice::estimateILWpParam( TComSlice* pcSlice )
1352{
1353  xCalcACDCParamSlice(pcSlice);
[1029]1354  WPACDCParam * temp_weightACDCParam;
[494]1355
1356  pcSlice->getWpAcDcParam(temp_weightACDCParam);
1357  g_refWeightACDCParam = (void *) temp_weightACDCParam;
1358}
1359#endif
[595]1360#endif //SVC_EXTENSION
[313]1361//! \}
Note: See TracBrowser for help on using the repository browser.