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

Last change on this file since 1263 was 940, checked in by seregin, 10 years ago

fix lambda refinement setting

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