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

Last change on this file since 1323 was 1318, checked in by seregin, 9 years ago

port rev 4393

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