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

Last change on this file since 1323 was 1318, checked in by seregin, 9 years ago

port rev 4393

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