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

Last change on this file since 1544 was 1540, checked in by seregin, 10 years ago

port rev 4692

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