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

Last change on this file since 1257 was 1246, checked in by seregin, 9 years ago

port rev 4240

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