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

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

port rev 4363

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