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

Last change on this file since 1353 was 1336, checked in by seregin, 9 years ago

port rev 4414

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