source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibEncoder/TEncTop.cpp @ 1590

Last change on this file since 1590 was 1578, checked in by seregin, 9 years ago

fix memory allocation for reference layer picture and REDUCED_ENCODER_MEMORY

  • Property svn:eol-style set to native
File size: 61.9 KB
RevLine 
[313]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
[1029]4 * granted under this license.
[313]5 *
[1549]6 * Copyright (c) 2010-2016, ITU/ISO/IEC
[313]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     TEncTop.cpp
35    \brief    encoder class
36*/
37
38#include "TLibCommon/CommonDef.h"
39#include "TEncTop.h"
40#include "TEncPic.h"
[1029]41#include "TLibCommon/TComChromaFormat.h"
[313]42#if FAST_BIT_EST
43#include "TLibCommon/ContextModel.h"
44#endif
45
46//! \ingroup TLibEncoder
47//! \{
48#if SVC_EXTENSION 
49Int TEncTop::m_iSPSIdCnt = 0;
50Int TEncTop::m_iPPSIdCnt = 0;
51TComVPS TEncCfg::m_cVPS;
52#endif
53
54// ====================================================================================================================
55// Constructor / destructor / create / destroy
56// ====================================================================================================================
57
58TEncTop::TEncTop()
59{
60  m_iPOCLast          = -1;
61  m_iNumPicRcvd       =  0;
62  m_uiNumAllPicCoded  =  0;
63  m_pppcRDSbacCoder   =  NULL;
64  m_pppcBinCoderCABAC =  NULL;
65  m_cRDGoOnSbacCoder.init( &m_cRDGoOnBinCoderCABAC );
66#if ENC_DEC_TRACE
[1029]67  if (g_hTrace == NULL)
68  {
69    g_hTrace = fopen( "TraceEnc.txt", "wb" );
70  }
[313]71  g_bJustDoIt = g_bEncDecTraceDisable;
72  g_nSymbolCounter = 0;
73#endif
74
75  m_iMaxRefPicNum     = 0;
76
77#if FAST_BIT_EST
78  ContextModel::buildNextStateTable();
79#endif
80
[442]81#if SVC_EXTENSION
[1226]82  memset( m_cIlpPic, 0, sizeof(m_cIlpPic) );
[313]83  m_bMFMEnabledFlag = false;
[1030]84  m_numRefLayerLocationOffsets = 0;
[442]85  m_pocAdjustmentValue     = 0;
[540]86#if NO_CLRAS_OUTPUT_FLAG
87  m_noClrasOutputFlag          = false;
88  m_layerInitializedFlag       = false;
89  m_firstPicInLayerDecodedFlag = false;
90  m_noOutputOfPriorPicsFlags   = false;
91#endif
[903]92  m_pocDecrementedInDPBFlag    = false;
[494]93#endif //SVC_EXTENSION
[313]94}
95
96TEncTop::~TEncTop()
97{
98#if ENC_DEC_TRACE
[1029]99  if (g_hTrace != stdout)
100  {
101    fclose( g_hTrace );
102  }
[313]103#endif
104}
105
106Void TEncTop::create ()
107{
108#if !SVC_EXTENSION
109  // initialize global variables
110  initROM();
111#endif
[442]112
[313]113  // create processing unit classes
114#if SVC_EXTENSION
115  m_cGOPEncoder.        create( m_layerId );
116#else
[1029]117  m_cGOPEncoder.        create( );
[313]118#endif
[1290]119  m_cSliceEncoder.      create( getSourceWidth(), getSourceHeight(), m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, m_maxTotalCUDepth );
120  m_cCuEncoder.         create( m_maxTotalCUDepth, m_maxCUWidth, m_maxCUHeight, m_chromaFormatIDC );
[313]121  if (m_bUseSAO)
122  {
[1316]123    m_cEncSAO.create( getSourceWidth(), getSourceHeight(), m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, m_maxTotalCUDepth, m_log2SaoOffsetScale[CHANNEL_TYPE_LUMA], m_log2SaoOffsetScale[CHANNEL_TYPE_CHROMA] );
[1029]124    m_cEncSAO.createEncData(getSaoCtuBoundary());
[313]125  }
126#if ADAPTIVE_QP_SELECTION
127  if (m_bUseAdaptQpSelect)
128  {
129    m_cTrQuant.initSliceQpDelta();
130  }
131#endif
[1029]132
[1290]133  m_cLoopFilter.create( m_maxTotalCUDepth );
[1029]134
[313]135  if ( m_RCEnableRateControl )
136  {
[1544]137    m_cRateCtrl.init( m_framesToBeEncoded, m_RCTargetBitrate, (Int)( (Double)m_iFrameRate/m_temporalSubsampleRatio + 0.5), m_iGOPSize, m_iSourceWidth, m_iSourceHeight,
138                      m_maxCUWidth, m_maxCUHeight,m_RCKeepHierarchicalBit, m_RCUseLCUSeparateModel, m_GOPList );
[313]139  }
[595]140
[1290]141  m_pppcRDSbacCoder = new TEncSbac** [m_maxTotalCUDepth+1];
[313]142#if FAST_BIT_EST
[1290]143  m_pppcBinCoderCABAC = new TEncBinCABACCounter** [m_maxTotalCUDepth+1];
[313]144#else
[1290]145  m_pppcBinCoderCABAC = new TEncBinCABAC** [m_maxTotalCUDepth+1];
[313]146#endif
[595]147
[1290]148  for ( Int iDepth = 0; iDepth < m_maxTotalCUDepth+1; iDepth++ )
[595]149  {
150    m_pppcRDSbacCoder[iDepth] = new TEncSbac* [CI_NUM];
[313]151#if FAST_BIT_EST
[595]152    m_pppcBinCoderCABAC[iDepth] = new TEncBinCABACCounter* [CI_NUM];
[313]153#else
[595]154    m_pppcBinCoderCABAC[iDepth] = new TEncBinCABAC* [CI_NUM];
[313]155#endif
[595]156
157    for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
158    {
159      m_pppcRDSbacCoder[iDepth][iCIIdx] = new TEncSbac;
[313]160#if FAST_BIT_EST
[595]161      m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABACCounter;
[313]162#else
[595]163      m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABAC;
[313]164#endif
[595]165      m_pppcRDSbacCoder   [iDepth][iCIIdx]->init( m_pppcBinCoderCABAC [iDepth][iCIIdx] );
[313]166    }
167  }
[494]168
169#if LAYER_CTB
170  memcpy(g_auiLayerZscanToRaster[m_layerId], g_auiZscanToRaster, sizeof( g_auiZscanToRaster ) );
171  memcpy(g_auiLayerRasterToZscan[m_layerId], g_auiRasterToZscan, sizeof( g_auiRasterToZscan ) );
172  memcpy(g_auiLayerRasterToPelX[m_layerId],  g_auiRasterToPelX,  sizeof( g_auiRasterToPelX ) );
173  memcpy(g_auiLayerRasterToPelY[m_layerId],  g_auiRasterToPelY,  sizeof( g_auiRasterToPelY ) );
174#endif
[313]175}
176
177Void TEncTop::destroy ()
178{
179  // destroy processing unit classes
180  m_cGOPEncoder.        destroy();
181  m_cSliceEncoder.      destroy();
182  m_cCuEncoder.         destroy();
[1235]183  m_cEncSAO.            destroyEncData();
184  m_cEncSAO.            destroy();
[313]185  m_cLoopFilter.        destroy();
186  m_cRateCtrl.          destroy();
[1372]187  m_cSearch.            destroy();
[595]188  Int iDepth;
[1290]189  for ( iDepth = 0; iDepth < m_maxTotalCUDepth+1; iDepth++ )
[313]190  {
[595]191    for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
192    {
193      delete m_pppcRDSbacCoder[iDepth][iCIIdx];
194      delete m_pppcBinCoderCABAC[iDepth][iCIIdx];
195    }
196  }
197
[1290]198  for ( iDepth = 0; iDepth < m_maxTotalCUDepth+1; iDepth++ )
[595]199  {
200    delete [] m_pppcRDSbacCoder[iDepth];
201    delete [] m_pppcBinCoderCABAC[iDepth];
202  }
203
204  delete [] m_pppcRDSbacCoder;
205  delete [] m_pppcBinCoderCABAC;
[1459]206
[442]207#if SVC_EXTENSION
[313]208  for(Int i=0; i<MAX_NUM_REF; i++)
209  {
210    if(m_cIlpPic[i])
211    {
212      m_cIlpPic[i]->destroy();
213      delete m_cIlpPic[i];
214      m_cIlpPic[i] = NULL;
215    }
[442]216  }
217#else
218  // destroy ROM
219  destroyROM();
[313]220#endif
221  return;
222}
223
[442]224Void TEncTop::init(Bool isFieldCoding)
[313]225{
226  // initialize SPS
227  xInitSPS();
[1235]228  xInitVPS();
[1029]229
[1433]230#if U0132_TARGET_BITS_SATURATION
231  if (m_RCCpbSaturationEnabled)
232  {
233    m_cRateCtrl.initHrdParam(m_cSPS.getVuiParameters()->getHrdParameters(), m_iFrameRate, m_RCInitialCpbFullness);
234  }
235#endif
[1029]236  m_cRdCost.setCostMode(m_costMode);
237
[313]238  // initialize PPS
239  xInitPPS();
[442]240  xInitRPS(isFieldCoding);
[313]241
242  xInitPPSforTiles();
243
244  // initialize processing unit classes
245  m_cGOPEncoder.  init( this );
246  m_cSliceEncoder.init( this );
247  m_cCuEncoder.   init( this );
[1029]248
[313]249  // initialize transform & quantization class
250  m_pcCavlcCoder = getCavlcCoder();
[1029]251
[313]252  m_cTrQuant.init( 1 << m_uiQuadtreeTULog2MaxSize,
[1029]253                   m_useRDOQ,
254                   m_useRDOQTS,
[1298]255#if T0196_SELECTIVE_RDOQ
256                   m_useSelectiveRDOQ,
257#endif
[1029]258                   true
[313]259                  ,m_useTransformSkipFast
[1029]260#if ADAPTIVE_QP_SELECTION
261                  ,m_bUseAdaptQpSelect
[313]262#endif
263                  );
[1029]264
[313]265  // initialize encoder search class
[1406]266  m_cSearch.init( this, &m_cTrQuant, m_iSearchRange, m_bipredSearchRange, m_motionEstimationSearchMethod, m_maxCUWidth, m_maxCUHeight, m_maxTotalCUDepth, &m_cEntropyCoder, &m_cRdCost, getRDSbacCoder(), getRDGoOnSbacCoder() );
[313]267
268  m_iMaxRefPicNum = 0;
[1235]269
270  xInitScalingLists();
271
[313]272#if SVC_EXTENSION
273  m_iSPSIdCnt ++;
274  m_iPPSIdCnt ++;
275  xInitILRP();
276#endif
277}
278
[1235]279Void TEncTop::xInitScalingLists()
280{
281  // Initialise scaling lists
282  // The encoder will only use the SPS scaling lists. The PPS will never be marked present.
[1285]283  const Int maxLog2TrDynamicRange[MAX_NUM_CHANNEL_TYPE] =
284  {
285      m_cSPS.getMaxLog2TrDynamicRange(CHANNEL_TYPE_LUMA),
286      m_cSPS.getMaxLog2TrDynamicRange(CHANNEL_TYPE_CHROMA)
287  };
[1235]288  if(getUseScalingListId() == SCALING_LIST_OFF)
289  {
[1307]290    getTrQuant()->setFlatScalingList(maxLog2TrDynamicRange, m_cSPS.getBitDepths());
[1235]291    getTrQuant()->setUseScalingList(false);
292    m_cSPS.setScalingListPresentFlag(false);
293    m_cPPS.setScalingListPresentFlag(false);
294  }
295  else if(getUseScalingListId() == SCALING_LIST_DEFAULT)
296  {
297#if SVC_EXTENSION
298    // inferring of the scaling list can be moved to the config file
299    UInt refLayerId = 0;
300    if( m_layerId > 0 && !m_cVPS.getNonHEVCBaseLayerFlag() && m_cVPS.getRecursiveRefLayerFlag( m_layerId, refLayerId ) )
301    {
302      m_cSPS.setInferScalingListFlag( true );
303      m_cSPS.setScalingListRefLayerId( refLayerId );
304      m_cSPS.setScalingListPresentFlag( false );
305      m_cPPS.setInferScalingListFlag( false );
306      m_cPPS.setScalingListPresentFlag( false );
307
308      // infer the scaling list from the reference layer
[1502]309      getTrQuant()->setScalingList( &m_ppcTEncTop[m_cVPS.getLayerIdxInVps(refLayerId)]->getSPS()->getScalingList(), maxLog2TrDynamicRange, m_ppcTEncTop[m_cVPS.getLayerIdxInVps(refLayerId)]->getSPS()->getBitDepths() );
[1235]310    }
311    else
312    {
313#endif
314    m_cSPS.getScalingList().setDefaultScalingList ();
315    m_cSPS.setScalingListPresentFlag(false);
316    m_cPPS.setScalingListPresentFlag(false);
[1285]317
[1307]318    getTrQuant()->setScalingList(&(m_cSPS.getScalingList()), maxLog2TrDynamicRange, m_cSPS.getBitDepths());
319#if SVC_EXTENSION
[1235]320    }
321#endif
322    getTrQuant()->setUseScalingList(true);
323  }
324  else if(getUseScalingListId() == SCALING_LIST_FILE_READ)
325  {
326#if SVC_EXTENSION
327    // inferring of the scaling list can be moved to the config file
328    UInt refLayerId = 0;
329    if( m_layerId > 0 && !m_cVPS.getNonHEVCBaseLayerFlag() && m_cVPS.getRecursiveRefLayerFlag( m_layerId, refLayerId ) )
330    {
331      m_cSPS.setInferScalingListFlag( true );
332      m_cSPS.setScalingListRefLayerId( refLayerId );
333      m_cSPS.setScalingListPresentFlag( false );
334      m_cPPS.setInferScalingListFlag( false );
335      m_cPPS.setScalingListPresentFlag( false );
336
337      // infer the scaling list from the reference layer
[1502]338      getTrQuant()->setScalingList( &m_ppcTEncTop[m_cVPS.getLayerIdxInVps(refLayerId)]->getSPS()->getScalingList(), maxLog2TrDynamicRange, m_ppcTEncTop[m_cVPS.getLayerIdxInVps(refLayerId)]->getSPS()->getBitDepths() );
[1235]339    }
340    else
341    {
342#endif
343    m_cSPS.getScalingList().setDefaultScalingList ();
[1442]344    if(m_cSPS.getScalingList().xParseScalingList(getScalingListFileName()))
[1235]345    {
346      Bool bParsedScalingList=false; // Use of boolean so that assertion outputs useful string
347      assert(bParsedScalingList);
348      exit(1);
349    }
350    m_cSPS.getScalingList().checkDcOfMatrix();
351    m_cSPS.setScalingListPresentFlag(m_cSPS.getScalingList().checkDefaultScalingList());
352    m_cPPS.setScalingListPresentFlag(false);
[1307]353    getTrQuant()->setScalingList(&(m_cSPS.getScalingList()), maxLog2TrDynamicRange, m_cSPS.getBitDepths());
[1235]354#if SVC_EXTENSION
355    }
356#endif
357    getTrQuant()->setUseScalingList(true);
358  }
359  else
360  {
361    printf("error : ScalingList == %d not supported\n",getUseScalingListId());
362    assert(0);
363  }
364
[1309]365  if (getUseScalingListId() != SCALING_LIST_OFF)
[1235]366  {
[1309]367    // Prepare delta's:
368    for(UInt sizeId = 0; sizeId < SCALING_LIST_SIZE_NUM; sizeId++)
369    {
370      const Int predListStep = (sizeId == SCALING_LIST_32x32? (SCALING_LIST_NUM/NUMBER_OF_PREDICTION_MODES) : 1); // if 32x32, skip over chroma entries.
[1235]371
[1309]372      for(UInt listId = 0; listId < SCALING_LIST_NUM; listId+=predListStep)
373      {
374        m_cSPS.getScalingList().checkPredMode( sizeId, listId );
375      }
[1235]376    }
377  }
378}
379
[313]380// ====================================================================================================================
381// Public member functions
382// ====================================================================================================================
383
384Void TEncTop::deletePicBuffer()
385{
386  TComList<TComPic*>::iterator iterPic = m_cListPic.begin();
387  Int iSize = Int( m_cListPic.size() );
[1029]388
[313]389  for ( Int i = 0; i < iSize; i++ )
390  {
391    TComPic* pcPic = *(iterPic++);
[1029]392
[313]393    pcPic->destroy();
394    delete pcPic;
395    pcPic = NULL;
396  }
397}
398
399/**
400 - Application has picture buffer list with size of GOP + 1
401 - Picture buffer list acts like as ring buffer
402 - End of the list has the latest picture
403 .
404 \param   flush               cause encoder to encode a partial GOP
405 \param   pcPicYuvOrg         original YUV picture
[1260]406 \param   pcPicYuvTrueOrg     
407 \param   snrCSC
[313]408 \retval  rcListPicYuvRecOut  list of reconstruction YUV pictures
[1260]409 \retval  accessUnitsOut      list of output access units
[313]410 \retval  iNumEncoded         number of encoded pictures
411 */
412#if SVC_EXTENSION
[1029]413Void TEncTop::encode( TComPicYuv* pcPicYuvOrg, const InputColourSpaceConversion snrCSC, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int iPicIdInGOP )
[313]414{
415  // compress GOP
416#if !RC_SHVC_HARMONIZATION
417  if ( m_RCEnableRateControl )
418  {
419    m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
420  }
421#endif
422
423  // compress GOP
[1029]424  m_cGOPEncoder.compressGOP(iPicIdInGOP, m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, false, false, snrCSC, m_printFrameMSE);
[313]425
426#if !RC_SHVC_HARMONIZATION
427  if ( m_RCEnableRateControl )
428  {
429    m_cRateCtrl.destroyRCGOP();
430  }
431#endif
432 
433  m_uiNumAllPicCoded ++;
434}
435
[1029]436Void TEncTop::encodePrep( TComPicYuv* pcPicYuvOrg, TComPicYuv* pcPicYuvTrueOrg )
[313]437{
[1029]438  if (pcPicYuvOrg != NULL)
[313]439  {
440    // get original YUV
441    TComPic* pcPicCurr = NULL;
442    xGetNewPicBuffer( pcPicCurr );
443    pcPicYuvOrg->copyToPic( pcPicCurr->getPicYuvOrg() );
[1029]444    pcPicYuvTrueOrg->copyToPic( pcPicCurr->getPicYuvTrueOrg() );
[313]445
446    // compute image characteristics
447    if ( getUseAdaptiveQP() )
448    {
449      m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcPicCurr ) );
450    }
451  }
452}
453#else
[1029]454Void TEncTop::encode( Bool flush, TComPicYuv* pcPicYuvOrg, TComPicYuv* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded )
[313]455{
[1029]456  if (pcPicYuvOrg != NULL)
457  {
[313]458    // get original YUV
459    TComPic* pcPicCurr = NULL;
[1029]460
[313]461    xGetNewPicBuffer( pcPicCurr );
462    pcPicYuvOrg->copyToPic( pcPicCurr->getPicYuvOrg() );
[1029]463    pcPicYuvTrueOrg->copyToPic( pcPicCurr->getPicYuvTrueOrg() );
[313]464
465    // compute image characteristics
466    if ( getUseAdaptiveQP() )
467    {
468      m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcPicCurr ) );
469    }
470  }
[1029]471
472  if ((m_iNumPicRcvd == 0) || (!flush && (m_iPOCLast != 0) && (m_iNumPicRcvd != m_iGOPSize) && (m_iGOPSize != 0)))
[313]473  {
474    iNumEncoded = 0;
475    return;
476  }
[1029]477
[313]478  if ( m_RCEnableRateControl )
479  {
480    m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
481  }
482
483  // compress GOP
[1029]484  m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, false, false, snrCSC, m_printFrameMSE);
[313]485
486  if ( m_RCEnableRateControl )
487  {
488    m_cRateCtrl.destroyRCGOP();
489  }
[1029]490
[313]491  iNumEncoded         = m_iNumPicRcvd;
492  m_iNumPicRcvd       = 0;
493  m_uiNumAllPicCoded += iNumEncoded;
494}
495#endif
496
[442]497/**------------------------------------------------
498 Separate interlaced frame into two fields
499 -------------------------------------------------**/
[1029]500Void separateFields(Pel* org, Pel* dstField, UInt stride, UInt width, UInt height, Bool isTop)
[442]501{
502  if (!isTop)
503  {
504    org += stride;
505  }
506  for (Int y = 0; y < height>>1; y++)
507  {
508    for (Int x = 0; x < width; x++)
509    {
510      dstField[x] = org[x];
511    }
[1029]512
[442]513    dstField += stride;
514    org += stride*2;
515  }
[1029]516
[442]517}
518
519#if SVC_EXTENSION
[1029]520Void TEncTop::encodePrep( TComPicYuv* pcPicYuvOrg, TComPicYuv* pcPicYuvTrueOrg, Bool isTff )
[442]521{
[1029]522  for (Int fieldNum=0; fieldNum<2; fieldNum++)
[442]523  {
[1029]524    if (pcPicYuvOrg)
[442]525    {
[1029]526      /* -- field initialization -- */
527      const Bool isTopField=isTff==(fieldNum==0);
[540]528
[1029]529      TComPic *pcField;
530      xGetNewPicBuffer( pcField );
531      pcField->setReconMark (false);                     // where is this normally?
532           
533      pcField->getSlice(0)->setPOC( m_iPOCLast );        // superfluous?
[1574]534#if !REDUCED_ENCODER_MEMORY
[1029]535      pcField->getPicYuvRec()->setBorderExtension(false);// where is this normally?
[1574]536#endif
[442]537
[1029]538      pcField->setTopField(isTopField);                  // interlaced requirement
[540]539
[1029]540      for (UInt componentIndex = 0; componentIndex < pcPicYuvOrg->getNumberValidComponents(); componentIndex++)
541      {
542        const ComponentID component = ComponentID(componentIndex);
543        const UInt stride = pcPicYuvOrg->getStride(component);
[540]544
[1029]545        separateFields((pcPicYuvOrg->getBuf(component) + pcPicYuvOrg->getMarginX(component) + (pcPicYuvOrg->getMarginY(component) * stride)),
546                       pcField->getPicYuvOrg()->getAddr(component),
547                       pcPicYuvOrg->getStride(component),
548                       pcPicYuvOrg->getWidth(component),
549                       pcPicYuvOrg->getHeight(component),
550                       isTopField);
551
552        separateFields((pcPicYuvTrueOrg->getBuf(component) + pcPicYuvTrueOrg->getMarginX(component) + (pcPicYuvTrueOrg->getMarginY(component) * stride)),
553                       pcField->getPicYuvTrueOrg()->getAddr(component),
554                       pcPicYuvTrueOrg->getStride(component),
555                       pcPicYuvTrueOrg->getWidth(component),
556                       pcPicYuvTrueOrg->getHeight(component),
557                       isTopField);
558      }
559
560      // compute image characteristics
561      if ( getUseAdaptiveQP() )
562      {
563        m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcField ) );
564      }
565    }
[442]566  }
567}
568
[1029]569Void TEncTop::encode( TComPicYuv* pcPicYuvOrg, const InputColourSpaceConversion snrCSC, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int iPicIdInGOP, Bool isTff )
[442]570{
[1029]571  for (Int fieldNum=0; fieldNum<2; fieldNum++)
[442]572  {
[1029]573    if (pcPicYuvOrg)
574    {
575      if (fieldNum==1)                                   // where is this normally?
576      {
577        TComPicYuv* rpcPicYuvRec;
[442]578
[1029]579        // org. buffer
580        if ( rcListPicYuvRecOut.size() >= (UInt)m_iGOPSize+1 ) // need to maintain field 0 in list of RecOuts while processing field 1. Hence +1 on m_iGOPSize.
581        {
582          rpcPicYuvRec = rcListPicYuvRecOut.popFront();
583        }
584        else
585        {
586          rpcPicYuvRec = new TComPicYuv;
[1290]587          rpcPicYuvRec->create( m_iSourceWidth, m_iSourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, m_maxTotalCUDepth, true);
[1029]588        }
589        rcListPicYuvRecOut.pushBack( rpcPicYuvRec );
590      }
[442]591    }
[1029]592
593    // compress GOP
594    m_cGOPEncoder.compressGOP(iPicIdInGOP, m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, true, isTff, snrCSC, m_printFrameMSE);
[442]595  }
596
597  m_uiNumAllPicCoded ++;
598}
599#else
[1029]600Void TEncTop::encode(Bool flush, TComPicYuv* pcPicYuvOrg, TComPicYuv* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded, Bool isTff)
[442]601{
[1029]602  iNumEncoded = 0;
603
604  for (Int fieldNum=0; fieldNum<2; fieldNum++)
[442]605  {
[1029]606    if (pcPicYuvOrg)
[442]607    {
[1029]608
609      /* -- field initialization -- */
610      const Bool isTopField=isTff==(fieldNum==0);
611
612      TComPic *pcField;
613      xGetNewPicBuffer( pcField );
614      pcField->setReconMark (false);                     // where is this normally?
615
616      if (fieldNum==1)                                   // where is this normally?
617      {
618        TComPicYuv* rpcPicYuvRec;
619
620        // org. buffer
621        if ( rcListPicYuvRecOut.size() >= (UInt)m_iGOPSize+1 ) // need to maintain field 0 in list of RecOuts while processing field 1. Hence +1 on m_iGOPSize.
622        {
623          rpcPicYuvRec = rcListPicYuvRecOut.popFront();
624        }
625        else
626        {
627          rpcPicYuvRec = new TComPicYuv;
[1290]628          rpcPicYuvRec->create( m_iSourceWidth, m_iSourceHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, m_maxTotalCUDepth, true);
[1029]629        }
630        rcListPicYuvRecOut.pushBack( rpcPicYuvRec );
631      }
632
633      pcField->getSlice(0)->setPOC( m_iPOCLast );        // superfluous?
[1574]634#if !REDUCED_ENCODER_MEMORY
[1029]635      pcField->getPicYuvRec()->setBorderExtension(false);// where is this normally?
[1574]636#endif
[1029]637
638      pcField->setTopField(isTopField);                  // interlaced requirement
639
640      for (UInt componentIndex = 0; componentIndex < pcPicYuvOrg->getNumberValidComponents(); componentIndex++)
641      {
642        const ComponentID component = ComponentID(componentIndex);
643        const UInt stride = pcPicYuvOrg->getStride(component);
644
645        separateFields((pcPicYuvOrg->getBuf(component) + pcPicYuvOrg->getMarginX(component) + (pcPicYuvOrg->getMarginY(component) * stride)),
646                       pcField->getPicYuvOrg()->getAddr(component),
647                       pcPicYuvOrg->getStride(component),
648                       pcPicYuvOrg->getWidth(component),
649                       pcPicYuvOrg->getHeight(component),
650                       isTopField);
651
652        separateFields((pcPicYuvTrueOrg->getBuf(component) + pcPicYuvTrueOrg->getMarginX(component) + (pcPicYuvTrueOrg->getMarginY(component) * stride)),
653                       pcField->getPicYuvTrueOrg()->getAddr(component),
654                       pcPicYuvTrueOrg->getStride(component),
655                       pcPicYuvTrueOrg->getWidth(component),
656                       pcPicYuvTrueOrg->getHeight(component),
657                       isTopField);
658      }
659
660      // compute image characteristics
661      if ( getUseAdaptiveQP() )
662      {
663        m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcField ) );
664      }
[442]665    }
[1029]666
667    if ( m_iNumPicRcvd && ((flush&&fieldNum==1) || (m_iPOCLast/2)==0 || m_iNumPicRcvd==m_iGOPSize ) )
[442]668    {
[1029]669      // compress GOP
670      m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, true, isTff, snrCSC, m_printFrameMSE);
671
672      iNumEncoded += m_iNumPicRcvd;
673      m_uiNumAllPicCoded += m_iNumPicRcvd;
674      m_iNumPicRcvd = 0;
[442]675    }
676  }
677}
678#endif
679
[313]680// ====================================================================================================================
681// Protected member functions
682// ====================================================================================================================
683
684/**
685 - Application has picture buffer list with size of GOP + 1
686 - Picture buffer list acts like as ring buffer
687 - End of the list has the latest picture
688 .
689 \retval rpcPic obtained picture buffer
690 */
691Void TEncTop::xGetNewPicBuffer ( TComPic*& rpcPic )
692{
[1235]693  // At this point, the SPS and PPS can be considered activated - they are copied to the new TComPic.
694
[313]695  TComSlice::sortPicList(m_cListPic);
[1029]696
[1249]697
[313]698  if (m_cListPic.size() >= (UInt)(m_iGOPSize + getMaxDecPicBuffering(MAX_TLAYER-1) + 2) )
699  {
700    TComList<TComPic*>::iterator iterPic  = m_cListPic.begin();
701    Int iSize = Int( m_cListPic.size() );
702    for ( Int i = 0; i < iSize; i++ )
703    {
704      rpcPic = *(iterPic++);
705      if(rpcPic->getSlice(0)->isReferenced() == false)
706      {
707        break;
708      }
709    }
[1574]710#if REDUCED_ENCODER_MEMORY
711    rpcPic->releaseAllReconstructionData();
712    rpcPic->prepareForEncoderSourcePicYuv();
713#endif
[313]714  }
715  else
716  {
717    if ( getUseAdaptiveQP() )
718    {
719      TEncPic* pcEPic = new TEncPic;
720
721#if SVC_EXTENSION //Temporal solution, should be modified
[1200]722      if( m_layerId > 0 )
[313]723      {
[1200]724        for( UInt i = 0; i < m_cVPS.getNumDirectRefLayers( m_layerId ); i++ )
[313]725        {
[1235]726          const Window scalEL = m_cPPS.getScaledRefLayerWindowForLayer(m_cVPS.getRefLayerId(m_layerId, i));
727          const Window altRL = m_cPPS.getRefLayerWindowForLayer(m_cVPS.getRefLayerId(m_layerId, i));
[873]728          Bool equalOffsets = scalEL.hasEqualOffset(altRL);
[1235]729          Bool zeroPhase = m_cPPS.hasZeroResamplingPhase(m_cVPS.getRefLayerId(m_layerId, i));
[313]730
731          TEncTop *pcEncTopBase = (TEncTop *)getRefLayerEnc( i );
[1200]732
[1502]733          const Int bitDepthLuma = m_cSPS.getBitDepth(CHANNEL_TYPE_LUMA);
734          const Int bitDepthChroma = m_cSPS.getBitDepth(CHANNEL_TYPE_CHROMA);
735          const Int refBitDepthLuma = pcEncTopBase->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
736          const Int refBitDepthChroma = pcEncTopBase->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA);
[644]737
[1287]738          Bool sameBitDepths = ( bitDepthLuma == refBitDepthLuma ) && ( bitDepthChroma == refBitDepthChroma );
739
[901]740          if( m_iSourceWidth == pcEncTopBase->getSourceWidth() && m_iSourceHeight == pcEncTopBase->getSourceHeight() && equalOffsets && zeroPhase )
741          {
742            pcEPic->setEqualPictureSizeAndOffsetFlag( i, true );
743          }
744
745          if( !pcEPic->equalPictureSizeAndOffsetFlag(i) || !sameBitDepths
[1212]746#if CGS_3D_ASYMLUT
[713]747            || m_cPPS.getCGSFlag() > 0
748#endif
749            )
[313]750          {
[1512]751            pcEPic->setRequireResamplingFlag( i, true );
[313]752
753            //only for scalable extension
[815]754            assert( m_cVPS.getScalabilityMask( SCALABILITY_ID ) == true );
[313]755          }
756        }
757      }
[1574]758#if REDUCED_ENCODER_MEMORY
[1578]759      pcEPic->create( m_cVPS, m_cSPS, m_cPPS, m_cPPS.getMaxCuDQPDepth()+1, m_layerId);
[1574]760#else
[1578]761      pcEPic->create( m_cVPS, m_cSPS, m_cPPS, m_cPPS.getMaxCuDQPDepth()+1, false, m_layerId);
[1574]762#endif
[815]763#else  //SVC_EXTENSION
[1574]764#if REDUCED_ENCODER_MEMORY
765      pcEPic->create( m_cSPS, m_cPPS, m_cPPS.getMaxCuDQPDepth()+1);
766#else
[1290]767      pcEPic->create( m_cSPS, m_cPPS, m_cPPS.getMaxCuDQPDepth()+1, false);
[1574]768#endif
[815]769#endif //SVC_EXTENSION
[313]770      rpcPic = pcEPic;
771    }
772    else
773    {
774      rpcPic = new TComPic;
775
776#if SVC_EXTENSION //Temporal solution, should be modified
[1200]777      if( m_layerId > 0 )
[313]778      {
[1200]779        for( UInt i = 0; i < m_cVPS.getNumDirectRefLayers( m_layerId ); i++ )
[313]780        {
[1235]781          const Window scalEL = m_cPPS.getScaledRefLayerWindowForLayer(m_cVPS.getRefLayerId(m_layerId, i));
782          const Window altRL = m_cPPS.getRefLayerWindowForLayer(m_cVPS.getRefLayerId(m_layerId, i));
[873]783          Bool equalOffsets = scalEL.hasEqualOffset(altRL);
[1235]784          Bool zeroPhase = m_cPPS.hasZeroResamplingPhase(m_cVPS.getRefLayerId(m_layerId, i));
[313]785
786          TEncTop *pcEncTopBase = (TEncTop *)getRefLayerEnc( i );
[1200]787
[1502]788          const Int bitDepthLuma = m_cSPS.getBitDepth(CHANNEL_TYPE_LUMA);
789          const Int bitDepthChroma = m_cSPS.getBitDepth(CHANNEL_TYPE_CHROMA);
[1513]790          const Int refBitDepthLuma = pcEncTopBase->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
791          const Int refBitDepthChroma = pcEncTopBase->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA);
[644]792
[1287]793          Bool sameBitDepths = ( bitDepthLuma == refBitDepthLuma ) && ( bitDepthChroma == refBitDepthChroma );
794
[873]795          if( m_iSourceWidth != pcEncTopBase->getSourceWidth() || m_iSourceHeight != pcEncTopBase->getSourceHeight() || !sameBitDepths
796            || !equalOffsets
797            || !zeroPhase
[1212]798#if CGS_3D_ASYMLUT
[713]799            || m_cPPS.getCGSFlag() > 0
800#endif
[1200]801            )
[313]802          {
[1512]803            rpcPic->setRequireResamplingFlag( i, true );
[313]804
805            //only for scalable extension
[815]806            assert( m_cVPS.getScalabilityMask( SCALABILITY_ID ) == true );
[313]807          }
808        }
809      }
810
[1574]811#if REDUCED_ENCODER_MEMORY
812      rpcPic->create( m_cSPS, m_cPPS, true, false, m_layerId );
813#else
[1503]814      rpcPic->create( m_cSPS, m_cPPS, false, m_layerId );
[1574]815#endif
[815]816#else  //SVC_EXTENSION
[1574]817#if REDUCED_ENCODER_MEMORY
818      rpcPic->create( m_cSPS, m_cPPS, true, false );
819#else
[1290]820      rpcPic->create( m_cSPS, m_cPPS, false );
[1574]821#endif     
[815]822#endif //SVC_EXTENSION
[313]823    }
[1029]824
[313]825    m_cListPic.pushBack( rpcPic );
826  }
827  rpcPic->setReconMark (false);
[1029]828
[313]829  m_iPOCLast++;
830  m_iNumPicRcvd++;
[1029]831
[313]832  rpcPic->getSlice(0)->setPOC( m_iPOCLast );
[1574]833#if !REDUCED_ENCODER_MEMORY
[313]834  // mark it should be extended
835  rpcPic->getPicYuvRec()->setBorderExtension(false);
[1574]836#endif
[313]837}
838
[1235]839Void TEncTop::xInitVPS()
840{
841  // The SPS must have already been set up.
842  // set the VPS profile information.
843#if SVC_EXTENSION
844  m_cVPS.setVpsVuiPresentFlag( true );
845#else
846  *m_cVPS.getPTL() = *m_cSPS.getPTL();
847  m_cVPS.setMaxOpSets(1);
848#endif
849  m_cVPS.getTimingInfo()->setTimingInfoPresentFlag       ( false );
850  m_cVPS.setNumHrdParameters( 0 );
851
852  m_cVPS.createHrdParamBuffer();
853  for( UInt i = 0; i < m_cVPS.getNumHrdParameters(); i ++ )
854  {
855    m_cVPS.setHrdOpSetIdx( 0, i );
856    m_cVPS.setCprmsPresentFlag( false, i );
857    // Set up HrdParameters here.
858  }
859}
860
[313]861Void TEncTop::xInitSPS()
862{
863#if SVC_EXTENSION
[815]864  m_cSPS.setExtensionFlag( m_layerId > 0 ? true : false );
[988]865  m_cSPS.setNumDirectRefLayers(m_numDirectRefLayers);
[1172]866
[830]867  if( !m_numDirectRefLayers && m_numAddLayerSets )
[815]868  {
869    m_cSPS.setLayerId(0); // layer ID 0 for independent layers
870  }
871  else
872  {
873    m_cSPS.setLayerId(m_layerId);
874  }
[1534]875#if VIEW_SCALABILITY
876  if( m_bUseDisparitySearchRangeRestriction )
877  {
878    m_cSPS.setInterViewMvVertConstraintFlag( true );
879  }
880  else
881  {
882    m_cSPS.setInterViewMvVertConstraintFlag( false );
883  }
884#endif
[494]885#endif //SVC_EXTENSION
[1172]886
[313]887  ProfileTierLevel& profileTierLevel = *m_cSPS.getPTL()->getGeneralPTL();
888  profileTierLevel.setLevelIdc(m_level);
889  profileTierLevel.setTierFlag(m_levelTier);
890  profileTierLevel.setProfileIdc(m_profile);
891  profileTierLevel.setProfileCompatibilityFlag(m_profile, 1);
892  profileTierLevel.setProgressiveSourceFlag(m_progressiveSourceFlag);
893  profileTierLevel.setInterlacedSourceFlag(m_interlacedSourceFlag);
894  profileTierLevel.setNonPackedConstraintFlag(m_nonPackedConstraintFlag);
895  profileTierLevel.setFrameOnlyConstraintFlag(m_frameOnlyConstraintFlag);
[1029]896  profileTierLevel.setBitDepthConstraint(m_bitDepthConstraintValue);
897  profileTierLevel.setChromaFormatConstraint(m_chromaFormatConstraintValue);
898  profileTierLevel.setIntraConstraintFlag(m_intraConstraintFlag);
[1356]899  profileTierLevel.setOnePictureOnlyConstraintFlag(m_onePictureOnlyConstraintFlag);
[1029]900  profileTierLevel.setLowerBitRateConstraintFlag(m_lowerBitRateConstraintFlag);
901
[1287]902  if ((m_profile == Profile::MAIN10) && (m_bitDepth[CHANNEL_TYPE_LUMA] == 8) && (m_bitDepth[CHANNEL_TYPE_CHROMA] == 8))
[313]903  {
904    /* The above constraint is equal to Profile::MAIN */
905    profileTierLevel.setProfileCompatibilityFlag(Profile::MAIN, 1);
906  }
907  if (m_profile == Profile::MAIN)
908  {
909    /* A Profile::MAIN10 decoder can always decode Profile::MAIN */
910    profileTierLevel.setProfileCompatibilityFlag(Profile::MAIN10, 1);
911  }
912  /* XXX: should Main be marked as compatible with still picture? */
913  /* XXX: may be a good idea to refactor the above into a function
914   * that chooses the actual compatibility based upon options */
915
[1290]916  m_cSPS.setPicWidthInLumaSamples  ( m_iSourceWidth      );
917  m_cSPS.setPicHeightInLumaSamples ( m_iSourceHeight     );
918  m_cSPS.setConformanceWindow      ( m_conformanceWindow );
919  m_cSPS.setMaxCUWidth             ( m_maxCUWidth        );
920  m_cSPS.setMaxCUHeight            ( m_maxCUHeight       );
921  m_cSPS.setMaxTotalCUDepth        ( m_maxTotalCUDepth   );
[494]922  m_cSPS.setChromaFormatIdc( m_chromaFormatIDC);
[1290]923  m_cSPS.setLog2DiffMaxMinCodingBlockSize(m_log2DiffMaxMinCodingBlockSize);
[313]924
[1290]925  Int minCUSize = m_cSPS.getMaxCUWidth() >> ( m_cSPS.getLog2DiffMaxMinCodingBlockSize() );
[313]926  Int log2MinCUSize = 0;
927  while(minCUSize > 1)
928  {
929    minCUSize >>= 1;
930    log2MinCUSize++;
931  }
932
933  m_cSPS.setLog2MinCodingBlockSize(log2MinCUSize);
[1459]934
[313]935#if SVC_EXTENSION
936  m_cSPS.setSPSId         ( m_iSPSIdCnt       );
937#endif
[1459]938
[313]939  m_cSPS.setPCMLog2MinSize (m_uiPCMLog2MinSize);
940  m_cSPS.setUsePCM        ( m_usePCM           );
941  m_cSPS.setPCMLog2MaxSize( m_pcmLog2MaxSize  );
942
943  m_cSPS.setQuadtreeTULog2MaxSize( m_uiQuadtreeTULog2MaxSize );
944  m_cSPS.setQuadtreeTULog2MinSize( m_uiQuadtreeTULog2MinSize );
945  m_cSPS.setQuadtreeTUMaxDepthInter( m_uiQuadtreeTUMaxDepthInter    );
946  m_cSPS.setQuadtreeTUMaxDepthIntra( m_uiQuadtreeTUMaxDepthIntra    );
[1029]947
[1568]948  m_cSPS.setSPSTemporalMVPEnabledFlag((getTMVPModeId() == 2 || getTMVPModeId() == 1));
[1235]949
[313]950  m_cSPS.setMaxTrSize   ( 1 << m_uiQuadtreeTULog2MaxSize );
[1284]951
[313]952  m_cSPS.setUseAMP ( m_useAMP );
953
[1029]954  for (UInt channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
955  {
[1203]956#if SVC_EXTENSION
[1290]957    m_cSPS.setBitDepth    (ChannelType(channelType), m_cVPS.getVpsRepFormat( m_cVPS.getVpsRepFormatIdx( m_cVPS.getLayerIdxInVps( m_layerId ) ) )->getBitDepthVps(ChannelType(channelType))            );   
[1287]958#if O0043_BEST_EFFORT_DECODING
[1290]959    m_cSPS.setStreamBitDepth(ChannelType(channelType), m_bitDepth[channelType] );
[1287]960#endif
[1290]961    m_cSPS.setQpBDOffset  (ChannelType(channelType), (6 * (m_cVPS.getVpsRepFormat( m_cVPS.getVpsRepFormatIdx( m_cVPS.getLayerIdxInVps( m_layerId ) ) )->getBitDepthVps(ChannelType(channelType)) - 8)));
[442]962#else
[1290]963    m_cSPS.setBitDepth      (ChannelType(channelType), m_bitDepth[channelType] );
[1287]964#if O0043_BEST_EFFORT_DECODING
965    m_cSPS.setStreamBitDepth(ChannelType(channelType), m_bitDepth[channelType] );
[442]966#endif
[1287]967    m_cSPS.setQpBDOffset  (ChannelType(channelType), (6 * (m_bitDepth[channelType] - 8)));
968#endif
[1284]969    m_cSPS.setPCMBitDepth (ChannelType(channelType), m_PCMBitDepth[channelType]         );
[1029]970  }
[313]971
972  m_cSPS.setUseSAO( m_bUseSAO );
973
974  m_cSPS.setMaxTLayers( m_maxTempLayer );
975  m_cSPS.setTemporalIdNestingFlag( ( m_maxTempLayer == 1 ) ? true : false );
[1029]976
[1252]977  for (Int i = 0; i < min(m_cSPS.getMaxTLayers(),(UInt) MAX_TLAYER); i++ )
[313]978  {
[1288]979#if SVC_EXTENSION
980    assert( i < MAX_TLAYER );
981#endif
[313]982    m_cSPS.setMaxDecPicBuffering(m_maxDecPicBuffering[i], i);
983    m_cSPS.setNumReorderPics(m_numReorderPics[i], i);
984  }
[1029]985
[313]986  m_cSPS.setPCMFilterDisableFlag  ( m_bPCMFilterDisableFlag );
[1235]987  m_cSPS.setScalingListFlag ( (m_useScalingListId == SCALING_LIST_OFF) ? 0 : 1 );
[313]988  m_cSPS.setUseStrongIntraSmoothing( m_useStrongIntraSmoothing );
[1029]989  m_cSPS.setVuiParametersPresentFlag(getVuiParametersPresentFlag());
[313]990
991  if (m_cSPS.getVuiParametersPresentFlag())
992  {
993    TComVUI* pcVUI = m_cSPS.getVuiParameters();
[823]994    pcVUI->setAspectRatioInfoPresentFlag(getAspectRatioInfoPresentFlag());
[313]995    pcVUI->setAspectRatioIdc(getAspectRatioIdc());
996    pcVUI->setSarWidth(getSarWidth());
997    pcVUI->setSarHeight(getSarHeight());
998    pcVUI->setOverscanInfoPresentFlag(getOverscanInfoPresentFlag());
999    pcVUI->setOverscanAppropriateFlag(getOverscanAppropriateFlag());
1000    pcVUI->setVideoSignalTypePresentFlag(getVideoSignalTypePresentFlag());
1001    pcVUI->setVideoFormat(getVideoFormat());
1002    pcVUI->setVideoFullRangeFlag(getVideoFullRangeFlag());
1003    pcVUI->setColourDescriptionPresentFlag(getColourDescriptionPresentFlag());
1004    pcVUI->setColourPrimaries(getColourPrimaries());
1005    pcVUI->setTransferCharacteristics(getTransferCharacteristics());
1006    pcVUI->setMatrixCoefficients(getMatrixCoefficients());
1007    pcVUI->setChromaLocInfoPresentFlag(getChromaLocInfoPresentFlag());
1008    pcVUI->setChromaSampleLocTypeTopField(getChromaSampleLocTypeTopField());
1009    pcVUI->setChromaSampleLocTypeBottomField(getChromaSampleLocTypeBottomField());
1010    pcVUI->setNeutralChromaIndicationFlag(getNeutralChromaIndicationFlag());
1011    pcVUI->setDefaultDisplayWindow(getDefaultDisplayWindow());
1012    pcVUI->setFrameFieldInfoPresentFlag(getFrameFieldInfoPresentFlag());
1013    pcVUI->setFieldSeqFlag(false);
1014    pcVUI->setHrdParametersPresentFlag(false);
1015    pcVUI->getTimingInfo()->setPocProportionalToTimingFlag(getPocProportionalToTimingFlag());
1016    pcVUI->getTimingInfo()->setNumTicksPocDiffOneMinus1   (getNumTicksPocDiffOneMinus1()   );
1017    pcVUI->setBitstreamRestrictionFlag(getBitstreamRestrictionFlag());
1018    pcVUI->setTilesFixedStructureFlag(getTilesFixedStructureFlag());
1019    pcVUI->setMotionVectorsOverPicBoundariesFlag(getMotionVectorsOverPicBoundariesFlag());
1020    pcVUI->setMinSpatialSegmentationIdc(getMinSpatialSegmentationIdc());
1021    pcVUI->setMaxBytesPerPicDenom(getMaxBytesPerPicDenom());
1022    pcVUI->setMaxBitsPerMinCuDenom(getMaxBitsPerMinCuDenom());
1023    pcVUI->setLog2MaxMvLengthHorizontal(getLog2MaxMvLengthHorizontal());
1024    pcVUI->setLog2MaxMvLengthVertical(getLog2MaxMvLengthVertical());
1025  }
[1235]1026  m_cSPS.setNumLongTermRefPicSPS(NUM_LONG_TERM_REF_PIC_SPS);
1027  assert (NUM_LONG_TERM_REF_PIC_SPS <= MAX_NUM_LONG_TERM_REF_PICS);
1028  for (Int k = 0; k < NUM_LONG_TERM_REF_PIC_SPS; k++)
1029  {
1030    m_cSPS.setLtRefPicPocLsbSps(k, 0);
1031    m_cSPS.setUsedByCurrPicLtSPSFlag(k, 0);
1032  }
[1433]1033
1034#if U0132_TARGET_BITS_SATURATION
1035  if( getPictureTimingSEIEnabled() || getDecodingUnitInfoSEIEnabled() || getCpbSaturationEnabled() )
1036#else
[1235]1037  if( getPictureTimingSEIEnabled() || getDecodingUnitInfoSEIEnabled() )
[1433]1038#endif
[1235]1039  {
[1348]1040    xInitHrdParameters();
[1235]1041  }
1042  if( getBufferingPeriodSEIEnabled() || getPictureTimingSEIEnabled() || getDecodingUnitInfoSEIEnabled() )
1043  {
1044    m_cSPS.getVuiParameters()->setHrdParametersPresentFlag( true );
1045  }
[1316]1046
1047  // Set up SPS range extension settings
1048  m_cSPS.getSpsRangeExtension().setTransformSkipRotationEnabledFlag(m_transformSkipRotationEnabledFlag);
1049  m_cSPS.getSpsRangeExtension().setTransformSkipContextEnabledFlag(m_transformSkipContextEnabledFlag);
1050  for (UInt signallingModeIndex = 0; signallingModeIndex < NUMBER_OF_RDPCM_SIGNALLING_MODES; signallingModeIndex++)
1051  {
1052    m_cSPS.getSpsRangeExtension().setRdpcmEnabledFlag(RDPCMSignallingMode(signallingModeIndex), m_rdpcmEnabledFlag[signallingModeIndex]);
1053  }
1054  m_cSPS.getSpsRangeExtension().setExtendedPrecisionProcessingFlag(m_extendedPrecisionProcessingFlag);
1055  m_cSPS.getSpsRangeExtension().setIntraSmoothingDisabledFlag( m_intraSmoothingDisabledFlag );
1056  m_cSPS.getSpsRangeExtension().setHighPrecisionOffsetsEnabledFlag(m_highPrecisionOffsetsEnabledFlag);
1057  m_cSPS.getSpsRangeExtension().setPersistentRiceAdaptationEnabledFlag(m_persistentRiceAdaptationEnabledFlag);
1058  m_cSPS.getSpsRangeExtension().setCabacBypassAlignmentEnabledFlag(m_cabacBypassAlignmentEnabledFlag);
[1502]1059
1060#if SVC_EXTENSION
1061  m_cSPS.inferSPS( m_layerId, &m_cVPS );
1062#endif
[313]1063}
1064
[1433]1065#if U0132_TARGET_BITS_SATURATION
1066// calculate scale value of bitrate and initial delay
1067Int calcScale(Int x)
1068{
[1563]1069  if (x==0)
1070  {
1071    return 0;
1072  }
[1433]1073  UInt iMask = 0xffffffff;
1074  Int ScaleValue = 32;
1075
1076  while ((x&iMask) != 0)
1077  {
1078    ScaleValue--;
1079    iMask = (iMask >> 1);
1080  }
1081
1082  return ScaleValue;
1083}
1084#endif
[1348]1085Void TEncTop::xInitHrdParameters()
1086{
1087  Bool useSubCpbParams = (getSliceMode() > 0) || (getSliceSegmentMode() > 0);
1088  Int  bitRate         = getTargetBitrate();
1089  Bool isRandomAccess  = getIntraPeriod() > 0;
[1433]1090# if U0132_TARGET_BITS_SATURATION
1091  Int cpbSize          = getCpbSize();
[1564]1092  assert (cpbSize!=0);  // CPB size may not be equal to zero. ToDo: have a better default and check for level constraints
[1433]1093  if( !getVuiParametersPresentFlag() && !getCpbSaturationEnabled() )
1094#else
[1348]1095  if( !getVuiParametersPresentFlag() )
[1433]1096#endif
[1348]1097  {
1098    return;
1099  }
1100
1101  TComVUI *vui = m_cSPS.getVuiParameters();
1102  TComHRD *hrd = vui->getHrdParameters();
1103
1104  TimingInfo *timingInfo = vui->getTimingInfo();
1105
1106#if SVC_EXTENSION
1107  if( m_layerId > 0 )
1108  {
1109    timingInfo->setTimingInfoPresentFlag( false );
1110    return;
1111  }
1112#endif
1113
1114  timingInfo->setTimingInfoPresentFlag( true );
1115  switch( getFrameRate() )
1116  {
1117  case 24:
1118    timingInfo->setNumUnitsInTick( 1125000 );    timingInfo->setTimeScale    ( 27000000 );
1119    break;
1120  case 25:
1121    timingInfo->setNumUnitsInTick( 1080000 );    timingInfo->setTimeScale    ( 27000000 );
1122    break;
1123  case 30:
1124    timingInfo->setNumUnitsInTick( 900900 );     timingInfo->setTimeScale    ( 27000000 );
1125    break;
1126  case 50:
1127    timingInfo->setNumUnitsInTick( 540000 );     timingInfo->setTimeScale    ( 27000000 );
1128    break;
1129  case 60:
1130    timingInfo->setNumUnitsInTick( 450450 );     timingInfo->setTimeScale    ( 27000000 );
1131    break;
1132  default:
1133    timingInfo->setNumUnitsInTick( 1001 );       timingInfo->setTimeScale    ( 60000 );
1134    break;
1135  }
1136
[1544]1137  if (getTemporalSubsampleRatio()>1)
1138  {
1139    UInt temporalSubsampleRatio = getTemporalSubsampleRatio();
1140    if ( Double(timingInfo->getNumUnitsInTick()) * temporalSubsampleRatio > std::numeric_limits<UInt>::max() )
1141    {
1142      timingInfo->setTimeScale( timingInfo->getTimeScale() / temporalSubsampleRatio );
1143    }
1144    else
1145    {
1146      timingInfo->setNumUnitsInTick( timingInfo->getNumUnitsInTick() * temporalSubsampleRatio );
1147    }
1148  }
1149
[1348]1150  Bool rateCnt = ( bitRate > 0 );
1151  hrd->setNalHrdParametersPresentFlag( rateCnt );
1152  hrd->setVclHrdParametersPresentFlag( rateCnt );
1153  hrd->setSubPicCpbParamsPresentFlag( useSubCpbParams );
1154
1155  if( hrd->getSubPicCpbParamsPresentFlag() )
1156  {
1157    hrd->setTickDivisorMinus2( 100 - 2 );                          //
1158    hrd->setDuCpbRemovalDelayLengthMinus1( 7 );                    // 8-bit precision ( plus 1 for last DU in AU )
1159    hrd->setSubPicCpbParamsInPicTimingSEIFlag( true );
1160    hrd->setDpbOutputDelayDuLengthMinus1( 5 + 7 );                 // With sub-clock tick factor of 100, at least 7 bits to have the same value as AU dpb delay
1161  }
1162  else
1163  {
1164    hrd->setSubPicCpbParamsInPicTimingSEIFlag( false );
1165  }
1166
[1433]1167#if U0132_TARGET_BITS_SATURATION
1168  if (calcScale(bitRate) <= 6)
1169  {
1170    hrd->setBitRateScale(0);
1171  }
1172  else
1173  {
1174    hrd->setBitRateScale(calcScale(bitRate) - 6);
1175  }
1176
1177  if (calcScale(cpbSize) <= 4)
1178  {
1179    hrd->setCpbSizeScale(0);
1180  }
1181  else
1182  {
1183    hrd->setCpbSizeScale(calcScale(cpbSize) - 4);
1184  }
1185#else
[1349]1186  hrd->setBitRateScale( 4 );                                       // in units of 2^( 6 + 4 ) = 1,024 bps
1187  hrd->setCpbSizeScale( 6 );                                       // in units of 2^( 4 + 6 ) = 1,024 bit
[1433]1188#endif
1189
[1349]1190  hrd->setDuCpbSizeScale( 6 );                                     // in units of 2^( 4 + 6 ) = 1,024 bit
[1348]1191
1192  hrd->setInitialCpbRemovalDelayLengthMinus1(15);                  // assuming 0.5 sec, log2( 90,000 * 0.5 ) = 16-bit
1193  if( isRandomAccess )
1194  {
1195    hrd->setCpbRemovalDelayLengthMinus1(5);                        // 32 = 2^5 (plus 1)
1196    hrd->setDpbOutputDelayLengthMinus1 (5);                        // 32 + 3 = 2^6
1197  }
1198  else
1199  {
1200    hrd->setCpbRemovalDelayLengthMinus1(9);                        // max. 2^10
1201    hrd->setDpbOutputDelayLengthMinus1 (9);                        // max. 2^10
1202  }
1203
1204  // Note: parameters for all temporal layers are initialized with the same values
1205  Int i, j;
1206  UInt bitrateValue, cpbSizeValue;
1207  UInt duCpbSizeValue;
1208  UInt duBitRateValue = 0;
1209
1210  for( i = 0; i < MAX_TLAYER; i ++ )
1211  {
1212    hrd->setFixedPicRateFlag( i, 1 );
1213    hrd->setPicDurationInTcMinus1( i, 0 );
1214    hrd->setLowDelayHrdFlag( i, 0 );
1215    hrd->setCpbCntMinus1( i, 0 );
1216
[1349]1217    //! \todo check for possible PTL violations
1218    // BitRate[ i ] = ( bit_rate_value_minus1[ i ] + 1 ) * 2^( 6 + bit_rate_scale )
1219    bitrateValue = bitRate / (1 << (6 + hrd->getBitRateScale()) );      // bitRate is in bits, so it needs to be scaled down
1220    // CpbSize[ i ] = ( cpb_size_value_minus1[ i ] + 1 ) * 2^( 4 + cpb_size_scale )
[1433]1221#if U0132_TARGET_BITS_SATURATION
1222    cpbSizeValue = cpbSize / (1 << (4 + hrd->getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
1223#else
[1349]1224    cpbSizeValue = bitRate / (1 << (4 + hrd->getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
[1433]1225#endif
[1349]1226
[1433]1227
[1349]1228    // DU CPB size could be smaller (i.e. bitrateValue / number of DUs), but we don't know
[1348]1229    // in how many DUs the slice segment settings will result
[1349]1230    duCpbSizeValue = bitrateValue;
1231    duBitRateValue = cpbSizeValue;
[1348]1232
1233    for( j = 0; j < ( hrd->getCpbCntMinus1( i ) + 1 ); j ++ )
1234    {
1235      hrd->setBitRateValueMinus1( i, j, 0, ( bitrateValue - 1 ) );
1236      hrd->setCpbSizeValueMinus1( i, j, 0, ( cpbSizeValue - 1 ) );
1237      hrd->setDuCpbSizeValueMinus1( i, j, 0, ( duCpbSizeValue - 1 ) );
[1360]1238      hrd->setDuBitRateValueMinus1( i, j, 0, ( duBitRateValue - 1 ) );
[1350]1239      hrd->setCbrFlag( i, j, 0, false );
[1348]1240
1241      hrd->setBitRateValueMinus1( i, j, 1, ( bitrateValue - 1) );
1242      hrd->setCpbSizeValueMinus1( i, j, 1, ( cpbSizeValue - 1 ) );
1243      hrd->setDuCpbSizeValueMinus1( i, j, 1, ( duCpbSizeValue - 1 ) );
1244      hrd->setDuBitRateValueMinus1( i, j, 1, ( duBitRateValue - 1 ) );
[1350]1245      hrd->setCbrFlag( i, j, 1, false );
[1348]1246    }
1247  }
1248}
1249
[313]1250Void TEncTop::xInitPPS()
1251{
1252  m_cPPS.setConstrainedIntraPred( m_bUseConstrainedIntraPred );
1253  Bool bUseDQP = (getMaxCuDQPDepth() > 0)? true : false;
1254
[595]1255  if((getMaxDeltaQP() != 0 )|| getUseAdaptiveQP())
[540]1256  {
[595]1257    bUseDQP = true;
[540]1258  }
[313]1259
[1235]1260  if (m_costMode==COST_SEQUENCE_LEVEL_LOSSLESS || m_costMode==COST_LOSSLESS_CODING)
1261  {
1262    bUseDQP=false;
1263  }
[1029]1264
[1235]1265
1266  if ( m_RCEnableRateControl )
[313]1267  {
1268    m_cPPS.setUseDQP(true);
[1235]1269    m_cPPS.setMaxCuDQPDepth( 0 );
1270  }
1271  else if(bUseDQP)
1272  {
1273    m_cPPS.setUseDQP(true);
[313]1274    m_cPPS.setMaxCuDQPDepth( m_iMaxCuDQPDepth );
1275  }
1276  else
1277  {
1278    m_cPPS.setUseDQP(false);
1279    m_cPPS.setMaxCuDQPDepth( 0 );
1280  }
1281
[1316]1282  if ( m_diffCuChromaQpOffsetDepth >= 0 )
[1029]1283  {
[1316]1284    m_cPPS.getPpsRangeExtension().setDiffCuChromaQpOffsetDepth(m_diffCuChromaQpOffsetDepth);
1285    m_cPPS.getPpsRangeExtension().clearChromaQpOffsetList();
1286    m_cPPS.getPpsRangeExtension().setChromaQpOffsetListEntry(1, 6, 6);
[1029]1287    /* todo, insert table entries from command line (NB, 0 should not be touched) */
1288  }
1289  else
1290  {
[1316]1291    m_cPPS.getPpsRangeExtension().setDiffCuChromaQpOffsetDepth(0);
1292    m_cPPS.getPpsRangeExtension().clearChromaQpOffsetList();
[1029]1293  }
[1316]1294  m_cPPS.getPpsRangeExtension().setCrossComponentPredictionEnabledFlag(m_crossComponentPredictionEnabledFlag);
1295  m_cPPS.getPpsRangeExtension().setLog2SaoOffsetScale(CHANNEL_TYPE_LUMA,   m_log2SaoOffsetScale[CHANNEL_TYPE_LUMA  ]);
1296  m_cPPS.getPpsRangeExtension().setLog2SaoOffsetScale(CHANNEL_TYPE_CHROMA, m_log2SaoOffsetScale[CHANNEL_TYPE_CHROMA]);
[1029]1297
1298  m_cPPS.setQpOffset(COMPONENT_Cb, m_chromaCbQpOffset );
1299  m_cPPS.setQpOffset(COMPONENT_Cr, m_chromaCrQpOffset );
[1545]1300#if W0038_CQP_ADJ
1301  Bool bChromaDeltaQPEnabled = false;
1302  {
1303    bChromaDeltaQPEnabled = ( m_sliceChromaQpOffsetIntraOrPeriodic[0] || m_sliceChromaQpOffsetIntraOrPeriodic[1] );
1304    if( !bChromaDeltaQPEnabled )
1305    {
1306      for( Int i=0; i<m_iGOPSize; i++ )
1307      {
1308        if( m_GOPList[i].m_CbQPoffset || m_GOPList[i].m_CrQPoffset )
1309        {
1310          bChromaDeltaQPEnabled = true;
1311          break;
1312        }
1313      }
1314    }
1315  }
1316  m_cPPS.setSliceChromaQpFlag(bChromaDeltaQPEnabled);
1317#endif
[1029]1318
[1459]1319  m_cPPS.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag );
[313]1320  m_cPPS.setTilesEnabledFlag( (m_iNumColumnsMinus1 > 0 || m_iNumRowsMinus1 > 0) );
1321  m_cPPS.setUseWP( m_useWeightedPred );
1322  m_cPPS.setWPBiPred( m_useWeightedBiPred );
1323  m_cPPS.setOutputFlagPresentFlag( false );
[1569]1324  m_cPPS.setSignDataHidingEnabledFlag(getSignDataHidingEnabledFlag());
[1322]1325
[313]1326  if ( getDeblockingFilterMetric() )
1327  {
1328    m_cPPS.setDeblockingFilterOverrideEnabledFlag(true);
[1570]1329    m_cPPS.setPPSDeblockingFilterDisabledFlag(false);
[1029]1330  }
[313]1331  else
1332  {
[1322]1333    m_cPPS.setDeblockingFilterOverrideEnabledFlag( !getLoopFilterOffsetInPPS() );
[1570]1334    m_cPPS.setPPSDeblockingFilterDisabledFlag( getLoopFilterDisable() );
[313]1335  }
[1235]1336
[1570]1337  if (! m_cPPS.getPPSDeblockingFilterDisabledFlag())
[1235]1338  {
1339    m_cPPS.setDeblockingFilterBetaOffsetDiv2( getLoopFilterBetaOffset() );
1340    m_cPPS.setDeblockingFilterTcOffsetDiv2( getLoopFilterTcOffset() );
1341  }
[1322]1342  else
1343  {
1344    m_cPPS.setDeblockingFilterBetaOffsetDiv2(0);
1345    m_cPPS.setDeblockingFilterTcOffsetDiv2(0);
1346  }
1347
1348  // deblockingFilterControlPresentFlag is true if any of the settings differ from the inferred values:
1349  const Bool deblockingFilterControlPresentFlag = m_cPPS.getDeblockingFilterOverrideEnabledFlag() ||
[1570]1350                                                  m_cPPS.getPPSDeblockingFilterDisabledFlag()      ||
[1322]1351                                                  m_cPPS.getDeblockingFilterBetaOffsetDiv2() != 0 ||
1352                                                  m_cPPS.getDeblockingFilterTcOffsetDiv2() != 0;
1353
1354  m_cPPS.setDeblockingFilterControlPresentFlag(deblockingFilterControlPresentFlag);
1355
[313]1356  m_cPPS.setLog2ParallelMergeLevelMinus2   (m_log2ParallelMergeLevelMinus2 );
1357  m_cPPS.setCabacInitPresentFlag(CABAC_INIT_PRESENT_FLAG);
1358  m_cPPS.setLoopFilterAcrossSlicesEnabledFlag( m_bLFCrossSliceBoundaryFlag );
[1029]1359
[1249]1360
[313]1361  Int histogram[MAX_NUM_REF + 1];
1362  for( Int i = 0; i <= MAX_NUM_REF; i++ )
1363  {
1364    histogram[i]=0;
1365  }
[1029]1366  for( Int i = 0; i < getGOPSize(); i++)
[313]1367  {
1368    assert(getGOPEntry(i).m_numRefPicsActive >= 0 && getGOPEntry(i).m_numRefPicsActive <= MAX_NUM_REF);
1369    histogram[getGOPEntry(i).m_numRefPicsActive]++;
1370  }
[1029]1371
[313]1372  Int maxHist=-1;
1373  Int bestPos=0;
1374  for( Int i = 0; i <= MAX_NUM_REF; i++ )
1375  {
1376    if(histogram[i]>maxHist)
1377    {
1378      maxHist=histogram[i];
1379      bestPos=i;
1380    }
1381  }
1382  assert(bestPos <= 15);
1383  m_cPPS.setNumRefIdxL0DefaultActive(bestPos);
1384  m_cPPS.setNumRefIdxL1DefaultActive(bestPos);
[1567]1385  m_cPPS.setTransquantBypassEnabledFlag(getTransquantBypassEnabledFlag());
[313]1386  m_cPPS.setUseTransformSkip( m_useTransformSkip );
[1316]1387  m_cPPS.getPpsRangeExtension().setLog2MaxTransformSkipBlockSize( m_log2MaxTransformSkipBlockSize  );
[1029]1388
1389  if (m_sliceSegmentMode != NO_SLICES)
[313]1390  {
1391    m_cPPS.setDependentSliceSegmentsEnabledFlag( true );
1392  }
[1029]1393 
[442]1394#if SVC_EXTENSION
[815]1395  m_cPPS.setLayerId( m_layerId );
1396
[830]1397  if( !m_numDirectRefLayers && m_numAddLayerSets )
[313]1398  {
[815]1399    m_cPPS.setLayerId(0); // layer ID 0 for independent layers
[313]1400  }
[815]1401
1402  if( m_layerId > 0 )
[313]1403  {
1404    m_cPPS.setListsModificationPresentFlag(true);
[815]1405    m_cPPS.setExtensionFlag(true);
[313]1406  }
[815]1407  else
1408  {
1409    m_cPPS.setListsModificationPresentFlag(false);
1410    m_cPPS.setExtensionFlag(false);
1411  }
[442]1412
[815]1413  m_cPPS.setPPSId( m_iPPSIdCnt );
1414  m_cPPS.setSPSId( m_iSPSIdCnt );
[1150]1415
1416  if( m_crossLayerBLAFlag )
[540]1417  {
1418    m_cPPS.setNumExtraSliceHeaderBits( 3 );
1419  }
[1150]1420
[1030]1421  m_cPPS.setNumRefLayerLocationOffsets(m_numRefLayerLocationOffsets);
1422  for(Int i = 0; i < m_cPPS.getNumRefLayerLocationOffsets(); i++)
[849]1423  {
[1030]1424    m_cPPS.setRefLocationOffsetLayerId(i, m_refLocationOffsetLayerId[i]);
[849]1425    m_cPPS.getScaledRefLayerWindow(i) = m_scaledRefLayerWindow[i];
1426    m_cPPS.getRefLayerWindow(i) = m_refLayerWindow[i];
[934]1427    m_cPPS.setScaledRefLayerOffsetPresentFlag( i, m_scaledRefLayerOffsetPresentFlag[i] );
1428    m_cPPS.setRefRegionOffsetPresentFlag( i, m_refRegionOffsetPresentFlag[i] );
1429    m_cPPS.setResamplePhaseSetPresentFlag( i, m_resamplePhaseSetPresentFlag[i] );
[1030]1430    m_cPPS.setPhaseHorLuma( m_refLocationOffsetLayerId[i], m_phaseHorLuma[i] );
1431    m_cPPS.setPhaseVerLuma( m_refLocationOffsetLayerId[i], m_phaseVerLuma[i] );
1432    m_cPPS.setPhaseHorChroma( m_refLocationOffsetLayerId[i], m_phaseHorChroma[i] );
1433    m_cPPS.setPhaseVerChroma( m_refLocationOffsetLayerId[i], m_phaseVerChroma[i] );
[849]1434  }
[1212]1435#if CGS_3D_ASYMLUT
[713]1436  m_cPPS.setCGSFlag( m_nCGSFlag );
1437#endif
[815]1438  m_cPPS.setPocResetInfoPresentFlag( true );
1439  m_cPPS.setExtensionFlag( true );
1440  m_cPPS.setSliceHeaderExtensionPresentFlag( true );
1441#endif //SVC_EXTENSION
[313]1442}
1443
1444//Function for initializing m_RPSList, a list of TComReferencePictureSet, based on the GOPEntry objects read from the config file.
[442]1445Void TEncTop::xInitRPS(Bool isFieldCoding)
[313]1446{
1447  TComReferencePictureSet*      rps;
[1029]1448
1449  m_cSPS.createRPSList(getGOPSize() + m_extraRPSs + 1);
[313]1450  TComRPSList* rpsList = m_cSPS.getRPSList();
1451
[1029]1452  for( Int i = 0; i < getGOPSize()+m_extraRPSs; i++)
[313]1453  {
1454    GOPEntry ge = getGOPEntry(i);
1455    rps = rpsList->getReferencePictureSet(i);
1456    rps->setNumberOfPictures(ge.m_numRefPics);
1457    rps->setNumRefIdc(ge.m_numRefIdc);
1458    Int numNeg = 0;
1459    Int numPos = 0;
1460    for( Int j = 0; j < ge.m_numRefPics; j++)
1461    {
1462      rps->setDeltaPOC(j,ge.m_referencePics[j]);
1463      rps->setUsed(j,ge.m_usedByCurrPic[j]);
1464      if(ge.m_referencePics[j]>0)
1465      {
1466        numPos++;
1467      }
1468      else
1469      {
1470        numNeg++;
1471      }
1472    }
1473    rps->setNumberOfNegativePictures(numNeg);
1474    rps->setNumberOfPositivePictures(numPos);
1475
1476    // handle inter RPS intialization from the config file.
1477    rps->setInterRPSPrediction(ge.m_interRPSPrediction > 0);  // not very clean, converting anything > 0 to true.
1478    rps->setDeltaRIdxMinus1(0);                               // index to the Reference RPS is always the previous one.
[1235]1479    TComReferencePictureSet*     RPSRef = i>0 ? rpsList->getReferencePictureSet(i-1): NULL;  // get the reference RPS
[313]1480
1481    if (ge.m_interRPSPrediction == 2)  // Automatic generation of the inter RPS idc based on the RIdx provided.
1482    {
[1235]1483      assert (RPSRef!=NULL);
[313]1484      Int deltaRPS = getGOPEntry(i-1).m_POC - ge.m_POC;  // the ref POC - current POC
1485      Int numRefDeltaPOC = RPSRef->getNumberOfPictures();
1486
1487      rps->setDeltaRPS(deltaRPS);           // set delta RPS
1488      rps->setNumRefIdc(numRefDeltaPOC+1);  // set the numRefIdc to the number of pictures in the reference RPS + 1.
1489      Int count=0;
1490      for (Int j = 0; j <= numRefDeltaPOC; j++ ) // cycle through pics in reference RPS.
1491      {
1492        Int RefDeltaPOC = (j<numRefDeltaPOC)? RPSRef->getDeltaPOC(j): 0;  // if it is the last decoded picture, set RefDeltaPOC = 0
1493        rps->setRefIdc(j, 0);
1494        for (Int k = 0; k < rps->getNumberOfPictures(); k++ )  // cycle through pics in current RPS.
1495        {
[1029]1496          if (rps->getDeltaPOC(k) == ( RefDeltaPOC + deltaRPS))  // if the current RPS has a same picture as the reference RPS.
[313]1497          {
1498              rps->setRefIdc(j, (rps->getUsed(k)?1:2));
1499              count++;
1500              break;
1501          }
1502        }
1503      }
1504      if (count != rps->getNumberOfPictures())
1505      {
1506        printf("Warning: Unable fully predict all delta POCs using the reference RPS index given in the config file.  Setting Inter RPS to false for this RPS.\n");
1507        rps->setInterRPSPrediction(0);
1508      }
1509    }
1510    else if (ge.m_interRPSPrediction == 1)  // inter RPS idc based on the RefIdc values provided in config file.
1511    {
[1235]1512      assert (RPSRef!=NULL);
[313]1513      rps->setDeltaRPS(ge.m_deltaRPS);
1514      rps->setNumRefIdc(ge.m_numRefIdc);
1515      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1516      {
1517        rps->setRefIdc(j, ge.m_refIdc[j]);
1518      }
[1252]1519      // the following code overwrite the deltaPOC and Used by current values read from the config file with the ones
[313]1520      // computed from the RefIdc.  A warning is printed if they are not identical.
1521      numNeg = 0;
1522      numPos = 0;
1523      TComReferencePictureSet      RPSTemp;  // temporary variable
1524
1525      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1526      {
1527        if (ge.m_refIdc[j])
1528        {
1529          Int deltaPOC = ge.m_deltaRPS + ((j < RPSRef->getNumberOfPictures())? RPSRef->getDeltaPOC(j) : 0);
1530          RPSTemp.setDeltaPOC((numNeg+numPos),deltaPOC);
1531          RPSTemp.setUsed((numNeg+numPos),ge.m_refIdc[j]==1?1:0);
1532          if (deltaPOC<0)
1533          {
1534            numNeg++;
1535          }
1536          else
1537          {
1538            numPos++;
1539          }
1540        }
1541      }
1542      if (numNeg != rps->getNumberOfNegativePictures())
1543      {
1544        printf("Warning: number of negative pictures in RPS is different between intra and inter RPS specified in the config file.\n");
1545        rps->setNumberOfNegativePictures(numNeg);
[442]1546        rps->setNumberOfPictures(numNeg+numPos);
[313]1547      }
1548      if (numPos != rps->getNumberOfPositivePictures())
1549      {
1550        printf("Warning: number of positive pictures in RPS is different between intra and inter RPS specified in the config file.\n");
1551        rps->setNumberOfPositivePictures(numPos);
[442]1552        rps->setNumberOfPictures(numNeg+numPos);
[313]1553      }
1554      RPSTemp.setNumberOfPictures(numNeg+numPos);
1555      RPSTemp.setNumberOfNegativePictures(numNeg);
1556      RPSTemp.sortDeltaPOC();     // sort the created delta POC before comparing
[1029]1557      // check if Delta POC and Used are the same
[313]1558      // print warning if they are not.
1559      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1560      {
1561        if (RPSTemp.getDeltaPOC(j) != rps->getDeltaPOC(j))
1562        {
1563          printf("Warning: delta POC is different between intra RPS and inter RPS specified in the config file.\n");
1564          rps->setDeltaPOC(j,RPSTemp.getDeltaPOC(j));
1565        }
1566        if (RPSTemp.getUsed(j) != rps->getUsed(j))
1567        {
1568          printf("Warning: Used by Current in RPS is different between intra and inter RPS specified in the config file.\n");
1569          rps->setUsed(j,RPSTemp.getUsed(j));
1570        }
1571      }
1572    }
1573  }
[1029]1574  //In case of field coding, we need to set special parameters for the first bottom field of the sequence, since it is not specified in the cfg file.
1575  //The position = GOPSize + extraRPSs which is (a priori) unused is reserved for this field in the RPS.
1576  if (isFieldCoding)
[442]1577  {
1578    rps = rpsList->getReferencePictureSet(getGOPSize()+m_extraRPSs);
1579    rps->setNumberOfPictures(1);
1580    rps->setNumberOfNegativePictures(1);
1581    rps->setNumberOfPositivePictures(0);
1582    rps->setNumberOfLongtermPictures(0);
1583    rps->setDeltaPOC(0,-1);
1584    rps->setPOC(0,0);
1585    rps->setUsed(0,true);
1586    rps->setInterRPSPrediction(false);
1587    rps->setDeltaRIdxMinus1(0);
1588    rps->setDeltaRPS(0);
1589    rps->setNumRefIdc(0);
[1029]1590  }
[313]1591}
1592
[1029]1593   // This is a function that
1594   // determines what Reference Picture Set to use
[313]1595   // for a specific slice (with POC = POCCurr)
1596Void TEncTop::selectReferencePictureSet(TComSlice* slice, Int POCCurr, Int GOPid )
1597{
1598  slice->setRPSidx(GOPid);
[1029]1599
[313]1600  for(Int extraNum=m_iGOPSize; extraNum<m_extraRPSs+m_iGOPSize; extraNum++)
[1029]1601  {
[313]1602    if(m_uiIntraPeriod > 0 && getDecodingRefreshType() > 0)
1603    {
1604      Int POCIndex = POCCurr%m_uiIntraPeriod;
1605      if(POCIndex == 0)
1606      {
1607        POCIndex = m_uiIntraPeriod;
1608      }
1609      if(POCIndex == m_GOPList[extraNum].m_POC)
1610      {
1611        slice->setRPSidx(extraNum);
1612      }
1613    }
1614    else
1615    {
1616      if(POCCurr==m_GOPList[extraNum].m_POC)
1617      {
1618        slice->setRPSidx(extraNum);
1619      }
1620    }
1621  }
1622
[442]1623  if(POCCurr == 1 && slice->getPic()->isField())
1624  {
1625    slice->setRPSidx(m_iGOPSize+m_extraRPSs);
1626  }
1627
[1366]1628  const TComReferencePictureSet *rps = (slice->getSPS()->getRPSList()->getReferencePictureSet(slice->getRPSidx()));
[1235]1629  slice->setRPS(rps);
[313]1630}
1631
[1307]1632Int TEncTop::getReferencePictureSetIdxForSOP(Int POCCurr, Int GOPid )
[313]1633{
[1029]1634  Int rpsIdx = GOPid;
[313]1635
1636  for(Int extraNum=m_iGOPSize; extraNum<m_extraRPSs+m_iGOPSize; extraNum++)
[1029]1637  {
[313]1638    if(m_uiIntraPeriod > 0 && getDecodingRefreshType() > 0)
1639    {
1640      Int POCIndex = POCCurr%m_uiIntraPeriod;
1641      if(POCIndex == 0)
1642      {
1643        POCIndex = m_uiIntraPeriod;
1644      }
1645      if(POCIndex == m_GOPList[extraNum].m_POC)
1646      {
1647        rpsIdx = extraNum;
1648      }
1649    }
1650    else
1651    {
1652      if(POCCurr==m_GOPList[extraNum].m_POC)
1653      {
1654        rpsIdx = extraNum;
1655      }
1656    }
1657  }
1658
1659  return rpsIdx;
1660}
1661
1662Void  TEncTop::xInitPPSforTiles()
1663{
[823]1664  m_cPPS.setTileUniformSpacingFlag( m_tileUniformSpacingFlag );
1665  m_cPPS.setNumTileColumnsMinus1( m_iNumColumnsMinus1 );
1666  m_cPPS.setNumTileRowsMinus1( m_iNumRowsMinus1 );
1667  if( !m_tileUniformSpacingFlag )
[313]1668  {
[823]1669    m_cPPS.setTileColumnWidth( m_tileColumnWidth );
1670    m_cPPS.setTileRowHeight( m_tileRowHeight );
[313]1671  }
1672  m_cPPS.setLoopFilterAcrossTilesEnabledFlag( m_loopFilterAcrossTilesEnabledFlag );
1673
1674  // # substreams is "per tile" when tiles are independent.
1675}
1676
1677Void  TEncCfg::xCheckGSParameters()
1678{
[1289]1679  Int   iWidthInCU = ( m_iSourceWidth%m_maxCUWidth ) ? m_iSourceWidth/m_maxCUWidth + 1 : m_iSourceWidth/m_maxCUWidth;
1680  Int   iHeightInCU = ( m_iSourceHeight%m_maxCUHeight ) ? m_iSourceHeight/m_maxCUHeight + 1 : m_iSourceHeight/m_maxCUHeight;
[313]1681  UInt  uiCummulativeColumnWidth = 0;
1682  UInt  uiCummulativeRowHeight = 0;
1683
1684  //check the column relative parameters
1685  if( m_iNumColumnsMinus1 >= (1<<(LOG2_MAX_NUM_COLUMNS_MINUS1+1)) )
1686  {
1687    printf( "The number of columns is larger than the maximum allowed number of columns.\n" );
1688    exit( EXIT_FAILURE );
1689  }
1690
1691  if( m_iNumColumnsMinus1 >= iWidthInCU )
1692  {
1693    printf( "The current picture can not have so many columns.\n" );
1694    exit( EXIT_FAILURE );
1695  }
1696
[823]1697  if( m_iNumColumnsMinus1 && !m_tileUniformSpacingFlag )
[313]1698  {
1699    for(Int i=0; i<m_iNumColumnsMinus1; i++)
1700    {
[823]1701      uiCummulativeColumnWidth += m_tileColumnWidth[i];
[313]1702    }
1703
1704    if( uiCummulativeColumnWidth >= iWidthInCU )
1705    {
1706      printf( "The width of the column is too large.\n" );
1707      exit( EXIT_FAILURE );
1708    }
1709  }
1710
1711  //check the row relative parameters
1712  if( m_iNumRowsMinus1 >= (1<<(LOG2_MAX_NUM_ROWS_MINUS1+1)) )
1713  {
1714    printf( "The number of rows is larger than the maximum allowed number of rows.\n" );
1715    exit( EXIT_FAILURE );
1716  }
1717
1718  if( m_iNumRowsMinus1 >= iHeightInCU )
1719  {
1720    printf( "The current picture can not have so many rows.\n" );
1721    exit( EXIT_FAILURE );
1722  }
1723
[823]1724  if( m_iNumRowsMinus1 && !m_tileUniformSpacingFlag )
[313]1725  {
1726    for(Int i=0; i<m_iNumRowsMinus1; i++)
[1246]1727    {
[823]1728      uiCummulativeRowHeight += m_tileRowHeight[i];
[1246]1729    }
[313]1730
1731    if( uiCummulativeRowHeight >= iHeightInCU )
1732    {
1733      printf( "The height of the row is too large.\n" );
1734      exit( EXIT_FAILURE );
1735    }
1736  }
1737}
1738
1739#if SVC_EXTENSION
[1048]1740TEncTop* TEncTop::getRefLayerEnc( UInt refLayerIdx )
[313]1741{
[1057]1742  if( m_ppcTEncTop[m_cVPS.getLayerIdxInVps(m_layerId)]->getNumDirectRefLayers() <= 0 )
[313]1743  {
1744    return (TEncTop *)getLayerEnc( 0 );
1745  }
1746
[1057]1747  return (TEncTop *)getLayerEnc( m_cVPS.getLayerIdxInVps(m_cVPS.getRefLayerId( m_layerId, refLayerIdx )) );
[313]1748}
1749
1750Void TEncTop::xInitILRP()
1751{
[1235]1752  if( m_layerId > 0 )
[442]1753  {
[1290]1754    if( m_cIlpPic[0] == NULL )
[442]1755    {
[588]1756      for (Int j=0; j < m_numDirectRefLayers; j++)
[442]1757      {
[1029]1758        m_cIlpPic[j] = new TComPic;
[1574]1759#if REDUCED_ENCODER_MEMORY
[1578]1760        m_cIlpPic[j]->create(m_cSPS, m_cPPS, false, true, m_layerId);
[1574]1761#else
[1503]1762        m_cIlpPic[j]->create(m_cSPS, m_cPPS, true, m_layerId);
[1574]1763#endif
[1029]1764        for (Int i=0; i<m_cIlpPic[j]->getPicSym()->getNumberOfCtusInFrame(); i++)
[442]1765        {
[1029]1766          m_cIlpPic[j]->getPicSym()->getCtu(i)->initCtu(m_cIlpPic[j], i);
[442]1767        }
1768      }
1769    }
[1009]1770
1771    if( m_cVPS.getNumRefLayers( m_layerId ) == 0 )
1772    {
[1043]1773      UInt layerIdx = m_cVPS.getLayerIdxInVps( m_layerId );
[1020]1774      RepFormat* repFmt = m_cVPS.getVpsRepFormat(m_cVPS.getVpsRepFormatIdx(layerIdx));
[1009]1775     
1776      if( m_cPPS.getLayerId() == 0 && 
1777          m_cSPS.getLayerId() == 0 &&
[1020]1778          repFmt->getChromaFormatVpsIdc() == m_cSPS.getChromaFormatIdc() &&
1779          repFmt->getSeparateColourPlaneVpsFlag() == 0 &&
1780          repFmt->getPicHeightVpsInLumaSamples() == m_cSPS.getPicHeightInLumaSamples() &&
1781          repFmt->getPicWidthVpsInLumaSamples()  == m_cSPS.getPicWidthInLumaSamples() &&
[1029]1782          repFmt->getBitDepthVpsLuma()   == m_cSPS.getBitDepth(CHANNEL_TYPE_LUMA) &&
1783          repFmt->getBitDepthVpsChroma() == m_cSPS.getBitDepth(CHANNEL_TYPE_CHROMA) &&
[1020]1784          repFmt->getConformanceWindowVps().getWindowLeftOffset()   == m_cSPS.getConformanceWindow().getWindowLeftOffset() &&
1785          repFmt->getConformanceWindowVps().getWindowRightOffset()  == m_cSPS.getConformanceWindow().getWindowRightOffset() &&
1786          repFmt->getConformanceWindowVps().getWindowTopOffset()    == m_cSPS.getConformanceWindow().getWindowTopOffset() &&
1787          repFmt->getConformanceWindowVps().getWindowBottomOffset() == m_cSPS.getConformanceWindow().getWindowBottomOffset() )
[1009]1788      {
1789        m_cVPS.setBaseLayerPSCompatibilityFlag(layerIdx, 1);
1790      }
1791      else
1792      {
1793        m_cVPS.setBaseLayerPSCompatibilityFlag(layerIdx, 0);
1794      }
1795    }
[442]1796  }
1797}
[540]1798
[1235]1799Window TEncTop::getScaledRefLayerWindowForLayer(Int layerId)
[540]1800{
[1030]1801  for (Int i = 0; i < m_numRefLayerLocationOffsets; i++)
[540]1802  {
[1030]1803    if (layerId == m_refLocationOffsetLayerId[i])
[540]1804    {
1805      return m_scaledRefLayerWindow[i];
1806    }
1807  }
1808
[1235]1809  return Window();
[540]1810}
[1090]1811
[1235]1812Window TEncTop::getRefLayerWindowForLayer(Int layerId)
[849]1813{
[1030]1814  for (Int i = 0; i < m_numRefLayerLocationOffsets; i++)
[849]1815  {
1816    if (layerId == m_refLayerId[i])
1817    {
1818      return m_refLayerWindow[i];
1819    }
1820  }
1821
[1235]1822  return Window();
[849]1823}
[494]1824#endif //SVC_EXTENSION
[313]1825//! \}
Note: See TracBrowser for help on using the repository browser.