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

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

port rev 4408

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