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

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

port rev 4487

  • Property svn:eol-style set to native
File size: 50.6 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, m_pcCfg->getFastDeltaQp());
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, const Bool bFastDeltaQP )
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  m_pcCuEncoder->setFastDeltaQp(bFastDeltaQP);
783
784  //------------------------------------------------------------------------------
785  //  Weighted Prediction parameters estimation.
786  //------------------------------------------------------------------------------
787  // calculate AC/DC values for current picture
788  if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
789  {
790    xCalcACDCParamSlice(pcSlice);
791  }
792#if SVC_EXTENSION
793  else if( m_ppcTEncTop[pcSlice->getLayerIdx()]->getInterLayerWeightedPredFlag() )
794  {
795    // Calculate for the base layer to be used in EL as Inter layer reference
796    estimateILWpParam( pcSlice );   
797  }
798#endif
799
800  const Bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
801
802  if ( bWp_explicit )
803  {
804    //------------------------------------------------------------------------------
805    //  Weighted Prediction implemented at Slice level. SliceMode=2 is not supported yet.
806    //------------------------------------------------------------------------------
807    if ( pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES || pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES )
808    {
809      printf("Weighted Prediction is not supported with slice mode determined by max number of bins.\n"); exit(0);
810    }
811
812    xEstimateWPParamSlice( pcSlice );
813    pcSlice->initWpScaling(pcSlice->getSPS());
814
815    // check WP on/off
816    xCheckWPEnable( pcSlice );
817  }
818
819#if ADAPTIVE_QP_SELECTION
820  if( m_pcCfg->getUseAdaptQpSelect() && !(pcSlice->getDependentSliceSegmentFlag()))
821  {
822    // TODO: this won't work with dependent slices: they do not have their own QP. Check fix to mask clause execution with && !(pcSlice->getDependentSliceSegmentFlag())
823    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)
824    if(pcSlice->getSliceType()!=I_SLICE)
825    {
826      Int qpBase = pcSlice->getSliceQpBase();
827      pcSlice->setSliceQp(qpBase + m_pcTrQuant->getQpDelta(qpBase));
828    }
829  }
830#endif
831
832
833
834  // Adjust initial state if this is the start of a dependent slice.
835  {
836    const UInt      ctuRsAddr               = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr);
837    const UInt      currentTileIdx          = pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
838    const TComTile *pCurrentTile            = pcPic->getPicSym()->getTComTile(currentTileIdx);
839    const UInt      firstCtuRsAddrOfTile    = pCurrentTile->getFirstCtuRsAddr();
840    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
841    {
842      // This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used.
843      if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getWaveFrontsynchro() )
844      {
845        m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_lastSliceSegmentEndContextState );
846      }
847    }
848  }
849
850  // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
851
852  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
853  {
854    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
855    // initialize CTU encoder
856    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
857    pCtu->initCtu( pcPic, ctuRsAddr );
858
859    // update CABAC state
860    const UInt firstCtuRsAddrOfTile = pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr))->getFirstCtuRsAddr();
861    const UInt tileXPosInCtus = firstCtuRsAddrOfTile % frameWidthInCtus;
862    const UInt ctuXPosInCtus  = ctuRsAddr % frameWidthInCtus;
863   
864    if (ctuRsAddr == firstCtuRsAddrOfTile)
865    {
866      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);
867    }
868    else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getWaveFrontsynchro())
869    {
870      // reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile).
871      m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);
872      // Sync if the Top-Right is available.
873      TComDataCU *pCtuUp = pCtu->getCtuAbove();
874      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
875      {
876        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
877        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
878        {
879          // Top-Right is available, we use it.
880          m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_entropyCodingSyncContextState );
881        }
882      }
883    }
884
885    // set go-on entropy coder (used for all trial encodings - the cu encoder and encoder search also have a copy of the same pointer)
886    m_pcEntropyCoder->setEntropyCoder ( m_pcRDGoOnSbacCoder );
887    m_pcEntropyCoder->setBitstream( &tempBitCounter );
888    tempBitCounter.resetBits();
889    m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] ); // this copy is not strictly necessary here, but indicates that the GoOnSbacCoder
890                                                                     // is reset to a known state before every decision process.
891
892    ((TEncBinCABAC*)m_pcRDGoOnSbacCoder->getEncBinIf())->setBinCountingEnableFlag(true);
893
894    Double oldLambda = m_pcRdCost->getLambda();
895    if ( m_pcCfg->getUseRateCtrl() )
896    {
897      Int estQP        = pcSlice->getSliceQp();
898      Double estLambda = -1.0;
899      Double bpp       = -1.0;
900
901      if ( ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE && m_pcCfg->getForceIntraQP() ) || !m_pcCfg->getLCULevelRC() )
902      {
903        estQP = pcSlice->getSliceQp();
904      }
905      else
906      {
907        bpp = m_pcRateCtrl->getRCPic()->getLCUTargetBpp(pcSlice->getSliceType());
908        if ( pcPic->getSlice( 0 )->getSliceType() == I_SLICE)
909        {
910          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambdaAndQP(bpp, pcSlice->getSliceQp(), &estQP);
911        }
912        else
913        {
914          estLambda = m_pcRateCtrl->getRCPic()->getLCUEstLambda( bpp );
915          estQP     = m_pcRateCtrl->getRCPic()->getLCUEstQP    ( estLambda, pcSlice->getSliceQp() );
916        }
917
918#if SVC_EXTENSION
919        estQP     = Clip3( -pcSlice->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP );
920
921        m_pcRdCost->setLambda(estLambda, pcSlice->getBitDepths());
922#else
923        estQP     = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, estQP );
924
925        m_pcRdCost->setLambda(estLambda, pcSlice->getSPS()->getBitDepths());
926#endif       
927
928#if RDOQ_CHROMA_LAMBDA
929        // set lambda for RDOQ
930        const Double chromaLambda = estLambda / m_pcRdCost->getChromaWeight();
931        const Double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda };
932        m_pcTrQuant->setLambdas( lambdaArray );
933#else
934        m_pcTrQuant->setLambda( estLambda );
935#endif
936      }
937
938      m_pcRateCtrl->setRCQP( estQP );
939#if ADAPTIVE_QP_SELECTION
940      pCtu->getSlice()->setSliceQpBase( estQP );
941#endif
942    }
943
944    // run CTU trial encoder
945    m_pcCuEncoder->compressCtu( pCtu );
946
947
948    // All CTU decisions have now been made. Restore entropy coder to an initial stage, ready to make a true encode,
949    // which will result in the state of the contexts being correct. It will also count up the number of bits coded,
950    // which is used if there is a limit of the number of bytes per slice-segment.
951
952    m_pcEntropyCoder->setEntropyCoder ( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
953    m_pcEntropyCoder->setBitstream( &tempBitCounter );
954    pRDSbacCoder->setBinCountingEnableFlag( true );
955    m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetBits();
956    pRDSbacCoder->setBinsCoded( 0 );
957
958    // encode CTU and calculate the true bit counters.
959    m_pcCuEncoder->encodeCtu( pCtu );
960
961
962    pRDSbacCoder->setBinCountingEnableFlag( false );
963
964    const Int numberOfWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();
965
966    // Calculate if this CTU puts us over slice bit size.
967    // cannot terminate if current slice/slice-segment would be 0 Ctu in size,
968    const UInt validEndOfSliceCtuTsAddr = ctuTsAddr + (ctuTsAddr == startCtuTsAddr ? 1 : 0);
969    // Set slice end parameter
970    if(pcSlice->getSliceMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceBits()+numberOfWrittenBits > (pcSlice->getSliceArgument()<<3))
971    {
972      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
973      pcSlice->setSliceCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
974      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
975    }
976    else if((!bCompressEntireSlice) && pcSlice->getSliceSegmentMode()==FIXED_NUMBER_OF_BYTES && pcSlice->getSliceSegmentBits()+numberOfWrittenBits > (pcSlice->getSliceSegmentArgument()<<3))
977    {
978      pcSlice->setSliceSegmentCurEndCtuTsAddr(validEndOfSliceCtuTsAddr);
979      boundingCtuTsAddr=validEndOfSliceCtuTsAddr;
980    }
981
982    if (boundingCtuTsAddr <= ctuTsAddr)
983    {
984      break;
985    }
986
987    pcSlice->setSliceBits( (UInt)(pcSlice->getSliceBits() + numberOfWrittenBits) );
988    pcSlice->setSliceSegmentBits(pcSlice->getSliceSegmentBits()+numberOfWrittenBits);
989
990    // Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled.
991    if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getWaveFrontsynchro())
992    {
993      m_entropyCodingSyncContextState.loadContexts(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
994    }
995
996
997    if ( m_pcCfg->getUseRateCtrl() )
998    {
999      Int actualQP        = g_RCInvalidQPValue;
1000      Double actualLambda = m_pcRdCost->getLambda();
1001      Int actualBits      = pCtu->getTotalBits();
1002      Int numberOfEffectivePixels    = 0;
1003      for ( Int idx = 0; idx < pcPic->getNumPartitionsInCtu(); idx++ )
1004      {
1005        if ( pCtu->getPredictionMode( idx ) != NUMBER_OF_PREDICTION_MODES && ( !pCtu->isSkipped( idx ) ) )
1006        {
1007          numberOfEffectivePixels = numberOfEffectivePixels + 16;
1008          break;
1009        }
1010      }
1011
1012      if ( numberOfEffectivePixels == 0 )
1013      {
1014        actualQP = g_RCInvalidQPValue;
1015      }
1016      else
1017      {
1018        actualQP = pCtu->getQP( 0 );
1019      }
1020#if SVC_EXTENSION
1021      m_pcRdCost->setLambda(oldLambda, pcSlice->getBitDepths());
1022#else
1023      m_pcRdCost->setLambda(oldLambda, pcSlice->getSPS()->getBitDepths());
1024#endif
1025      m_pcRateCtrl->getRCPic()->updateAfterCTU( m_pcRateCtrl->getRCPic()->getLCUCoded(), actualBits, actualQP, actualLambda,
1026                                                pCtu->getSlice()->getSliceType() == I_SLICE ? 0 : m_pcCfg->getLCULevelRC() );
1027    }
1028
1029    m_uiPicTotalBits += pCtu->getTotalBits();
1030    m_dPicRdCost     += pCtu->getTotalCost();
1031    m_uiPicDist      += pCtu->getTotalDistortion();
1032  }
1033
1034  // 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.
1035  if( pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag() )
1036  {
1037    m_lastSliceSegmentEndContextState.loadContexts( m_pppcRDSbacCoder[0][CI_CURR_BEST] );//ctx end of dep.slice
1038  }
1039
1040  // stop use of temporary bit counter object.
1041  m_pppcRDSbacCoder[0][CI_CURR_BEST]->setBitstream(NULL);
1042  m_pcRDGoOnSbacCoder->setBitstream(NULL); // stop use of tempBitCounter.
1043
1044  // TODO: optimise cabac_init during compress slice to improve multi-slice operation
1045  //if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1046  //{
1047  //  m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx();
1048  //}
1049  //else
1050  //{
1051  //  m_encCABACTableIdx = pcSlice->getSliceType();
1052  //}
1053}
1054
1055Void TEncSlice::encodeSlice   ( TComPic* pcPic, TComOutputBitstream* pcSubstreams, UInt &numBinsCoded )
1056{
1057  TComSlice *const pcSlice           = pcPic->getSlice(getSliceIdx());
1058
1059  const UInt startCtuTsAddr          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1060  const UInt boundingCtuTsAddr       = pcSlice->getSliceSegmentCurEndCtuTsAddr();
1061
1062  const UInt frameWidthInCtus        = pcPic->getPicSym()->getFrameWidthInCtus();
1063  const Bool depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag();
1064  const Bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
1065
1066  // initialise entropy coder for the slice
1067  m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1068  m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder );
1069  m_pcEntropyCoder->resetEntropy    ( pcSlice );
1070
1071  numBinsCoded = 0;
1072  m_pcBinCABAC->setBinCountingEnableFlag( true );
1073  m_pcBinCABAC->setBinsCoded(0);
1074
1075#if ENC_DEC_TRACE
1076  g_bJustDoIt = g_bEncDecTraceEnable;
1077#endif
1078  DTRACE_CABAC_VL( g_nSymbolCounter++ );
1079  DTRACE_CABAC_T( "\tPOC: " );
1080  DTRACE_CABAC_V( pcPic->getPOC() );
1081  DTRACE_CABAC_T( "\n" );
1082#if ENC_DEC_TRACE
1083  g_bJustDoIt = g_bEncDecTraceDisable;
1084#endif
1085
1086
1087  if (depSliceSegmentsEnabled)
1088  {
1089    // modify initial contexts with previous slice segment if this is a dependent slice.
1090    const UInt ctuRsAddr        = pcPic->getPicSym()->getCtuTsToRsAddrMap( startCtuTsAddr );
1091    const UInt currentTileIdx=pcPic->getPicSym()->getTileIdxMap(ctuRsAddr);
1092    const TComTile *pCurrentTile=pcPic->getPicSym()->getTComTile(currentTileIdx);
1093    const UInt firstCtuRsAddrOfTile = pCurrentTile->getFirstCtuRsAddr();
1094
1095    if( pcSlice->getDependentSliceSegmentFlag() && ctuRsAddr != firstCtuRsAddrOfTile )
1096    {
1097      if( pCurrentTile->getTileWidthInCtus() >= 2 || !wavefrontsEnabled )
1098      {
1099        m_pcSbacCoder->loadContexts(&m_lastSliceSegmentEndContextState);
1100      }
1101    }
1102  }
1103
1104  // for every CTU in the slice segment...
1105
1106  for( UInt ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ++ctuTsAddr )
1107  {
1108    const UInt ctuRsAddr = pcPic->getPicSym()->getCtuTsToRsAddrMap(ctuTsAddr);
1109    const TComTile &currentTile = *(pcPic->getPicSym()->getTComTile(pcPic->getPicSym()->getTileIdxMap(ctuRsAddr)));
1110    const UInt firstCtuRsAddrOfTile = currentTile.getFirstCtuRsAddr();
1111    const UInt tileXPosInCtus       = firstCtuRsAddrOfTile % frameWidthInCtus;
1112    const UInt tileYPosInCtus       = firstCtuRsAddrOfTile / frameWidthInCtus;
1113    const UInt ctuXPosInCtus        = ctuRsAddr % frameWidthInCtus;
1114    const UInt ctuYPosInCtus        = ctuRsAddr / frameWidthInCtus;
1115    const UInt uiSubStrm=pcPic->getSubstreamForCtuAddr(ctuRsAddr, true, pcSlice);
1116    TComDataCU* pCtu = pcPic->getCtu( ctuRsAddr );
1117
1118    m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
1119
1120    // set up CABAC contexts' state for this CTU
1121    if (ctuRsAddr == firstCtuRsAddrOfTile)
1122    {
1123      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1124      {
1125        m_pcEntropyCoder->resetEntropy(pcSlice);
1126      }
1127    }
1128    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
1129    {
1130      // Synchronize cabac probabilities with upper-right CTU if it's available and at the start of a line.
1131      if (ctuTsAddr != startCtuTsAddr) // if it is the first CTU, then the entropy coder has already been reset
1132      {
1133        m_pcEntropyCoder->resetEntropy(pcSlice);
1134      }
1135      TComDataCU *pCtuUp = pCtu->getCtuAbove();
1136      if ( pCtuUp && ((ctuRsAddr%frameWidthInCtus+1) < frameWidthInCtus)  )
1137      {
1138        TComDataCU *pCtuTR = pcPic->getCtu( ctuRsAddr - frameWidthInCtus + 1 );
1139        if ( pCtu->CUIsFromSameSliceAndTile(pCtuTR) )
1140        {
1141          // Top-right is available, so use it.
1142          m_pcSbacCoder->loadContexts( &m_entropyCodingSyncContextState );
1143        }
1144      }
1145    }
1146
1147
1148    if ( pcSlice->getSPS()->getUseSAO() )
1149    {
1150      Bool bIsSAOSliceEnabled = false;
1151      Bool sliceEnabled[MAX_NUM_COMPONENT];
1152      for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
1153      {
1154        ComponentID compId=ComponentID(comp);
1155        sliceEnabled[compId] = pcSlice->getSaoEnabledFlag(toChannelType(compId)) && (comp < pcPic->getNumberValidComponents());
1156        if (sliceEnabled[compId])
1157        {
1158          bIsSAOSliceEnabled=true;
1159        }
1160      }
1161      if (bIsSAOSliceEnabled)
1162      {
1163        SAOBlkParam& saoblkParam = (pcPic->getPicSym()->getSAOBlkParam())[ctuRsAddr];
1164
1165        Bool leftMergeAvail = false;
1166        Bool aboveMergeAvail= false;
1167        //merge left condition
1168        Int rx = (ctuRsAddr % frameWidthInCtus);
1169        if(rx > 0)
1170        {
1171          leftMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-1);
1172        }
1173
1174        //merge up condition
1175        Int ry = (ctuRsAddr / frameWidthInCtus);
1176        if(ry > 0)
1177        {
1178          aboveMergeAvail = pcPic->getSAOMergeAvailability(ctuRsAddr, ctuRsAddr-frameWidthInCtus);
1179        }
1180
1181#if SVC_EXTENSION
1182        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, pcPic->getPicSym()->getSlice(0)->getBitDepths(), sliceEnabled, leftMergeAvail, aboveMergeAvail);
1183#else
1184        m_pcEntropyCoder->encodeSAOBlkParam(saoblkParam, pcPic->getPicSym()->getSPS().getBitDepths(), sliceEnabled, leftMergeAvail, aboveMergeAvail);
1185#endif
1186      }
1187    }
1188
1189#if ENC_DEC_TRACE
1190    g_bJustDoIt = g_bEncDecTraceEnable;
1191#endif
1192      m_pcCuEncoder->encodeCtu( pCtu );
1193#if ENC_DEC_TRACE
1194    g_bJustDoIt = g_bEncDecTraceDisable;
1195#endif
1196
1197    //Store probabilities of second CTU in line into buffer
1198    if ( ctuXPosInCtus == tileXPosInCtus+1 && wavefrontsEnabled)
1199    {
1200      m_entropyCodingSyncContextState.loadContexts( m_pcSbacCoder );
1201    }
1202
1203    // terminate the sub-stream, if required (end of slice-segment, end of tile, end of wavefront-CTU-row):
1204    if (ctuTsAddr+1 == boundingCtuTsAddr ||
1205         (  ctuXPosInCtus + 1 == tileXPosInCtus + currentTile.getTileWidthInCtus() &&
1206          ( ctuYPosInCtus + 1 == tileYPosInCtus + currentTile.getTileHeightInCtus() || wavefrontsEnabled)
1207         )
1208       )
1209    {
1210      m_pcEntropyCoder->encodeTerminatingBit(1);
1211      m_pcEntropyCoder->encodeSliceFinish();
1212      // Byte-alignment in slice_data() when new tile
1213      pcSubstreams[uiSubStrm].writeByteAlignment();
1214
1215      // write sub-stream size
1216      if (ctuTsAddr+1 != boundingCtuTsAddr)
1217      {
1218        pcSlice->addSubstreamSize( (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations() );
1219      }
1220    }
1221  } // CTU-loop
1222
1223  if( depSliceSegmentsEnabled )
1224  {
1225    m_lastSliceSegmentEndContextState.loadContexts( m_pcSbacCoder );//ctx end of dep.slice
1226  }
1227
1228#if ADAPTIVE_QP_SELECTION
1229  if( m_pcCfg->getUseAdaptQpSelect() )
1230  {
1231    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.
1232  }
1233#endif
1234
1235  if (pcSlice->getPPS()->getCabacInitPresentFlag() && !pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag())
1236  {
1237    m_encCABACTableIdx = m_pcEntropyCoder->determineCabacInitIdx(pcSlice);
1238  }
1239  else
1240  {
1241    m_encCABACTableIdx = pcSlice->getSliceType();
1242  }
1243 
1244  numBinsCoded = m_pcBinCABAC->getBinsCoded();
1245}
1246
1247Void TEncSlice::calculateBoundingCtuTsAddrForSlice(UInt &startCtuTSAddrSlice, UInt &boundingCtuTSAddrSlice, Bool &haveReachedTileBoundary,
1248                                                   TComPic* pcPic, const Int sliceMode, const Int sliceArgument)
1249{
1250  TComSlice* pcSlice = pcPic->getSlice(getSliceIdx());
1251  const UInt numberOfCtusInFrame = pcPic->getNumberOfCtusInFrame();
1252  const TComPPS &pps=*(pcSlice->getPPS());
1253  boundingCtuTSAddrSlice=0;
1254  haveReachedTileBoundary=false;
1255
1256  switch (sliceMode)
1257  {
1258    case FIXED_NUMBER_OF_CTU:
1259      {
1260        UInt ctuAddrIncrement    = sliceArgument;
1261        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
1262      }
1263      break;
1264    case FIXED_NUMBER_OF_BYTES:
1265      boundingCtuTSAddrSlice  = numberOfCtusInFrame; // This will be adjusted later if required.
1266      break;
1267    case FIXED_NUMBER_OF_TILES:
1268      {
1269        const UInt tileIdx        = pcPic->getPicSym()->getTileIdxMap( pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice) );
1270        const UInt tileTotalCount = (pcPic->getPicSym()->getNumTileColumnsMinus1()+1) * (pcPic->getPicSym()->getNumTileRowsMinus1()+1);
1271        UInt ctuAddrIncrement   = 0;
1272
1273        for(UInt tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++)
1274        {
1275          if((tileIdx + tileIdxIncrement) < tileTotalCount)
1276          {
1277            UInt tileWidthInCtus   = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidthInCtus();
1278            UInt tileHeightInCtus  = pcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeightInCtus();
1279            ctuAddrIncrement    += (tileWidthInCtus * tileHeightInCtus);
1280          }
1281        }
1282
1283        boundingCtuTSAddrSlice  = ((startCtuTSAddrSlice + ctuAddrIncrement) < numberOfCtusInFrame) ? (startCtuTSAddrSlice + ctuAddrIncrement) : numberOfCtusInFrame;
1284      }
1285      break;
1286    default:
1287      boundingCtuTSAddrSlice    = numberOfCtusInFrame;
1288      break;
1289  }
1290
1291  // Adjust for tiles and wavefronts.
1292  const Bool wavefrontsAreEnabled = pps.getEntropyCodingSyncEnabledFlag();
1293
1294  if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) &&
1295      (pps.getNumTileRowsMinus1() > 0 || pps.getNumTileColumnsMinus1() > 0))
1296  {
1297    const UInt ctuRSAddr                  = pcPic->getPicSym()->getCtuTsToRsAddrMap(startCtuTSAddrSlice);
1298    const UInt startTileIdx               = pcPic->getPicSym()->getTileIdxMap(ctuRSAddr);
1299
1300    const TComTile *pStartingTile         = pcPic->getPicSym()->getTComTile(startTileIdx);
1301    const UInt tileStartTsAddr            = pcPic->getPicSym()->getCtuRsToTsAddrMap(pStartingTile->getFirstCtuRsAddr());
1302    const UInt tileStartWidth             = pStartingTile->getTileWidthInCtus();
1303    const UInt tileStartHeight            = pStartingTile->getTileHeightInCtus();
1304    const UInt tileLastTsAddr_excl        = tileStartTsAddr + tileStartWidth*tileStartHeight;
1305    const UInt tileBoundingCtuTsAddrSlice = tileLastTsAddr_excl;
1306
1307    const UInt ctuColumnOfStartingTile    = ((startCtuTSAddrSlice-tileStartTsAddr)%tileStartWidth);
1308    if (wavefrontsAreEnabled && ctuColumnOfStartingTile!=0)
1309    {
1310      // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1311      const UInt numberOfCTUsToEndOfRow            = tileStartWidth - ctuColumnOfStartingTile;
1312      const UInt wavefrontTileBoundingCtuAddrSlice = startCtuTSAddrSlice + numberOfCTUsToEndOfRow;
1313      if (wavefrontTileBoundingCtuAddrSlice < boundingCtuTSAddrSlice)
1314      {
1315        boundingCtuTSAddrSlice = wavefrontTileBoundingCtuAddrSlice;
1316      }
1317    }
1318
1319    if (tileBoundingCtuTsAddrSlice < boundingCtuTSAddrSlice)
1320    {
1321      boundingCtuTSAddrSlice = tileBoundingCtuTsAddrSlice;
1322      haveReachedTileBoundary = true;
1323    }
1324  }
1325  else if ((sliceMode == FIXED_NUMBER_OF_CTU || sliceMode == FIXED_NUMBER_OF_BYTES) && wavefrontsAreEnabled && ((startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) != 0))
1326  {
1327    // Adjust for wavefronts (no tiles).
1328    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row
1329    boundingCtuTSAddrSlice = min(boundingCtuTSAddrSlice, startCtuTSAddrSlice - (startCtuTSAddrSlice % pcPic->getFrameWidthInCtus()) + (pcPic->getFrameWidthInCtus()));
1330  }
1331}
1332
1333/** Determines the starting and bounding CTU address of current slice / dependent slice
1334 * \param [out] startCtuTsAddr
1335 * \param [out] boundingCtuTsAddr
1336 * \param [in]  pcPic
1337
1338 * Updates startCtuTsAddr, boundingCtuTsAddr with appropriate CTU address
1339 */
1340Void TEncSlice::xDetermineStartAndBoundingCtuTsAddr  ( UInt& startCtuTsAddr, UInt& boundingCtuTsAddr, TComPic* pcPic )
1341{
1342  TComSlice* pcSlice                 = pcPic->getSlice(getSliceIdx());
1343
1344  // Non-dependent slice
1345  UInt startCtuTsAddrSlice           = pcSlice->getSliceCurStartCtuTsAddr();
1346  Bool haveReachedTileBoundarySlice  = false;
1347  UInt boundingCtuTsAddrSlice;
1348  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSlice, boundingCtuTsAddrSlice, haveReachedTileBoundarySlice, pcPic,
1349                                     m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument());
1350  pcSlice->setSliceCurEndCtuTsAddr(   boundingCtuTsAddrSlice );
1351  pcSlice->setSliceCurStartCtuTsAddr( startCtuTsAddrSlice    );
1352
1353  // Dependent slice
1354  UInt startCtuTsAddrSliceSegment          = pcSlice->getSliceSegmentCurStartCtuTsAddr();
1355  Bool haveReachedTileBoundarySliceSegment = false;
1356  UInt boundingCtuTsAddrSliceSegment;
1357  calculateBoundingCtuTsAddrForSlice(startCtuTsAddrSliceSegment, boundingCtuTsAddrSliceSegment, haveReachedTileBoundarySliceSegment, pcPic,
1358                                     m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument());
1359  if (boundingCtuTsAddrSliceSegment>boundingCtuTsAddrSlice)
1360  {
1361    boundingCtuTsAddrSliceSegment = boundingCtuTsAddrSlice;
1362  }
1363  pcSlice->setSliceSegmentCurEndCtuTsAddr( boundingCtuTsAddrSliceSegment );
1364  pcSlice->setSliceSegmentCurStartCtuTsAddr(startCtuTsAddrSliceSegment);
1365
1366  // Make a joint decision based on reconstruction and dependent slice bounds
1367  startCtuTsAddr    = max(startCtuTsAddrSlice   , startCtuTsAddrSliceSegment   );
1368  boundingCtuTsAddr = boundingCtuTsAddrSliceSegment;
1369}
1370
1371Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
1372{
1373  return 4.2005*log(lambda) + 13.7122;
1374}
1375
1376#if SVC_EXTENSION
1377#if JCTVC_M0259_LAMBDAREFINEMENT
1378Double TEncSlice::xCalEnhLambdaFactor( Double deltaQP , Double beta )
1379{
1380  double tmp = beta * pow( 2.0 , deltaQP / 6 );
1381  double gamma = tmp / ( tmp + 1 );
1382  return( gamma );
1383}
1384#endif
1385
1386Void TEncSlice::estimateILWpParam( TComSlice* pcSlice )
1387{
1388  xCalcACDCParamSlice(pcSlice);
1389}
1390#endif
1391//! \}
Note: See TracBrowser for help on using the repository browser.