source: 3DVCSoftware/branches/HTM-15.1-MV-draft-4/source/Lib/TLibEncoder/TEncSlice.cpp @ 1389

Last change on this file since 1389 was 1325, checked in by tech, 10 years ago

Removed 3D-HEVC.

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