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

Last change on this file since 1263 was 1260, checked in by seregin, 9 years ago

port rev 4257

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