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

Last change on this file since 1335 was 1322, checked in by seregin, 9 years ago

port rev 4399

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