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

Last change on this file since 1114 was 1065, checked in by seregin, 10 years ago

fix index for m_ppcTEncTop

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