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

Last change on this file since 1497 was 1474, checked in by seregin, 9 years ago

put the fix for the ticket #85 under SVC_EXTENSION macro

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