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

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

port rev 4721

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