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

Last change on this file since 1465 was 1459, checked in by seregin, 9 years ago

port rev 4593

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