source: SHVCSoftware/branches/SHM-upgrade/source/Lib/TLibEncoder/TEncSlice.cpp @ 918

Last change on this file since 918 was 916, checked in by seregin, 10 years ago

initial porting

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