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

Last change on this file since 1334 was 1330, checked in by seregin, 10 years ago

port rev 4408

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