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

Last change on this file since 1590 was 1570, checked in by seregin, 9 years ago

port rev 4748

  • Property svn:eol-style set to native
File size: 50.7 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-2016, 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()->getTransquantBypassEnabledFlag())))
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#if W0062_RECALCULATE_QP_TO_ALIGN_WITH_LAMBDA
379    Double lambdaRef = 0.57*pow(2.0, qp_temp/3.0);
380    // QP correction due to modified lambda
381    Double qpOffset = floor((3.0*log(dLambda/lambdaRef)/log(2.0)) +0.5);
382    dQP += qpOffset;
383#endif
384
385    iQP = max( -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
386
387    m_vdRdPicLambda[iDQpIdx] = dLambda;
388    m_vdRdPicQp    [iDQpIdx] = dQP;
389    m_viRdPicQp    [iDQpIdx] = iQP;
390  }
391
392  // obtain dQP = 0 case
393  dLambda = m_vdRdPicLambda[0];
394  dQP     = m_vdRdPicQp    [0];
395  iQP     = m_viRdPicQp    [0];
396
397  const Int temporalId=m_pcCfg->getGOPEntry(iGOPid).m_temporalId;
398  const std::vector<Double> &intraLambdaModifiers=m_pcCfg->getIntraLambdaModifier();
399
400#if W0038_CQP_ADJ
401  if(rpcSlice->getPPS()->getSliceChromaQpFlag())
402  {
403    const Bool bUseIntraOrPeriodicOffset = rpcSlice->getSliceType()==I_SLICE || (m_pcCfg->getSliceChromaOffsetQpPeriodicity()!=0 && (rpcSlice->getPOC()%m_pcCfg->getSliceChromaOffsetQpPeriodicity())==0);
404    Int cbQP = bUseIntraOrPeriodicOffset? m_pcCfg->getSliceChromaOffsetQpIntraOrPeriodic(false) : m_pcCfg->getGOPEntry(iGOPid).m_CbQPoffset;
405    Int crQP = bUseIntraOrPeriodicOffset? m_pcCfg->getSliceChromaOffsetQpIntraOrPeriodic(true)  : m_pcCfg->getGOPEntry(iGOPid).m_CrQPoffset;
406
407    cbQP = Clip3( -12, 12, cbQP + rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb) ) - rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb); 
408    crQP = Clip3( -12, 12, crQP + rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr) ) - rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr); 
409    rpcSlice->setSliceChromaQpDelta(COMPONENT_Cb, Clip3( -12, 12, cbQP));
410    assert(rpcSlice->getSliceChromaQpDelta(COMPONENT_Cb)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb)<=12 && rpcSlice->getSliceChromaQpDelta(COMPONENT_Cb)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb)>=-12);
411    rpcSlice->setSliceChromaQpDelta(COMPONENT_Cr, Clip3( -12, 12, crQP));
412    assert(rpcSlice->getSliceChromaQpDelta(COMPONENT_Cr)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr)<=12 && rpcSlice->getSliceChromaQpDelta(COMPONENT_Cr)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr)>=-12);
413  }
414  else
415  {
416    rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
417    rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
418  }
419#endif
420
421  Double lambdaModifier;
422  if( rpcSlice->getSliceType( ) != I_SLICE || intraLambdaModifiers.empty())
423  {
424    lambdaModifier = m_pcCfg->getLambdaModifier( temporalId );
425  }
426  else
427  {
428    lambdaModifier = intraLambdaModifiers[ (temporalId < intraLambdaModifiers.size()) ? temporalId : (intraLambdaModifiers.size()-1) ];
429  }
430
431  dLambda *= lambdaModifier;
432
433#if JCTVC_M0259_LAMBDAREFINEMENT
434  setUpLambda(rpcSlice, dLambda, iQP, depth);
435#else
436  setUpLambda(rpcSlice, dLambda, iQP);
437#endif
438
439  if (m_pcCfg->getFastMEForGenBLowDelayEnabled())
440  {
441    // restore original slice type
442
443    if(!(isField && pocLast == 1) || !m_pcCfg->getEfficientFieldIRAPEnabled())
444    {
445      if(m_pcCfg->getDecodingRefreshType() == 3)
446      {
447        eSliceType = (pocLast == 0 || (pocCurr)                     % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
448      }
449      else
450      {
451        eSliceType = (pocLast == 0 || (pocCurr - (isField ? 1 : 0)) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
452      }
453    }
454
455#if SVC_EXTENSION
456    if( m_pcCfg->getLayerId() > 0 && m_pcCfg->getNumActiveRefLayers() > 0 )
457    {
458      eSliceType=B_SLICE;
459    }
460#endif
461
462    rpcSlice->setSliceType        ( eSliceType );
463  }
464
465  if (m_pcCfg->getUseRecalculateQPAccordingToLambda())
466  {
467    dQP = xGetQPValueAccordingToLambda( dLambda );
468    iQP = max( -rpcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), min( MAX_QP, (Int) floor( dQP + 0.5 ) ) );
469  }
470
471  rpcSlice->setSliceQp           ( iQP );
472#if ADAPTIVE_QP_SELECTION
473  rpcSlice->setSliceQpBase       ( iQP );
474#endif
475  rpcSlice->setSliceQpDelta      ( 0 );
476#if !W0038_CQP_ADJ
477  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cb, 0 );
478  rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
479#endif
480  rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getPpsRangeExtension().getChromaQpOffsetListEnabledFlag() );
481  rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
482  rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive);
483
484  if ( m_pcCfg->getDeblockingFilterMetric() )
485  {
486    rpcSlice->setDeblockingFilterOverrideFlag(true);
487    rpcSlice->setDeblockingFilterDisable(false);
488    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
489    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
490  }
491  else if (rpcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
492  {
493    rpcSlice->setDeblockingFilterOverrideFlag( rpcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() );
494    rpcSlice->setDeblockingFilterDisable( rpcSlice->getPPS()->getPPSDeblockingFilterDisabledFlag() );
495    if ( !rpcSlice->getDeblockingFilterDisable())
496    {
497      if ( rpcSlice->getDeblockingFilterOverrideFlag() && eSliceType!=I_SLICE)
498      {
499        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_betaOffsetDiv2 + m_pcCfg->getLoopFilterBetaOffset()  );
500        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getGOPEntry(iGOPid).m_tcOffsetDiv2 + m_pcCfg->getLoopFilterTcOffset() );
501      }
502      else
503      {
504        rpcSlice->setDeblockingFilterBetaOffsetDiv2( m_pcCfg->getLoopFilterBetaOffset() );
505        rpcSlice->setDeblockingFilterTcOffsetDiv2( m_pcCfg->getLoopFilterTcOffset() );
506      }
507    }
508  }
509  else
510  {
511    rpcSlice->setDeblockingFilterOverrideFlag( false );
512    rpcSlice->setDeblockingFilterDisable( false );
513    rpcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
514    rpcSlice->setDeblockingFilterTcOffsetDiv2( 0 );
515  }
516
517  rpcSlice->setDepth            ( depth );
518
519  pcPic->setTLayer( temporalId );
520#if SVC_EXTENSION
521  if( eSliceType==I_SLICE || m_ppcTEncTop[pcPic->getLayerIdx()]->getPOCLast() == 0 )
522#else
523  if(eSliceType==I_SLICE)
524#endif
525  {
526    pcPic->setTLayer(0);
527  }
528  rpcSlice->setTLayer( pcPic->getTLayer() );
529
530  pcPic->setPicYuvPred( &m_picYuvPred );
531  pcPic->setPicYuvResi( &m_picYuvResi );
532  rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
533  rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
534  rpcSlice->setSliceSegmentMode     ( m_pcCfg->getSliceSegmentMode()     );
535  rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() );
536  rpcSlice->setMaxNumMergeCand        ( m_pcCfg->getMaxNumMergeCand()        );
537
538#if HIGHER_LAYER_IRAP_SKIP_FLAG
539  if( m_pcCfg->getSkipPictureAtArcSwitch() && m_pcCfg->getAdaptiveResolutionChange() > 0 && rpcSlice->getLayerId() == 1 && rpcSlice->getPOC() == m_pcCfg->getAdaptiveResolutionChange() )
540  {
541    rpcSlice->setMaxNumMergeCand        ( 1 );
542  }
543#endif
544
545#if SVC_EXTENSION
546  if( layerId > 0 )
547  {
548    if( rpcSlice->getNumILRRefIdx() > 0 )
549    {
550      rpcSlice->setActiveNumILRRefIdx( m_ppcTEncTop[rpcSlice->getVPS()->getLayerIdxInVps(layerId)]->getNumActiveRefLayers() );
551      for( Int i = 0; i < rpcSlice->getActiveNumILRRefIdx(); i++ )
552      {
553        rpcSlice->setInterLayerPredLayerIdc( m_ppcTEncTop[rpcSlice->getVPS()->getLayerIdxInVps(layerId)]->getPredLayerIdx(i), i );
554      }
555      rpcSlice->setInterLayerPredEnabledFlag(1);
556    }
557    rpcSlice->setMFMEnabledFlag(m_ppcTEncTop[rpcSlice->getVPS()->getLayerIdxInVps(layerId)]->getMFMEnabledFlag());
558  }
559
560#endif
561}
562
563Void TEncSlice::resetQP( TComPic* pic, Int sliceQP, Double lambda )
564{
565  TComSlice* slice = pic->getSlice(0);
566
567  // store lambda
568  slice->setSliceQp( sliceQP );
569#if ADAPTIVE_QP_SELECTION
570  slice->setSliceQpBase ( sliceQP );
571#endif
572  setUpLambda(slice, lambda, sliceQP);
573}
574
575// ====================================================================================================================
576// Public member functions
577// ====================================================================================================================
578
579//! set adaptive search range based on poc difference
580Void TEncSlice::setSearchRange( TComSlice* pcSlice )
581{
582  Int iCurrPOC = pcSlice->getPOC();
583  Int iRefPOC;
584  Int iGOPSize = m_pcCfg->getGOPSize();
585  Int iOffset = (iGOPSize >> 1);
586  Int iMaxSR = m_pcCfg->getSearchRange();
587  Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
588
589  for (Int iDir = 0; iDir < iNumPredDir; iDir++)
590  {
591    RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
592    for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
593    {
594      iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
595      Int newSearchRange = Clip3(m_pcCfg->getMinSearchWindow(), iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
596      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, newSearchRange);
597    }
598  }
599}
600
601/**
602 Multi-loop slice encoding for different slice QP
603
604 \param pcPic    picture class
605 */
606Void TEncSlice::precompressSlice( TComPic* pcPic )
607{
608  // if deltaQP RD is not used, simply return
609  if ( m_pcCfg->getDeltaQpRD() == 0 )
610  {
611    return;
612  }
613
614  if ( m_pcCfg->getUseRateCtrl() )
615  {
616    printf( "\nMultiple QP optimization is not allowed when rate control is enabled." );
617    assert(0);
618    return;
619  }
620
621  TComSlice* pcSlice        = pcPic->getSlice(getSliceIdx());
622
623  if (pcSlice->getDependentSliceSegmentFlag())
624  {
625    // if this is a dependent slice segment, then it was optimised
626    // when analysing the entire slice.
627    return;
628  }
629
630  if (pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES)
631  {
632    // TODO: investigate use of average cost per CTU so that this Slice Mode can be used.
633    printf( "\nUnable to optimise Slice-level QP if Slice Mode is set to FIXED_NUMBER_OF_BYTES\n" );
634    assert(0);
635    return;
636  }
637
638  Double     dPicRdCostBest = MAX_DOUBLE;
639  UInt       uiQpIdxBest = 0;
640
641  Double dFrameLambda;
642#if FULL_NBIT
643  Int    SHIFT_QP = 12 + 6 * (pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - 8);
644#else
645  Int    SHIFT_QP = 12;
646#endif
647
648  // set frame lambda
649  if (m_pcCfg->getGOPSize() > 1)
650  {
651    dFrameLambda = 0.68 * pow (2, (m_viRdPicQp[0]  - SHIFT_QP) / 3.0) * (pcSlice->isInterB()? 2 : 1);
652  }
653  else
654  {
655    dFrameLambda = 0.68 * pow (2, (m_viRdPicQp[0] - SHIFT_QP) / 3.0);
656  }
657  m_pcRdCost      ->setFrameLambda(dFrameLambda);
658
659  // for each QP candidate
660  for ( UInt uiQpIdx = 0; uiQpIdx < 2 * m_pcCfg->getDeltaQpRD() + 1; uiQpIdx++ )
661  {
662    pcSlice       ->setSliceQp             ( m_viRdPicQp    [uiQpIdx] );
663#if ADAPTIVE_QP_SELECTION
664    pcSlice       ->setSliceQpBase         ( m_viRdPicQp    [uiQpIdx] );
665#endif
666    setUpLambda(pcSlice, m_vdRdPicLambda[uiQpIdx], m_viRdPicQp    [uiQpIdx]);
667
668    // try compress
669    compressSlice   ( pcPic, true, m_pcCfg->getFastDeltaQp());
670
671    UInt64 uiPicDist        = m_uiPicDist; // Distortion, as calculated by compressSlice.
672    // NOTE: This distortion is the chroma-weighted SSE distortion for the slice.
673    //       Previously a standard SSE distortion was calculated (for the entire frame).
674    //       Which is correct?
675
676    // TODO: Update loop filter, SAO and distortion calculation to work on one slice only.
677    // m_pcGOPEncoder->preLoopFilterPicAll( pcPic, uiPicDist );
678
679    // compute RD cost and choose the best
680    Double dPicRdCost = m_pcRdCost->calcRdCost( (Double)m_uiPicTotalBits, (Double)uiPicDist, DF_SSE_FRAME);
681
682    if ( dPicRdCost < dPicRdCostBest )
683    {
684      uiQpIdxBest    = uiQpIdx;
685      dPicRdCostBest = dPicRdCost;
686    }
687  }
688
689  // set best values
690  pcSlice       ->setSliceQp             ( m_viRdPicQp    [uiQpIdxBest] );
691#if ADAPTIVE_QP_SELECTION
692  pcSlice       ->setSliceQpBase         ( m_viRdPicQp    [uiQpIdxBest] );
693#endif
694  setUpLambda(pcSlice, m_vdRdPicLambda[uiQpIdxBest], m_viRdPicQp    [uiQpIdxBest]);
695}
696
697Void TEncSlice::calCostSliceI(TComPic* pcPic) // TODO: this only analyses the first slice segment. What about the others?
698{
699  Double            iSumHadSlice      = 0;
700  TComSlice * const pcSlice           = pcPic->getSlice(getSliceIdx());
701  const TComSPS    &sps               = *(pcSlice->getSPS());
702  const Int         shift             = sps.getBitDepth(CHANNEL_TYPE_LUMA)-8;
703  const Int         offset            = (shift>0)?(1<<(shift-1)):0;
704
705  pcSlice->setSliceSegmentBits(0);
706
707  UInt startCtuTsAddr, boundingCtuTsAddr;
708  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic );
709
710  for( UInt ctuTsAddr = startCtuTsAddr, ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
711       ctuTsAddr < boundingCtuTsAddr;
712       ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(++ctuTsAddr) )
713  {
714    // initialize CU encoder
715    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
716    pCtu->initCtu( pcPic, ctuRsAddr );
717
718    Int height  = min( sps.getMaxCUHeight(),sps.getPicHeightInLumaSamples() - ctuRsAddr / pcPic->getFrameWidthInCtus() * sps.getMaxCUHeight() );
719    Int width   = min( sps.getMaxCUWidth(), sps.getPicWidthInLumaSamples()  - ctuRsAddr % pcPic->getFrameWidthInCtus() * sps.getMaxCUWidth() );
720
721    Int iSumHad = m_pcCuEncoder->updateCtuDataISlice(pCtu, width, height);
722
723    (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra=(iSumHad+offset)>>shift;
724    iSumHadSlice += (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_costIntra;
725
726  }
727  m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice);
728}
729
730/** \param pcPic   picture class
731 */
732Void TEncSlice::compressSlice( TComPic* pcPic, const Bool bCompressEntireSlice, const Bool bFastDeltaQP )
733{
734  // if bCompressEntireSlice is true, then the entire slice (not slice segment) is compressed,
735  //   effectively disabling the slice-segment-mode.
736
737  UInt   startCtuTsAddr;
738  UInt   boundingCtuTsAddr;
739  TComSlice* const pcSlice            = pcPic->getSlice(getSliceIdx());
740  pcSlice->setSliceSegmentBits(0);
741  xDetermineStartAndBoundingCtuTsAddr ( startCtuTsAddr, boundingCtuTsAddr, pcPic );
742  if (bCompressEntireSlice)
743  {
744    boundingCtuTsAddr = pcSlice->getSliceCurEndCtuTsAddr();
745    pcSlice->setSliceSegmentCurEndCtuTsAddr(boundingCtuTsAddr);
746  }
747
748  // initialize cost values - these are used by precompressSlice (they should be parameters).
749  m_uiPicTotalBits  = 0;
750  m_dPicRdCost      = 0; // NOTE: This is a write-only variable!
751  m_uiPicDist       = 0;
752
753  m_pcEntropyCoder->setEntropyCoder   ( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
754  m_pcEntropyCoder->resetEntropy      ( pcSlice );
755
756  TEncBinCABAC* pRDSbacCoder = (TEncBinCABAC *) m_pppcRDSbacCoder[0][CI_CURR_BEST]->getEncBinIf();
757  pRDSbacCoder->setBinCountingEnableFlag( false );
758  pRDSbacCoder->setBinsCoded( 0 );
759
760  TComBitCounter  tempBitCounter;
761  const UInt      frameWidthInCtus = pcPic->getPicSym()->getFrameWidthInCtus();
762 
763  m_pcCuEncoder->setFastDeltaQp(bFastDeltaQP);
764
765  //------------------------------------------------------------------------------
766  //  Weighted Prediction parameters estimation.
767  //------------------------------------------------------------------------------
768  // calculate AC/DC values for current picture
769  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
770  {
771    xCalcACDCParamSlice(pcSlice);
772  }
773#if SVC_EXTENSION
774  else if( m_ppcTEncTop[pcSlice->getLayerIdx()]->getInterLayerWeightedPredFlag() )
775  {
776    // Calculate for the base layer to be used in EL as Inter layer reference
777    estimateILWpParam( pcSlice );   
778  }
779#endif
780
781  const Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
782
783  if ( bWp_explicit )
784  {
785    //------------------------------------------------------------------------------
786    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
787    //------------------------------------------------------------------------------
788    if ( pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES || pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES )
789    {
790      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
791    }
792
793    xEstimateWPParamSlice( pcSlice, m_pcCfg->getWeightedPredictionMethod() );
794    pcSlice->initWpScaling(pcSlice->getSPS());
795
796    // check WP on/off
797    xCheckWPEnable( pcSlice );
798  }
799
800#if ADAPTIVE_QP_SELECTION
801  if( m_pcCfg->getUseAdaptQpSelect() && !(pcSlice->getDependentSliceSegmentFlag()))
802  {
803    // TODO: this won't work with dependent slices: they do not have their own QP. Check fix to mask clause execution with && !(pcSlice->getDependentSliceSegmentFlag())
804    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)
805    if(pcSlice->getSliceType()!=I_SLICE)
806    {
807      Int qpBase = pcSlice->getSliceQpBase();
808      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
809    }
810  }
811#endif
812
813
814
815  // Adjust initial state if this is the start of a dependent slice.
816  {
817    const UInt      ctuRsAddr               = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
818    const UInt      currentTileIdx          = pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
819    const TComTile *pCurrentTile            = pcPic->getPicSym()->getTComTile(currentTileIdx);
820    const UInt      firstCtuRsAddrOfTile    = pCurrentTile->getFirstCtuRsAddr();
821    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
822    {
823      // This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used.
824      if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getEntropyCodingSyncEnabledFlag() )
825      {
826        m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_lastSliceSegmentEndContextState );
827      }
828    }
829  }
830
831  // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
832
833  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
834  {
835    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
836    // initialize CTU encoder
837    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
838    pCtu->initCtu( pcPic, ctuRsAddr );
839
840    // update CABAC state
841    const UInt firstCtuRsAddrOfTile = pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr))->getFirstCtuRsAddr();
842    const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;
843    const UInt ctuXPosInCtus  = ctuRsAddr % frameWidthInCtus;
844   
845    if (ctuRsAddr == firstCtuRsAddrOfTile)
846    {
847      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);
848    }
849    else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getEntropyCodingSyncEnabledFlag())
850    {
851      // reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile).
852      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);
853      // Sync if the Top-Right is available.
854      TComDataCU *pCtuUp = pCtu->getCtuAbove();
855      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
856      {
857        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
858        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
859        {
860          // Top-Right is available, we use it.
861          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_entropyCodingSyncContextState );
862        }
863      }
864    }
865
866    // set go-on entropy coder (used for all trial encodings - the cu encoder and encoder search also have a copy of the same pointer)
867    m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder );
868    m_pcEntropyCoder->setBitstream( &tempBitCounter );
869    tempBitCounter.resetBits();
870    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); // this copy is not strictly necessary here, but indicates that the GoOnSbacCoder
871                                                                     // is reset to a known state before every decision process.
872
873    ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
874
875    Double oldLambda = m_pcRdCost->getLambda();
876    if ( m_pcCfg->getUseRateCtrl() )
877    {
878      Int estQP        = pcSlice->getSliceQp();
879      Double estLambda = -1.0;
880      Double bpp       = -1.0;
881
882      if ( ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
883      {
884        estQP = pcSlice->getSliceQp();
885      }
886      else
887      {
888        bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
889        if ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE)
890        {
891          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
892        }
893        else
894        {
895          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
896          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
897        }
898
899        estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP );
900
901        m_pcRdCost->setLambda(estLambda, pcSlice->getSPS()->getBitDepths());
902
903#if RDOQ_CHROMA_LAMBDA
904        // set lambda for RDOQ
905        const Double chromaLambda = estLambda / m_pcRdCost->getChromaWeight();
906        const Double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda };
907        m_pcTrQuant->setLambdas( lambdaArray );
908#else
909        m_pcTrQuant->setLambda( estLambda );
910#endif
911      }
912
913      m_pcRateCtrl->setRCQP( estQP );
914#if ADAPTIVE_QP_SELECTION
915      pCtu->getSlice()->setSliceQpBase( estQP );
916#endif
917    }
918
919    // run CTU trial encoder
920    m_pcCuEncoder->compressCtu( pCtu );
921
922
923    // All CTU decisions have now been made. Restore entropy coder to an initial stage, ready to make a true encode,
924    // which will result in the state of the contexts being correct. It will also count up the number of bits coded,
925    // which is used if there is a limit of the number of bytes per slice-segment.
926
927    m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
928    m_pcEntropyCoder->setBitstream( &tempBitCounter );
929    pRDSbacCoder->setBinCountingEnableFlag( true );
930    m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetBits();
931    pRDSbacCoder->setBinsCoded( 0 );
932
933    // encode CTU and calculate the true bit counters.
934    m_pcCuEncoder->encodeCtu( pCtu );
935
936
937    pRDSbacCoder->setBinCountingEnableFlag( false );
938
939    const Int numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();
940
941    // Calculate if this CTU puts us over slice bit size.
942    // cannot terminate if current slice/slice-segment would be 0 Ctu in size,
943    const UInt validEndOfSliceCtuTsAddr = ctuTsAddr + (ctuTsAddr == startCtuTsAddr ? 1 : 0);
944    // Set slice end parameter
945    if(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceBits()+numberOfWrittenBits > (pcSlice->getSliceArgument()<<3))
946    {
947      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
948      pcSlice->setSliceCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
949      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
950    }
951    else if((!bCompressEntireSlice) && pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+numberOfWrittenBits > (pcSlice->getSliceSegmentArgument()<<3))
952    {
953      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
954      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
955    }
956
957    if (boundingCtuTsAddr <= ctuTsAddr)
958    {
959      break;
960    }
961
962    pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) );
963    pcSlice->setSliceSegmentBits(pcSlice->getSliceSegmentBits()+numberOfWrittenBits);
964
965    // Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled.
966    if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getEntropyCodingSyncEnabledFlag())
967    {
968      m_entropyCodingSyncContextState.loadContexts(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
969    }
970
971
972    if ( m_pcCfg->getUseRateCtrl() )
973    {
974      Int actualQP        = g_RCInvalidQPValue;
975      Double actualLambda = m_pcRdCost->getLambda();
976      Int actualBits      = pCtu->getTotalBits();
977      Int numberOfEffectivePixels    = 0;
978      for ( Int idx = 0; idx < pcPic->getNumPartitionsInCtu(); idx++ )
979      {
980        if ( pCtu->getPredictionMode( idx ) != NUMBER_OF_PREDICTION_MODES && ( !pCtu->isSkipped( idx ) ) )
981        {
982          numberOfEffectivePixels = numberOfEffectivePixels + 16;
983          break;
984        }
985      }
986
987      if ( numberOfEffectivePixels == 0 )
988      {
989        actualQP = g_RCInvalidQPValue;
990      }
991      else
992      {
993        actualQP = pCtu->getQP( 0 );
994      }
995      m_pcRdCost->setLambda(oldLambda, pcSlice->getSPS()->getBitDepths());
996      m_pcRateCtrl->getRCPic()->updateAfterCTU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
997                                                pCtu->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
998    }
999
1000    m_uiPicTotalBits += pCtu->getTotalBits();
1001    m_dPicRdCost     += pCtu->getTotalCost();
1002    m_uiPicDist      += pCtu->getTotalDistortion();
1003  }
1004
1005  // store context state at the end of this slice-segment, in case the next slice is a dependent slice and continues using the CABAC contexts.
1006  if( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() )
1007  {
1008    m_lastSliceSegmentEndContextState.loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1009  }
1010
1011  // stop use of temporary bit counter object.
1012  m_pppcRDSbacCoder[0][CI_CURR_BEST]->setBitstream(NULL);
1013  m_pcRDGoOnSbacCoder->setBitstream(NULL); // stop use of tempBitCounter.
1014
1015  // TODO: optimise cabac_init during compress slice to improve multi-slice operation
1016  //if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1017  //{
1018  //  m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx();
1019  //}
1020  //else
1021  //{
1022  //  m_encCABACTableIdx = pcSlice->getSliceType();
1023  //}
1024}
1025
1026Void TEncSlice::encodeSlice   ( TComPic* pcPic, TComOutputBitstream* pcSubstreams, UInt &numBinsCoded )
1027{
1028  TComSlice *const pcSlice           = pcPic->getSlice(getSliceIdx());
1029
1030  const UInt startCtuTsAddr          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1031  const UInt boundingCtuTsAddr       = pcSlice->getSliceSegmentCurEndCtuTsAddr();
1032
1033  const UInt frameWidthInCtus        = pcPic->getPicSym()->getFrameWidthInCtus();
1034  const Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1035  const Bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
1036
1037  // initialise entropy coder for the slice
1038  m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1039  m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder );
1040  m_pcEntropyCoder->resetEntropy    ( pcSlice );
1041
1042  numBinsCoded = 0;
1043  m_pcBinCABAC->setBinCountingEnableFlag( true );
1044  m_pcBinCABAC->setBinsCoded(0);
1045
1046#if ENC_DEC_TRACE
1047  g_bJustDoIt = g_bEncDecTraceEnable;
1048#endif
1049  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1050  DTRACE_CABAC_T( "\tPOC: " );
1051  DTRACE_CABAC_V( pcPic->getPOC() );
1052  DTRACE_CABAC_T( "\n" );
1053#if ENC_DEC_TRACE
1054  g_bJustDoIt = g_bEncDecTraceDisable;
1055#endif
1056
1057
1058  if (depSliceSegmentsEnabled)
1059  {
1060    // modify initial contexts with previous slice segment if this is a dependent slice.
1061    const UInt ctuRsAddr        = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr );
1062    const UInt currentTileIdx=pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
1063    const TComTile *pCurrentTile=pcPic->getPicSym()->getTComTile(currentTileIdx);
1064    const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr();
1065
1066    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
1067    {
1068      if( pCurrentTile->getTileWidthInCtus() >= 2 || !wavefrontsEnabled )
1069      {
1070        m_pcSbacCoder->loadContexts(&m_lastSliceSegmentEndContextState);
1071      }
1072    }
1073  }
1074
1075  // for every CTU in the slice segment...
1076
1077  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
1078  {
1079    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
1080    const TComTile &currentTile = *(pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr)));
1081    const UInt firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
1082    const UInt tileXPosInCtus       = firstCtuRsAddrOfTile % frameWidthInCtus;
1083    const UInt tileYPosInCtus       = firstCtuRsAddrOfTile / frameWidthInCtus;
1084    const UInt ctuXPosInCtus        = ctuRsAddr % frameWidthInCtus;
1085    const UInt ctuYPosInCtus        = ctuRsAddr / frameWidthInCtus;
1086    const UInt uiSubStrm=pcPic->getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice);
1087    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
1088
1089    m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1090
1091    // set up CABAC contexts' state for this CTU
1092    if (ctuRsAddr == firstCtuRsAddrOfTile)
1093    {
1094      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1095      {
1096        m_pcEntropyCoder->resetEntropy(pcSlice);
1097      }
1098    }
1099    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
1100    {
1101      // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line.
1102      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1103      {
1104        m_pcEntropyCoder->resetEntropy(pcSlice);
1105      }
1106      TComDataCU *pCtuUp = pCtu->getCtuAbove();
1107      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
1108      {
1109        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
1110        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
1111        {
1112          // Top-right is available, so use it.
1113          m_pcSbacCoder->loadContexts( &m_entropyCodingSyncContextState );
1114        }
1115      }
1116    }
1117
1118
1119    if ( pcSlice->getSPS()->getUseSAO() )
1120    {
1121      Bool bIsSAOSliceEnabled = false;
1122      Bool sliceEnabled[MAX_NUM_COMPONENT];
1123      for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
1124      {
1125        ComponentID compId=ComponentID(comp);
1126        sliceEnabled[compId] = pcSlice->getSaoEnabledFlag(toChannelType(compId)) && (comp < pcPic->getNumberValidComponents());
1127        if (sliceEnabled[compId])
1128        {
1129          bIsSAOSliceEnabled=true;
1130        }
1131      }
1132      if (bIsSAOSliceEnabled)
1133      {
1134        SAOBlkParam& saoblkParam = (pcPic->getPicSym()->getSAOBlkParam())[ctuRsAddr];
1135
1136        Bool leftMergeAvail = false;
1137        Bool aboveMergeAvail= false;
1138        //merge left condition
1139        Int rx = (ctuRsAddr % frameWidthInCtus);
1140        if(rx > 0)
1141        {
1142          leftMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-1);
1143        }
1144
1145        //merge up condition
1146        Int ry = (ctuRsAddr / frameWidthInCtus);
1147        if(ry > 0)
1148        {
1149          aboveMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-frameWidthInCtus);
1150        }
1151
1152        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, pcPic->getPicSym()->getSPS().getBitDepths(), sliceEnabled, leftMergeAvail, aboveMergeAvail);
1153      }
1154    }
1155
1156#if ENC_DEC_TRACE
1157    g_bJustDoIt = g_bEncDecTraceEnable;
1158#endif
1159      m_pcCuEncoder->encodeCtu( pCtu );
1160#if ENC_DEC_TRACE
1161    g_bJustDoIt = g_bEncDecTraceDisable;
1162#endif
1163
1164    //Store probabilities of second CTU in line into buffer
1165    if ( ctuXPosInCtus == tileXPosInCtus+1 && wavefrontsEnabled)
1166    {
1167      m_entropyCodingSyncContextState.loadContexts( m_pcSbacCoder );
1168    }
1169
1170    // terminate the sub-stream, if required (end of slice-segment, end of tile, end of wavefront-CTU-row):
1171    if (ctuTsAddr+1 == boundingCtuTsAddr ||
1172         (  ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus() &&
1173          ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled)
1174         )
1175       )
1176    {
1177      m_pcEntropyCoder->encodeTerminatingBit(1);
1178      m_pcEntropyCoder->encodeSliceFinish();
1179      // Byte-alignment in slice_data() when new tile
1180      pcSubstreams[uiSubStrm].writeByteAlignment();
1181
1182      // write sub-stream size
1183      if (ctuTsAddr+1 != boundingCtuTsAddr)
1184      {
1185        pcSlice->addSubstreamSize( (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations() );
1186      }
1187    }
1188  } // CTU-loop
1189
1190  if( depSliceSegmentsEnabled )
1191  {
1192    m_lastSliceSegmentEndContextState.loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1193  }
1194
1195#if ADAPTIVE_QP_SELECTION
1196  if( m_pcCfg->getUseAdaptQpSelect() )
1197  {
1198    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.
1199  }
1200#endif
1201
1202  if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1203  {
1204    m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx(pcSlice);
1205  }
1206  else
1207  {
1208    m_encCABACTableIdx = pcSlice->getSliceType();
1209  }
1210 
1211  numBinsCoded = m_pcBinCABAC->getBinsCoded();
1212}
1213
1214Void TEncSlice::calculateBoundingCtuTsAddrForSlice(UInt &startCtuTSAddrSlice, UInt &boundingCtuTSAddrSlice, Bool &haveReachedTileBoundary,
1215                                                   TComPic* pcPic, const Int sliceMode, const Int sliceArgument)
1216{
1217  TComSlice* pcSlice = pcPic->getSlice(getSliceIdx());
1218  const UInt numberOfCtusInFrame = pcPic->getNumberOfCtusInFrame();
1219  const TComPPS &pps=*(pcSlice->getPPS());
1220  boundingCtuTSAddrSlice=0;
1221  haveReachedTileBoundary=false;
1222
1223  switch (sliceMode)
1224  {
1225    case FIXED_NUMBER_OF_CTU:
1226      {
1227        UInt ctuAddrIncrement    = sliceArgument;
1228        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
1229      }
1230      break;
1231    case FIXED_NUMBER_OF_BYTES:
1232      boundingCtuTSAddrSlice  = numberOfCtusInFrame; // This will be adjusted later if required.
1233      break;
1234    case FIXED_NUMBER_OF_TILES:
1235      {
1236        const UInt tileIdx        = pcPic->getPicSym()->getTileIdxMap( pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice) );
1237        const UInt tileTotalCount = (pcPic->getPicSym()->getNumTileColumnsMinus1()+1) * (pcPic->getPicSym()->getNumTileRowsMinus1()+1);
1238        UInt ctuAddrIncrement   = 0;
1239
1240        for(UInt tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++)
1241        {
1242          if((tileIdx + tileIdxIncrement) < tileTotalCount)
1243          {
1244            UInt tileWidthInCtus   = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidthInCtus();
1245            UInt tileHeightInCtus  = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeightInCtus();
1246            ctuAddrIncrement    += (tileWidthInCtus * tileHeightInCtus);
1247          }
1248        }
1249
1250        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
1251      }
1252      break;
1253    default:
1254      boundingCtuTSAddrSlice    = numberOfCtusInFrame;
1255      break;
1256  }
1257
1258  // Adjust for tiles and wavefronts.
1259  const Bool wavefrontsAreEnabled = pps.getEntropyCodingSyncEnabledFlag();
1260
1261  if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) &&
1262      (pps.getNumTileRowsMinus1() > 0 || pps.getNumTileColumnsMinus1() > 0))
1263  {
1264    const UInt ctuRSAddr                  = pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice);
1265    const UInt startTileIdx               = pcPic->getPicSym()->getTileIdxMap(ctuRSAddr);
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) && wavefrontsAreEnabled && ((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 [out] startCtuTsAddr
1302 * \param [out] boundingCtuTsAddr
1303 * \param [in]  pcPic
1304
1305 * Updates startCtuTsAddr, boundingCtuTsAddr with appropriate CTU address
1306 */
1307Void TEncSlice::xDetermineStartAndBoundingCtuTsAddr  ( UInt& startCtuTsAddr, UInt& boundingCtuTsAddr, TComPic* pcPic )
1308{
1309  TComSlice* pcSlice                 = pcPic->getSlice(getSliceIdx());
1310
1311  // Non-dependent slice
1312  UInt startCtuTsAddrSlice           = pcSlice->getSliceCurStartCtuTsAddr();
1313  Bool haveReachedTileBoundarySlice  = false;
1314  UInt boundingCtuTsAddrSlice;
1315  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSlice, boundingCtuTsAddrSlice, haveReachedTileBoundarySlice, pcPic,
1316                                     m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument());
1317  pcSlice->setSliceCurEndCtuTsAddr(   boundingCtuTsAddrSlice );
1318  pcSlice->setSliceCurStartCtuTsAddr( startCtuTsAddrSlice    );
1319
1320  // Dependent slice
1321  UInt startCtuTsAddrSliceSegment          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1322  Bool haveReachedTileBoundarySliceSegment = false;
1323  UInt boundingCtuTsAddrSliceSegment;
1324  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSliceSegment, boundingCtuTsAddrSliceSegment, haveReachedTileBoundarySliceSegment, pcPic,
1325                                     m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument());
1326  if (boundingCtuTsAddrSliceSegment>boundingCtuTsAddrSlice)
1327  {
1328    boundingCtuTsAddrSliceSegment = boundingCtuTsAddrSlice;
1329  }
1330  pcSlice->setSliceSegmentCurEndCtuTsAddr( boundingCtuTsAddrSliceSegment );
1331  pcSlice->setSliceSegmentCurStartCtuTsAddr(startCtuTsAddrSliceSegment);
1332
1333  // Make a joint decision based on reconstruction and dependent slice bounds
1334  startCtuTsAddr    = max(startCtuTsAddrSlice   , startCtuTsAddrSliceSegment   );
1335  boundingCtuTsAddr = boundingCtuTsAddrSliceSegment;
1336}
1337
1338Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1339{
1340  return 4.2005*log(lambda) + 13.7122;
1341}
1342
1343#if SVC_EXTENSION
1344#if JCTVC_M0259_LAMBDAREFINEMENT
1345Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP, Double beta )
1346{
1347  Double tmp = beta * pow( 2.0 , deltaQP / 6 );
1348  Double gamma = tmp / ( tmp + 1 );
1349  return gamma;
1350}
1351#endif
1352
1353Void TEncSlice::estimateILWpParam( TComSlice* pcSlice )
1354{
1355  xCalcACDCParamSlice(pcSlice);
1356}
1357#endif
1358//! \}
Note: See TracBrowser for help on using the repository browser.