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

Last change on this file since 1465 was 1459, checked in by seregin, 9 years ago

port rev 4593

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