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

Last change on this file since 1243 was 1235, checked in by seregin, 9 years ago

port rev 4219 and rev 4246

  • Property svn:eol-style set to native
File size: 49.9 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: m_encCABACTableIdx(I_SLICE)
51{
52  m_apcPicYuvPred = NULL;
53  m_apcPicYuvResi = NULL;
54
55  m_pdRdPicLambda = NULL;
56  m_pdRdPicQp     = NULL;
57  m_piRdPicQp     = NULL;
58}
59
60TEncSlice::~TEncSlice()
61{
62}
63
64Void TEncSlice::create( Int iWidth, Int iHeight, ChromaFormat chromaFormat, UInt iMaxCUWidth, UInt iMaxCUHeight, UChar uhTotalDepth )
65{
66  // create prediction picture
67  if ( m_apcPicYuvPred == NULL )
68  {
69    m_apcPicYuvPred  = new TComPicYuv;
70    m_apcPicYuvPred->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
71  }
72
73  // create residual picture
74  if( m_apcPicYuvResi == NULL )
75  {
76    m_apcPicYuvResi  = new TComPicYuv;
77    m_apcPicYuvResi->create( iWidth, iHeight, chromaFormat, iMaxCUWidth, iMaxCUHeight, uhTotalDepth );
78  }
79}
80
81Void TEncSlice::destroy()
82{
83  // destroy prediction picture
84  if ( m_apcPicYuvPred )
85  {
86    m_apcPicYuvPred->destroy();
87    delete m_apcPicYuvPred;
88    m_apcPicYuvPred  = NULL;
89  }
90
91  // destroy residual picture
92  if ( m_apcPicYuvResi )
93  {
94    m_apcPicYuvResi->destroy();
95    delete m_apcPicYuvResi;
96    m_apcPicYuvResi  = NULL;
97  }
98
99  // free lambda and QP arrays
100  if ( m_pdRdPicLambda ) { xFree( m_pdRdPicLambda ); m_pdRdPicLambda = NULL; }
101  if ( m_pdRdPicQp     ) { xFree( m_pdRdPicQp     ); m_pdRdPicQp     = NULL; }
102  if ( m_piRdPicQp     ) { xFree( m_piRdPicQp     ); m_piRdPicQp     = NULL; }
103}
104
105Void TEncSlice::init( TEncTop* pcEncTop )
106{
107  m_pcCfg             = pcEncTop;
108  m_pcListPic         = pcEncTop->getListPic();
109#if SVC_EXTENSION
110  m_ppcTEncTop        = pcEncTop->getLayerEnc();
111#endif
112  m_pcGOPEncoder      = pcEncTop->getGOPEncoder();
113  m_pcCuEncoder       = pcEncTop->getCuEncoder();
114  m_pcPredSearch      = pcEncTop->getPredSearch();
115
116  m_pcEntropyCoder    = pcEncTop->getEntropyCoder();
117  m_pcSbacCoder       = pcEncTop->getSbacCoder();
118  m_pcBinCABAC        = pcEncTop->getBinCABAC();
119  m_pcTrQuant         = pcEncTop->getTrQuant();
120
121  m_pcRdCost          = pcEncTop->getRdCost();
122  m_pppcRDSbacCoder   = pcEncTop->getRDSbacCoder();
123  m_pcRDGoOnSbacCoder = pcEncTop->getRDGoOnSbacCoder();
124
125  // create lambda and QP arrays
126  m_pdRdPicLambda     = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
127  m_pdRdPicQp         = (Double*)xMalloc( Double, m_pcCfg->getDeltaQpRD() * 2 + 1 );
128  m_piRdPicQp         = (Int*   )xMalloc( Int,    m_pcCfg->getDeltaQpRD() * 2 + 1 );
129  m_pcRateCtrl        = pcEncTop->getRateCtrl();
130}
131
132
133
134Void
135#if JCTVC_M0259_LAMBDAREFINEMENT
136TEncSlice::setUpLambda(TComSlice* slice, Double dLambda, Int iQP, Int depth)
137#else
138TEncSlice::setUpLambda(TComSlice* slice, const Double dLambda, Int iQP)
139#endif
140{
141#if JCTVC_M0259_LAMBDAREFINEMENT
142  Int layerIdx = slice->getLayerIdx();
143
144  if( slice->getLayerId() > 0 && m_ppcTEncTop[layerIdx]->getNumActiveRefLayers() && depth >= 3 && m_pcCfg->getGOPSize() == ( 1 << depth ) )
145  {
146    UInt prevLayerIdx = 0; 
147    if( m_ppcTEncTop[layerIdx]->getNumActiveRefLayers() > 0 )
148    {
149      prevLayerIdx = m_ppcTEncTop[layerIdx]->getPredLayerIdx( m_ppcTEncTop[layerIdx]->getNumActiveRefLayers() - 1);
150    }
151
152    Double gamma = xCalEnhLambdaFactor( m_ppcTEncTop[prevLayerIdx]->getQP() - m_ppcTEncTop[layerIdx]->getQP() ,
153                                        1.0 * m_ppcTEncTop[layerIdx]->getSourceWidth() * m_ppcTEncTop[layerIdx]->getSourceHeight()
154                                        / m_ppcTEncTop[prevLayerIdx]->getSourceWidth() / m_ppcTEncTop[prevLayerIdx]->getSourceHeight() );
155
156    dLambda *= gamma;
157  }
158#endif
159
160  // store lambda
161  m_pcRdCost ->setLambda( dLambda );
162
163  // for RDO
164  // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
165  Double dLambdas[MAX_NUM_COMPONENT] = { dLambda };
166  for(UInt compIdx=1; compIdx<MAX_NUM_COMPONENT; compIdx++)
167  {
168    const ComponentID compID=ComponentID(compIdx);
169    Int chromaQPOffset = slice->getPPS()->getQpOffset(compID) + slice->getSliceChromaQpDelta(compID);
170    Int qpc=(iQP + chromaQPOffset < 0) ? iQP : getScaledChromaQP(iQP + chromaQPOffset, m_pcCfg->getChromaFormatIdc());
171    Double tmpWeight = pow( 2.0, (iQP-qpc)/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
172
173#if JCTVC_M0259_LAMBDAREFINEMENT
174    if( slice->getLayerId() > 0 && m_ppcTEncTop[slice->getLayerIdx()]->getNumActiveRefLayers() && m_pcCfg->getGOPSize() >= 8 && slice->isIntra() == false && depth == 0 )
175    {
176      dLambdas[0] = dLambda * 1.1;
177      m_pcRdCost->setLambda( dLambdas[0] );
178
179      m_pcRdCost->setDistortionWeight(compID, tmpWeight * 1.15);
180      dLambdas[compIdx] = dLambdas[0] / tmpWeight / 1.15;
181    }
182    else
183    {
184#endif
185    m_pcRdCost->setDistortionWeight(compID, tmpWeight);
186    dLambdas[compIdx]=dLambda/tmpWeight;
187#if JCTVC_M0259_LAMBDAREFINEMENT
188    }
189#endif
190  }
191
192#if RDOQ_CHROMA_LAMBDA
193// for RDOQ
194  m_pcTrQuant->setLambdas( dLambdas );
195#else
196  m_pcTrQuant->setLambda( dLambda );
197#endif
198
199// For SAO
200  slice   ->setLambdas( dLambdas );
201}
202
203
204
205/**
206 - non-referenced frame marking
207 - QP computation based on temporal structure
208 - lambda computation based on QP
209 - set temporal layer ID and the parameter sets
210 .
211 \param pcPic         picture class
212 \param pocLast      POC of last picture
213 \param pocCurr     current POC
214 \param iNumPicRcvd   number of received pictures
215 \param iTimeOffset   POC offset for hierarchical structure
216 \param iDepth        temporal layer depth
217 \param rpcSlice      slice header class
218 \param pSPS          SPS associated with the slice
219 \param pPPS          PPS associated with the slice
220 */
221#if SVC_EXTENSION
222//\param vps          VPS associated with the slice
223Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, Bool isField )
224#else
225Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iNumPicRcvd, Int iGOPid, TComSlice*& rpcSlice, const TComSPS* pSPS, const TComPPS *pPPS, Bool isField )
226#endif
227{
228  Double dQP;
229  Double dLambda;
230
231  rpcSlice = pcPic->getSlice(0);
232  rpcSlice->setSliceBits(0);
233  rpcSlice->setPic( pcPic );
234#if SVC_EXTENSION
235  const TComPPS* pPPS = &pcPic->getPicSym()->getPPS();
236
237  UInt layerId = pcPic->getLayerId();
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 SVC_EXTENSION
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 SVC_EXTENSION
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 SVC_EXTENSION
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->setDeblockingFilterOverrideFlag( rpcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() );
504    rpcSlice->setDeblockingFilterDisable( rpcSlice->getPPS()->getPicDisableDeblockingFilterFlag() );
505    if ( !rpcSlice->getDeblockingFilterDisable())
506    {
507      if ( rpcSlice->getDeblockingFilterOverrideFlag() && eSliceType!=I_SLICE)
508      {
509        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
510        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
511      }
512      else
513      {
514        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
515        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
516      }
517    }
518  }
519  else
520  {
521    rpcSlice->setDeblockingFilterOverrideFlag( false );
522    rpcSlice->setDeblockingFilterDisable( false );
523    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
524    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
525  }
526
527  rpcSlice->setDepth            ( depth );
528
529  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
530  if(eSliceType==I_SLICE)
531  {
532    pcPic->setTLayer(0);
533  }
534  rpcSlice->setTLayer( pcPic->getTLayer() );
535
536  assert( m_apcPicYuvPred );
537  assert( m_apcPicYuvResi );
538
539  pcPic->setPicYuvPred( m_apcPicYuvPred );
540  pcPic->setPicYuvResi( m_apcPicYuvResi );
541  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
542  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
543  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
544  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
545  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
546
547#if HIGHER_LAYER_IRAP_SKIP_FLAG
548  if( m_pcCfg->getSkipPictureAtArcSwitch() && m_pcCfg->getAdaptiveResolutionChange() > 0 && rpcSlice->getLayerId() == 1 && rpcSlice->getPOC() == m_pcCfg->getAdaptiveResolutionChange() )
549  {
550    rpcSlice->setMaxNumMergeCand        ( 1 );
551  }
552#endif
553
554#if SVC_EXTENSION
555  if( layerId > 0 )
556  {
557    if( rpcSlice->getNumILRRefIdx() > 0 )
558    {
559      rpcSlice->setActiveNumILRRefIdx( m_ppcTEncTop[rpcSlice->getVPS()->getLayerIdxInVps(layerId)]->getNumActiveRefLayers() );
560      for( Int i = 0; i < rpcSlice->getActiveNumILRRefIdx(); i++ )
561      {
562        rpcSlice->setInterLayerPredLayerIdc( m_ppcTEncTop[rpcSlice->getVPS()->getLayerIdxInVps(layerId)]->getPredLayerIdx(i), i );
563      }
564      rpcSlice->setInterLayerPredEnabledFlag(1);
565    }
566    rpcSlice->setMFMEnabledFlag(m_ppcTEncTop[rpcSlice->getVPS()->getLayerIdxInVps(layerId)]->getMFMEnabledFlag());
567  }
568
569#endif
570}
571
572Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
573{
574  TComSlice* slice = pic->getSlice(0);
575
576  // store lambda
577  slice->setSliceQp( sliceQP );
578#if ADAPTIVE_QP_SELECTION
579  slice->setSliceQpBase ( sliceQP );
580#endif
581  setUpLambda(slice, lambda, sliceQP);
582}
583
584// ====================================================================================================================
585// Public member functions
586// ====================================================================================================================
587
588Void TEncSlice::setSearchRange( TComSlice* pcSlice )
589{
590  Int iCurrPOC = pcSlice->getPOC();
591  Int iRefPOC;
592  Int iGOPSize = m_pcCfg->getGOPSize();
593  Int iOffset = (iGOPSize >> 1);
594  Int iMaxSR = m_pcCfg->getSearchRange();
595  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
596
597  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
598  {
599    //RefPicList e = (RefPicList)iDir;
600    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
601    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
602    {
603      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
604      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
605      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
606    }
607  }
608}
609
610/**
611 - multi-loop slice encoding for different slice QP
612 .
613 \param rpcPic    picture class
614 */
615Void TEncSlice::precompressSlice( TComPic* pcPic )
616{
617  // if deltaQP RD is not used, simply return
618  if ( m_pcCfg->getDeltaQpRD() == 0 )
619  {
620    return;
621  }
622
623  if ( m_pcCfg->getUseRateCtrl() )
624  {
625    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
626    assert(0);
627  }
628
629  TComSlice* pcSlice        = pcPic->getSlice(getSliceIdx());
630  Double     dPicRdCostBest = MAX_DOUBLE;
631  UInt       uiQpIdxBest = 0;
632
633  Double dFrameLambda;
634#if FULL_NBIT
635  Int    SHIFT_QP = 12 + 6 * (g_bitDepth[CHANNEL_TYPE_LUMA] - 8);
636#else
637  Int    SHIFT_QP = 12;
638#endif
639
640  // set frame lambda
641  if (m_pcCfg->getGOPSize() > 1)
642  {
643    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
644  }
645  else
646  {
647    dFrameLambda = 0.68 * pow (2, (m_piRdPicQp[0] - SHIFT_QP) / 3.0);
648  }
649  m_pcRdCost      ->setFrameLambda(dFrameLambda);
650
651  const UInt initialSliceQp=pcSlice->getSliceQp();
652  // for each QP candidate
653  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
654  {
655    pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdx] );
656#if ADAPTIVE_QP_SELECTION
657    pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdx] );
658#endif
659    setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdx], m_piRdPicQp    [uiQpIdx]);
660
661    // try compress
662    compressSlice   ( pcPic );
663
664    Double dPicRdCost;
665    UInt64 uiPicDist        = m_uiPicDist;
666    // TODO: will this work if multiple slices are being used? There may not be any reconstruction data yet.
667    //       Will this also be ideal if a byte-restriction is placed on the slice?
668    //         - what if the last CTU was sometimes included, sometimes not, and that had all the distortion?
669    m_pcGOPEncoder->preLoopFilterPicAll( pcPic, uiPicDist );
670
671    // compute RD cost and choose the best
672    dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits, uiPicDist, true, DF_SSE_FRAME);
673
674    if ( dPicRdCost < dPicRdCostBest )
675    {
676      uiQpIdxBest    = uiQpIdx;
677      dPicRdCostBest = dPicRdCost;
678    }
679  }
680
681  if (pcSlice->getDependentSliceSegmentFlag() && initialSliceQp!=m_piRdPicQp[uiQpIdxBest] )
682  {
683    // TODO: this won't work with dependent slices: they do not have their own QP.
684    fprintf(stderr,"ERROR - attempt to change QP for a dependent slice-segment, having already coded the slice\n");
685    assert(pcSlice->getDependentSliceSegmentFlag()==false || initialSliceQp==m_piRdPicQp[uiQpIdxBest]);
686  }
687  // set best values
688  pcSlice       ->setSliceQp             ( m_piRdPicQp    [uiQpIdxBest] );
689#if ADAPTIVE_QP_SELECTION
690  pcSlice       ->setSliceQpBase         ( m_piRdPicQp    [uiQpIdxBest] );
691#endif
692  setUpLambda(pcSlice, m_pdRdPicLambda[uiQpIdxBest], m_piRdPicQp    [uiQpIdxBest]);
693}
694
695Void TEncSlice::calCostSliceI(TComPic* pcPic)
696{
697  UInt    ctuRsAddr;
698  UInt    startCtuTsAddr;
699  UInt    boundingCtuTsAddr;
700  Int     iSumHad, shift = g_bitDepth[CHANNEL_TYPE_LUMA]-8, offset = (shift>0)?(1<<(shift-1)):0;;
701  Double  iSumHadSlice = 0;
702
703  pcPic->getSlice(getSliceIdx())->setSliceSegmentBits(0);
704  TComSlice* pcSlice            = pcPic->getSlice(getSliceIdx());
705  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic, false );
706
707  UInt ctuTsAddr;
708  ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
709  for( ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(++ctuTsAddr) )
710  {
711    // initialize CU encoder
712    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
713    pCtu->initCtu( pcPic, ctuRsAddr );
714
715#if SVC_EXTENSION
716    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getPicHeightInLumaSamples() - ctuRsAddr / pcPic->getFrameWidthInCtus() * pcSlice->getSPS()->getMaxCUHeight() );
717    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getPicWidthInLumaSamples() - ctuRsAddr % pcPic->getFrameWidthInCtus() * pcSlice->getSPS()->getMaxCUWidth() );
718#else
719    Int height  = min( pcSlice->getSPS()->getMaxCUHeight(),pcSlice->getSPS()->getPicHeightInLumaSamples() - ctuRsAddr / pcPic->getFrameWidthInCtus() * pcSlice->getSPS()->getMaxCUHeight() );
720    Int width   = min( pcSlice->getSPS()->getMaxCUWidth(),pcSlice->getSPS()->getPicWidthInLumaSamples() - ctuRsAddr % pcPic->getFrameWidthInCtus() * pcSlice->getSPS()->getMaxCUWidth() );
721#endif
722
723    iSumHad = m_pcCuEncoder->updateCtuDataISlice(pCtu, width, height);
724
725    (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra=(iSumHad+offset)>>shift;
726    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra;
727
728  }
729  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
730}
731
732/** \param rpcPic   picture class
733 */
734Void TEncSlice::compressSlice( TComPic* pcPic )
735{
736  UInt   startCtuTsAddr;
737  UInt   boundingCtuTsAddr;
738  TComSlice* pcSlice            = pcPic->getSlice(getSliceIdx());
739  pcSlice->setSliceSegmentBits(0);
740  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic, false );
741
742  // initialize cost values - these are used by precompressSlice (they should be parameters).
743  m_uiPicTotalBits  = 0;
744  m_dPicRdCost      = 0; // NOTE: This is a write-only variable!
745  m_uiPicDist       = 0;
746
747  m_pcEntropyCoder->setEntropyCoder   ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
748  m_pcEntropyCoder->resetEntropy      ();
749
750  TEncBinCABAC* pRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
751  pRDSbacCoder->setBinCountingEnableFlag( false );
752  pRDSbacCoder->setBinsCoded( 0 );
753
754  TComBitCounter  tempBitCounter;
755  const UInt      frameWidthInCtus = pcPic->getPicSym()->getFrameWidthInCtus();
756
757  //------------------------------------------------------------------------------
758  //  Weighted Prediction parameters estimation.
759  //------------------------------------------------------------------------------
760  // calculate AC/DC values for current picture
761  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
762  {
763    xCalcACDCParamSlice(pcSlice);
764  }
765#if SVC_EXTENSION
766  else if( m_ppcTEncTop[pcSlice->getLayerIdx()]->getInterLayerWeightedPredFlag() )
767  {
768    // Calculate for the base layer to be used in EL as Inter layer reference
769    estimateILWpParam( pcSlice );   
770  }
771#endif
772
773  const Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
774
775  if ( bWp_explicit )
776  {
777    //------------------------------------------------------------------------------
778    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
779    //------------------------------------------------------------------------------
780    if ( pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES || pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES )
781    {
782      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
783    }
784
785    xEstimateWPParamSlice( pcSlice );
786    pcSlice->initWpScaling(pcSlice->getSPS());
787
788    // check WP on/off
789    xCheckWPEnable( pcSlice );
790  }
791
792#if ADAPTIVE_QP_SELECTION
793  if( m_pcCfg->getUseAdaptQpSelect() && !(pcSlice->getDependentSliceSegmentFlag()))
794  {
795    // TODO: this won't work with dependent slices: they do not have their own QP. Check fix to mask clause execution with && !(pcSlice->getDependentSliceSegmentFlag())
796    m_pcTrQuant->clearSliceARLCnt();
797    if(pcSlice->getSliceType()!=I_SLICE)
798    {
799      Int qpBase = pcSlice->getSliceQpBase();
800      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
801    }
802  }
803#endif
804
805
806
807  // Adjust initial state if this is the start of a dependent slice.
808  {
809    const UInt      ctuRsAddr               = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
810    const UInt      currentTileIdx          = pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
811    const TComTile *pCurrentTile            = pcPic->getPicSym()->getTComTile(currentTileIdx);
812    const UInt      firstCtuRsAddrOfTile    = pCurrentTile->getFirstCtuRsAddr();
813    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
814    {
815      // This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used.
816      if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getWaveFrontsynchro() )
817      {
818        m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_lastSliceSegmentEndContextState );
819      }
820    }
821  }
822
823  // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
824
825  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
826  {
827    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
828    // initialize CTU encoder
829    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
830    pCtu->initCtu( pcPic, ctuRsAddr );
831
832    // update CABAC state
833    const UInt firstCtuRsAddrOfTile = pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr))->getFirstCtuRsAddr();
834    const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;
835    const UInt ctuXPosInCtus  = ctuRsAddr % frameWidthInCtus;
836   
837    if (ctuRsAddr == firstCtuRsAddrOfTile)
838    {
839      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy();
840    }
841    else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getWaveFrontsynchro())
842    {
843      // reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile).
844      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy();
845      // Sync if the Top-Right is available.
846      TComDataCU *pCtuUp = pCtu->getCtuAbove();
847      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
848      {
849        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
850        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
851        {
852          // Top-Right is available, we use it.
853          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_entropyCodingSyncContextState );
854        }
855      }
856    }
857
858    // set go-on entropy coder (used for all trial encodings - the cu encoder and encoder search also have a copy of the same pointer)
859    m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder, pcSlice );
860    m_pcEntropyCoder->setBitstream( &tempBitCounter );
861    tempBitCounter.resetBits();
862    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); // this copy is not strictly necessary here, but indicates that the GoOnSbacCoder
863                                                                     // is reset to a known state before every decision process.
864
865    ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
866
867    Double oldLambda = m_pcRdCost->getLambda();
868    if ( m_pcCfg->getUseRateCtrl() )
869    {
870      Int estQP        = pcSlice->getSliceQp();
871      Double estLambda = -1.0;
872      Double bpp       = -1.0;
873
874      if ( ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
875      {
876        estQP = pcSlice->getSliceQp();
877      }
878      else
879      {
880        bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
881        if ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE)
882        {
883          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
884        }
885        else
886        {
887          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
888          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
889        }
890
891#if SVC_EXTENSION
892        estQP     = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, estQP );
893#else
894        estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP );
895#endif
896
897        m_pcRdCost->setLambda(estLambda);
898
899#if RDOQ_CHROMA_LAMBDA
900        // set lambda for RDOQ
901        const Double chromaLambda = estLambda / m_pcRdCost->getChromaWeight();
902        const Double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda };
903        m_pcTrQuant->setLambdas( lambdaArray );
904#else
905        m_pcTrQuant->setLambda( estLambda );
906#endif
907      }
908
909      m_pcRateCtrl->setRCQP( estQP );
910#if ADAPTIVE_QP_SELECTION
911      pCtu->getSlice()->setSliceQpBase( estQP );
912#endif
913    }
914
915    // run CTU trial encoder
916    m_pcCuEncoder->compressCtu( pCtu );
917
918
919    // All CTU decisions have now been made. Restore entropy coder to an initial stage, ready to make a true encode,
920    // which will result in the state of the contexts being correct. It will also count up the number of bits coded,
921    // which is used if there is a limit of the number of bytes per slice-segment.
922
923    m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST], pcSlice );
924    m_pcEntropyCoder->setBitstream( &tempBitCounter );
925    pRDSbacCoder->setBinCountingEnableFlag( true );
926    m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetBits();
927    pRDSbacCoder->setBinsCoded( 0 );
928
929    // encode CTU and calculate the true bit counters.
930    m_pcCuEncoder->encodeCtu( pCtu );
931
932
933    pRDSbacCoder->setBinCountingEnableFlag( false );
934
935    const Int numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();
936
937    // Calculate if this CTU puts us over slice bit size.
938    // cannot terminate if current slice/slice-segment would be 0 Ctu in size,
939    const UInt validEndOfSliceCtuTsAddr = ctuTsAddr + (ctuTsAddr == startCtuTsAddr ? 1 : 0);
940    // Set slice end parameter
941    if(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceBits()+numberOfWrittenBits > (pcSlice->getSliceArgument()<<3))
942    {
943      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
944      pcSlice->setSliceCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
945      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
946    }
947    else if(pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+numberOfWrittenBits > (pcSlice->getSliceSegmentArgument()<<3))
948    {
949      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
950      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
951    }
952
953    if (boundingCtuTsAddr <= ctuTsAddr)
954      break;
955
956    pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) );
957    pcSlice->setSliceSegmentBits(pcSlice->getSliceSegmentBits()+numberOfWrittenBits);
958
959    // Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled.
960    if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getWaveFrontsynchro())
961    {
962      m_entropyCodingSyncContextState.loadContexts(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
963    }
964
965
966    if ( m_pcCfg->getUseRateCtrl() )
967    {
968      Int actualQP        = g_RCInvalidQPValue;
969      Double actualLambda = m_pcRdCost->getLambda();
970      Int actualBits      = pCtu->getTotalBits();
971      Int numberOfEffectivePixels    = 0;
972      for ( Int idx = 0; idx < pcPic->getNumPartitionsInCtu(); idx++ )
973      {
974        if ( pCtu->getPredictionMode( idx ) != NUMBER_OF_PREDICTION_MODES && ( !pCtu->isSkipped( idx ) ) )
975        {
976          numberOfEffectivePixels = numberOfEffectivePixels + 16;
977          break;
978        }
979      }
980
981      if ( numberOfEffectivePixels == 0 )
982      {
983        actualQP = g_RCInvalidQPValue;
984      }
985      else
986      {
987        actualQP = pCtu->getQP( 0 );
988      }
989      m_pcRdCost->setLambda(oldLambda);
990      m_pcRateCtrl->getRCPic()->updateAfterCTU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
991                                                pCtu->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
992    }
993
994    m_uiPicTotalBits += pCtu->getTotalBits();
995    m_dPicRdCost     += pCtu->getTotalCost();
996    m_uiPicDist      += pCtu->getTotalDistortion();
997  }
998
999  // 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.
1000  if( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() )
1001  {
1002    m_lastSliceSegmentEndContextState.loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1003  }
1004
1005  // stop use of temporary bit counter object.
1006  m_pppcRDSbacCoder[0][CI_CURR_BEST]->setBitstream(NULL);
1007  m_pcRDGoOnSbacCoder->setBitstream(NULL); // stop use of tempBitCounter.
1008
1009  // TODO: optimise cabac_init during compress slice to improve multi-slice operation
1010  //if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1011  //{
1012  //  m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx();
1013  //}
1014  //else
1015  //{
1016  //  m_encCABACTableIdx = pcSlice->getSliceType();
1017  //}
1018}
1019
1020/**
1021 \param  rpcPic        picture class
1022 \retval rpcBitstream  bitstream class
1023 */
1024Void TEncSlice::encodeSlice   ( TComPic* pcPic, TComOutputBitstream* pcSubstreams, UInt &numBinsCoded )
1025{
1026  TComSlice* pcSlice                 = pcPic->getSlice(getSliceIdx());
1027
1028  const UInt startCtuTsAddr          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1029  const UInt boundingCtuTsAddr       = pcSlice->getSliceSegmentCurEndCtuTsAddr();
1030
1031  const UInt frameWidthInCtus        = pcPic->getPicSym()->getFrameWidthInCtus();
1032  const Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1033  const Bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
1034
1035  // initialise entropy coder for the slice
1036  m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1037  m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1038  m_pcEntropyCoder->resetEntropy      ();
1039
1040  numBinsCoded = 0;
1041  m_pcBinCABAC->setBinCountingEnableFlag( true );
1042  m_pcBinCABAC->setBinsCoded(0);
1043
1044#if ENC_DEC_TRACE
1045  g_bJustDoIt = g_bEncDecTraceEnable;
1046#endif
1047  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1048  DTRACE_CABAC_T( "\tPOC: " );
1049  DTRACE_CABAC_V( pcPic->getPOC() );
1050  DTRACE_CABAC_T( "\n" );
1051#if ENC_DEC_TRACE
1052  g_bJustDoIt = g_bEncDecTraceDisable;
1053#endif
1054
1055
1056  if (depSliceSegmentsEnabled)
1057  {
1058    // modify initial contexts with previous slice segment if this is a dependent slice.
1059    const UInt ctuRsAddr        = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr );
1060    const UInt currentTileIdx=pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
1061    const TComTile *pCurrentTile=pcPic->getPicSym()->getTComTile(currentTileIdx);
1062    const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr();
1063
1064    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
1065    {
1066      if( pCurrentTile->getTileWidthInCtus() >= 2 || !wavefrontsEnabled )
1067      {
1068        m_pcSbacCoder->loadContexts(&m_lastSliceSegmentEndContextState);
1069      }
1070    }
1071  }
1072
1073  // for every CTU in the slice segment...
1074
1075  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
1076  {
1077    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
1078    const TComTile &currentTile = *(pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr)));
1079    const UInt firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
1080    const UInt tileXPosInCtus       = firstCtuRsAddrOfTile % frameWidthInCtus;
1081    const UInt tileYPosInCtus       = firstCtuRsAddrOfTile / frameWidthInCtus;
1082    const UInt ctuXPosInCtus        = ctuRsAddr % frameWidthInCtus;
1083    const UInt ctuYPosInCtus        = ctuRsAddr / frameWidthInCtus;
1084    const UInt uiSubStrm=pcPic->getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice);
1085    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
1086
1087    m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1088
1089    // set up CABAC contexts' state for this CTU
1090    if (ctuRsAddr == firstCtuRsAddrOfTile)
1091    {
1092      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1093      {
1094        m_pcEntropyCoder->resetEntropy();
1095      }
1096    }
1097    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
1098    {
1099      // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line.
1100      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1101      {
1102        m_pcEntropyCoder->resetEntropy();
1103      }
1104      TComDataCU *pCtuUp = pCtu->getCtuAbove();
1105      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
1106      {
1107        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
1108        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
1109        {
1110          // Top-right is available, so use it.
1111          m_pcSbacCoder->loadContexts( &m_entropyCodingSyncContextState );
1112        }
1113      }
1114    }
1115
1116
1117    if ( pcSlice->getSPS()->getUseSAO() )
1118    {
1119      Bool bIsSAOSliceEnabled = false;
1120      Bool sliceEnabled[MAX_NUM_COMPONENT];
1121      for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
1122      {
1123        ComponentID compId=ComponentID(comp);
1124        sliceEnabled[compId] = pcSlice->getSaoEnabledFlag(toChannelType(compId)) && (comp < pcPic->getNumberValidComponents());
1125        if (sliceEnabled[compId]) bIsSAOSliceEnabled=true;
1126      }
1127      if (bIsSAOSliceEnabled)
1128      {
1129        SAOBlkParam& saoblkParam = (pcPic->getPicSym()->getSAOBlkParam())[ctuRsAddr];
1130
1131        Bool leftMergeAvail = false;
1132        Bool aboveMergeAvail= false;
1133        //merge left condition
1134        Int rx = (ctuRsAddr % frameWidthInCtus);
1135        if(rx > 0)
1136        {
1137          leftMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-1);
1138        }
1139
1140        //merge up condition
1141        Int ry = (ctuRsAddr / frameWidthInCtus);
1142        if(ry > 0)
1143        {
1144          aboveMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-frameWidthInCtus);
1145        }
1146
1147#if SVC_EXTENSION
1148        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, m_ppcTEncTop[pcSlice->getLayerIdx()]->getSAO()->getSaoMaxOffsetQVal(), sliceEnabled, leftMergeAvail, aboveMergeAvail);
1149#else
1150        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, sliceEnabled, leftMergeAvail, aboveMergeAvail);
1151#endif
1152      }
1153    }
1154
1155#if ENC_DEC_TRACE
1156    g_bJustDoIt = g_bEncDecTraceEnable;
1157#endif
1158      m_pcCuEncoder->encodeCtu( pCtu );
1159#if ENC_DEC_TRACE
1160    g_bJustDoIt = g_bEncDecTraceDisable;
1161#endif
1162
1163    //Store probabilities of second CTU in line into buffer
1164    if ( ctuXPosInCtus == tileXPosInCtus+1 && wavefrontsEnabled)
1165    {
1166      m_entropyCodingSyncContextState.loadContexts( m_pcSbacCoder );
1167    }
1168
1169    // terminate the sub-stream, if required (end of slice-segment, end of tile, end of wavefront-CTU-row):
1170    if (ctuTsAddr+1 == boundingCtuTsAddr ||
1171         (  ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus() &&
1172          ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled)
1173         )
1174       )
1175    {
1176      m_pcEntropyCoder->encodeTerminatingBit(1);
1177      m_pcEntropyCoder->encodeSliceFinish();
1178      // Byte-alignment in slice_data() when new tile
1179      pcSubstreams[uiSubStrm].writeByteAlignment();
1180
1181      // write sub-stream size
1182      if (ctuTsAddr+1 != boundingCtuTsAddr)
1183      {
1184        pcSlice->addSubstreamSize( (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations() );
1185      }
1186    }
1187  } // CTU-loop
1188
1189  if( depSliceSegmentsEnabled )
1190  {
1191    m_lastSliceSegmentEndContextState.loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1192  }
1193
1194#if ADAPTIVE_QP_SELECTION
1195  if( m_pcCfg->getUseAdaptQpSelect() )
1196  {
1197    m_pcTrQuant->storeSliceQpNext(pcSlice);
1198  }
1199#endif
1200
1201  if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1202  {
1203    m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx();
1204  }
1205  else
1206  {
1207    m_encCABACTableIdx = pcSlice->getSliceType();
1208  }
1209 
1210  numBinsCoded = m_pcBinCABAC->getBinsCoded();
1211}
1212
1213Void TEncSlice::calculateBoundingCtuTsAddrForSlice(UInt &startCtuTSAddrSlice, UInt &boundingCtuTSAddrSlice, Bool &haveReachedTileBoundary,
1214                                                   TComPic* pcPic, const Bool encodingSlice, const Int sliceMode, const Int sliceArgument, const UInt sliceCurEndCtuTSAddr)
1215{
1216  TComSlice* pcSlice = pcPic->getSlice(getSliceIdx());
1217  const UInt numberOfCtusInFrame = pcPic->getNumberOfCtusInFrame();
1218  boundingCtuTSAddrSlice=0;
1219  haveReachedTileBoundary=false;
1220
1221  switch (sliceMode)
1222  {
1223    case FIXED_NUMBER_OF_CTU:
1224      {
1225        UInt ctuAddrIncrement    = sliceArgument;
1226        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
1227      }
1228      break;
1229    case FIXED_NUMBER_OF_BYTES:
1230      if (encodingSlice)
1231        boundingCtuTSAddrSlice  = sliceCurEndCtuTSAddr;
1232      else
1233        boundingCtuTSAddrSlice  = numberOfCtusInFrame;
1234      break;
1235    case FIXED_NUMBER_OF_TILES:
1236      {
1237        const UInt tileIdx        = pcPic->getPicSym()->getTileIdxMap( pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice) );
1238        const UInt tileTotalCount = (pcPic->getPicSym()->getNumTileColumnsMinus1()+1) * (pcPic->getPicSym()->getNumTileRowsMinus1()+1);
1239        UInt ctuAddrIncrement   = 0;
1240
1241        for(UInt tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++)
1242        {
1243          if((tileIdx + tileIdxIncrement) < tileTotalCount)
1244          {
1245            UInt tileWidthInCtus   = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidthInCtus();
1246            UInt tileHeightInCtus  = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeightInCtus();
1247            ctuAddrIncrement    += (tileWidthInCtus * tileHeightInCtus);
1248          }
1249        }
1250
1251        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
1252      }
1253      break;
1254    default:
1255      boundingCtuTSAddrSlice    = numberOfCtusInFrame;
1256      break;
1257  }
1258
1259  // Adjust for tiles and wavefronts.
1260  if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) &&
1261      (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0))
1262  {
1263    const UInt ctuRSAddr                  = pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice);
1264    const UInt startTileIdx               = pcPic->getPicSym()->getTileIdxMap(ctuRSAddr);
1265    const Bool wavefrontsAreEnabled       = m_pcCfg->getWaveFrontsynchro();
1266
1267    const TComTile *pStartingTile         = pcPic->getPicSym()->getTComTile(startTileIdx);
1268    const UInt tileStartTsAddr            = pcPic->getPicSym()->getCtuRsToTsAddrMap(pStartingTile->getFirstCtuRsAddr());
1269    const UInt tileStartWidth             = pStartingTile->getTileWidthInCtus();
1270    const UInt tileStartHeight            = pStartingTile->getTileHeightInCtus();
1271    const UInt tileLastTsAddr_excl        = tileStartTsAddr + tileStartWidth*tileStartHeight;
1272    const UInt tileBoundingCtuTsAddrSlice = tileLastTsAddr_excl;
1273
1274    const UInt ctuColumnOfStartingTile    = ((startCtuTSAddrSlice-tileStartTsAddr)%tileStartWidth);
1275    if (wavefrontsAreEnabled && ctuColumnOfStartingTile!=0)
1276    {
1277      // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1278      const UInt numberOfCTUsToEndOfRow            = tileStartWidth - ctuColumnOfStartingTile;
1279      const UInt wavefrontTileBoundingCtuAddrSlice = startCtuTSAddrSlice + numberOfCTUsToEndOfRow;
1280      if (wavefrontTileBoundingCtuAddrSlice < boundingCtuTSAddrSlice)
1281      {
1282        boundingCtuTSAddrSlice = wavefrontTileBoundingCtuAddrSlice;
1283      }
1284    }
1285
1286    if (tileBoundingCtuTsAddrSlice < boundingCtuTSAddrSlice)
1287    {
1288      boundingCtuTSAddrSlice = tileBoundingCtuTsAddrSlice;
1289      haveReachedTileBoundary = true;
1290    }
1291  }
1292  else if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) && pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() && ((startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) != 0))
1293  {
1294    // Adjust for wavefronts (no tiles).
1295    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1296    boundingCtuTSAddrSlice = min(boundingCtuTSAddrSlice, startCtuTSAddrSlice - (startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) + (pcPic->getFrameWidthInCtus()));
1297  }
1298}
1299
1300/** Determines the starting and bounding CTU address of current slice / dependent slice
1301 * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
1302 * \returns Updates startCtuTsAddr, boundingCtuTsAddr with appropriate CTU address
1303 */
1304Void TEncSlice::xDetermineStartAndBoundingCtuTsAddr  ( UInt& startCtuTsAddr, UInt& boundingCtuTsAddr, TComPic* pcPic, const Bool encodingSlice )
1305{
1306  TComSlice* pcSlice                 = pcPic->getSlice(getSliceIdx());
1307
1308  // Non-dependent slice
1309  UInt startCtuTsAddrSlice           = pcSlice->getSliceCurStartCtuTsAddr();
1310  Bool haveReachedTileBoundarySlice  = false;
1311  UInt boundingCtuTsAddrSlice;
1312  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSlice, boundingCtuTsAddrSlice, haveReachedTileBoundarySlice, pcPic,
1313                                     encodingSlice, m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument(), pcSlice->getSliceCurEndCtuTsAddr());
1314  pcSlice->setSliceCurEndCtuTsAddr(   boundingCtuTsAddrSlice );
1315  pcSlice->setSliceCurStartCtuTsAddr( startCtuTsAddrSlice    );
1316
1317  // Dependent slice
1318  UInt startCtuTsAddrSliceSegment          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1319  Bool haveReachedTileBoundarySliceSegment = false;
1320  UInt boundingCtuTsAddrSliceSegment;
1321  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSliceSegment, boundingCtuTsAddrSliceSegment, haveReachedTileBoundarySliceSegment, pcPic,
1322                                     encodingSlice, m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument(), pcSlice->getSliceSegmentCurEndCtuTsAddr());
1323  if (boundingCtuTsAddrSliceSegment>boundingCtuTsAddrSlice)
1324  {
1325    boundingCtuTsAddrSliceSegment = boundingCtuTsAddrSlice;
1326  }
1327  pcSlice->setSliceSegmentCurEndCtuTsAddr( boundingCtuTsAddrSliceSegment );
1328  pcSlice->setSliceSegmentCurStartCtuTsAddr(startCtuTsAddrSliceSegment);
1329
1330  // Make a joint decision based on reconstruction and dependent slice bounds
1331  startCtuTsAddr    = max(startCtuTsAddrSlice   , startCtuTsAddrSliceSegment   );
1332  boundingCtuTsAddr = boundingCtuTsAddrSliceSegment;
1333}
1334
1335Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1336{
1337  return 4.2005*log(lambda) + 13.7122;
1338}
1339
1340#if SVC_EXTENSION
1341#if JCTVC_M0259_LAMBDAREFINEMENT
1342Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
1343{
1344  double tmp = beta * pow( 2.0 , deltaQP / 6 );
1345  double gamma = tmp / ( tmp + 1 );
1346  return( gamma );
1347}
1348#endif
1349
1350Void TEncSlice::estimateILWpParam( TComSlice* pcSlice )
1351{
1352  xCalcACDCParamSlice(pcSlice);
1353  WPACDCParam * temp_weightACDCParam;
1354
1355  pcSlice->getWpAcDcParam(temp_weightACDCParam);
1356  g_refWeightACDCParam = (void *) temp_weightACDCParam;
1357}
1358#endif //SVC_EXTENSION
1359//! \}
Note: See TracBrowser for help on using the repository browser.