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

Last change on this file since 1263 was 1260, checked in by seregin, 9 years ago

port rev 4257

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