source: SHVCSoftware/branches/SHM-temp/source/Lib/TLibEncoder/TEncGOP.cpp @ 1497

Last change on this file since 1497 was 1039, checked in by interdigital, 10 years ago
  1. fixed if statement with fixed "m_layerId == 1" as test condition
  2. fixed assert bug of O0092_0094_DEPENDENCY_CONSTRAINT which mistakenly use PPS Id instead of PPS layer_id for constraint check.
  • Property svn:eol-style set to native
File size: 206.2 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2014, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncGOP.cpp
35    \brief    GOP encoder class
36*/
37
38#include <list>
39#include <algorithm>
40#include <functional>
41
42#include "TEncTop.h"
43#include "TEncGOP.h"
44#include "TEncAnalyze.h"
45#include "libmd5/MD5.h"
46#include "TLibCommon/SEI.h"
47#include "TLibCommon/NAL.h"
48#include "NALwrite.h"
49#include <time.h>
50#include <math.h>
51#if P0297_VPS_POC_LSB_ALIGNED_FLAG
52#include <limits.h>
53#endif
54
55using namespace std;
56
57#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
58Bool g_bFinalEncode = false;
59#endif
60
61//! \ingroup TLibEncoder
62//! \{
63
64// ====================================================================================================================
65// Constructor / destructor / initialization / destroy
66// ====================================================================================================================
67Int getLSB(Int poc, Int maxLSB)
68{
69  if (poc >= 0)
70  {
71    return poc % maxLSB;
72  }
73  else
74  {
75    return (maxLSB - ((-poc) % maxLSB)) % maxLSB;
76  }
77}
78
79TEncGOP::TEncGOP()
80{
81  m_iLastIDR            = 0;
82  m_iGopSize            = 0;
83  m_iNumPicCoded        = 0; //Niko
84  m_bFirst              = true;
85#if ALLOW_RECOVERY_POINT_AS_RAP
86  m_iLastRecoveryPicPOC = 0;
87#endif
88
89  m_pcCfg               = NULL;
90  m_pcSliceEncoder      = NULL;
91  m_pcListPic           = NULL;
92
93  m_pcEntropyCoder      = NULL;
94  m_pcCavlcCoder        = NULL;
95  m_pcSbacCoder         = NULL;
96  m_pcBinCABAC          = NULL;
97
98  m_bSeqFirst           = true;
99
100  m_bRefreshPending     = 0;
101  m_pocCRA            = 0;
102  m_numLongTermRefPicSPS = 0;
103  ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps));
104  ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag));
105  m_cpbRemovalDelay   = 0;
106  m_lastBPSEI         = 0;
107  xResetNonNestedSEIPresentFlags();
108  xResetNestedSEIPresentFlags();
109  m_associatedIRAPType = NAL_UNIT_CODED_SLICE_IDR_N_LP;
110  m_associatedIRAPPOC  = 0;
111#if POC_RESET_IDC_ENCODER
112  m_pocCraWithoutReset = 0;
113  m_associatedIrapPocBeforeReset = 0;
114#endif
115#if SVC_EXTENSION
116  m_pcPredSearch        = NULL;
117#if Q0048_CGS_3D_ASYMLUT
118  m_temp = NULL;
119  m_pColorMappedPic = NULL;
120#endif
121#if POC_RESET_IDC_ENCODER
122  m_lastPocPeriodId = -1;
123#endif
124#if R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
125  m_noRaslOutputFlag = false;
126  m_prevPicHasEos    = false;
127#endif
128#endif //SVC_EXTENSION
129  return;
130}
131
132TEncGOP::~TEncGOP()
133{
134#if Q0048_CGS_3D_ASYMLUT
135  if(m_pColorMappedPic)
136  {
137    m_pColorMappedPic->destroy();
138    delete m_pColorMappedPic;
139    m_pColorMappedPic = NULL;               
140  }
141  if(m_temp)
142  {
143    free_mem2DintWithPad(m_temp, m_iTap>>1, 0);
144    m_temp = NULL;
145  }
146#endif
147}
148
149/** Create list to contain pointers to CTU start addresses of slice.
150 */
151#if SVC_EXTENSION
152Void  TEncGOP::create( UInt layerId )
153{
154  m_bLongtermTestPictureHasBeenCoded = 0;
155  m_bLongtermTestPictureHasBeenCoded2 = 0;
156  m_layerId = layerId;
157}
158#else
159Void  TEncGOP::create()
160{
161  m_bLongtermTestPictureHasBeenCoded = 0;
162  m_bLongtermTestPictureHasBeenCoded2 = 0;
163}
164#endif
165
166Void  TEncGOP::destroy()
167{
168}
169
170Void TEncGOP::init ( TEncTop* pcTEncTop )
171{
172  m_pcEncTop     = pcTEncTop;
173  m_pcCfg                = pcTEncTop;
174  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
175  m_pcListPic            = pcTEncTop->getListPic();
176
177  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
178  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
179  m_pcSbacCoder          = pcTEncTop->getSbacCoder();
180  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
181  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
182
183  m_pcSAO                = pcTEncTop->getSAO();
184  m_pcRateCtrl           = pcTEncTop->getRateCtrl();
185  m_lastBPSEI          = 0;
186  m_totalCoded         = 0;
187
188#if SVC_EXTENSION
189  m_ppcTEncTop           = pcTEncTop->getLayerEnc();
190  m_pcPredSearch         = pcTEncTop->getPredSearch();                       ///< encoder search class
191#if Q0048_CGS_3D_ASYMLUT
192  if( pcTEncTop->getLayerId() )
193  {
194    m_Enc3DAsymLUTPicUpdate.create( m_pcCfg->getCGSMaxOctantDepth() , g_bitDepthLayer[CHANNEL_TYPE_LUMA][pcTEncTop->getLayerId()-1] , g_bitDepthLayer[CHANNEL_TYPE_CHROMA][pcTEncTop->getLayerId()-1] , g_bitDepthLayer[CHANNEL_TYPE_LUMA][pcTEncTop->getLayerId()] , g_bitDepthLayer[CHANNEL_TYPE_CHROMA][pcTEncTop->getLayerId()] , m_pcCfg->getCGSMaxYPartNumLog2() /*, m_pcCfg->getCGSPhaseAlignment()*/ );
195    m_Enc3DAsymLUTPPS.create(   m_pcCfg->getCGSMaxOctantDepth() , g_bitDepthLayer[CHANNEL_TYPE_LUMA][pcTEncTop->getLayerId()-1] , g_bitDepthLayer[CHANNEL_TYPE_CHROMA][pcTEncTop->getLayerId()-1] , g_bitDepthLayer[CHANNEL_TYPE_LUMA][pcTEncTop->getLayerId()] , g_bitDepthLayer[CHANNEL_TYPE_CHROMA][pcTEncTop->getLayerId()] , m_pcCfg->getCGSMaxYPartNumLog2() /*, m_pcCfg->getCGSPhaseAlignment()*/ );
196    if(!m_pColorMappedPic)
197    {
198      m_pColorMappedPic = new TComPicYuv;
199      m_pColorMappedPic->create( m_ppcTEncTop[0]->getSourceWidth(), m_ppcTEncTop[0]->getSourceHeight(), m_ppcTEncTop[0]->getChromaFormatIDC(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, NULL );
200    }
201  }
202#endif
203#endif //SVC_EXTENSION
204}
205
206SEIActiveParameterSets* TEncGOP::xCreateSEIActiveParameterSets (TComSPS *sps)
207{
208  SEIActiveParameterSets *seiActiveParameterSets = new SEIActiveParameterSets();
209  seiActiveParameterSets->activeVPSId = m_pcCfg->getVPS()->getVPSId();
210  seiActiveParameterSets->m_selfContainedCvsFlag = false;
211  seiActiveParameterSets->m_noParameterSetUpdateFlag = false;
212#if !R0247_SEI_ACTIVE
213  seiActiveParameterSets->numSpsIdsMinus1 = 0;
214  seiActiveParameterSets->activeSeqParameterSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1);
215  seiActiveParameterSets->activeSeqParameterSetId[0] = sps->getSPSId();
216#else
217  seiActiveParameterSets->numSpsIdsMinus1 = m_pcCfg->getNumLayer()-1;
218  seiActiveParameterSets->activeSeqParameterSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1);
219  seiActiveParameterSets->layerSpsIdx.resize(seiActiveParameterSets->numSpsIdsMinus1+ 1); 
220  for (Int c=0; c <= seiActiveParameterSets->numSpsIdsMinus1; c++)
221  {
222     seiActiveParameterSets->activeSeqParameterSetId[c] = c;
223  }
224  for (Int c=1; c <= seiActiveParameterSets->numSpsIdsMinus1; c++)
225  {
226     seiActiveParameterSets->layerSpsIdx[c] = c;
227  }
228#endif
229  return seiActiveParameterSets;
230}
231
232SEIFramePacking* TEncGOP::xCreateSEIFramePacking()
233{
234  SEIFramePacking *seiFramePacking = new SEIFramePacking();
235  seiFramePacking->m_arrangementId = m_pcCfg->getFramePackingArrangementSEIId();
236  seiFramePacking->m_arrangementCancelFlag = 0;
237  seiFramePacking->m_arrangementType = m_pcCfg->getFramePackingArrangementSEIType();
238  assert((seiFramePacking->m_arrangementType > 2) && (seiFramePacking->m_arrangementType < 6) );
239  seiFramePacking->m_quincunxSamplingFlag = m_pcCfg->getFramePackingArrangementSEIQuincunx();
240  seiFramePacking->m_contentInterpretationType = m_pcCfg->getFramePackingArrangementSEIInterpretation();
241  seiFramePacking->m_spatialFlippingFlag = 0;
242  seiFramePacking->m_frame0FlippedFlag = 0;
243  seiFramePacking->m_fieldViewsFlag = (seiFramePacking->m_arrangementType == 2);
244  seiFramePacking->m_currentFrameIsFrame0Flag = ((seiFramePacking->m_arrangementType == 5) && (m_iNumPicCoded&1));
245  seiFramePacking->m_frame0SelfContainedFlag = 0;
246  seiFramePacking->m_frame1SelfContainedFlag = 0;
247  seiFramePacking->m_frame0GridPositionX = 0;
248  seiFramePacking->m_frame0GridPositionY = 0;
249  seiFramePacking->m_frame1GridPositionX = 0;
250  seiFramePacking->m_frame1GridPositionY = 0;
251  seiFramePacking->m_arrangementReservedByte = 0;
252  seiFramePacking->m_arrangementPersistenceFlag = true;
253  seiFramePacking->m_upsampledAspectRatio = 0;
254  return seiFramePacking;
255}
256
257SEISegmentedRectFramePacking* TEncGOP::xCreateSEISegmentedRectFramePacking()
258{
259  SEISegmentedRectFramePacking *seiSegmentedRectFramePacking = new SEISegmentedRectFramePacking();
260  seiSegmentedRectFramePacking->m_arrangementCancelFlag = m_pcCfg->getSegmentedRectFramePackingArrangementSEICancel();
261  seiSegmentedRectFramePacking->m_contentInterpretationType = m_pcCfg->getSegmentedRectFramePackingArrangementSEIType();
262  seiSegmentedRectFramePacking->m_arrangementPersistenceFlag = m_pcCfg->getSegmentedRectFramePackingArrangementSEIPersistence();
263  return seiSegmentedRectFramePacking;
264}
265
266SEIDisplayOrientation* TEncGOP::xCreateSEIDisplayOrientation()
267{
268  SEIDisplayOrientation *seiDisplayOrientation = new SEIDisplayOrientation();
269  seiDisplayOrientation->cancelFlag = false;
270  seiDisplayOrientation->horFlip = false;
271  seiDisplayOrientation->verFlip = false;
272  seiDisplayOrientation->anticlockwiseRotation = m_pcCfg->getDisplayOrientationSEIAngle();
273  return seiDisplayOrientation;
274}
275SEIToneMappingInfo*  TEncGOP::xCreateSEIToneMappingInfo()
276{
277  SEIToneMappingInfo *seiToneMappingInfo = new SEIToneMappingInfo();
278  seiToneMappingInfo->m_toneMapId = m_pcCfg->getTMISEIToneMapId();
279  seiToneMappingInfo->m_toneMapCancelFlag = m_pcCfg->getTMISEIToneMapCancelFlag();
280  seiToneMappingInfo->m_toneMapPersistenceFlag = m_pcCfg->getTMISEIToneMapPersistenceFlag();
281
282  seiToneMappingInfo->m_codedDataBitDepth = m_pcCfg->getTMISEICodedDataBitDepth();
283  assert(seiToneMappingInfo->m_codedDataBitDepth >= 8 && seiToneMappingInfo->m_codedDataBitDepth <= 14);
284  seiToneMappingInfo->m_targetBitDepth = m_pcCfg->getTMISEITargetBitDepth();
285  assert(seiToneMappingInfo->m_targetBitDepth >= 1 && seiToneMappingInfo->m_targetBitDepth <= 17);
286  seiToneMappingInfo->m_modelId = m_pcCfg->getTMISEIModelID();
287  assert(seiToneMappingInfo->m_modelId >=0 &&seiToneMappingInfo->m_modelId<=4);
288
289  switch( seiToneMappingInfo->m_modelId)
290  {
291  case 0:
292    {
293      seiToneMappingInfo->m_minValue = m_pcCfg->getTMISEIMinValue();
294      seiToneMappingInfo->m_maxValue = m_pcCfg->getTMISEIMaxValue();
295      break;
296    }
297  case 1:
298    {
299      seiToneMappingInfo->m_sigmoidMidpoint = m_pcCfg->getTMISEISigmoidMidpoint();
300      seiToneMappingInfo->m_sigmoidWidth = m_pcCfg->getTMISEISigmoidWidth();
301      break;
302    }
303  case 2:
304    {
305      UInt num = 1u<<(seiToneMappingInfo->m_targetBitDepth);
306      seiToneMappingInfo->m_startOfCodedInterval.resize(num);
307      Int* ptmp = m_pcCfg->getTMISEIStartOfCodedInterva();
308      if(ptmp)
309      {
310        for(Int i=0; i<num;i++)
311        {
312          seiToneMappingInfo->m_startOfCodedInterval[i] = ptmp[i];
313        }
314      }
315      break;
316    }
317  case 3:
318    {
319      seiToneMappingInfo->m_numPivots = m_pcCfg->getTMISEINumPivots();
320      seiToneMappingInfo->m_codedPivotValue.resize(seiToneMappingInfo->m_numPivots);
321      seiToneMappingInfo->m_targetPivotValue.resize(seiToneMappingInfo->m_numPivots);
322      Int* ptmpcoded = m_pcCfg->getTMISEICodedPivotValue();
323      Int* ptmptarget = m_pcCfg->getTMISEITargetPivotValue();
324      if(ptmpcoded&&ptmptarget)
325      {
326        for(Int i=0; i<(seiToneMappingInfo->m_numPivots);i++)
327        {
328          seiToneMappingInfo->m_codedPivotValue[i]=ptmpcoded[i];
329          seiToneMappingInfo->m_targetPivotValue[i]=ptmptarget[i];
330         }
331       }
332       break;
333     }
334  case 4:
335     {
336       seiToneMappingInfo->m_cameraIsoSpeedIdc = m_pcCfg->getTMISEICameraIsoSpeedIdc();
337       seiToneMappingInfo->m_cameraIsoSpeedValue = m_pcCfg->getTMISEICameraIsoSpeedValue();
338       assert( seiToneMappingInfo->m_cameraIsoSpeedValue !=0 );
339       seiToneMappingInfo->m_exposureIndexIdc = m_pcCfg->getTMISEIExposurIndexIdc();
340       seiToneMappingInfo->m_exposureIndexValue = m_pcCfg->getTMISEIExposurIndexValue();
341       assert( seiToneMappingInfo->m_exposureIndexValue !=0 );
342       seiToneMappingInfo->m_exposureCompensationValueSignFlag = m_pcCfg->getTMISEIExposureCompensationValueSignFlag();
343       seiToneMappingInfo->m_exposureCompensationValueNumerator = m_pcCfg->getTMISEIExposureCompensationValueNumerator();
344       seiToneMappingInfo->m_exposureCompensationValueDenomIdc = m_pcCfg->getTMISEIExposureCompensationValueDenomIdc();
345       seiToneMappingInfo->m_refScreenLuminanceWhite = m_pcCfg->getTMISEIRefScreenLuminanceWhite();
346       seiToneMappingInfo->m_extendedRangeWhiteLevel = m_pcCfg->getTMISEIExtendedRangeWhiteLevel();
347       assert( seiToneMappingInfo->m_extendedRangeWhiteLevel >= 100 );
348       seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue = m_pcCfg->getTMISEINominalBlackLevelLumaCodeValue();
349       seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue = m_pcCfg->getTMISEINominalWhiteLevelLumaCodeValue();
350       assert( seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue > seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue );
351       seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue = m_pcCfg->getTMISEIExtendedWhiteLevelLumaCodeValue();
352       assert( seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue >= seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue );
353       break;
354    }
355  default:
356    {
357      assert(!"Undefined SEIToneMapModelId");
358      break;
359    }
360  }
361  return seiToneMappingInfo;
362}
363
364SEITempMotionConstrainedTileSets* TEncGOP::xCreateSEITempMotionConstrainedTileSets ()
365{
366  TComPPS *pps = m_pcEncTop->getPPS();
367  SEITempMotionConstrainedTileSets *sei = new SEITempMotionConstrainedTileSets();
368  if(pps->getTilesEnabledFlag())
369  {
370    sei->m_mc_all_tiles_exact_sample_value_match_flag = false;
371    sei->m_each_tile_one_tile_set_flag                = false;
372    sei->m_limited_tile_set_display_flag              = false;
373    sei->setNumberOfTileSets((pps->getNumTileColumnsMinus1() + 1) * (pps->getNumTileRowsMinus1() + 1));
374
375    for(Int i=0; i < sei->getNumberOfTileSets(); i++)
376    {
377      sei->tileSetData(i).m_mcts_id = i;  //depends the application;
378      sei->tileSetData(i).setNumberOfTileRects(1);
379
380      for(Int j=0; j<sei->tileSetData(i).getNumberOfTileRects(); j++)
381      {
382        sei->tileSetData(i).topLeftTileIndex(j)     = i+j;
383        sei->tileSetData(i).bottomRightTileIndex(j) = i+j;
384      }
385
386      sei->tileSetData(i).m_exact_sample_value_match_flag    = false;
387      sei->tileSetData(i).m_mcts_tier_level_idc_present_flag = false;
388    }
389  }
390  else
391  {
392    assert(!"Tile is not enabled");
393  }
394  return sei;
395}
396
397SEIKneeFunctionInfo* TEncGOP::xCreateSEIKneeFunctionInfo()
398{
399  SEIKneeFunctionInfo *seiKneeFunctionInfo = new SEIKneeFunctionInfo();
400  seiKneeFunctionInfo->m_kneeId = m_pcCfg->getKneeSEIId();
401  seiKneeFunctionInfo->m_kneeCancelFlag = m_pcCfg->getKneeSEICancelFlag();
402  if ( !seiKneeFunctionInfo->m_kneeCancelFlag )
403  {
404    seiKneeFunctionInfo->m_kneePersistenceFlag = m_pcCfg->getKneeSEIPersistenceFlag();
405    seiKneeFunctionInfo->m_kneeInputDrange = m_pcCfg->getKneeSEIInputDrange();
406    seiKneeFunctionInfo->m_kneeInputDispLuminance = m_pcCfg->getKneeSEIInputDispLuminance();
407    seiKneeFunctionInfo->m_kneeOutputDrange = m_pcCfg->getKneeSEIOutputDrange();
408    seiKneeFunctionInfo->m_kneeOutputDispLuminance = m_pcCfg->getKneeSEIOutputDispLuminance();
409
410    seiKneeFunctionInfo->m_kneeNumKneePointsMinus1 = m_pcCfg->getKneeSEINumKneePointsMinus1();
411    Int* piInputKneePoint  = m_pcCfg->getKneeSEIInputKneePoint();
412    Int* piOutputKneePoint = m_pcCfg->getKneeSEIOutputKneePoint();
413    if(piInputKneePoint&&piOutputKneePoint)
414    {
415      seiKneeFunctionInfo->m_kneeInputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
416      seiKneeFunctionInfo->m_kneeOutputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
417      for(Int i=0; i<=seiKneeFunctionInfo->m_kneeNumKneePointsMinus1; i++)
418      {
419        seiKneeFunctionInfo->m_kneeInputKneePoint[i] = piInputKneePoint[i];
420        seiKneeFunctionInfo->m_kneeOutputKneePoint[i] = piOutputKneePoint[i];
421       }
422    }
423  }
424  return seiKneeFunctionInfo;
425}
426
427SEIChromaSamplingFilterHint* TEncGOP::xCreateSEIChromaSamplingFilterHint(Bool bChromaLocInfoPresent, Int iHorFilterIndex, Int iVerFilterIndex)
428{
429  SEIChromaSamplingFilterHint *seiChromaSamplingFilterHint = new SEIChromaSamplingFilterHint();
430  seiChromaSamplingFilterHint->m_verChromaFilterIdc = iVerFilterIndex;
431  seiChromaSamplingFilterHint->m_horChromaFilterIdc = iHorFilterIndex;
432  seiChromaSamplingFilterHint->m_verFilteringProcessFlag = 1;
433  seiChromaSamplingFilterHint->m_targetFormatIdc = 3;
434  seiChromaSamplingFilterHint->m_perfectReconstructionFlag = false;
435  if(seiChromaSamplingFilterHint->m_verChromaFilterIdc == 1)
436  {
437    seiChromaSamplingFilterHint->m_numVerticalFilters = 1;
438    seiChromaSamplingFilterHint->m_verTapLengthMinus1 = (Int*)malloc(seiChromaSamplingFilterHint->m_numVerticalFilters * sizeof(Int));
439    seiChromaSamplingFilterHint->m_verFilterCoeff =    (Int**)malloc(seiChromaSamplingFilterHint->m_numVerticalFilters * sizeof(Int*));
440    for(Int i = 0; i < seiChromaSamplingFilterHint->m_numVerticalFilters; i ++)
441    {
442      seiChromaSamplingFilterHint->m_verTapLengthMinus1[i] = 0;
443      seiChromaSamplingFilterHint->m_verFilterCoeff[i] = (Int*)malloc(seiChromaSamplingFilterHint->m_verTapLengthMinus1[i] * sizeof(Int));
444      for(Int j = 0; j < seiChromaSamplingFilterHint->m_verTapLengthMinus1[i]; j ++)
445      {
446        seiChromaSamplingFilterHint->m_verFilterCoeff[i][j] = 0;
447      }
448    }
449  }
450  else
451  {
452    seiChromaSamplingFilterHint->m_numVerticalFilters = 0;
453    seiChromaSamplingFilterHint->m_verTapLengthMinus1 = NULL;
454    seiChromaSamplingFilterHint->m_verFilterCoeff = NULL;
455  }
456  if(seiChromaSamplingFilterHint->m_horChromaFilterIdc == 1)
457  {
458    seiChromaSamplingFilterHint->m_numHorizontalFilters = 1;
459    seiChromaSamplingFilterHint->m_horTapLengthMinus1 = (Int*)malloc(seiChromaSamplingFilterHint->m_numHorizontalFilters * sizeof(Int));
460    seiChromaSamplingFilterHint->m_horFilterCoeff = (Int**)malloc(seiChromaSamplingFilterHint->m_numHorizontalFilters * sizeof(Int*));
461    for(Int i = 0; i < seiChromaSamplingFilterHint->m_numHorizontalFilters; i ++)
462    {
463      seiChromaSamplingFilterHint->m_horTapLengthMinus1[i] = 0;
464      seiChromaSamplingFilterHint->m_horFilterCoeff[i] = (Int*)malloc(seiChromaSamplingFilterHint->m_horTapLengthMinus1[i] * sizeof(Int));
465      for(Int j = 0; j < seiChromaSamplingFilterHint->m_horTapLengthMinus1[i]; j ++)
466      {
467        seiChromaSamplingFilterHint->m_horFilterCoeff[i][j] = 0;
468      }
469    }
470  }
471  else
472  {
473    seiChromaSamplingFilterHint->m_numHorizontalFilters = 0;
474    seiChromaSamplingFilterHint->m_horTapLengthMinus1 = NULL;
475    seiChromaSamplingFilterHint->m_horFilterCoeff = NULL;
476  }
477  return seiChromaSamplingFilterHint;
478}
479
480Void TEncGOP::xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps)
481{
482  OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
483
484  if(m_pcCfg->getActiveParameterSetsSEIEnabled()
485#if R0247_SEI_ACTIVE
486    && m_layerId == 0
487#endif
488    )
489  {
490    SEIActiveParameterSets *sei = xCreateSEIActiveParameterSets (sps);
491
492    //nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
493    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
494#if O0164_MULTI_LAYER_HRD
495    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
496#else
497    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
498#endif
499    writeRBSPTrailingBits(nalu.m_Bitstream);
500    accessUnit.push_back(new NALUnitEBSP(nalu));
501    delete sei;
502    m_activeParameterSetSEIPresentInAU = true;
503  }
504
505  if(m_pcCfg->getFramePackingArrangementSEIEnabled())
506  {
507    SEIFramePacking *sei = xCreateSEIFramePacking ();
508
509    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
510    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
511#if O0164_MULTI_LAYER_HRD
512    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps);
513#else
514    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
515#endif
516    writeRBSPTrailingBits(nalu.m_Bitstream);
517    accessUnit.push_back(new NALUnitEBSP(nalu));
518    delete sei;
519  }
520  if(m_pcCfg->getSegmentedRectFramePackingArrangementSEIEnabled())
521  {
522    SEISegmentedRectFramePacking *sei = xCreateSEISegmentedRectFramePacking ();
523
524    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
525    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
526#if O0164_MULTI_LAYER_HRD
527    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
528#else
529    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
530#endif
531    writeRBSPTrailingBits(nalu.m_Bitstream);
532    accessUnit.push_back(new NALUnitEBSP(nalu));
533    delete sei;
534  }
535  if (m_pcCfg->getDisplayOrientationSEIAngle())
536  {
537    SEIDisplayOrientation *sei = xCreateSEIDisplayOrientation();
538
539    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
540    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
541#if O0164_MULTI_LAYER_HRD
542    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
543#else
544    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
545#endif
546    writeRBSPTrailingBits(nalu.m_Bitstream);
547    accessUnit.push_back(new NALUnitEBSP(nalu));
548    delete sei;
549  }
550
551  if(m_pcCfg->getToneMappingInfoSEIEnabled())
552  {
553    SEIToneMappingInfo *sei = xCreateSEIToneMappingInfo ();
554
555    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
556    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
557#if O0164_MULTI_LAYER_HRD
558    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps);
559#else
560    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
561#endif
562    writeRBSPTrailingBits(nalu.m_Bitstream);
563    accessUnit.push_back(new NALUnitEBSP(nalu));
564    delete sei;
565  }
566
567  if(m_pcCfg->getTMCTSSEIEnabled())
568  {
569    SEITempMotionConstrainedTileSets *sei_tmcts = xCreateSEITempMotionConstrainedTileSets ();
570
571    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
572    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
573#if O0164_MULTI_LAYER_HRD
574    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei_tmcts, m_pcEncTop->getVPS(), sps);
575#else
576    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei_tmcts, sps);
577#endif
578    writeRBSPTrailingBits(nalu.m_Bitstream);
579    accessUnit.push_back(new NALUnitEBSP(nalu));
580    delete sei_tmcts;
581  }
582
583  if(m_pcCfg->getTimeCodeSEIEnabled())
584  {
585    SEITimeCode sei_time_code;
586    //  Set data as per command line options
587    sei_time_code.numClockTs = m_pcCfg->getNumberOfTimesets();
588    for(Int i = 0; i < sei_time_code.numClockTs; i++)
589      sei_time_code.timeSetArray[i] = m_pcCfg->getTimeSet(i);
590
591    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
592    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
593#if O0164_MULTI_LAYER_HRD
594    m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_time_code, m_pcEncTop->getVPS(), sps);
595#else
596    m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_time_code, sps);
597#endif
598    writeRBSPTrailingBits(nalu.m_Bitstream);
599    accessUnit.push_back(new NALUnitEBSP(nalu));
600  }
601
602  if(m_pcCfg->getKneeSEIEnabled())
603  {
604    SEIKneeFunctionInfo *sei = xCreateSEIKneeFunctionInfo();
605
606    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
607    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
608#if O0164_MULTI_LAYER_HRD
609    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps);
610#else
611    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
612#endif
613    writeRBSPTrailingBits(nalu.m_Bitstream);
614    accessUnit.push_back(new NALUnitEBSP(nalu));
615    delete sei;
616  }
617   
618  if(m_pcCfg->getMasteringDisplaySEI().colourVolumeSEIEnabled)
619  {
620    const TComSEIMasteringDisplay &seiCfg=m_pcCfg->getMasteringDisplaySEI();
621    SEIMasteringDisplayColourVolume mdcv;
622    mdcv.values = seiCfg;
623
624    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
625    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
626#if O0164_MULTI_LAYER_HRD
627    m_seiWriter.writeSEImessage(nalu.m_Bitstream, mdcv, m_pcEncTop->getVPS(), sps);
628#else
629    m_seiWriter.writeSEImessage(nalu.m_Bitstream, mdcv, sps);
630#endif
631    writeRBSPTrailingBits(nalu.m_Bitstream);
632    accessUnit.push_back(new NALUnitEBSP(nalu));
633     
634  }
635
636#if Q0074_COLOUR_REMAPPING_SEI
637  if(m_pcCfg->getCRISEIFile() && strlen(m_pcCfg->getCRISEIFile()))
638  {
639    SEIColourRemappingInfo *sei = xCreateSEIColourRemappingInfo ();
640     
641#if SVC_EXTENSION
642    nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, sps->getLayerId());  // SEI-CRI is applied per layer
643#else
644    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
645#endif
646    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
647#if O0164_MULTI_LAYER_HRD
648    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps);
649#else
650    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
651#endif
652    writeRBSPTrailingBits(nalu.m_Bitstream);
653    accessUnit.push_back(new NALUnitEBSP(nalu));
654    delete sei;
655  }
656#endif
657
658#if SVC_EXTENSION
659#if LAYERS_NOT_PRESENT_SEI
660  if(m_pcCfg->getLayersNotPresentSEIEnabled())
661  {
662    SEILayersNotPresent *sei = xCreateSEILayersNotPresent ();
663    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
664#if O0164_MULTI_LAYER_HRD
665    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
666#else
667    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
668#endif
669    writeRBSPTrailingBits(nalu.m_Bitstream);
670    accessUnit.push_back(new NALUnitEBSP(nalu));
671    delete sei;
672  }
673#endif
674
675#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
676  if(m_pcCfg->getInterLayerConstrainedTileSetsSEIEnabled())
677  {
678    SEIInterLayerConstrainedTileSets *sei = xCreateSEIInterLayerConstrainedTileSets ();
679
680    nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, m_pcCfg->getNumLayer()-1); // For highest layer
681    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
682#if O0164_MULTI_LAYER_HRD
683    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
684#else
685    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
686#endif
687    writeRBSPTrailingBits(nalu.m_Bitstream);
688    accessUnit.push_back(new NALUnitEBSP(nalu));
689    delete sei;
690  }
691#endif
692
693#if P0123_ALPHA_CHANNEL_SEI
694  if( m_pcCfg->getAlphaSEIEnabled() && m_pcEncTop->getVPS()->getScalabilityId(m_layerId, AUX_ID) && m_pcEncTop->getVPS()->getDimensionId(m_layerId, m_pcEncTop->getVPS()->getNumScalabilityTypes() - 1) == AUX_ALPHA )
695  {
696    SEIAlphaChannelInfo *sei = xCreateSEIAlphaChannelInfo();
697    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
698#if O0164_MULTI_LAYER_HRD
699    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps);
700#else
701    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
702#endif
703    writeRBSPTrailingBits(nalu.m_Bitstream);
704    accessUnit.push_back(new NALUnitEBSP(nalu));
705    delete sei;
706  }
707#endif
708
709#if Q0096_OVERLAY_SEI
710  if(m_pcCfg->getOverlaySEIEnabled())
711  {   
712    SEIOverlayInfo *sei = xCreateSEIOverlayInfo();       
713    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
714#if O0164_MULTI_LAYER_HRD
715    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
716#else
717    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
718#endif
719    writeRBSPTrailingBits(nalu.m_Bitstream);
720    accessUnit.push_back(new NALUnitEBSP(nalu));
721    delete sei;
722  }
723#endif
724#endif //SVC_EXTENSION
725}
726
727// ====================================================================================================================
728// Public member functions
729// ====================================================================================================================
730#if SVC_EXTENSION
731Void TEncGOP::compressGOP( Int iPicIdInGOP, Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic,
732                           TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP,
733                           Bool isField, Bool isTff, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE )
734#else
735Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic,
736                           TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP,
737                           Bool isField, Bool isTff, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE )
738#endif
739{
740  // TODO: Split this function up.
741
742  TComPic*        pcPic = NULL;
743  TComPicYuv*     pcPicYuvRecOut;
744  TComSlice*      pcSlice;
745  TComOutputBitstream  *pcBitstreamRedirect;
746  pcBitstreamRedirect = new TComOutputBitstream;
747  AccessUnit::iterator  itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted
748
749  xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut, isField );
750
751  m_iNumPicCoded = 0;
752  SEIPictureTiming pictureTimingSEI;
753  Bool writeSOP = m_pcCfg->getSOPDescriptionSEIEnabled();
754
755  // Initialize Scalable Nesting SEI with single layer values
756  SEIScalableNesting scalableNestingSEI;
757  scalableNestingSEI.m_bitStreamSubsetFlag           = 1;      // If the nested SEI messages are picture buffereing SEI mesages, picure timing SEI messages or sub-picture timing SEI messages, bitstream_subset_flag shall be equal to 1
758  scalableNestingSEI.m_nestingOpFlag                 = 0;
759  scalableNestingSEI.m_nestingNumOpsMinus1           = 0;      //nesting_num_ops_minus1
760  scalableNestingSEI.m_allLayersFlag                 = 0;
761  scalableNestingSEI.m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1;  //nesting_no_op_max_temporal_id_plus1
762  scalableNestingSEI.m_nestingNumLayersMinus1        = 1 - 1;  //nesting_num_layers_minus1
763  scalableNestingSEI.m_nestingLayerId[0]             = 0;
764  scalableNestingSEI.m_callerOwnsSEIs                = true;
765
766  Int picSptDpbOutputDuDelay = 0;
767  UInt *accumBitsDU = NULL;
768  UInt *accumNalsDU = NULL;
769  SEIDecodingUnitInfo decodingUnitInfoSEI;
770
771#if EFFICIENT_FIELD_IRAP
772  Int IRAPGOPid = -1;
773  Bool IRAPtoReorder = false;
774  Bool swapIRAPForward = false;
775  if(isField)
776  {
777    Int pocCurr;
778#if SVC_EXTENSION
779    for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ )
780#else
781    for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
782#endif   
783    {
784      // determine actual POC
785      if(iPOCLast == 0) //case first frame or first top field
786      {
787        pocCurr=0;
788      }
789      else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
790      {
791        pocCurr = 1;
792      }
793      else
794      {
795        pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField;
796      }
797
798      // check if POC corresponds to IRAP
799      NalUnitType tmpUnitType = getNalUnitType(pocCurr, m_iLastIDR, isField);
800      if(tmpUnitType >= NAL_UNIT_CODED_SLICE_BLA_W_LP && tmpUnitType <= NAL_UNIT_CODED_SLICE_CRA) // if picture is an IRAP
801      {
802        if(pocCurr%2 == 0 && iGOPid < m_iGopSize-1 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid+1).m_POC-1)
803        { // if top field and following picture in enc order is associated bottom field
804          IRAPGOPid = iGOPid;
805          IRAPtoReorder = true;
806          swapIRAPForward = true; 
807          break;
808        }
809        if(pocCurr%2 != 0 && iGOPid > 0 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid-1).m_POC+1)
810        {
811          // if picture is an IRAP remember to process it first
812          IRAPGOPid = iGOPid;
813          IRAPtoReorder = true;
814          swapIRAPForward = false; 
815          break;
816        }
817      }
818    }
819  }
820#endif
821  // reset flag indicating whether pictures have been encoded
822  for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
823  {
824    m_pcCfg->setEncodedFlag(iGOPid, false);
825  }
826#if SVC_EXTENSION
827  for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ )
828#else
829  for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
830#endif
831  {
832#if EFFICIENT_FIELD_IRAP
833    if(IRAPtoReorder)
834    {
835      if(swapIRAPForward)
836      {
837        if(iGOPid == IRAPGOPid)
838        {
839          iGOPid = IRAPGOPid +1;
840        }
841        else if(iGOPid == IRAPGOPid +1)
842        {
843          iGOPid = IRAPGOPid;
844        }
845      }
846      else
847      {
848        if(iGOPid == IRAPGOPid -1)
849        {
850          iGOPid = IRAPGOPid;
851        }
852        else if(iGOPid == IRAPGOPid)
853        {
854          iGOPid = IRAPGOPid -1;
855        }
856      }
857    }
858#endif
859
860    UInt uiColDir = 1;
861    //-- For time output for each slice
862    clock_t iBeforeTime = clock();
863
864    //select uiColDir
865    Int iCloseLeft=1, iCloseRight=-1;
866    for(Int i = 0; i<m_pcCfg->getGOPEntry(iGOPid).m_numRefPics; i++)
867    {
868      Int iRef = m_pcCfg->getGOPEntry(iGOPid).m_referencePics[i];
869      if(iRef>0&&(iRef<iCloseRight||iCloseRight==-1))
870      {
871        iCloseRight=iRef;
872      }
873      else if(iRef<0&&(iRef>iCloseLeft||iCloseLeft==1))
874      {
875        iCloseLeft=iRef;
876      }
877    }
878    if(iCloseRight>-1)
879    {
880      iCloseRight=iCloseRight+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
881    }
882    if(iCloseLeft<1)
883    {
884      iCloseLeft=iCloseLeft+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
885      while(iCloseLeft<0)
886      {
887        iCloseLeft+=m_iGopSize;
888      }
889    }
890    Int iLeftQP=0, iRightQP=0;
891    for(Int i=0; i<m_iGopSize; i++)
892    {
893      if(m_pcCfg->getGOPEntry(i).m_POC==(iCloseLeft%m_iGopSize)+1)
894      {
895        iLeftQP= m_pcCfg->getGOPEntry(i).m_QPOffset;
896      }
897      if (m_pcCfg->getGOPEntry(i).m_POC==(iCloseRight%m_iGopSize)+1)
898      {
899        iRightQP=m_pcCfg->getGOPEntry(i).m_QPOffset;
900      }
901    }
902    if(iCloseRight>-1&&iRightQP<iLeftQP)
903    {
904      uiColDir=0;
905    }
906
907    /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
908    Int iTimeOffset;
909    Int pocCurr;
910
911    if(iPOCLast == 0) //case first frame or first top field
912    {
913      pocCurr=0;
914      iTimeOffset = 1;
915    }
916    else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
917    {
918      pocCurr = 1;
919      iTimeOffset = 1;
920    }
921    else
922    {
923      pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - ((isField && m_iGopSize>1) ? 1:0);
924      iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;
925    }
926
927    if(pocCurr>=m_pcCfg->getFramesToBeEncoded())
928    {
929#if EFFICIENT_FIELD_IRAP
930      if(IRAPtoReorder)
931      {
932        if(swapIRAPForward)
933        {
934          if(iGOPid == IRAPGOPid)
935          {
936            iGOPid = IRAPGOPid +1;
937            IRAPtoReorder = false;
938          }
939          else if(iGOPid == IRAPGOPid +1)
940          {
941            iGOPid --;
942          }
943        }
944        else
945        {
946          if(iGOPid == IRAPGOPid)
947          {
948            iGOPid = IRAPGOPid -1;
949          }
950          else if(iGOPid == IRAPGOPid -1)
951          {
952            iGOPid = IRAPGOPid;
953            IRAPtoReorder = false;
954          }
955        }
956      }
957#endif
958      continue;
959    }
960
961#if M0040_ADAPTIVE_RESOLUTION_CHANGE
962    if (m_pcEncTop->getAdaptiveResolutionChange() > 0 && ((m_layerId > 0 && pocCurr < m_pcEncTop->getAdaptiveResolutionChange()) ||
963                                                          (m_layerId == 0 && pocCurr > m_pcEncTop->getAdaptiveResolutionChange())) )
964    {
965      continue;
966    }
967#endif
968#if R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
969    if (pocCurr > m_pcEncTop->getLayerSwitchOffBegin() && pocCurr < m_pcEncTop->getLayerSwitchOffEnd())
970    {
971      continue;
972    }
973#endif
974
975    if( getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP )
976    {
977      m_iLastIDR = pocCurr;
978    }
979    // start a new access unit: create an entry in the list of output access units
980    accessUnitsInGOP.push_back(AccessUnit());
981    AccessUnit& accessUnit = accessUnitsInGOP.back();
982    xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField );
983
984    //  Slice data initialization
985    pcPic->clearSliceBuffer();
986    assert(pcPic->getNumAllocatedSlice() == 1);
987    m_pcSliceEncoder->setSliceIdx(0);
988    pcPic->setCurrSliceIdx(0);
989#if SVC_EXTENSION
990    pcPic->setLayerId( m_layerId );
991    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), m_pcEncTop->getVPS(), isField );
992#else
993    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), isField );
994#endif
995
996    //Set Frame/Field coding
997    pcSlice->getPic()->setField(isField);
998
999#if SVC_EXTENSION
1000#if POC_RESET_FLAG
1001    if( !pcSlice->getPocResetFlag() ) // For picture that are not reset, we should adjust the value of POC calculated from the configuration files.
1002    {
1003      // Subtract POC adjustment value until now.
1004      pcSlice->setPOC( pcSlice->getPOC() - m_pcEncTop->getPocAdjustmentValue() );
1005    }
1006    else
1007    {
1008      // Check if this is the first slice in the picture
1009      // In the encoder, the POC values are copied along with copySliceInfo, so we only need
1010      // to do this for the first slice.
1011      Int pocAdjustValue = pcSlice->getPOC() - m_pcEncTop->getPocAdjustmentValue();
1012      if( pcSlice->getSliceIdx() == 0 )
1013      {
1014        TComList<TComPic*>::iterator  iterPic = rcListPic.begin(); 
1015
1016        // Iterate through all picture in DPB
1017        while( iterPic != rcListPic.end() )
1018        {             
1019          TComPic *dpbPic = *iterPic;
1020          if( dpbPic->getPOC() == pocCurr )
1021          {
1022            if( dpbPic->getReconMark() )
1023            {
1024              assert( !( dpbPic->getSlice(0)->isReferenced() ) && !( dpbPic->getOutputMark() ) );
1025            }
1026          }
1027          // Check if the picture pointed to by iterPic is either used for reference or
1028          // needed for output, are in the same layer, and not the current picture.
1029          if( /* ( ( dpbPic->getSlice(0)->isReferenced() ) || ( dpbPic->getOutputMark() ) )
1030              && */ ( dpbPic->getLayerId() == pcSlice->getLayerId() )
1031              && ( dpbPic->getReconMark() ) 
1032            )
1033          {
1034            for(Int i = dpbPic->getNumAllocatedSlice()-1; i >= 0; i--)
1035            {
1036              TComSlice *slice = dpbPic->getSlice(i);
1037              TComReferencePictureSet *rps = slice->getRPS();
1038              slice->setPOC( dpbPic->getSlice(i)->getPOC() - pocAdjustValue );
1039
1040              // Also adjust the POC value stored in the RPS of each such slice
1041              for(Int j = rps->getNumberOfPictures(); j >= 0; j--)
1042              {
1043                rps->setPOC( j, rps->getPOC(j) - pocAdjustValue );
1044              }
1045              // Also adjust the value of refPOC
1046              for(Int k = 0; k < 2; k++)  // For List 0 and List 1
1047              {
1048                RefPicList list = (k == 1) ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
1049                for(Int j = 0; j < slice->getNumRefIdx(list); j++)
1050                {
1051                  slice->setRefPOC( slice->getRefPOC(list, j) - pocAdjustValue, list, j);
1052                }
1053              }
1054            }
1055          }
1056          iterPic++;
1057        }
1058        m_pcEncTop->setPocAdjustmentValue( m_pcEncTop->getPocAdjustmentValue() + pocAdjustValue );
1059      }
1060      pcSlice->setPocValueBeforeReset( pcSlice->getPOC() - m_pcEncTop->getPocAdjustmentValue() + pocAdjustValue );
1061      pcSlice->setPOC( 0 );
1062    }
1063#endif
1064#if POC_RESET_IDC_ENCODER
1065    pcSlice->setPocValueBeforeReset( pocCurr );
1066    // Check if the current picture is to be assigned as a reset picture
1067    determinePocResetIdc(pocCurr, pcSlice);
1068
1069#if P0297_VPS_POC_LSB_ALIGNED_FLAG
1070    Bool pocResettingFlag = false;
1071
1072    if (pcSlice->getPocResetIdc() != 0)
1073    {
1074      if (pcSlice->getVPS()->getVpsPocLsbAlignedFlag())
1075      {
1076        pocResettingFlag = true;
1077      }
1078      else if (m_pcEncTop->getPocDecrementedInDPBFlag())
1079      {
1080        pocResettingFlag = false;
1081      }
1082      else
1083      {
1084        pocResettingFlag = true;
1085      }
1086    }
1087#endif
1088
1089    // If reset, do the following steps:
1090#if P0297_VPS_POC_LSB_ALIGNED_FLAG
1091    if( pocResettingFlag )
1092#else
1093    if( pcSlice->getPocResetIdc() )
1094#endif
1095    {
1096      updatePocValuesOfPics(pocCurr, pcSlice);
1097    }
1098    else
1099    {
1100      // Check the base layer picture is IDR. If so, just set current POC equal to 0 (alignment of POC)
1101      if( ( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2) && ( pocCurr % m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshInterval() == 0 ) )       
1102      {
1103        m_pcEncTop->setPocAdjustmentValue( pocCurr );
1104      }
1105      // else
1106      {
1107        // Just subtract POC by the current cumulative POC delta
1108        pcSlice->setPOC( pocCurr - m_pcEncTop->getPocAdjustmentValue() );
1109      }
1110
1111      Int maxPocLsb = 1 << pcSlice->getSPS()->getBitsForPOC();
1112      pcSlice->setPocMsbVal( pcSlice->getPOC() - ( pcSlice->getPOC() & (maxPocLsb-1) ) );
1113    }
1114    // Update the POC of current picture, pictures in the DPB, including references inside the reference pictures
1115
1116#endif
1117
1118#if O0149_CROSS_LAYER_BLA_FLAG
1119    if( m_layerId == 0 && (getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP) )
1120    {
1121      pcSlice->setCrossLayerBLAFlag(m_pcEncTop->getCrossLayerBLAFlag());
1122    }
1123    else
1124    {
1125      pcSlice->setCrossLayerBLAFlag(false);
1126    }
1127#endif
1128#if R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
1129    // Set the nal unit type
1130    pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
1131#endif
1132#if NO_CLRAS_OUTPUT_FLAG
1133    if (m_layerId == 0 &&
1134        (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1135      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1136      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
1137      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1138      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1139      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA))
1140    {
1141      if (m_bFirst)
1142      {
1143        m_pcEncTop->setNoClrasOutputFlag(true);
1144      }
1145#if R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
1146      else if (m_prevPicHasEos)
1147      {
1148        m_pcEncTop->setNoClrasOutputFlag(true);
1149      }
1150#endif
1151      else if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1152            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1153            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP)
1154      {
1155        m_pcEncTop->setNoClrasOutputFlag(true);
1156      }
1157#if O0149_CROSS_LAYER_BLA_FLAG
1158      else if ((pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP) &&
1159               pcSlice->getCrossLayerBLAFlag())
1160      {
1161        m_pcEncTop->setNoClrasOutputFlag(true);
1162      }
1163#endif
1164      else
1165      {
1166        m_pcEncTop->setNoClrasOutputFlag(false);
1167      }
1168      if (m_pcEncTop->getNoClrasOutputFlag())
1169      {
1170        for (UInt i = 0; i < m_pcCfg->getNumLayer(); i++)
1171        {
1172          m_ppcTEncTop[i]->setLayerInitializedFlag(false);
1173          m_ppcTEncTop[i]->setFirstPicInLayerDecodedFlag(false);
1174        }
1175      }
1176    }
1177#endif
1178#if R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
1179    xCheckLayerReset(pcSlice);
1180    xSetNoRaslOutputFlag(pcSlice);
1181    xSetLayerInitializedFlag(pcSlice);
1182#endif
1183#if M0040_ADAPTIVE_RESOLUTION_CHANGE
1184    if (m_pcEncTop->getAdaptiveResolutionChange() > 0 && m_layerId > 0 && pocCurr > m_pcEncTop->getAdaptiveResolutionChange())
1185    {
1186      pcSlice->setActiveNumILRRefIdx(0);
1187      pcSlice->setInterLayerPredEnabledFlag(false);
1188      pcSlice->setMFMEnabledFlag(false);
1189    }
1190#endif
1191#endif //SVC_EXTENSION
1192
1193    pcSlice->setLastIDR(m_iLastIDR);
1194    pcSlice->setSliceIdx(0);
1195    //set default slice level flag to the same as SPS level flag
1196    pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag()  );
1197    pcSlice->setScalingList ( m_pcEncTop->getScalingList()  );
1198    if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_OFF)
1199    {
1200      m_pcEncTop->getTrQuant()->setFlatScalingList(pcSlice->getSPS()->getChromaFormatIdc());
1201      m_pcEncTop->getTrQuant()->setUseScalingList(false);
1202      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
1203      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
1204    }
1205    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_DEFAULT)
1206    {
1207#if SCALINGLIST_INFERRING
1208      // inferring of the scaling list can be moved to the config file
1209      UInt refLayerId = 0;
1210#if VPS_AVC_BL_FLAG_REMOVAL
1211      if( m_layerId > 0 && !m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) )
1212#else
1213      if( m_layerId > 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) )
1214#endif
1215      {
1216        m_pcEncTop->getSPS()->setInferScalingListFlag( true );
1217        m_pcEncTop->getSPS()->setScalingListRefLayerId( refLayerId );
1218        m_pcEncTop->getSPS()->setScalingListPresentFlag( false );
1219        m_pcEncTop->getPPS()->setInferScalingListFlag( false );
1220        m_pcEncTop->getPPS()->setScalingListPresentFlag( false );
1221
1222        // infer the scaling list from the reference layer
1223        pcSlice->setScalingList ( m_ppcTEncTop[refLayerId]->getScalingList() );
1224      }
1225      else
1226      {
1227#endif
1228      pcSlice->setDefaultScalingList ();
1229      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
1230      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
1231
1232#if SCALINGLIST_INFERRING
1233      }
1234#endif
1235
1236      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList(), pcSlice->getSPS()->getChromaFormatIdc());
1237      m_pcEncTop->getTrQuant()->setUseScalingList(true);
1238    }
1239    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_FILE_READ)
1240    {
1241#if SCALINGLIST_INFERRING
1242      // inferring of the scaling list can be moved to the config file
1243      UInt refLayerId = 0;
1244#if VPS_AVC_BL_FLAG_REMOVAL
1245      if( m_layerId > 0 && !m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) )
1246#else
1247      if( m_layerId > 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) )
1248#endif
1249      {
1250        m_pcEncTop->getSPS()->setInferScalingListFlag( true );
1251        m_pcEncTop->getSPS()->setScalingListRefLayerId( refLayerId );
1252        m_pcEncTop->getSPS()->setScalingListPresentFlag( false );
1253        m_pcEncTop->getPPS()->setInferScalingListFlag( false );
1254        m_pcEncTop->getPPS()->setScalingListPresentFlag( false );
1255
1256        // infer the scaling list from the reference layer
1257        pcSlice->setScalingList ( m_ppcTEncTop[refLayerId]->getScalingList() );
1258      }
1259      else
1260      {
1261#endif
1262      pcSlice->setDefaultScalingList ();
1263      if(pcSlice->getScalingList()->xParseScalingList(m_pcCfg->getScalingListFile()))
1264      {
1265        Bool bParsedScalingList=false; // Use of boolean so that assertion outputs useful string
1266        assert(bParsedScalingList);
1267        exit(1);
1268      }
1269      pcSlice->getScalingList()->checkDcOfMatrix();
1270      m_pcEncTop->getSPS()->setScalingListPresentFlag(pcSlice->checkDefaultScalingList());
1271      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
1272
1273#if SCALINGLIST_INFERRING
1274    }
1275#endif
1276
1277      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList(), pcSlice->getSPS()->getChromaFormatIdc());
1278      m_pcEncTop->getTrQuant()->setUseScalingList(true);
1279    }
1280    else
1281    {
1282      printf("error : ScalingList == %d no support\n",m_pcEncTop->getUseScalingListId());
1283      assert(0);
1284    }
1285
1286    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P')
1287    {
1288      pcSlice->setSliceType(P_SLICE);
1289    }
1290    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='I')
1291    {
1292      pcSlice->setSliceType(I_SLICE);
1293    }
1294   
1295#if !R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
1296    // Set the nal unit type
1297    pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
1298#endif
1299#if SVC_EXTENSION
1300    if (m_layerId > 0)
1301    {
1302      Int interLayerPredLayerIdcTmp[MAX_VPS_LAYER_ID_PLUS1];
1303      Int activeNumILRRefIdxTmp = 0;
1304
1305      for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
1306      {
1307        UInt refLayerIdc = pcSlice->getInterLayerPredLayerIdc(i);
1308        UInt refLayerId = pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc);
1309#if VPS_EXTN_DIRECT_REF_LAYERS
1310        TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId]->getRefLayerEnc(refLayerIdc)->getListPic();
1311#else
1312        TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId-1]->getListPic();
1313#endif
1314        pcSlice->setBaseColPic( *cListPic, refLayerIdc );
1315
1316        // Apply temporal layer restriction to inter-layer prediction
1317#if O0225_MAX_TID_FOR_REF_LAYERS
1318        Int maxTidIlRefPicsPlus1 = m_pcEncTop->getVPS()->getMaxTidIlRefPicsPlus1(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getLayerId(),m_layerId);
1319#else
1320        Int maxTidIlRefPicsPlus1 = m_pcEncTop->getVPS()->getMaxTidIlRefPicsPlus1(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getLayerId());
1321#endif
1322        if( ((Int)(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getTLayer())<=maxTidIlRefPicsPlus1-1) || (maxTidIlRefPicsPlus1==0 && pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getRapPicFlag()) )
1323        {
1324          interLayerPredLayerIdcTmp[activeNumILRRefIdxTmp++] = refLayerIdc; // add picture to the list of valid inter-layer pictures
1325        }
1326        else
1327        {
1328          continue; // ILP is not valid due to temporal layer restriction
1329        }
1330
1331#if O0098_SCALED_REF_LAYER_ID
1332        const Window &scalEL = m_pcEncTop->getScaledRefLayerWindowForLayer(refLayerId);
1333#else
1334        const Window &scalEL = m_pcEncTop->getScaledRefLayerWindow(refLayerIdc);
1335#endif
1336
1337#if REF_REGION_OFFSET
1338        const Window &windowRL  = m_pcEncTop->getRefLayerWindowForLayer(pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc));
1339        Int widthBL   = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getWidth(COMPONENT_Y) - windowRL.getWindowLeftOffset() - windowRL.getWindowRightOffset();
1340        Int heightBL  = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getHeight(COMPONENT_Y) - windowRL.getWindowTopOffset() - windowRL.getWindowBottomOffset();
1341#else
1342        Int widthBL   = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getWidth(COMPONENT_Y);
1343        Int heightBL  = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getHeight(COMPONENT_Y);
1344#if Q0200_CONFORMANCE_BL_SIZE
1345        Int chromaFormatIdc = pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getChromaFormatIdc();
1346        const Window &confBL = pcSlice->getBaseColPic(refLayerIdc)->getConformanceWindow();
1347        widthBL  -= ( confBL.getWindowLeftOffset() + confBL.getWindowRightOffset() ) * TComSPS::getWinUnitX( chromaFormatIdc );
1348        heightBL -= ( confBL.getWindowTopOffset() + confBL.getWindowBottomOffset() ) * TComSPS::getWinUnitY( chromaFormatIdc );
1349#endif
1350#endif
1351        Int widthEL   = pcPic->getPicYuvRec()->getWidth(COMPONENT_Y)  - scalEL.getWindowLeftOffset() - scalEL.getWindowRightOffset();
1352        Int heightEL  = pcPic->getPicYuvRec()->getHeight(COMPONENT_Y) - scalEL.getWindowTopOffset()  - scalEL.getWindowBottomOffset();
1353
1354#if RESAMPLING_FIX
1355#if REF_REGION_OFFSET
1356        // conformance check: the values of RefLayerRegionWidthInSamplesY, RefLayerRegionHeightInSamplesY, ScaledRefRegionWidthInSamplesY and ScaledRefRegionHeightInSamplesY shall be greater than 0
1357        assert(widthEL > 0 && heightEL > 0 && widthBL > 0 && widthEL > 0);
1358
1359        // conformance check: ScaledRefRegionWidthInSamplesY shall be greater or equal to RefLayerRegionWidthInSamplesY and ScaledRefRegionHeightInSamplesY shall be greater or equal to RefLayerRegionHeightInSamplesY
1360        assert(widthEL >= widthBL && heightEL >= heightBL);
1361
1362#if R0209_GENERIC_PHASE
1363        // conformance check: when ScaledRefRegionWidthInSamplesY is equal to RefLayerRegionWidthInSamplesY, PhaseHorY shall be equal to 0, when ScaledRefRegionWidthInSamplesC is equal to RefLayerRegionWidthInSamplesC, PhaseHorC shall be equal to 0, when ScaledRefRegionHeightInSamplesY is equal to RefLayerRegionHeightInSamplesY, PhaseVerY shall be equal to 0, and when ScaledRefRegionHeightInSamplesC is equal to RefLayerRegionHeightInSamplesC, PhaseVerC shall be equal to 0.
1364        Bool phaseSetPresentFlag;
1365        Int phaseHorLuma, phaseVerLuma, phaseHorChroma, phaseVerChroma;
1366        pcSlice->getPPS()->getResamplingPhase( refLayerId, phaseSetPresentFlag, phaseHorLuma, phaseVerLuma, phaseHorChroma, phaseVerChroma );
1367
1368        assert( ( (widthEL  != widthBL)  || (phaseHorLuma == 0 && phaseHorChroma == 0) )
1369             && ( (heightEL != heightBL) || (phaseVerLuma == 0 && phaseVerChroma == 0) ) );
1370#endif
1371#endif
1372#endif
1373
1374        g_mvScalingFactor[refLayerIdc][0] = widthEL  == widthBL  ? 4096 : Clip3(-4096, 4095, ((widthEL  << 8) + (widthBL  >> 1)) / widthBL);
1375        g_mvScalingFactor[refLayerIdc][1] = heightEL == heightBL ? 4096 : Clip3(-4096, 4095, ((heightEL << 8) + (heightBL >> 1)) / heightBL);
1376
1377        g_posScalingFactor[refLayerIdc][0] = ((widthBL  << 16) + (widthEL  >> 1)) / widthEL;
1378        g_posScalingFactor[refLayerIdc][1] = ((heightBL << 16) + (heightEL >> 1)) / heightEL;
1379
1380#if Q0048_CGS_3D_ASYMLUT
1381        TComPicYuv* pBaseColRec = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec();
1382        if( pcSlice->getPPS()->getCGSFlag() )
1383        {
1384#if R0150_CGS_SIGNAL_CONSTRAINTS
1385          // all reference layers are currently taken as CGS reference layers
1386          m_Enc3DAsymLUTPPS.addRefLayerId( pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc) );
1387          m_Enc3DAsymLUTPicUpdate.addRefLayerId( pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc) );
1388#endif
1389          if(g_posScalingFactor[refLayerIdc][0] < (1<<16) || g_posScalingFactor[refLayerIdc][1] < (1<<16)) //if(pcPic->isSpatialEnhLayer(refLayerIdc))
1390          {
1391            //downsampling;
1392            downScalePic(pcPic->getPicYuvOrg(), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
1393            //pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg()->dump("ds.yuv", true, true);
1394            m_Enc3DAsymLUTPPS.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
1395            m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
1396          }
1397          else
1398          {
1399            m_Enc3DAsymLUTPPS.setDsOrigPic(pcPic->getPicYuvOrg());
1400            m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcPic->getPicYuvOrg());
1401          }
1402
1403          Bool bSignalPPS = m_bSeqFirst;
1404          bSignalPPS |= m_pcCfg->getGOPSize() > 1 ? pocCurr % m_pcCfg->getIntraPeriod() == 0 : pocCurr % m_pcCfg->getFrameRate() == 0;
1405          xDetermin3DAsymLUT( pcSlice , pcPic , refLayerIdc , m_pcCfg , bSignalPPS );
1406          m_Enc3DAsymLUTPPS.colorMapping( pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(),  m_pColorMappedPic );
1407          pBaseColRec = m_pColorMappedPic;
1408        }
1409#endif
1410#if SVC_EXTENSION
1411        if( pcPic->isSpatialEnhLayer(refLayerIdc) )
1412        {
1413          // check for the sample prediction picture type
1414          if( m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag(refLayerId) )
1415          {
1416#if P0312_VERT_PHASE_ADJ
1417            //when PhasePositionEnableFlag is equal to 1, set vertPhasePositionFlag to 0 if BL is top field and 1 if bottom
1418            if( scalEL.getVertPhasePositionEnableFlag() )
1419            {
1420              pcSlice->setVertPhasePositionFlag( pcSlice->getPOC()%2, refLayerIdc );
1421            }
1422#endif
1423#if O0215_PHASE_ALIGNMENT_REMOVAL
1424            m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec() );
1425#else
1426#if O0215_PHASE_ALIGNMENT
1427#if O0194_JOINT_US_BITSHIFT
1428#if Q0048_CGS_3D_ASYMLUT
1429            m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), pcSlice->getVPS()->getPhaseAlignFlag() );
1430#else
1431            m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), pcSlice->getVPS()->getPhaseAlignFlag() );
1432#endif
1433#else
1434#if Q0048_CGS_3D_ASYMLUT
1435            m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
1436#else
1437            m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
1438#endif
1439#endif
1440#else
1441#if O0194_JOINT_US_BITSHIFT
1442#if Q0048_CGS_3D_ASYMLUT
1443#if REF_REGION_OFFSET
1444          m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL, altRL );
1445#else
1446          m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL );
1447#endif
1448#else
1449          m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL );
1450#endif
1451#else
1452#if Q0048_CGS_3D_ASYMLUT
1453            m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL );
1454#else
1455            m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL );
1456#endif
1457#endif
1458#endif
1459#endif
1460          }
1461        }
1462        else
1463        {
1464#if Q0048_CGS_3D_ASYMLUT
1465          pcPic->setFullPelBaseRec( refLayerIdc, pBaseColRec );
1466#else
1467          pcPic->setFullPelBaseRec( refLayerIdc, pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec() );
1468#endif
1469        }
1470        pcSlice->setFullPelBaseRec ( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc) );
1471#endif //SVC_EXTENSION
1472      }
1473
1474      // Update the list of active inter-layer pictures
1475      for ( Int i = 0; i < activeNumILRRefIdxTmp; i++)
1476      {
1477        pcSlice->setInterLayerPredLayerIdc( interLayerPredLayerIdcTmp[i], i );
1478      }
1479
1480#if !O0225_TID_BASED_IL_RPS_DERIV || Q0060_MAX_TID_REF_EQUAL_TO_ZERO
1481      pcSlice->setActiveNumILRRefIdx( activeNumILRRefIdxTmp );
1482#endif
1483      if ( pcSlice->getActiveNumILRRefIdx() == 0 )
1484      {
1485        // No valid inter-layer pictures -> disable inter-layer prediction
1486        pcSlice->setInterLayerPredEnabledFlag(false);
1487      }
1488
1489      if( pocCurr % m_pcCfg->getIntraPeriod() == 0 )
1490      {
1491        if(pcSlice->getVPS()->getCrossLayerIrapAlignFlag())
1492        {
1493          TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId]->getRefLayerEnc(0)->getListPic();
1494          TComPic* picLayer0 = pcSlice->getRefPic(*cListPic, pcSlice->getPOC() );
1495          if(picLayer0)
1496          {
1497            pcSlice->setNalUnitType(picLayer0->getSlice(0)->getNalUnitType());
1498          }
1499          else
1500          {
1501            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_CRA);
1502          }
1503        }
1504        else
1505        {
1506#if !ALIGN_IRAP_BUGFIX
1507          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_CRA);
1508#endif
1509        }
1510      }
1511#if ISLICE_TYPE_NUMDIR
1512      if( pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA && (m_pcEncTop->getNumDirectRefLayers() == 0) )
1513#else
1514      if( pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA )
1515#endif
1516      {
1517        pcSlice->setSliceType(I_SLICE);
1518      }
1519      else if( !m_pcEncTop->getElRapSliceTypeB() )
1520      {
1521        if( (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP) &&
1522          (pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA) &&
1523          pcSlice->getSliceType() == B_SLICE )
1524        {
1525          pcSlice->setSliceType(P_SLICE);
1526        }
1527      }     
1528    }
1529#endif //#if SVC_EXTENSION
1530
1531    if(pcSlice->getTemporalLayerNonReferenceFlag())
1532    {
1533      if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_TRAIL_R &&
1534#if SVC_EXTENSION
1535        ( m_iGopSize != 1 || m_ppcTEncTop[m_layerId]->getIntraPeriod() > 1 ) )
1536#else
1537          !(m_iGopSize == 1 && pcSlice->getSliceType() == I_SLICE))
1538#endif
1539        // Add this condition to avoid POC issues with encoder_intra_main.cfg configuration (see #1127 in bug tracker)
1540      {
1541        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TRAIL_N);
1542      }
1543      if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RADL_R)
1544      {
1545        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RADL_N);
1546      }
1547      if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RASL_R)
1548      {
1549        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RASL_N);
1550      }
1551    }
1552
1553#if EFFICIENT_FIELD_IRAP
1554    if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1555      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1556      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
1557      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1558      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1559      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
1560    {
1561      m_associatedIRAPType = pcSlice->getNalUnitType();
1562#if POC_RESET_IDC_ENCODER
1563      m_associatedIRAPPOC = pcSlice->getPOC();
1564      m_associatedIrapPocBeforeReset = pocCurr;
1565#else
1566      m_associatedIRAPPOC = pocCurr;
1567#endif
1568    }
1569    pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
1570    pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
1571#if POC_RESET_IDC_ENCODER
1572    pcSlice->setAssociatedIrapPocBeforeReset(m_associatedIrapPocBeforeReset);
1573#endif
1574#endif
1575    // Do decoding refresh marking if any
1576#if NO_CLRAS_OUTPUT_FLAG
1577    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcEncTop->getNoClrasOutputFlag());
1578#else
1579    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic);
1580#endif
1581#if POC_RESET_IDC_ENCODER
1582    // m_pocCRA may have been update here; update m_pocCraWithoutReset
1583    m_pocCraWithoutReset = m_pocCRA + m_pcEncTop->getPocAdjustmentValue();
1584#endif
1585    m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid);
1586    pcSlice->getRPS()->setNumberOfLongtermPictures(0);
1587#if !EFFICIENT_FIELD_IRAP
1588    if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1589      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1590      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
1591      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1592      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1593      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
1594    {
1595      m_associatedIRAPType = pcSlice->getNalUnitType();
1596      m_associatedIRAPPOC = pocCurr;
1597    }
1598    pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
1599    pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
1600#endif
1601
1602#if ALLOW_RECOVERY_POINT_AS_RAP
1603    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP()) 
1604#if EFFICIENT_FIELD_IRAP
1605      || (isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1)
1606#endif
1607      )
1608    {
1609      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3);
1610    }
1611#else
1612    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false) != 0) || (pcSlice->isIRAP()))
1613    {
1614      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP());
1615    }
1616#endif
1617#if ALIGNED_BUMPING
1618#if POC_RESET_IDC_ENCODER
1619    pcSlice->checkLeadingPictureRestrictions(rcListPic, true);
1620#else
1621    pcSlice->checkLeadingPictureRestrictions(rcListPic);
1622#endif
1623#endif
1624    pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS());
1625
1626    if(pcSlice->getTLayer() > 0 
1627      &&  !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N     // Check if not a leading picture
1628          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R
1629          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N
1630          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R )
1631        )
1632    {
1633      if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic) || pcSlice->getSPS()->getTemporalIdNestingFlag())
1634      {
1635#if SVC_EXTENSION && !Q0108_TSA_STSA
1636        if( pcSlice->getLayerId() > 0 )
1637        {
1638          Bool oneRefLayerTSA = false, oneRefLayerNotTSA = false;
1639          for( Int i = 0; i < pcSlice->getLayerId(); i++)
1640          {
1641            TComList<TComPic *> *cListPic = m_ppcTEncTop[i]->getListPic();
1642            TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC());
1643            if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerId(), i) )
1644            {
1645              if( ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_TSA_N ) ||
1646                  ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_TSA_R ) 
1647                )
1648              {
1649                if(pcSlice->getTemporalLayerNonReferenceFlag() )
1650                {
1651                  pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
1652                }
1653                else
1654                {
1655                  pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R );
1656                }
1657                oneRefLayerTSA = true;
1658              }
1659              else
1660              {
1661                oneRefLayerNotTSA = true;
1662              }
1663            }
1664          }
1665          assert( !( oneRefLayerNotTSA && oneRefLayerTSA ) ); // Only one variable should be true - failure of this assert means
1666                                                                // that two independent reference layers that are not dependent on
1667                                                                // each other, but are reference for current layer have inconsistency
1668          if( oneRefLayerNotTSA /*&& !oneRefLayerTSA*/ )          // No reference layer is TSA - set current as TRAIL
1669          {
1670            if(pcSlice->getTemporalLayerNonReferenceFlag() )
1671            {
1672              pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_N );
1673            }
1674            else
1675            {
1676              pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_R );
1677            }
1678          }
1679          else  // This means there is no reference layer picture for current picture in this AU
1680          {
1681            if(pcSlice->getTemporalLayerNonReferenceFlag() )
1682            {
1683              pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
1684            }
1685            else
1686            {
1687              pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R );
1688            }
1689          }
1690        }
1691#else
1692        if(pcSlice->getTemporalLayerNonReferenceFlag())
1693        {
1694          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
1695        }
1696        else
1697        {
1698          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R);
1699        }
1700#endif
1701      }
1702      else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
1703      {
1704        Bool isSTSA=true;
1705        for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
1706        {
1707          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
1708          if(lTid==pcSlice->getTLayer())
1709          {
1710            TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
1711            for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++)
1712            {
1713              if(nRPS->getUsed(jj))
1714              {
1715                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
1716                Int kk=0;
1717                for(kk=0;kk<m_pcCfg->getGOPSize();kk++)
1718                {
1719                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
1720                    break;
1721                }
1722                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
1723                if(tTid >= pcSlice->getTLayer())
1724                {
1725                  isSTSA=false;
1726                  break;
1727                }
1728              }
1729            }
1730          }
1731        }
1732        if(isSTSA==true)
1733        {
1734#if SVC_EXTENSION && !Q0108_TSA_STSA
1735          if( pcSlice->getLayerId() > 0 )
1736          {
1737            Bool oneRefLayerSTSA = false, oneRefLayerNotSTSA = false;
1738            for( Int i = 0; i < pcSlice->getLayerId(); i++)
1739            {
1740              TComList<TComPic *> *cListPic = m_ppcTEncTop[i]->getListPic();
1741              TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC());
1742              if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerId(), i) )
1743              {
1744                if( ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_STSA_N ) ||
1745                    ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_STSA_R ) 
1746                  )
1747                {
1748                  if(pcSlice->getTemporalLayerNonReferenceFlag() )
1749                  {
1750                    pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
1751                  }
1752                  else
1753                  {
1754                    pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R );
1755                  }
1756                  oneRefLayerSTSA = true;
1757                }
1758                else
1759                {
1760                  oneRefLayerNotSTSA = true;
1761                }
1762              }
1763            }
1764            assert( !( oneRefLayerNotSTSA && oneRefLayerSTSA ) ); // Only one variable should be true - failure of this assert means
1765                                                                  // that two independent reference layers that are not dependent on
1766                                                                  // each other, but are reference for current layer have inconsistency
1767            if( oneRefLayerNotSTSA /*&& !oneRefLayerSTSA*/ )          // No reference layer is STSA - set current as TRAIL
1768            {
1769              if(pcSlice->getTemporalLayerNonReferenceFlag() )
1770              {
1771                pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_N );
1772              }
1773              else
1774              {
1775                pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_R );
1776              }
1777            }
1778            else  // This means there is no reference layer picture for current picture in this AU
1779            {
1780              if(pcSlice->getTemporalLayerNonReferenceFlag() )
1781              {
1782                pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
1783              }
1784              else
1785              {
1786                pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R );
1787              }
1788            }
1789          }
1790#else
1791          if(pcSlice->getTemporalLayerNonReferenceFlag())
1792          {
1793            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
1794          }
1795          else
1796          {
1797            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
1798          }
1799#endif
1800        }
1801      }
1802    }
1803    arrangeLongtermPicturesInRPS(pcSlice, rcListPic);
1804    TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
1805    refPicListModification->setRefPicListModificationFlagL0(0);
1806    refPicListModification->setRefPicListModificationFlagL1(0);
1807    pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
1808    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
1809
1810#if SVC_EXTENSION
1811    if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() )
1812    {
1813#if POC_RESET_FLAG || POC_RESET_IDC_ENCODER
1814      if ( pocCurr > 0 && pcSlice->isRADL() && pcPic->getSlice(0)->getBaseColPic(pcPic->getSlice(0)->getInterLayerPredLayerIdc(0))->getSlice(0)->isRASL())
1815#else
1816      if (pcSlice->getPOC()>0  && pcSlice->isRADL() && pcPic->getSlice(0)->getBaseColPic(pcPic->getSlice(0)->getInterLayerPredLayerIdc(0))->getSlice(0)->isRASL())
1817#endif
1818      {
1819        pcSlice->setActiveNumILRRefIdx(0);
1820        pcSlice->setInterLayerPredEnabledFlag(0);
1821      }
1822      if( pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA )
1823      {
1824        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getActiveNumILRRefIdx());
1825        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getActiveNumILRRefIdx());
1826      }
1827      else
1828      {
1829        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getNumRefIdx(REF_PIC_LIST_0)+pcSlice->getActiveNumILRRefIdx());
1830        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getNumRefIdx(REF_PIC_LIST_1)+pcSlice->getActiveNumILRRefIdx());
1831      }
1832
1833      // check for the reference pictures whether there is at least one either temporal picture or ILRP with sample prediction type
1834      if( pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) - pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) - pcSlice->getActiveNumILRRefIdx() == 0 )
1835      {
1836        Bool foundSamplePredPicture = false;               
1837
1838        for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
1839        {
1840          if( m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag( pcSlice->getVPS()->getRefLayerId( m_layerId, pcSlice->getInterLayerPredLayerIdc(i) ) ) )
1841          {
1842            foundSamplePredPicture = true;
1843            break;
1844          }
1845        }
1846
1847        if( !foundSamplePredPicture )
1848        {
1849          pcSlice->setSliceType(I_SLICE);
1850          pcSlice->setInterLayerPredEnabledFlag(0);
1851          pcSlice->setActiveNumILRRefIdx(0);
1852        }
1853      }
1854    }
1855#endif //SVC_EXTENSION
1856
1857#if Q0108_TSA_STSA
1858   if( ( pcSlice->getTLayer() == 0 && pcSlice->getLayerId() > 0  )    // only for enhancement layer and with temporal layer 0
1859     && !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N     
1860          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R
1861          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N
1862          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R
1863          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1864          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1865          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA
1866          )
1867        )
1868    {
1869        Bool isSTSA=true;
1870        Bool isIntra=false;
1871
1872        for( Int i = 0; i < pcSlice->getLayerId(); i++)
1873        {
1874          TComList<TComPic *> *cListPic = m_ppcTEncTop[i]->getListPic();
1875          TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC());
1876          if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerId(), i) )
1877          {
1878            if( lowerLayerPic->getSlice(0)->getSliceType() == I_SLICE)
1879            { 
1880              isIntra = true;
1881            }
1882          }
1883        }
1884
1885        for(Int ii=iGOPid+1; ii < m_pcCfg->getGOPSize() && isSTSA; ii++)
1886        {
1887          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
1888          if(lTid==pcSlice->getTLayer()) 
1889          {
1890            TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
1891            for(Int jj=0; jj<nRPS->getNumberOfPictures(); jj++)
1892            {
1893              if(nRPS->getUsed(jj)) 
1894              {
1895                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
1896                Int kk=0;
1897                for(kk=0; kk<m_pcCfg->getGOPSize(); kk++)
1898                {
1899                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
1900                  {
1901                    break;
1902                  }
1903                }
1904                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
1905                if(tTid >= pcSlice->getTLayer())
1906                {
1907                  isSTSA = false;
1908                  break;
1909                }
1910              }
1911            }
1912          }
1913        }
1914        if(isSTSA==true && isIntra == false)
1915        {   
1916          if(pcSlice->getTemporalLayerNonReferenceFlag())
1917          {
1918            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
1919          }
1920          else
1921          {
1922            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
1923          }
1924        }
1925    }
1926#endif
1927
1928#if ADAPTIVE_QP_SELECTION
1929    pcSlice->setTrQuant( m_pcEncTop->getTrQuant() );
1930#endif     
1931
1932#if SVC_EXTENSION
1933    if( pcSlice->getSliceType() == B_SLICE )
1934    {
1935      pcSlice->setColFromL0Flag(1-uiColDir);
1936    }
1937
1938    //  Set reference list
1939    if(m_layerId ==  0 || ( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() == 0 ) )
1940    {
1941      pcSlice->setRefPicList( rcListPic );
1942    }
1943
1944    if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() )
1945    {
1946      pcSlice->setILRPic( m_pcEncTop->getIlpList() );
1947#if !REF_IDX_MFM
1948      //  Set reference list
1949      pcSlice->setRefPicList ( rcListPic );
1950#endif
1951      pcSlice->setRefPicListModificationSvc();
1952      pcSlice->setRefPicList( rcListPic, false, m_pcEncTop->getIlpList());
1953
1954#if REF_IDX_MFM
1955      if( pcSlice->getMFMEnabledFlag() )
1956      {
1957        Bool found         = false;
1958        UInt ColFromL0Flag = pcSlice->getColFromL0Flag();
1959        UInt ColRefIdx     = pcSlice->getColRefIdx();
1960
1961        for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
1962        {
1963          RefPicList refList = RefPicList(1 - ColFromL0Flag);
1964          TComPic* refPic = pcSlice->getRefPic(refList, colIdx);
1965
1966          // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
1967          // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
1968          if( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getMotionPredEnabledFlag( refPic->getLayerId() )
1969#if MFM_ENCCONSTRAINT
1970            && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerId()]->getListPic() )->checkSameRefInfo() == true 
1971#endif
1972            ) 
1973          { 
1974            ColRefIdx = colIdx; 
1975            found = true;
1976            break; 
1977          }
1978        }
1979
1980        if( found == false )
1981        {
1982          ColFromL0Flag = 1 - ColFromL0Flag;
1983          for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
1984          {
1985            RefPicList refList = RefPicList(1 - ColFromL0Flag);
1986            TComPic* refPic = pcSlice->getRefPic(refList, colIdx);
1987
1988            // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
1989            // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
1990            if( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getMotionPredEnabledFlag( refPic->getLayerId() )
1991#if MFM_ENCCONSTRAINT
1992              && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerId()]->getListPic() )->checkSameRefInfo() == true 
1993#endif
1994              ) 
1995            { 
1996              ColRefIdx = colIdx; 
1997              found = true; 
1998              break; 
1999            } 
2000          }
2001        }
2002
2003        if(found == true)
2004        {
2005          pcSlice->setColFromL0Flag(ColFromL0Flag);
2006          pcSlice->setColRefIdx(ColRefIdx);
2007        }
2008      }
2009#endif
2010    }
2011#else //SVC_EXTENSION
2012    //  Set reference list
2013    pcSlice->setRefPicList ( rcListPic );
2014#endif //#if SVC_EXTENSION
2015
2016    //  Slice info. refinement
2017    if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
2018    {
2019      pcSlice->setSliceType ( P_SLICE );
2020    }
2021
2022    if (pcSlice->getSliceType() == B_SLICE)
2023    {
2024#if !SVC_EXTENSION
2025      pcSlice->setColFromL0Flag(1-uiColDir);
2026#endif
2027      Bool bLowDelay = true;
2028      Int  iCurrPOC  = pcSlice->getPOC();
2029      Int iRefIdx = 0;
2030
2031      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
2032      {
2033        if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
2034        {
2035          bLowDelay = false;
2036        }
2037      }
2038      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
2039      {
2040        if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
2041        {
2042          bLowDelay = false;
2043        }
2044      }
2045
2046      pcSlice->setCheckLDC(bLowDelay);
2047    }
2048    else
2049    {
2050      pcSlice->setCheckLDC(true);
2051    }
2052
2053    uiColDir = 1-uiColDir;
2054
2055    //-------------------------------------------------------------
2056    pcSlice->setRefPOCList();
2057
2058    pcSlice->setList1IdxToList0Idx();
2059
2060    if (m_pcEncTop->getTMVPModeId() == 2)
2061    {
2062      if (iGOPid == 0) // first picture in SOP (i.e. forward B)
2063      {
2064        pcSlice->setEnableTMVPFlag(0);
2065      }
2066      else
2067      {
2068        // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
2069        pcSlice->setEnableTMVPFlag(1);
2070      }
2071      pcSlice->getSPS()->setTMVPFlagsPresent(1);
2072    }
2073    else if (m_pcEncTop->getTMVPModeId() == 1)
2074    {
2075      pcSlice->getSPS()->setTMVPFlagsPresent(1);
2076#if SVC_EXTENSION
2077      if( pcSlice->getIdrPicFlag() )
2078      {
2079        pcSlice->setEnableTMVPFlag(0);
2080      }
2081      else
2082#endif
2083      pcSlice->setEnableTMVPFlag(1);
2084    }
2085    else
2086    {
2087      pcSlice->getSPS()->setTMVPFlagsPresent(0);
2088      pcSlice->setEnableTMVPFlag(0);
2089    }
2090
2091#if SVC_EXTENSION
2092    if( m_layerId > 0 && !pcSlice->isIntra() )
2093    {
2094      Int colFromL0Flag = 1;
2095      Int colRefIdx = 0;
2096
2097      // check whether collocated picture is valid
2098      if( pcSlice->getEnableTMVPFlag() )
2099      {
2100        colFromL0Flag = pcSlice->getColFromL0Flag();
2101        colRefIdx = pcSlice->getColRefIdx();
2102
2103        TComPic* refPic = pcSlice->getRefPic(RefPicList(1-colFromL0Flag), colRefIdx);
2104
2105        assert( refPic );
2106
2107        // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
2108        // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
2109        if( refPic->isILR(m_layerId) && !m_ppcTEncTop[m_layerId]->getMotionPredEnabledFlag(refPic->getLayerId()) )
2110        {
2111          pcSlice->setEnableTMVPFlag(false);
2112          pcSlice->setMFMEnabledFlag(false);
2113          colRefIdx = 0;
2114        }
2115      }
2116
2117      // remove motion only ILRP from the end of the colFromL0Flag reference picture list
2118      RefPicList refList = RefPicList(colFromL0Flag);
2119      Int numRefIdx = pcSlice->getNumRefIdx(refList);
2120
2121      if( numRefIdx > 0 )
2122      {
2123        for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > 0; refIdx-- )
2124        {
2125          TComPic* refPic = pcSlice->getRefPic(refList, refIdx);
2126
2127          if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag( refPic->getLayerId() ) ) )
2128          {
2129            break;
2130          }
2131          else
2132          {
2133            assert( numRefIdx > 1 );
2134            numRefIdx--;             
2135          }
2136        }
2137
2138        pcSlice->setNumRefIdx( refList, numRefIdx );
2139      }
2140
2141      // remove motion only ILRP from the end of the (1-colFromL0Flag) reference picture list up to colRefIdx
2142      refList = RefPicList(1 - colFromL0Flag);
2143      numRefIdx = pcSlice->getNumRefIdx(refList);
2144
2145      if( numRefIdx > 0 )
2146      {
2147        for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > colRefIdx; refIdx-- )
2148        {
2149          TComPic* refPic = pcSlice->getRefPic(refList, refIdx);
2150
2151          if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag( refPic->getLayerId() ) ) )
2152          {
2153            break;
2154          }
2155          else
2156          {
2157            assert( numRefIdx > 1 );
2158            numRefIdx--;             
2159          }
2160        }
2161
2162        pcSlice->setNumRefIdx( refList, numRefIdx );
2163      }
2164
2165      assert( pcSlice->getNumRefIdx(REF_PIC_LIST_0) > 0 && ( pcSlice->isInterP() || (pcSlice->isInterB() && pcSlice->getNumRefIdx(REF_PIC_LIST_1) > 0) ) );
2166    }
2167#endif
2168
2169    /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
2170    //  Slice compression
2171    if (m_pcCfg->getUseASR())
2172    {
2173      m_pcSliceEncoder->setSearchRange(pcSlice);
2174    }
2175
2176    Bool bGPBcheck=false;
2177    if ( pcSlice->getSliceType() == B_SLICE)
2178    {
2179      if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
2180      {
2181        bGPBcheck=true;
2182        Int i;
2183        for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
2184        {
2185          if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) )
2186          {
2187            bGPBcheck=false;
2188            break;
2189          }
2190        }
2191      }
2192    }
2193    if(bGPBcheck)
2194    {
2195      pcSlice->setMvdL1ZeroFlag(true);
2196    }
2197    else
2198    {
2199      pcSlice->setMvdL1ZeroFlag(false);
2200    }
2201    pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
2202
2203    pcPic->getPicSym()->initTiles(pcSlice->getPPS());
2204    pcPic->getPicSym()->initCtuTsRsAddrMaps();
2205
2206    Double lambda            = 0.0;
2207    Int actualHeadBits       = 0;
2208    Int actualTotalBits      = 0;
2209    Int estimatedBits        = 0;
2210    Int tmpBitsBeforeWriting = 0;
2211    if ( m_pcCfg->getUseRateCtrl() )
2212    {
2213      Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
2214      if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )
2215      {
2216        frameLevel = 0;
2217      }
2218      m_pcRateCtrl->initRCPic( frameLevel );
2219      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
2220
2221      Int sliceQP = m_pcCfg->getInitialQP();
2222#if POC_RESET_FLAG || POC_RESET_IDC_ENCODER
2223      if ( ( pocCurr == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
2224#else
2225      if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
2226#endif
2227      {
2228        Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
2229        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
2230        Double dQPFactor     = 0.57*dLambda_scale;
2231        Int    SHIFT_QP      = 12;
2232        Int    bitdepth_luma_qp_scale = 0;
2233        Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP;
2234        lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
2235      }
2236      else if ( frameLevel == 0 )   // intra case, but use the model
2237      {
2238        m_pcSliceEncoder->calCostSliceI(pcPic);
2239
2240        if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case
2241        {
2242          Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
2243          bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );
2244          if ( bits < 200 )
2245          {
2246            bits = 200;
2247          }
2248          m_pcRateCtrl->getRCPic()->setTargetBits( bits );
2249        }
2250
2251        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
2252        m_pcRateCtrl->getRCPic()->getLCUInitTargetBits();
2253        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
2254        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
2255      }
2256      else    // normal case
2257      {
2258        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
2259        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
2260        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
2261      }
2262
2263#if REPN_FORMAT_IN_VPS
2264      sliceQP = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, sliceQP );
2265#else
2266      sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, sliceQP );
2267#endif
2268      m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );
2269
2270      m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );
2271    }
2272
2273    UInt uiNumSliceSegments = 1;
2274
2275#if AVC_BASE
2276#if VPS_AVC_BL_FLAG_REMOVAL
2277    if( m_layerId == 0 && m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() )
2278#else
2279    if( m_layerId == 0 && m_pcEncTop->getVPS()->getAvcBaseLayerFlag() )
2280#endif
2281    {
2282      pcPic->getPicYuvOrg()->copyToPic( pcPic->getPicYuvRec() );
2283#if O0194_WEIGHTED_PREDICTION_CGS
2284      // Calculate for the base layer to be used in EL as Inter layer reference
2285      if( m_pcEncTop->getInterLayerWeightedPredFlag() )
2286      {
2287        m_pcSliceEncoder->estimateILWpParam( pcSlice );
2288      }
2289#endif
2290      return;
2291    }
2292#endif
2293
2294    // Allocate some coders, now the number of tiles are known.
2295    const Int numSubstreams = pcSlice->getPPS()->getNumSubstreams();
2296    std::vector<TComOutputBitstream> substreamsOut(numSubstreams);
2297
2298    // now compress (trial encode) the various slice segments (slices, and dependent slices)
2299    {
2300      const UInt numberOfCtusInFrame=pcPic->getPicSym()->getNumberOfCtusInFrame();
2301      pcSlice->setSliceCurStartCtuTsAddr( 0 );
2302      pcSlice->setSliceSegmentCurStartCtuTsAddr( 0 );
2303
2304      for(UInt nextCtuTsAddr = 0; nextCtuTsAddr < numberOfCtusInFrame; )
2305      {
2306        m_pcSliceEncoder->precompressSlice( pcPic );
2307        m_pcSliceEncoder->compressSlice   ( pcPic );
2308
2309        const UInt curSliceSegmentEnd = pcSlice->getSliceSegmentCurEndCtuTsAddr();
2310        if (curSliceSegmentEnd < numberOfCtusInFrame)
2311        {
2312          const Bool bNextSegmentIsDependentSlice=curSliceSegmentEnd<pcSlice->getSliceCurEndCtuTsAddr();
2313          const UInt sliceBits=pcSlice->getSliceBits();
2314          pcPic->allocateNewSlice();
2315          // prepare for next slice
2316          pcPic->setCurrSliceIdx                    ( uiNumSliceSegments );
2317          m_pcSliceEncoder->setSliceIdx             ( uiNumSliceSegments   );
2318          pcSlice = pcPic->getSlice                 ( uiNumSliceSegments   );
2319          pcSlice->copySliceInfo                    ( pcPic->getSlice(uiNumSliceSegments-1)  );
2320          pcSlice->setSliceIdx                      ( uiNumSliceSegments   );
2321          if (bNextSegmentIsDependentSlice)
2322          {
2323            pcSlice->setSliceBits(sliceBits);
2324          }
2325          else
2326          {
2327            pcSlice->setSliceCurStartCtuTsAddr      ( curSliceSegmentEnd );
2328            pcSlice->setSliceBits(0);
2329          }
2330          pcSlice->setDependentSliceSegmentFlag(bNextSegmentIsDependentSlice);
2331          pcSlice->setSliceSegmentCurStartCtuTsAddr ( curSliceSegmentEnd );
2332          uiNumSliceSegments ++;
2333        }
2334        nextCtuTsAddr = curSliceSegmentEnd;
2335      }
2336    }
2337
2338#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
2339    if (m_pcCfg->getInterLayerConstrainedTileSetsSEIEnabled())
2340    {
2341      xBuildTileSetsMap(pcPic->getPicSym());
2342    }
2343#endif
2344
2345    pcSlice = pcPic->getSlice(0);
2346
2347    // SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
2348    if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoCtuBoundary() )
2349    {
2350      m_pcSAO->getPreDBFStatistics(pcPic);
2351    }
2352
2353    //-- Loop filter
2354    Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
2355    m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
2356    if ( m_pcCfg->getDeblockingFilterMetric() )
2357    {
2358      dblMetric(pcPic, uiNumSliceSegments);
2359    }
2360    m_pcLoopFilter->loopFilterPic( pcPic );
2361
2362    /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
2363    // Set entropy coder
2364    m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
2365
2366    /* write various header sets. */
2367    if ( m_bSeqFirst )
2368    {
2369#if SVC_EXTENSION
2370      OutputNALUnit nalu( NAL_UNIT_VPS, 0, 0 ); // The value of nuh_layer_id of VPS NAL unit shall be equal to 0.
2371#if AVC_BASE
2372#if VPS_AVC_BL_FLAG_REMOVAL
2373      if( ( m_layerId > 0 && m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() ) || ( m_layerId == 0 && !m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() ) )
2374#else
2375      if( ( m_layerId > 0 && m_pcEncTop->getVPS()->getAvcBaseLayerFlag() ) || ( m_layerId == 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() ) )
2376#endif
2377#else
2378      if( m_layerId == 0 )
2379#endif
2380      {
2381#else
2382      OutputNALUnit nalu(NAL_UNIT_VPS);
2383#endif
2384#if VPS_VUI_OFFSET
2385      // The following code also calculates the VPS VUI offset
2386#endif
2387#if !P0125_REVERT_VPS_EXTN_OFFSET_TO_RESERVED
2388#if VPS_EXTN_OFFSET_CALC
2389      OutputNALUnit tempNalu(NAL_UNIT_VPS, 0, 0        ); // The value of nuh_layer_id of VPS NAL unit shall be equal to 0.
2390      m_pcEntropyCoder->setBitstream(&tempNalu.m_Bitstream);
2391      m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());  // Use to calculate the VPS extension offset
2392#endif
2393#endif
2394      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2395      m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());
2396      writeRBSPTrailingBits(nalu.m_Bitstream);
2397      accessUnit.push_back(new NALUnitEBSP(nalu));
2398      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2399#if SVC_EXTENSION
2400      }
2401#endif
2402
2403#if SVC_EXTENSION
2404      nalu = NALUnit(NAL_UNIT_SPS, 0, m_layerId);
2405#else
2406      nalu = NALUnit(NAL_UNIT_SPS);
2407#endif
2408#if Q0078_ADD_LAYER_SETS
2409      if (m_pcEncTop->getVPS()->getNumDirectRefLayers(m_layerId) == 0 && m_pcEncTop->getVPS()->getNumAddLayerSets() > 0)
2410      {
2411        nalu.m_layerId = 0; // For independent base layer rewriting
2412      }
2413#endif
2414      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2415      if (m_bSeqFirst)
2416      {
2417        pcSlice->getSPS()->setNumLongTermRefPicSPS(m_numLongTermRefPicSPS);
2418        assert (m_numLongTermRefPicSPS <= MAX_NUM_LONG_TERM_REF_PICS);
2419        for (Int k = 0; k < m_numLongTermRefPicSPS; k++)
2420        {
2421          pcSlice->getSPS()->setLtRefPicPocLsbSps(k, m_ltRefPicPocLsbSps[k]);
2422          pcSlice->getSPS()->setUsedByCurrPicLtSPSFlag(k, m_ltRefPicUsedByCurrPicFlag[k]);
2423        }
2424      }
2425      if( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
2426      {
2427        UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1);
2428        UInt numDU = ( m_pcCfg->getSliceMode() == FIXED_NUMBER_OF_CTU ) ? ( pcPic->getNumberOfCtusInFrame() / maxCU ) : ( 0 );
2429        if( pcPic->getNumberOfCtusInFrame() % maxCU != 0 || numDU == 0 )
2430        {
2431          numDU ++;
2432        }
2433        pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->setNumDU( numDU );
2434        pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) );
2435      }
2436      if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
2437      {
2438        pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true );
2439      }
2440#if O0092_0094_DEPENDENCY_CONSTRAINT
2441      assert( pcSlice->getSPS()->getLayerId() == 0 || pcSlice->getSPS()->getLayerId() == m_layerId || m_pcEncTop->getVPS()->getRecursiveRefLayerFlag(m_layerId, pcSlice->getSPS()->getLayerId()) );
2442#endif
2443      m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
2444      writeRBSPTrailingBits(nalu.m_Bitstream);
2445      accessUnit.push_back(new NALUnitEBSP(nalu));
2446      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2447
2448#if SVC_EXTENSION
2449      nalu = NALUnit(NAL_UNIT_PPS, 0, m_layerId);
2450#else
2451      nalu = NALUnit(NAL_UNIT_PPS);
2452#endif
2453#if Q0078_ADD_LAYER_SETS
2454      if (m_pcEncTop->getVPS()->getNumDirectRefLayers(m_layerId) == 0 && m_pcEncTop->getVPS()->getNumAddLayerSets() > 0)
2455      {
2456        nalu.m_layerId = 0; // For independent base layer rewriting
2457      }
2458#endif
2459      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2460#if O0092_0094_DEPENDENCY_CONSTRAINT
2461      assert( pcSlice->getPPS()->getLayerId() == 0 || pcSlice->getPPS()->getLayerId() == m_layerId || m_pcEncTop->getVPS()->getRecursiveRefLayerFlag(m_layerId, pcSlice->getPPS()->getLayerId()) );
2462#endif
2463#if Q0048_CGS_3D_ASYMLUT
2464      m_pcEntropyCoder->encodePPS(pcSlice->getPPS(), &m_Enc3DAsymLUTPPS);
2465#else
2466      m_pcEntropyCoder->encodePPS(pcSlice->getPPS());
2467#endif
2468      writeRBSPTrailingBits(nalu.m_Bitstream);
2469      accessUnit.push_back(new NALUnitEBSP(nalu));
2470      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2471
2472      xCreateLeadingSEIMessages(accessUnit, pcSlice->getSPS());
2473
2474#if O0164_MULTI_LAYER_HRD
2475      if (pcSlice->getLayerId() == 0 && m_pcEncTop->getVPS()->getVpsVuiBspHrdPresentFlag())
2476      {
2477        Int j;
2478#if VPS_VUI_BSP_HRD_PARAMS
2479        TComVPS *vps = m_pcEncTop->getVPS();
2480        for(Int i = 0; i < vps->getNumOutputLayerSets(); i++)
2481        {
2482          for(Int k = 0; k < vps->getNumSignalledPartitioningSchemes(i); k++)
2483          {
2484            for(Int l = 0; l < vps->getNumPartitionsInSchemeMinus1(i, k)+1; l++)
2485            {
2486#endif
2487              nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, 1);
2488              m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2489              m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2490#if VPS_VUI_BSP_HRD_PARAMS
2491              SEIScalableNesting *scalableBspNestingSei = xCreateBspNestingSEI(pcSlice, i, k, l);
2492#else
2493              SEIScalableNesting *scalableBspNestingSei = xCreateBspNestingSEI(pcSlice);
2494#endif
2495              m_seiWriter.writeSEImessage(nalu.m_Bitstream, *scalableBspNestingSei, m_pcEncTop->getVPS(), pcSlice->getSPS());
2496              writeRBSPTrailingBits(nalu.m_Bitstream);
2497
2498              UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2499              UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2500                + m_bufferingPeriodSEIPresentInAU
2501                + m_pictureTimingSEIPresentInAU
2502                + m_nestedPictureTimingSEIPresentInAU;  // Insert SEI after APS, BP and PT SEI
2503              AccessUnit::iterator it;
2504              for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2505              {
2506                it++;
2507              }
2508              accessUnit.insert(it, new NALUnitEBSP(nalu));
2509#if VPS_VUI_BSP_HRD_PARAMS
2510            }
2511          }
2512        }
2513#endif
2514      }
2515#endif
2516
2517      m_bSeqFirst = false;
2518    }
2519#if Q0048_CGS_3D_ASYMLUT
2520    else if( m_pcCfg->getCGSFlag() && pcSlice->getLayerId() && pcSlice->getCGSOverWritePPS() )
2521    {
2522      OutputNALUnit nalu(NAL_UNIT_PPS, 0, m_layerId);
2523      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2524      m_pcEntropyCoder->encodePPS(pcSlice->getPPS() , &m_Enc3DAsymLUTPPS );
2525      writeRBSPTrailingBits(nalu.m_Bitstream);
2526      accessUnit.push_back(new NALUnitEBSP(nalu));
2527    }
2528#endif
2529
2530    if (writeSOP) // write SOP description SEI (if enabled) at the beginning of GOP
2531    {
2532      Int SOPcurrPOC = pocCurr;
2533
2534      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2535      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2536      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2537
2538      SEISOPDescription SOPDescriptionSEI;
2539      SOPDescriptionSEI.m_sopSeqParameterSetId = pcSlice->getSPS()->getSPSId();
2540
2541      UInt i = 0;
2542      UInt prevEntryId = iGOPid;
2543      for (Int j = iGOPid; j < m_iGopSize; j++)
2544      {
2545        Int deltaPOC = m_pcCfg->getGOPEntry(j).m_POC - m_pcCfg->getGOPEntry(prevEntryId).m_POC;
2546        if ((SOPcurrPOC + deltaPOC) < m_pcCfg->getFramesToBeEncoded())
2547        {
2548          SOPcurrPOC += deltaPOC;
2549          SOPDescriptionSEI.m_sopDescVclNaluType[i] = getNalUnitType(SOPcurrPOC, m_iLastIDR, isField);
2550          SOPDescriptionSEI.m_sopDescTemporalId[i] = m_pcCfg->getGOPEntry(j).m_temporalId;
2551          SOPDescriptionSEI.m_sopDescStRpsIdx[i] = m_pcEncTop->getReferencePictureSetIdxForSOP(pcSlice, SOPcurrPOC, j);
2552          SOPDescriptionSEI.m_sopDescPocDelta[i] = deltaPOC;
2553
2554          prevEntryId = j;
2555          i++;
2556        }
2557      }
2558
2559      SOPDescriptionSEI.m_numPicsInSopMinus1 = i - 1;
2560
2561#if O0164_MULTI_LAYER_HRD
2562      m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
2563#else
2564      m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, pcSlice->getSPS());
2565#endif
2566      writeRBSPTrailingBits(nalu.m_Bitstream);
2567      accessUnit.push_back(new NALUnitEBSP(nalu));
2568
2569      writeSOP = false;
2570    }
2571#if Q0189_TMVP_CONSTRAINTS
2572   if( m_pcEncTop->getTMVPConstraintsSEIEnabled() == 1 &&
2573      (m_pcEncTop->getTMVPModeId() == 1 || m_pcEncTop->getTMVPModeId() == 2) &&
2574      pcSlice->getLayerId() >0 && 
2575      (pcSlice->getNalUnitType() ==  NAL_UNIT_CODED_SLICE_IDR_W_RADL || pcSlice->getNalUnitType() ==  NAL_UNIT_CODED_SLICE_IDR_N_LP))
2576   {
2577      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2578      SEITMVPConstrains seiTMVPConstrains;
2579      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2580      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2581      seiTMVPConstrains.no_intra_layer_col_pic_flag = 1;
2582      seiTMVPConstrains.prev_pics_not_used_flag = 1;
2583#if O0164_MULTI_LAYER_HRD
2584      m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiTMVPConstrains, m_pcEncTop->getVPS(), pcSlice->getSPS() );
2585#else
2586      m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiTMVPConstrains, pcSlice->getSPS() );
2587#endif
2588      writeRBSPTrailingBits(nalu.m_Bitstream);
2589      accessUnit.push_back(new NALUnitEBSP(nalu));
2590   }
2591#endif
2592#if Q0247_FRAME_FIELD_INFO
2593    if(  pcSlice->getLayerId()> 0 &&
2594     ( (m_pcCfg->getProgressiveSourceFlag() && m_pcCfg->getInterlacedSourceFlag()) || m_pcCfg->getFrameFieldInfoPresentFlag()))
2595    {
2596      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2597      SEIFrameFieldInfo seiFFInfo;
2598      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2599      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2600      seiFFInfo.m_ffinfo_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0;
2601#if O0164_MULTI_LAYER_HRD
2602      m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiFFInfo, m_pcEncTop->getVPS(), pcSlice->getSPS() );
2603#else
2604      m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiFFInfo, pcSlice->getSPS() );
2605#endif
2606      writeRBSPTrailingBits(nalu.m_Bitstream);
2607      accessUnit.push_back(new NALUnitEBSP(nalu));
2608    }
2609#endif
2610
2611    if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2612        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2613        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
2614       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
2615    {
2616      if( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() )
2617      {
2618        UInt numDU = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumDU();
2619        pictureTimingSEI.m_numDecodingUnitsMinus1     = ( numDU - 1 );
2620        pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = false;
2621
2622        if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL )
2623        {
2624          pictureTimingSEI.m_numNalusInDuMinus1       = new UInt[ numDU ];
2625        }
2626        if( pictureTimingSEI.m_duCpbRemovalDelayMinus1  == NULL )
2627        {
2628          pictureTimingSEI.m_duCpbRemovalDelayMinus1  = new UInt[ numDU ];
2629        }
2630        if( accumBitsDU == NULL )
2631        {
2632          accumBitsDU                                  = new UInt[ numDU ];
2633        }
2634        if( accumNalsDU == NULL )
2635        {
2636          accumNalsDU                                  = new UInt[ numDU ];
2637        }
2638      }
2639      pictureTimingSEI.m_auCpbRemovalDelay = std::min<Int>(std::max<Int>(1, m_totalCoded - m_lastBPSEI), static_cast<Int>(pow(2, static_cast<Double>(pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getCpbRemovalDelayLengthMinus1()+1)))); // Syntax element signalled as minus, hence the .
2640#if POC_RESET_FLAG || POC_RESET_IDC_ENCODER
2641      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pocCurr - m_totalCoded;
2642#else
2643      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pcSlice->getPOC() - m_totalCoded;
2644#endif
2645#if EFFICIENT_FIELD_IRAP
2646      if(IRAPGOPid > 0 && IRAPGOPid < m_iGopSize)
2647      {
2648        // if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation
2649        pictureTimingSEI.m_picDpbOutputDelay ++;
2650      }
2651#endif
2652      Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2;
2653      pictureTimingSEI.m_picDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
2654      if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
2655      {
2656        picSptDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
2657      }
2658    }
2659
2660    if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) &&
2661        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2662        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
2663       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
2664    {
2665      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2666      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2667      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2668
2669      SEIBufferingPeriod sei_buffering_period;
2670
2671      UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
2672      sei_buffering_period.m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
2673      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
2674      sei_buffering_period.m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
2675      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
2676
2677      Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
2678
2679      UInt uiTmp = (UInt)( dTmp * 90000.0 );
2680      uiInitialCpbRemovalDelay -= uiTmp;
2681      uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
2682      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
2683      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
2684      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
2685      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
2686
2687      sei_buffering_period.m_rapCpbParamsPresentFlag              = 0;
2688      //for the concatenation, it can be set to one during splicing.
2689      sei_buffering_period.m_concatenationFlag = 0;
2690      //since the temporal layer HRD is not ready, we assumed it is fixed
2691      sei_buffering_period.m_auCpbRemovalDelayDelta = 1;
2692
2693      sei_buffering_period.m_cpbDelayOffset = 0;
2694      sei_buffering_period.m_dpbDelayOffset = 0;
2695
2696#if O0164_MULTI_LAYER_HRD
2697      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, m_pcEncTop->getVPS(), pcSlice->getSPS());
2698#else
2699      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, pcSlice->getSPS());
2700#endif
2701      writeRBSPTrailingBits(nalu.m_Bitstream);
2702
2703      {
2704        UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2705        UInt offsetPosition = m_activeParameterSetSEIPresentInAU;   // Insert BP SEI after APS SEI
2706        AccessUnit::iterator it = accessUnit.begin();
2707        for(Int j = 0; j < seiPositionInAu + offsetPosition; j++)
2708        {
2709          it++;
2710        }
2711        accessUnit.insert(it, new NALUnitEBSP(nalu));
2712        m_bufferingPeriodSEIPresentInAU = true;
2713      }
2714
2715      if (m_pcCfg->getScalableNestingSEIEnabled())
2716      {
2717        OutputNALUnit naluTmp(NAL_UNIT_PREFIX_SEI);
2718        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2719        m_pcEntropyCoder->setBitstream(&naluTmp.m_Bitstream);
2720        scalableNestingSEI.m_nestedSEIs.clear();
2721        scalableNestingSEI.m_nestedSEIs.push_back(&sei_buffering_period);
2722#if O0164_MULTI_LAYER_HRD
2723        m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
2724#else
2725        m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
2726#endif
2727        writeRBSPTrailingBits(naluTmp.m_Bitstream);
2728        UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2729        UInt offsetPosition = m_activeParameterSetSEIPresentInAU + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU;   // Insert BP SEI after non-nested APS, BP and PT SEIs
2730        AccessUnit::iterator it = accessUnit.begin();
2731        for(Int j = 0; j < seiPositionInAu + offsetPosition; j++)
2732        {
2733          it++;
2734        }
2735        accessUnit.insert(it, new NALUnitEBSP(naluTmp));
2736        m_nestedBufferingPeriodSEIPresentInAU = true;
2737      }
2738
2739      m_lastBPSEI = m_totalCoded;
2740      m_cpbRemovalDelay = 0;
2741    }
2742    m_cpbRemovalDelay ++;
2743
2744    if(pcSlice->getSPS()->getVuiParametersPresentFlag() && m_pcCfg->getChromaSamplingFilterHintEnabled() && ( pcSlice->getSliceType() == I_SLICE ))
2745    {
2746      SEIChromaSamplingFilterHint *seiChromaSamplingFilterHint = xCreateSEIChromaSamplingFilterHint(m_pcCfg->getChromaLocInfoPresentFlag(), m_pcCfg->getChromaSamplingHorFilterIdc(), m_pcCfg->getChromaSamplingVerFilterIdc());
2747
2748      OutputNALUnit naluTmp(NAL_UNIT_PREFIX_SEI); 
2749      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2750      m_pcEntropyCoder->setBitstream(&naluTmp.m_Bitstream);
2751#if O0164_MULTI_LAYER_HRD
2752      m_seiWriter.writeSEImessage(naluTmp.m_Bitstream, *seiChromaSamplingFilterHint, m_pcEncTop->getVPS(), pcSlice->getSPS());
2753#else
2754      m_seiWriter.writeSEImessage(naluTmp.m_Bitstream, *seiChromaSamplingFilterHint, pcSlice->getSPS()); 
2755#endif
2756      writeRBSPTrailingBits(naluTmp.m_Bitstream);
2757      accessUnit.push_back(new NALUnitEBSP(naluTmp));
2758      delete seiChromaSamplingFilterHint;
2759    }
2760
2761    if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) )
2762    {
2763      if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !pcSlice->getRapPicFlag() )
2764      {
2765        // Gradual decoding refresh SEI
2766        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2767        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2768        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2769
2770        SEIGradualDecodingRefreshInfo seiGradualDecodingRefreshInfo;
2771        seiGradualDecodingRefreshInfo.m_gdrForegroundFlag = true; // Indicating all "foreground"
2772
2773#if O0164_MULTI_LAYER_HRD
2774        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, m_pcEncTop->getVPS(), pcSlice->getSPS() );
2775#else
2776        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, pcSlice->getSPS() );
2777#endif
2778        writeRBSPTrailingBits(nalu.m_Bitstream);
2779        accessUnit.push_back(new NALUnitEBSP(nalu));
2780      }
2781    // Recovery point SEI
2782      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2783      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2784      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2785
2786      SEIRecoveryPoint sei_recovery_point;
2787      sei_recovery_point.m_recoveryPocCnt    = 0;
2788#if POC_RESET_FLAG || POC_RESET_IDC_ENCODER
2789      sei_recovery_point.m_exactMatchingFlag = ( pocCurr == 0 ) ? (true) : (false);
2790#else
2791      sei_recovery_point.m_exactMatchingFlag = ( pcSlice->getPOC() == 0 ) ? (true) : (false);
2792#endif
2793      sei_recovery_point.m_brokenLinkFlag    = false;
2794#if ALLOW_RECOVERY_POINT_AS_RAP
2795      if(m_pcCfg->getDecodingRefreshType() == 3)
2796      {
2797        m_iLastRecoveryPicPOC = pocCurr;
2798      }
2799#endif
2800
2801#if O0164_MULTI_LAYER_HRD
2802      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, m_pcEncTop->getVPS(), pcSlice->getSPS() );
2803#else
2804      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, pcSlice->getSPS() );
2805#endif
2806      writeRBSPTrailingBits(nalu.m_Bitstream);
2807      accessUnit.push_back(new NALUnitEBSP(nalu));
2808    }
2809
2810    if( m_pcEncTop->getNoDisplaySEITLayer() )
2811    {
2812      if( pcSlice->getTLayer() >= m_pcEncTop->getNoDisplaySEITLayer() )
2813      {
2814        // No display SEI
2815        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2816        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2817        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2818
2819        SEINoDisplay seiNoDisplay;
2820        seiNoDisplay.m_noDisplay = true;
2821
2822#if O0164_MULTI_LAYER_HRD
2823        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiNoDisplay, m_pcEncTop->getVPS(), pcSlice->getSPS() );
2824#else
2825        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiNoDisplay, pcSlice->getSPS() );
2826#endif
2827        writeRBSPTrailingBits(nalu.m_Bitstream);
2828        accessUnit.push_back(new NALUnitEBSP(nalu));
2829      }
2830    }
2831
2832    /* use the main bitstream buffer for storing the marshalled picture */
2833    m_pcEntropyCoder->setBitstream(NULL);
2834
2835    pcSlice = pcPic->getSlice(0);
2836
2837
2838#if HIGHER_LAYER_IRAP_SKIP_FLAG
2839    if ( pcSlice->getSPS()->getUseSAO() && !( m_pcEncTop->getSkipPictureAtArcSwitch() && m_pcEncTop->getAdaptiveResolutionChange() > 0 && pcSlice->getLayerId() == 1 && pcSlice->getPOC() == m_pcEncTop->getAdaptiveResolutionChange()) )
2840#else
2841    if (pcSlice->getSPS()->getUseSAO())
2842#endif
2843    {
2844      Bool sliceEnabled[MAX_NUM_COMPONENT];
2845      TComBitCounter tempBitCounter;
2846      tempBitCounter.resetBits();
2847      m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(&tempBitCounter);
2848      m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);
2849      m_pcSAO->SAOProcess(pcPic, sliceEnabled, pcPic->getSlice(0)->getLambdas()
2850#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
2851                          , m_pcCfg->getSaoCtuBoundary()
2852#endif
2853                         );
2854      m_pcSAO->PCMLFDisableProcess(pcPic);
2855      m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(NULL);
2856
2857      //assign SAO slice header
2858      for(Int s=0; s< uiNumSliceSegments; s++)
2859      {
2860        pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, sliceEnabled[COMPONENT_Y]);
2861        assert(sliceEnabled[COMPONENT_Cb] == sliceEnabled[COMPONENT_Cr]);
2862        pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, sliceEnabled[COMPONENT_Cb]);
2863      }
2864    }
2865
2866    // pcSlice is currently slice 0.
2867    Int64 binCountsInNalUnits   = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
2868    Int64 numBytesInVclNalUnits = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
2869
2870    for( UInt sliceSegmentStartCtuTsAddr = 0, sliceIdxCount=0; sliceSegmentStartCtuTsAddr < pcPic->getPicSym()->getNumberOfCtusInFrame(); sliceIdxCount++, sliceSegmentStartCtuTsAddr=pcSlice->getSliceSegmentCurEndCtuTsAddr() )
2871    {
2872      pcSlice = pcPic->getSlice(sliceIdxCount);
2873      if(sliceIdxCount > 0 && pcSlice->getSliceType()!= I_SLICE)
2874      {
2875        pcSlice->checkColRefIdx(sliceIdxCount, pcPic);
2876      }
2877      pcPic->setCurrSliceIdx(sliceIdxCount);
2878      m_pcSliceEncoder->setSliceIdx(sliceIdxCount);
2879
2880      pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
2881      pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
2882
2883      for ( UInt ui = 0 ; ui < numSubstreams; ui++ )
2884      {
2885        substreamsOut[ui].clear();
2886      }
2887
2888      m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
2889      m_pcEntropyCoder->resetEntropy      ();
2890      /* start slice NALunit */
2891#if SVC_EXTENSION
2892      OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), m_layerId );
2893#else
2894      OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
2895#endif
2896      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2897
2898#if R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
2899      if (pcSlice->isIRAP())
2900      {
2901        //the inference for NoOutputPriorPicsFlag
2902        // KJS: This cannot happen at the encoder
2903        if (!m_bFirst && pcSlice->isIRAP() && m_noRaslOutputFlag)
2904        {
2905          if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
2906          {
2907            pcSlice->setNoOutputPriorPicsFlag(true);
2908          }
2909        }
2910      }
2911#else
2912      pcSlice->setNoRaslOutputFlag(false);
2913      if (pcSlice->isIRAP())
2914      {
2915        if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
2916        {
2917          pcSlice->setNoRaslOutputFlag(true);
2918        }
2919        //the inference for NoOutputPriorPicsFlag
2920        // KJS: This cannot happen at the encoder
2921        if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag())
2922        {
2923          if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
2924          {
2925            pcSlice->setNoOutputPriorPicsFlag(true);
2926          }
2927        }
2928      }
2929#endif
2930
2931      tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
2932      m_pcEntropyCoder->encodeSliceHeader(pcSlice);
2933      actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
2934
2935      pcSlice->setFinalized(true);
2936
2937#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
2938      g_bFinalEncode = true;
2939#endif
2940
2941      pcSlice->clearSubstreamSizes(  );
2942      {
2943        UInt numBinsCoded = 0;
2944        m_pcSliceEncoder->encodeSlice(pcPic, &(substreamsOut[0]), numBinsCoded);
2945        binCountsInNalUnits+=numBinsCoded;
2946      }
2947
2948#if ENVIRONMENT_VARIABLE_DEBUG_AND_TEST
2949      g_bFinalEncode = false;
2950#endif
2951
2952      {
2953        // Construct the final bitstream by concatenating substreams.
2954        // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
2955        // Complete the slice header info.
2956        m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
2957        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2958#if POC_RESET_IDC_SIGNALLING
2959        tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
2960        m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
2961        actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
2962        m_pcEntropyCoder->encodeSliceHeaderExtn( pcSlice, actualHeadBits );
2963#else
2964        m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
2965#endif
2966
2967        // Append substreams...
2968        TComOutputBitstream *pcOut = pcBitstreamRedirect;
2969        const Int numZeroSubstreamsAtStartOfSlice  = pcPic->getSubstreamForCtuAddr(pcSlice->getSliceSegmentCurStartCtuTsAddr(), false, pcSlice);
2970        const Int numSubstreamsToCode  = pcSlice->getNumberOfSubstreamSizes()+1;
2971        for ( UInt ui = 0 ; ui < numSubstreamsToCode; ui++ )
2972        {
2973          pcOut->addSubstream(&(substreamsOut[ui+numZeroSubstreamsAtStartOfSlice]));
2974        }
2975      }
2976
2977      // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
2978      // If current NALU is the last NALU of slice and a NALU was buffered, then (a) Write current NALU (b) Update an write buffered NALU at approproate location in NALU list.
2979      Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
2980      xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
2981      accessUnit.push_back(new NALUnitEBSP(nalu));
2982      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2983      numBytesInVclNalUnits += Int64(accessUnit.back()->m_nalUnitData.str().size());
2984      bNALUAlignedWrittenToList = true;
2985
2986      if (!bNALUAlignedWrittenToList)
2987      {
2988        nalu.m_Bitstream.writeAlignZero();
2989        accessUnit.push_back(new NALUnitEBSP(nalu));
2990      }
2991
2992      if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2993          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2994          ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
2995         || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
2996          ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
2997      {
2998          UInt numNalus = 0;
2999        UInt numRBSPBytes = 0;
3000        for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3001        {
3002          UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3003          if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3004          {
3005            numRBSPBytes += numRBSPBytes_nal;
3006            numNalus ++;
3007          }
3008        }
3009        accumBitsDU[ pcSlice->getSliceIdx() ] = ( numRBSPBytes << 3 );
3010        accumNalsDU[ pcSlice->getSliceIdx() ] = numNalus;   // SEI not counted for bit count; hence shouldn't be counted for # of NALUs - only for consistency
3011      }
3012    } // end iteration over slices
3013
3014    // cabac_zero_words processing
3015    {
3016      const Int log2subWidthCxsubHeightC = (pcPic->getComponentScaleX(COMPONENT_Cb)+pcPic->getComponentScaleY(COMPONENT_Cb));
3017      const Int minCuWidth  = pcPic->getMinCUWidth();
3018      const Int minCuHeight = pcPic->getMinCUHeight();
3019#if REPN_FORMAT_IN_VPS
3020      const Int paddedWidth = ((pcSlice->getPicWidthInLumaSamples()  + minCuWidth  - 1) / minCuWidth) * minCuWidth;
3021      const Int paddedHeight= ((pcSlice->getPicHeightInLumaSamples() + minCuHeight - 1) / minCuHeight) * minCuHeight;
3022#else
3023      const Int paddedWidth = ((pcSlice->getSPS()->getPicWidthInLumaSamples()  + minCuWidth  - 1) / minCuWidth) * minCuWidth;
3024      const Int paddedHeight= ((pcSlice->getSPS()->getPicHeightInLumaSamples() + minCuHeight - 1) / minCuHeight) * minCuHeight;
3025#endif
3026      const Int rawBits = paddedWidth * paddedHeight *
3027                             (g_bitDepth[CHANNEL_TYPE_LUMA] + 2*(g_bitDepth[CHANNEL_TYPE_CHROMA]>>log2subWidthCxsubHeightC));
3028      const Int64 threshold = (32LL/3)*numBytesInVclNalUnits + (rawBits/32);
3029      if (binCountsInNalUnits >= threshold)
3030      {
3031        // need to add additional cabac zero words (each one accounts for 3 bytes (=00 00 03)) to increase numBytesInVclNalUnits
3032        const Int64 targetNumBytesInVclNalUnits = ((binCountsInNalUnits - (rawBits/32))*3+31)/32;
3033        const Int64 numberOfAdditionalBytesNeeded=targetNumBytesInVclNalUnits - numBytesInVclNalUnits;
3034
3035        if (numberOfAdditionalBytesNeeded>0) // It should be!
3036        {
3037          const Int64 numberOfAdditionalCabacZeroWords=(numberOfAdditionalBytesNeeded+2)/3;
3038          const Int64 numberOfAdditionalCabacZeroBytes=numberOfAdditionalCabacZeroWords*3;
3039          if (m_pcCfg->getCabacZeroWordPaddingEnabled())
3040          {
3041            std::vector<Char> zeroBytesPadding(numberOfAdditionalCabacZeroBytes, Char(0));
3042            for(Int64 i=0; i<numberOfAdditionalCabacZeroWords; i++)
3043            {
3044              zeroBytesPadding[i*3+2]=3;  // 00 00 03
3045            }
3046            accessUnit.back()->m_nalUnitData.write(&(zeroBytesPadding[0]), numberOfAdditionalCabacZeroBytes);
3047            printf("Adding %lld bytes of padding\n", numberOfAdditionalCabacZeroWords*3);
3048          }
3049          else
3050          {
3051            printf("Standard would normally require adding %lld bytes of padding\n", numberOfAdditionalCabacZeroWords*3);
3052          }
3053        }
3054      }
3055    }
3056
3057    pcPic->compressMotion();
3058
3059    //-- For time output for each slice
3060    Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
3061
3062    std::string digestStr;
3063    if (m_pcCfg->getDecodedPictureHashSEIEnabled())
3064    {
3065      /* calculate MD5sum for entire reconstructed picture */
3066      SEIDecodedPictureHash sei_recon_picture_digest;
3067      if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
3068      {
3069        sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5;
3070        UInt numChar=calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.m_digest);
3071        digestStr = digestToString(sei_recon_picture_digest.m_digest, numChar);
3072      }
3073      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
3074      {
3075        sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC;
3076        UInt numChar=calcCRC(*pcPic->getPicYuvRec(), sei_recon_picture_digest.m_digest);
3077        digestStr = digestToString(sei_recon_picture_digest.m_digest, numChar);
3078      }
3079      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
3080      {
3081        sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM;
3082        UInt numChar=calcChecksum(*pcPic->getPicYuvRec(), sei_recon_picture_digest.m_digest);
3083        digestStr = digestToString(sei_recon_picture_digest.m_digest, numChar);
3084      }
3085
3086#if SVC_EXTENSION
3087      OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer(), m_layerId);
3088#else
3089      OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer());
3090#endif
3091
3092      /* write the SEI messages */
3093      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3094#if O0164_MULTI_LAYER_HRD
3095      m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, m_pcEncTop->getVPS(), pcSlice->getSPS());
3096#else
3097      m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, pcSlice->getSPS());
3098#endif
3099      writeRBSPTrailingBits(nalu.m_Bitstream);
3100
3101      accessUnit.insert(accessUnit.end(), new NALUnitEBSP(nalu));
3102    }
3103    if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
3104    {
3105      SEITemporalLevel0Index sei_temporal_level0_index;
3106      if (pcSlice->getRapPicFlag())
3107      {
3108        m_tl0Idx = 0;
3109        m_rapIdx = (m_rapIdx + 1) & 0xFF;
3110      }
3111      else
3112      {
3113        m_tl0Idx = (m_tl0Idx + (pcSlice->getTLayer() ? 0 : 1)) & 0xFF;
3114      }
3115      sei_temporal_level0_index.tl0Idx = m_tl0Idx;
3116      sei_temporal_level0_index.rapIdx = m_rapIdx;
3117
3118      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
3119
3120      /* write the SEI messages */
3121      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3122#if O0164_MULTI_LAYER_HRD
3123      m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, m_pcEncTop->getVPS(), pcSlice->getSPS());
3124#else
3125      m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, pcSlice->getSPS());     
3126#endif
3127      writeRBSPTrailingBits(nalu.m_Bitstream);
3128
3129      /* insert the SEI message NALUnit before any Slice NALUnits */
3130      AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
3131      accessUnit.insert(it, new NALUnitEBSP(nalu));
3132    }
3133
3134    m_pcCfg->setEncodedFlag(iGOPid, true);
3135    xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
3136
3137    //In case of field coding, compute the interlaced PSNR for both fields
3138    if(isField)
3139    {
3140      Bool bothFieldsAreEncoded = false;
3141      Int correspondingFieldPOC = pcPic->getPOC();
3142      Int currentPicGOPPoc = m_pcCfg->getGOPEntry(iGOPid).m_POC;
3143      if(pcPic->getPOC() == 0)
3144      {
3145        // particular case for POC 0 and 1.
3146        // If they are not encoded first and separately from other pictures, we need to change this
3147        // POC 0 is always encoded first then POC 1 is encoded
3148        bothFieldsAreEncoded = false;
3149      }
3150      else if(pcPic->getPOC() == 1)
3151      {
3152        // if we are at POC 1, POC 0 has been encoded for sure
3153        correspondingFieldPOC = 0;
3154        bothFieldsAreEncoded = true;
3155      }
3156      else 
3157      {
3158        if(pcPic->getPOC()%2 == 1)
3159        {
3160          correspondingFieldPOC -= 1; // all odd POC are associated with the preceding even POC (e.g poc 1 is associated to poc 0)
3161          currentPicGOPPoc      -= 1;
3162        }
3163        else
3164        {
3165          correspondingFieldPOC += 1; // all even POC are associated with the following odd POC (e.g poc 0 is associated to poc 1)
3166          currentPicGOPPoc      += 1;
3167        }
3168        for(Int i = 0; i < m_iGopSize; i ++)
3169        {
3170          if(m_pcCfg->getGOPEntry(i).m_POC == currentPicGOPPoc)
3171          {
3172            bothFieldsAreEncoded = m_pcCfg->getGOPEntry(i).m_isEncoded;
3173            break;
3174          }
3175        }
3176      }
3177
3178      if(bothFieldsAreEncoded)
3179      {       
3180        //get complementary top field
3181        TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
3182        while ((*iterPic)->getPOC() != correspondingFieldPOC)
3183        {
3184          iterPic ++;
3185        }
3186        TComPic* correspondingFieldPic = *(iterPic);
3187
3188        if( (pcPic->isTopField() && isTff) || (!pcPic->isTopField() && !isTff))
3189        {
3190          xCalculateInterlacedAddPSNR(pcPic, correspondingFieldPic, pcPic->getPicYuvRec(), correspondingFieldPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
3191        }
3192        else
3193        {
3194          xCalculateInterlacedAddPSNR(correspondingFieldPic, pcPic, correspondingFieldPic->getPicYuvRec(), pcPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
3195        }
3196      }
3197    }
3198
3199    if (!digestStr.empty())
3200    {
3201      if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
3202      {
3203        printf(" [MD5:%s]", digestStr.c_str());
3204      }
3205      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
3206      {
3207        printf(" [CRC:%s]", digestStr.c_str());
3208      }
3209      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
3210      {
3211        printf(" [Checksum:%s]", digestStr.c_str());
3212      }
3213    }
3214
3215    if ( m_pcCfg->getUseRateCtrl() )
3216    {
3217      Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
3218      Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
3219      if ( avgLambda < 0.0 )
3220      {
3221        avgLambda = lambda;
3222      }
3223
3224      m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
3225      m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
3226
3227      m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
3228      if ( pcSlice->getSliceType() != I_SLICE )
3229      {
3230        m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
3231      }
3232      else    // for intra picture, the estimated bits are used to update the current status in the GOP
3233      {
3234        m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
3235      }
3236    }
3237
3238    if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
3239        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
3240        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
3241        || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
3242    {
3243      TComVUI *vui = pcSlice->getSPS()->getVuiParameters();
3244      TComHRD *hrd = vui->getHrdParameters();
3245
3246      if( hrd->getSubPicCpbParamsPresentFlag() )
3247      {
3248        Int i;
3249        UInt64 ui64Tmp;
3250        UInt uiPrev = 0;
3251        UInt numDU = ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 );
3252        UInt *pCRD = &pictureTimingSEI.m_duCpbRemovalDelayMinus1[0];
3253        UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
3254
3255        for( i = 0; i < numDU; i ++ )
3256        {
3257          pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] - 1 ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
3258        }
3259
3260        if( numDU == 1 )
3261        {
3262          pCRD[ 0 ] = 0; /* don't care */
3263        }
3264        else
3265        {
3266          pCRD[ numDU - 1 ] = 0;/* by definition */
3267          UInt tmp = 0;
3268          UInt accum = 0;
3269
3270          for( i = ( numDU - 2 ); i >= 0; i -- )
3271          {
3272            ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
3273            if( (UInt)ui64Tmp > maxDiff )
3274            {
3275              tmp ++;
3276            }
3277          }
3278          uiPrev = 0;
3279
3280          UInt flag = 0;
3281          for( i = ( numDU - 2 ); i >= 0; i -- )
3282          {
3283            flag = 0;
3284            ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
3285
3286            if( (UInt)ui64Tmp > maxDiff )
3287            {
3288              if(uiPrev >= maxDiff - tmp)
3289              {
3290                ui64Tmp = uiPrev + 1;
3291                flag = 1;
3292              }
3293              else                            ui64Tmp = maxDiff - tmp + 1;
3294            }
3295            pCRD[ i ] = (UInt)ui64Tmp - uiPrev - 1;
3296            if( (Int)pCRD[ i ] < 0 )
3297            {
3298              pCRD[ i ] = 0;
3299            }
3300            else if (tmp > 0 && flag == 1)
3301            {
3302              tmp --;
3303            }
3304            accum += pCRD[ i ] + 1;
3305            uiPrev = accum;
3306          }
3307        }
3308      }
3309
3310      if( m_pcCfg->getPictureTimingSEIEnabled() )
3311      {
3312        {
3313          OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
3314          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3315          pictureTimingSEI.m_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0;
3316#if O0164_MULTI_LAYER_HRD
3317          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3318#else
3319          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, pcSlice->getSPS());
3320#endif
3321          writeRBSPTrailingBits(nalu.m_Bitstream);
3322          UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
3323          UInt offsetPosition = m_activeParameterSetSEIPresentInAU
3324                                    + m_bufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
3325          AccessUnit::iterator it = accessUnit.begin();
3326          for(Int j = 0; j < seiPositionInAu + offsetPosition; j++)
3327          {
3328            it++;
3329          }
3330          accessUnit.insert(it, new NALUnitEBSP(nalu));
3331          m_pictureTimingSEIPresentInAU = true;
3332        }
3333
3334        if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI
3335        {
3336          OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
3337          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3338          scalableNestingSEI.m_nestedSEIs.clear();
3339          scalableNestingSEI.m_nestedSEIs.push_back(&pictureTimingSEI);
3340#if O0164_MULTI_LAYER_HRD
3341          m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3342#else
3343          m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
3344#endif
3345          writeRBSPTrailingBits(nalu.m_Bitstream);
3346          UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
3347          UInt offsetPosition = m_activeParameterSetSEIPresentInAU
3348            + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU + m_nestedBufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
3349          AccessUnit::iterator it = accessUnit.begin();
3350          for(Int j = 0; j < seiPositionInAu + offsetPosition; j++)
3351          {
3352            it++;
3353          }
3354          accessUnit.insert(it, new NALUnitEBSP(nalu));
3355          m_nestedPictureTimingSEIPresentInAU = true;
3356        }
3357      }
3358
3359      if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
3360      {
3361        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3362        for( Int i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
3363        {
3364          OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
3365
3366          SEIDecodingUnitInfo tempSEI;
3367          tempSEI.m_decodingUnitIdx = i;
3368          tempSEI.m_duSptCpbRemovalDelay = pictureTimingSEI.m_duCpbRemovalDelayMinus1[i] + 1;
3369          tempSEI.m_dpbOutputDuDelayPresentFlag = false;
3370          tempSEI.m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
3371
3372          // Insert the first one in the right location, before the first slice
3373          if(i == 0)
3374          {
3375            // Insert before the first slice.
3376#if O0164_MULTI_LAYER_HRD
3377            m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3378#else
3379            m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
3380#endif
3381            writeRBSPTrailingBits(nalu.m_Bitstream);
3382
3383            UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
3384            UInt offsetPosition = m_activeParameterSetSEIPresentInAU
3385                                  + m_bufferingPeriodSEIPresentInAU
3386                                  + m_pictureTimingSEIPresentInAU;  // Insert DU info SEI after APS, BP and PT SEI
3387            AccessUnit::iterator it = accessUnit.begin();
3388            for(Int j = 0; j < seiPositionInAu + offsetPosition; j++)
3389            {
3390              it++;
3391            }
3392            accessUnit.insert(it, new NALUnitEBSP(nalu));
3393          }
3394          else
3395          {
3396            // For the second decoding unit onwards we know how many NALUs are present
3397            AccessUnit::iterator it = accessUnit.begin();
3398            for (Int ctr = 0; it != accessUnit.end(); it++)
3399            {
3400              if(ctr == accumNalsDU[ i - 1 ])
3401              {
3402                // Insert before the first slice.
3403#if O0164_MULTI_LAYER_HRD
3404                m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3405#else
3406                m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
3407#endif
3408                writeRBSPTrailingBits(nalu.m_Bitstream);
3409
3410                accessUnit.insert(it, new NALUnitEBSP(nalu));
3411                break;
3412              }
3413              if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3414              {
3415                ctr++;
3416              }
3417            }
3418          }
3419        }
3420      }
3421    }
3422
3423#if R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
3424    m_prevPicHasEos = false;
3425    if (m_pcCfg->getLayerSwitchOffBegin() < m_pcCfg->getLayerSwitchOffEnd())
3426    {
3427      Int pocNext;
3428      if (iGOPid == m_iGopSize - 1)
3429      {
3430        pocNext = iPOCLast - iNumPicRcvd + m_iGopSize + m_pcCfg->getGOPEntry(0).m_POC;
3431      }
3432      else
3433      {
3434        pocNext = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid + 1).m_POC;
3435      }
3436
3437      if (pocNext > m_pcCfg->getLayerSwitchOffBegin() && pocCurr < m_pcCfg->getLayerSwitchOffEnd())
3438      {
3439        OutputNALUnit nalu(NAL_UNIT_EOS, 0, pcSlice->getLayerId());
3440        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3441        accessUnit.push_back(new NALUnitEBSP(nalu));
3442        m_prevPicHasEos = true;
3443      }
3444    }
3445#endif
3446
3447    xResetNonNestedSEIPresentFlags();
3448    xResetNestedSEIPresentFlags();
3449
3450    pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
3451
3452#if M0040_ADAPTIVE_RESOLUTION_CHANGE
3453    pcPicYuvRecOut->setReconstructed(true);
3454#endif
3455#if P0297_VPS_POC_LSB_ALIGNED_FLAG
3456    m_pcEncTop->setFirstPicInLayerDecodedFlag(true);
3457#endif
3458    pcPic->setReconMark   ( true );
3459    m_bFirst = false;
3460    m_iNumPicCoded++;
3461    m_totalCoded ++;
3462    /* logging: insert a newline at end of picture period */
3463    printf("\n");
3464    fflush(stdout);
3465
3466#if EFFICIENT_FIELD_IRAP
3467    if(IRAPtoReorder)
3468    {
3469      if(swapIRAPForward)
3470      {
3471        if(iGOPid == IRAPGOPid)
3472        {
3473          iGOPid = IRAPGOPid +1;
3474          IRAPtoReorder = false;
3475        }
3476        else if(iGOPid == IRAPGOPid +1)
3477        {
3478          iGOPid --;
3479        }
3480      }
3481      else
3482      {
3483        if(iGOPid == IRAPGOPid)
3484        {
3485          iGOPid = IRAPGOPid -1;
3486        }
3487        else if(iGOPid == IRAPGOPid -1)
3488        {
3489          iGOPid = IRAPGOPid;
3490          IRAPtoReorder = false;
3491        }
3492      }
3493    }
3494#endif
3495  } // iGOPid-loop
3496
3497  delete pcBitstreamRedirect;
3498
3499  if( accumBitsDU != NULL) delete accumBitsDU;
3500  if( accumNalsDU != NULL) delete accumNalsDU;
3501
3502#if SVC_EXTENSION
3503  assert ( m_iNumPicCoded <= 1 );
3504#else
3505  assert ( (m_iNumPicCoded == iNumPicRcvd) );
3506#endif
3507}
3508
3509#if !SVC_EXTENSION
3510Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField, const Bool printMSEBasedSNR, const Bool printSequenceMSE)
3511{
3512  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
3513
3514
3515  //--CFG_KDY
3516  const Int rateMultiplier=(isField?2:1);
3517  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
3518  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
3519  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
3520  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
3521  const ChromaFormat chFmt = m_pcCfg->getChromaFormatIdc();
3522
3523  //-- all
3524  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
3525  m_gcAnalyzeAll.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE);
3526
3527  printf( "\n\nI Slices--------------------------------------------------------\n" );
3528  m_gcAnalyzeI.printOut('i', chFmt, printMSEBasedSNR, printSequenceMSE);
3529
3530  printf( "\n\nP Slices--------------------------------------------------------\n" );
3531  m_gcAnalyzeP.printOut('p', chFmt, printMSEBasedSNR, printSequenceMSE);
3532
3533  printf( "\n\nB Slices--------------------------------------------------------\n" );
3534  m_gcAnalyzeB.printOut('b', chFmt, printMSEBasedSNR, printSequenceMSE);
3535
3536#if _SUMMARY_OUT_
3537  m_gcAnalyzeAll.printSummary(chFmt, printSequenceMSE);
3538#endif
3539#if _SUMMARY_PIC_
3540  m_gcAnalyzeI.printSummary(chFmt, printSequenceMSE,'I');
3541  m_gcAnalyzeP.printSummary(chFmt, printSequenceMSE,'P');
3542  m_gcAnalyzeB.printSummary(chFmt, printSequenceMSE,'B');
3543#endif
3544
3545  if(isField)
3546  {
3547    //-- interlaced summary
3548    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
3549    m_gcAnalyzeAll_in.setBits(m_gcAnalyzeAll.getBits());
3550    // prior to the above statement, the interlace analyser does not contain the correct total number of bits.
3551
3552    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
3553    m_gcAnalyzeAll_in.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE);
3554
3555#if _SUMMARY_OUT_
3556    m_gcAnalyzeAll_in.printSummary(chFmt, printSequenceMSE);
3557#endif
3558  }
3559
3560  printf("\nRVM: %.3lf\n" , xCalculateRVM());
3561}
3562#endif
3563
3564Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist )
3565{
3566  Bool bCalcDist = false;
3567  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
3568  m_pcLoopFilter->loopFilterPic( pcPic );
3569
3570  if (!bCalcDist)
3571    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
3572}
3573
3574// ====================================================================================================================
3575// Protected member functions
3576// ====================================================================================================================
3577
3578
3579Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, Bool isField )
3580{
3581  assert( iNumPicRcvd > 0 );
3582  //  Exception for the first frames
3583  if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField  && (iPOCLast == 0))  )
3584  {
3585    m_iGopSize    = 1;
3586  }
3587  else
3588  {
3589    m_iGopSize    = m_pcCfg->getGOPSize();
3590  }
3591  assert (m_iGopSize > 0);
3592
3593  return;
3594}
3595
3596
3597Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
3598                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
3599                         Int                       iNumPicRcvd,
3600                         Int                       iTimeOffset,
3601                         TComPic*&                 rpcPic,
3602                         TComPicYuv*&              rpcPicYuvRecOut,
3603                         Int                       pocCurr,
3604                         Bool                      isField)
3605{
3606  Int i;
3607  //  Rec. output
3608  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
3609
3610  if (isField && pocCurr > 1 && m_iGopSize!=1)
3611  {
3612    iTimeOffset--;
3613  }
3614
3615  for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
3616  {
3617    iterPicYuvRec--;
3618  }
3619
3620  rpcPicYuvRecOut = *(iterPicYuvRec);
3621
3622  //  Current pic.
3623  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
3624  while (iterPic != rcListPic.end())
3625  {
3626    rpcPic = *(iterPic);
3627    rpcPic->setCurrSliceIdx(0);
3628    if (rpcPic->getPOC() == pocCurr)
3629    {
3630      break;
3631    }
3632    iterPic++;
3633  }
3634
3635  assert (rpcPic != NULL);
3636  assert (rpcPic->getPOC() == pocCurr);
3637
3638  return;
3639}
3640
3641UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
3642{
3643  UInt64  uiTotalDiff = 0;
3644
3645  for(Int chan=0; chan<pcPic0 ->getNumberValidComponents(); chan++)
3646  {
3647    const ComponentID ch=ComponentID(chan);
3648    Pel*  pSrc0   = pcPic0 ->getAddr(ch);
3649    Pel*  pSrc1   = pcPic1 ->getAddr(ch);
3650    UInt  uiShift     = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepth[toChannelType(ch)]-8);
3651
3652    const Int   iStride = pcPic0->getStride(ch);
3653    const Int   iWidth  = pcPic0->getWidth(ch);
3654    const Int   iHeight = pcPic0->getHeight(ch);
3655
3656    for(Int y = 0; y < iHeight; y++ )
3657    {
3658      for(Int x = 0; x < iWidth; x++ )
3659      {
3660        Intermediate_Int iTemp = pSrc0[x] - pSrc1[x];
3661        uiTotalDiff += UInt64((iTemp*iTemp) >> uiShift);
3662      }
3663      pSrc0 += iStride;
3664      pSrc1 += iStride;
3665    }
3666  }
3667
3668  return uiTotalDiff;
3669}
3670
3671#if VERBOSE_RATE
3672static const Char* nalUnitTypeToString(NalUnitType type)
3673{
3674  switch (type)
3675  {
3676    case NAL_UNIT_CODED_SLICE_TRAIL_R:    return "TRAIL_R";
3677    case NAL_UNIT_CODED_SLICE_TRAIL_N:    return "TRAIL_N";
3678    case NAL_UNIT_CODED_SLICE_TSA_R:      return "TSA_R";
3679    case NAL_UNIT_CODED_SLICE_TSA_N:      return "TSA_N";
3680    case NAL_UNIT_CODED_SLICE_STSA_R:     return "STSA_R";
3681    case NAL_UNIT_CODED_SLICE_STSA_N:     return "STSA_N";
3682    case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
3683    case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
3684    case NAL_UNIT_CODED_SLICE_BLA_N_LP:   return "BLA_N_LP";
3685    case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
3686    case NAL_UNIT_CODED_SLICE_IDR_N_LP:   return "IDR_N_LP";
3687    case NAL_UNIT_CODED_SLICE_CRA:        return "CRA";
3688    case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
3689    case NAL_UNIT_CODED_SLICE_RADL_N:     return "RADL_N";
3690    case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
3691    case NAL_UNIT_CODED_SLICE_RASL_N:     return "RASL_N";
3692    case NAL_UNIT_VPS:                    return "VPS";
3693    case NAL_UNIT_SPS:                    return "SPS";
3694    case NAL_UNIT_PPS:                    return "PPS";
3695    case NAL_UNIT_ACCESS_UNIT_DELIMITER:  return "AUD";
3696    case NAL_UNIT_EOS:                    return "EOS";
3697    case NAL_UNIT_EOB:                    return "EOB";
3698    case NAL_UNIT_FILLER_DATA:            return "FILLER";
3699    case NAL_UNIT_PREFIX_SEI:             return "SEI";
3700    case NAL_UNIT_SUFFIX_SEI:             return "SEI";
3701    default:                              return "UNK";
3702  }
3703}
3704#endif
3705
3706Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime, const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3707{
3708  Double  dPSNR[MAX_NUM_COMPONENT];
3709
3710  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3711  {
3712    dPSNR[i]=0.0;
3713  }
3714
3715  TComPicYuv cscd;
3716  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3717  {
3718    cscd.create(pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), pcPicD->getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
3719    TVideoIOYuv::ColourSpaceConvert(*pcPicD, cscd, conversion, g_bitDepth, false);
3720  }
3721  TComPicYuv &picd=(conversion==IPCOLOURSPACE_UNCHANGED)?*pcPicD : cscd;
3722
3723  //===== calculate PSNR =====
3724  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3725
3726  for(Int chan=0; chan<pcPicD->getNumberValidComponents(); chan++)
3727  {
3728    const ComponentID ch=ComponentID(chan);
3729    const Pel*  pOrg    = (conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg()->getAddr(ch) : pcPic ->getPicYuvOrg()->getAddr(ch);
3730    Pel*  pRec    = picd.getAddr(ch);
3731    const Int   iStride = pcPicD->getStride(ch);
3732
3733    const Int   iWidth  = pcPicD->getWidth (ch) - (m_pcEncTop->getPad(0) >> pcPic->getComponentScaleX(ch));
3734    const Int   iHeight = pcPicD->getHeight(ch) - ((m_pcEncTop->getPad(1) >> (pcPic->isField()?1:0)) >> pcPic->getComponentScaleY(ch));
3735
3736    Int   iSize   = iWidth*iHeight;
3737
3738    UInt64 uiSSDtemp=0;
3739    for(Int y = 0; y < iHeight; y++ )
3740    {
3741      for(Int x = 0; x < iWidth; x++ )
3742      {
3743        Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3744        uiSSDtemp   += iDiff * iDiff;
3745      }
3746      pOrg += iStride;
3747      pRec += iStride;
3748    }
3749    const Int maxval = 255 << (g_bitDepth[toChannelType(ch)] - 8);
3750    const Double fRefValue = (Double) maxval * maxval * iSize;
3751    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3752    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize);
3753  }
3754
3755
3756  /* calculate the size of the access unit, excluding:
3757   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
3758   *  - SEI NAL units
3759   */
3760  UInt numRBSPBytes = 0;
3761  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3762  {
3763    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3764#if VERBOSE_RATE
3765    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
3766#endif
3767    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3768    {
3769      numRBSPBytes += numRBSPBytes_nal;
3770    }
3771  }
3772
3773  UInt uibits = numRBSPBytes * 8;
3774  m_vRVM_RP.push_back( uibits );
3775
3776  //===== add PSNR =====
3777#if SVC_EXTENSION
3778  m_gcAnalyzeAll[m_layerId].addResult (dPSNR, (Double)uibits, MSEyuvframe);
3779  TComSlice*  pcSlice = pcPic->getSlice(0);
3780  if (pcSlice->isIntra())
3781  {
3782    m_gcAnalyzeI[m_layerId].addResult (dPSNR, (Double)uibits, MSEyuvframe);
3783  }
3784  if (pcSlice->isInterP())
3785  {
3786    m_gcAnalyzeP[m_layerId].addResult (dPSNR, (Double)uibits, MSEyuvframe);
3787  }
3788  if (pcSlice->isInterB())
3789  {
3790    m_gcAnalyzeB[m_layerId].addResult (dPSNR, (Double)uibits, MSEyuvframe);
3791  }
3792#else
3793  m_gcAnalyzeAll.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3794  TComSlice*  pcSlice = pcPic->getSlice(0);
3795  if (pcSlice->isIntra())
3796  {
3797    m_gcAnalyzeI.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3798  }
3799  if (pcSlice->isInterP())
3800  {
3801    m_gcAnalyzeP.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3802  }
3803  if (pcSlice->isInterB())
3804  {
3805    m_gcAnalyzeB.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3806  }
3807#endif
3808
3809  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
3810  if (!pcSlice->isReferenced()) c += 32;
3811
3812#if SVC_EXTENSION
3813#if ADAPTIVE_QP_SELECTION 
3814  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, nQP %d QP %d ) %10d bits",
3815         pcSlice->getPOC(),
3816         pcSlice->getLayerId(),
3817         pcSlice->getTLayer(),
3818         c,
3819         NaluToStr( pcSlice->getNalUnitType() ).data(),
3820         pcSlice->getSliceQpBase(),
3821         pcSlice->getSliceQp(),
3822         uibits );
3823#else
3824  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, QP %d ) %10d bits",
3825         pcSlice->getPOC()-pcSlice->getLastIDR(),
3826         pcSlice->getLayerId(),
3827         pcSlice->getTLayer(),
3828         c,
3829         NaluToStr( pcSlice->getNalUnitType() ).data(),
3830         pcSlice->getSliceQp(),
3831         uibits );
3832#endif
3833#else
3834#if ADAPTIVE_QP_SELECTION
3835  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
3836         pcSlice->getPOC(),
3837         pcSlice->getTLayer(),
3838         c,
3839         pcSlice->getSliceQpBase(),
3840         pcSlice->getSliceQp(),
3841         uibits );
3842#else
3843  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
3844         pcSlice->getPOC()-pcSlice->getLastIDR(),
3845         pcSlice->getTLayer(),
3846         c,
3847         pcSlice->getSliceQp(),
3848         uibits );
3849#endif
3850#endif
3851
3852  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
3853  if (printFrameMSE)
3854  {
3855    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3856  }
3857  printf(" [ET %5.0f ]", dEncTime );
3858
3859  for (Int iRefList = 0; iRefList < 2; iRefList++)
3860  {
3861    printf(" [L%d ", iRefList);
3862    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
3863    {
3864#if SVC_EXTENSION
3865#if VPS_EXTN_DIRECT_REF_LAYERS
3866      if( pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->isILR(m_layerId) )
3867      {
3868#if POC_RESET_IDC_ENCODER
3869        UInt refLayerId = pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId();
3870        UInt refLayerIdc = pcSlice->getReferenceLayerIdc(refLayerId);
3871        assert( g_posScalingFactor[refLayerIdc][0] );
3872        assert( g_posScalingFactor[refLayerIdc][1] );
3873
3874        printf( "%d(%d, {%1.2f, %1.2f}x)", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex), refLayerId, 65536.0/g_posScalingFactor[refLayerIdc][0], 65536.0/g_posScalingFactor[refLayerIdc][1] );
3875#else
3876        printf( "%d(%d)", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR(), pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId() );
3877#endif
3878      }
3879      else
3880      {
3881#if POC_RESET_IDC_ENCODER
3882        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
3883#else
3884        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3885#endif
3886      }
3887#endif
3888      if( pcSlice->getEnableTMVPFlag() && iRefList == 1 - pcSlice->getColFromL0Flag() && iRefIndex == pcSlice->getColRefIdx() )
3889      {
3890        printf( "c" );
3891      }
3892
3893      printf( " " );
3894#else
3895      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3896#endif
3897    }
3898    printf("]");
3899  }
3900#if Q0048_CGS_3D_ASYMLUT
3901  pcPic->setFrameBit( (Int)uibits );
3902  if( m_layerId && pcSlice->getPPS()->getCGSFlag() )
3903  {
3904#if R0179_ENC_OPT_3DLUT_SIZE
3905      m_Enc3DAsymLUTPicUpdate.update3DAsymLUTParam( &m_Enc3DAsymLUTPPS );
3906#else
3907    if( m_Enc3DAsymLUTPPS.getPPSBit() > 0 )
3908      m_Enc3DAsymLUTPicUpdate.copy3DAsymLUT( &m_Enc3DAsymLUTPPS );
3909#endif
3910    m_Enc3DAsymLUTPicUpdate.updatePicCGSBits( pcSlice , m_Enc3DAsymLUTPPS.getPPSBit() );
3911  }
3912#endif
3913
3914  cscd.destroy();
3915}
3916
3917Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgFirstField, TComPic* pcPicOrgSecondField,
3918                                           TComPicYuv* pcPicRecFirstField, TComPicYuv* pcPicRecSecondField,
3919                                           const AccessUnit& accessUnit, Double dEncTime, const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3920{
3921  Double  dPSNR[MAX_NUM_COMPONENT];
3922  TComPic    *apcPicOrgFields[2]={pcPicOrgFirstField, pcPicOrgSecondField};
3923  TComPicYuv *apcPicRecFields[2]={pcPicRecFirstField, pcPicRecSecondField};
3924
3925  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3926  {
3927    dPSNR[i]=0.0;
3928  }
3929
3930  TComPicYuv cscd[2 /* first/second field */];
3931  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3932  {
3933    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3934    {
3935      TComPicYuv &reconField=*(apcPicRecFields[fieldNum]);
3936      cscd[fieldNum].create(reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), reconField.getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
3937      TVideoIOYuv::ColourSpaceConvert(reconField, cscd[fieldNum], conversion, g_bitDepth, false);
3938      apcPicRecFields[fieldNum]=cscd+fieldNum;
3939    }
3940  }
3941
3942  //===== calculate PSNR =====
3943  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3944
3945  assert(apcPicRecFields[0]->getChromaFormat()==apcPicRecFields[1]->getChromaFormat());
3946  const UInt numValidComponents=apcPicRecFields[0]->getNumberValidComponents();
3947
3948  for(Int chan=0; chan<numValidComponents; chan++)
3949  {
3950    const ComponentID ch=ComponentID(chan);
3951    assert(apcPicRecFields[0]->getWidth(ch)==apcPicRecFields[1]->getWidth(ch));
3952    assert(apcPicRecFields[0]->getHeight(ch)==apcPicRecFields[1]->getHeight(ch));
3953
3954    UInt64 uiSSDtemp=0;
3955    const Int   iWidth  = apcPicRecFields[0]->getWidth (ch) - (m_pcEncTop->getPad(0) >> apcPicRecFields[0]->getComponentScaleX(ch));
3956    const Int   iHeight = apcPicRecFields[0]->getHeight(ch) - ((m_pcEncTop->getPad(1) >> 1) >> apcPicRecFields[0]->getComponentScaleY(ch));
3957
3958    Int   iSize   = iWidth*iHeight;
3959
3960    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3961    {
3962      TComPic *pcPic=apcPicOrgFields[fieldNum];
3963      TComPicYuv *pcPicD=apcPicRecFields[fieldNum];
3964
3965      const Pel*  pOrg    = (conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg()->getAddr(ch) : pcPic ->getPicYuvOrg()->getAddr(ch);
3966      Pel*  pRec    = pcPicD->getAddr(ch);
3967      const Int   iStride = pcPicD->getStride(ch);
3968
3969
3970      for(Int y = 0; y < iHeight; y++ )
3971      {
3972        for(Int x = 0; x < iWidth; x++ )
3973        {
3974          Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3975          uiSSDtemp   += iDiff * iDiff;
3976        }
3977        pOrg += iStride;
3978        pRec += iStride;
3979      }
3980    }
3981    const Int maxval = 255 << (g_bitDepth[toChannelType(ch)] - 8);
3982    const Double fRefValue = (Double) maxval * maxval * iSize*2;
3983    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3984    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize*2);
3985  }
3986
3987  UInt uibits = 0; // the number of bits for the pair is not calculated here - instead the overall total is used elsewhere.
3988
3989  //===== add PSNR =====
3990  m_gcAnalyzeAll_in.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3991
3992  printf("\n                                      Interlaced frame %d: [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", pcPicOrgSecondField->getPOC()/2 , dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
3993  if (printFrameMSE)
3994  {
3995    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3996  }
3997
3998  for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3999  {
4000    cscd[fieldNum].destroy();
4001  }
4002}
4003
4004/** Function for deciding the nal_unit_type.
4005 * \param pocCurr POC of the current picture
4006 * \returns the nal unit type of the picture
4007 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
4008 */
4009NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR, Bool isField)
4010{
4011  if (pocCurr == 0)
4012  {
4013    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
4014  }
4015
4016#if EFFICIENT_FIELD_IRAP
4017  if(isField && pocCurr == 1)
4018  {
4019    // to avoid the picture becoming an IRAP
4020    return NAL_UNIT_CODED_SLICE_TRAIL_R;
4021  }
4022#endif
4023
4024#if ALLOW_RECOVERY_POINT_AS_RAP
4025  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
4026#else
4027  if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
4028#endif
4029  {
4030    if (m_pcCfg->getDecodingRefreshType() == 1)
4031    {
4032      return NAL_UNIT_CODED_SLICE_CRA;
4033    }
4034    else if (m_pcCfg->getDecodingRefreshType() == 2)
4035    {
4036      return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
4037    }
4038  }
4039
4040#if POC_RESET_IDC_ENCODER
4041  if(m_pocCraWithoutReset > 0 && this->m_associatedIRAPType == NAL_UNIT_CODED_SLICE_CRA)
4042  {
4043    if(pocCurr < m_pocCraWithoutReset)
4044#else
4045  if(m_pocCRA>0)
4046  {
4047    if(pocCurr<m_pocCRA)
4048#endif
4049    {
4050      // All leading pictures are being marked as TFD pictures here since current encoder uses all
4051      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
4052      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
4053      // controlling the reference pictures used for encoding that leading picture. Such a leading
4054      // picture need not be marked as a TFD picture.
4055      return NAL_UNIT_CODED_SLICE_RASL_R;
4056    }
4057  }
4058  if (lastIDR>0)
4059  {
4060    if (pocCurr < lastIDR)
4061    {
4062      return NAL_UNIT_CODED_SLICE_RADL_R;
4063    }
4064  }
4065  return NAL_UNIT_CODED_SLICE_TRAIL_R;
4066}
4067
4068Double TEncGOP::xCalculateRVM()
4069{
4070  Double dRVM = 0;
4071
4072  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
4073  {
4074    // calculate RVM only for lowdelay configurations
4075    std::vector<Double> vRL , vB;
4076    size_t N = m_vRVM_RP.size();
4077    vRL.resize( N );
4078    vB.resize( N );
4079
4080    Int i;
4081    Double dRavg = 0 , dBavg = 0;
4082    vB[RVM_VCEGAM10_M] = 0;
4083    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
4084    {
4085      vRL[i] = 0;
4086      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
4087        vRL[i] += m_vRVM_RP[j];
4088      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
4089      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
4090      dRavg += m_vRVM_RP[i];
4091      dBavg += vB[i];
4092    }
4093
4094    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
4095    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
4096
4097    Double dSigamB = 0;
4098    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
4099    {
4100      Double tmp = vB[i] - dBavg;
4101      dSigamB += tmp * tmp;
4102    }
4103    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
4104
4105    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
4106
4107    dRVM = dSigamB / dRavg * f;
4108  }
4109
4110  return( dRVM );
4111}
4112
4113/** Attaches the input bitstream to the stream in the output NAL unit
4114    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
4115 *  \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu
4116 *  \param rNalu          target NAL unit
4117 */
4118Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream* codedSliceData)
4119{
4120  // Byte-align
4121  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
4122
4123  // Perform bitstream concatenation
4124  if (codedSliceData->getNumberOfWrittenBits() > 0)
4125  {
4126    rNalu.m_Bitstream.addSubstream(codedSliceData);
4127  }
4128
4129  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
4130
4131  codedSliceData->clear();
4132}
4133
4134// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
4135// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
4136Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
4137{
4138  TComReferencePictureSet *rps = pcSlice->getRPS();
4139  if(!rps->getNumberOfLongtermPictures())
4140  {
4141    return;
4142  }
4143
4144  // Arrange long-term reference pictures in the correct order of LSB and MSB,
4145  // and assign values for pocLSBLT and MSB present flag
4146  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
4147  Int longtermPicsMSB[MAX_NUM_REF_PICS];
4148  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
4149  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
4150  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
4151  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
4152  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
4153  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
4154
4155  // Get the long-term reference pictures
4156  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
4157  Int i, ctr = 0;
4158  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
4159  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
4160  {
4161    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
4162    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
4163    indices[ctr]      = i;
4164    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
4165  }
4166  Int numLongPics = rps->getNumberOfLongtermPictures();
4167  assert(ctr == numLongPics);
4168
4169  // Arrange pictures in decreasing order of MSB;
4170  for(i = 0; i < numLongPics; i++)
4171  {
4172    for(Int j = 0; j < numLongPics - 1; j++)
4173    {
4174      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
4175      {
4176        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
4177        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
4178        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
4179        std::swap(indices[j]        , indices[j+1]        );
4180      }
4181    }
4182  }
4183
4184  for(i = 0; i < numLongPics; i++)
4185  {
4186    // Check if MSB present flag should be enabled.
4187    // Check if the buffer contains any pictures that have the same LSB.
4188    TComList<TComPic*>::iterator  iterPic = rcListPic.begin();
4189    TComPic*                      pcPic;
4190    while ( iterPic != rcListPic.end() )
4191    {
4192      pcPic = *iterPic;
4193      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
4194                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
4195                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
4196      {
4197        mSBPresentFlag[i] = true;
4198        break;
4199      }
4200      iterPic++;
4201    }
4202  }
4203
4204  // tempArray for usedByCurr flag
4205  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
4206  for(i = 0; i < numLongPics; i++)
4207  {
4208    tempArray[i] = rps->getUsed(indices[i]);
4209  }
4210  // Now write the final values;
4211  ctr = 0;
4212  Int currMSB = 0, currLSB = 0;
4213  // currPicPoc = currMSB + currLSB
4214  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB);
4215  currMSB = pcSlice->getPOC() - currLSB;
4216
4217  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
4218  {
4219    rps->setPOC                   (i, longtermPicsPoc[ctr]);
4220    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
4221    rps->setUsed                  (i, tempArray[ctr]);
4222    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
4223    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
4224    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);
4225
4226    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
4227  }
4228  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
4229  {
4230    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
4231    {
4232      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
4233      // don't have to check the MSB present flag values for this constraint.
4234      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
4235    }
4236  }
4237}
4238
4239/** Function for finding the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
4240 * \param accessUnit Access Unit of the current picture
4241 * This function finds the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
4242 */
4243Int TEncGOP::xGetFirstSeiLocation(AccessUnit &accessUnit)
4244{
4245  // Find the location of the first SEI message
4246  Int seiStartPos = 0;
4247  for(AccessUnit::iterator it = accessUnit.begin(); it != accessUnit.end(); it++, seiStartPos++)
4248  {
4249     if ((*it)->isSei() || (*it)->isVcl())
4250     {
4251       break;
4252     }
4253  }
4254  //  assert(it != accessUnit.end());  // Triggers with some legit configurations
4255  return seiStartPos;
4256}
4257
4258Void TEncGOP::dblMetric( TComPic* pcPic, UInt uiNumSlices )
4259{
4260  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
4261  Pel* Rec    = pcPicYuvRec->getAddr(COMPONENT_Y);
4262  Pel* tempRec = Rec;
4263  Int  stride = pcPicYuvRec->getStride(COMPONENT_Y);
4264  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
4265  UInt maxTBsize = (1<<log2maxTB);
4266  const UInt minBlockArtSize = 8;
4267  const UInt picWidth = pcPicYuvRec->getWidth(COMPONENT_Y);
4268  const UInt picHeight = pcPicYuvRec->getHeight(COMPONENT_Y);
4269  const UInt noCol = (picWidth>>log2maxTB);
4270  const UInt noRows = (picHeight>>log2maxTB);
4271  assert(noCol > 1);
4272  assert(noRows > 1);
4273  UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64));
4274  UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64));
4275  UInt colIdx = 0;
4276  UInt rowIdx = 0;
4277  Pel p0, p1, p2, q0, q1, q2;
4278
4279  Int qp = pcPic->getSlice(0)->getSliceQp();
4280  Int bitdepthScale = 1 << (g_bitDepth[CHANNEL_TYPE_LUMA]-8);
4281  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
4282  const Int thr2 = (beta>>2);
4283  const Int thr1 = 2*bitdepthScale;
4284  UInt a = 0;
4285
4286  memset(colSAD, 0, noCol*sizeof(UInt64));
4287  memset(rowSAD, 0, noRows*sizeof(UInt64));
4288
4289  if (maxTBsize > minBlockArtSize)
4290  {
4291    // Analyze vertical artifact edges
4292    for(Int c = maxTBsize; c < picWidth; c += maxTBsize)
4293    {
4294      for(Int r = 0; r < picHeight; r++)
4295      {
4296        p2 = Rec[c-3];
4297        p1 = Rec[c-2];
4298        p0 = Rec[c-1];
4299        q0 = Rec[c];
4300        q1 = Rec[c+1];
4301        q2 = Rec[c+2];
4302        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
4303        if ( thr1 < a && a < thr2)
4304        {
4305          colSAD[colIdx] += abs(p0 - q0);
4306        }
4307        Rec += stride;
4308      }
4309      colIdx++;
4310      Rec = tempRec;
4311    }
4312
4313    // Analyze horizontal artifact edges
4314    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
4315    {
4316      for(Int c = 0; c < picWidth; c++)
4317      {
4318        p2 = Rec[c + (r-3)*stride];
4319        p1 = Rec[c + (r-2)*stride];
4320        p0 = Rec[c + (r-1)*stride];
4321        q0 = Rec[c + r*stride];
4322        q1 = Rec[c + (r+1)*stride];
4323        q2 = Rec[c + (r+2)*stride];
4324        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
4325        if (thr1 < a && a < thr2)
4326        {
4327          rowSAD[rowIdx] += abs(p0 - q0);
4328        }
4329      }
4330      rowIdx++;
4331    }
4332  }
4333
4334  UInt64 colSADsum = 0;
4335  UInt64 rowSADsum = 0;
4336  for(Int c = 0; c < noCol-1; c++)
4337  {
4338    colSADsum += colSAD[c];
4339  }
4340  for(Int r = 0; r < noRows-1; r++)
4341  {
4342    rowSADsum += rowSAD[r];
4343  }
4344
4345  colSADsum <<= 10;
4346  rowSADsum <<= 10;
4347  colSADsum /= (noCol-1);
4348  colSADsum /= picHeight;
4349  rowSADsum /= (noRows-1);
4350  rowSADsum /= picWidth;
4351
4352  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
4353  avgSAD >>= (g_bitDepth[CHANNEL_TYPE_LUMA]-8);
4354
4355  if ( avgSAD > 2048 )
4356  {
4357    avgSAD >>= 9;
4358    Int offset = Clip3(2,6,(Int)avgSAD);
4359    for (Int i=0; i<uiNumSlices; i++)
4360    {
4361      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
4362      pcPic->getSlice(i)->setDeblockingFilterDisable(false);
4363      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset );
4364      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset );
4365    }
4366  }
4367  else
4368  {
4369    for (Int i=0; i<uiNumSlices; i++)
4370    {
4371      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
4372      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
4373      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
4374      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
4375    }
4376  }
4377
4378  free(colSAD);
4379  free(rowSAD);
4380}
4381
4382#if P0123_ALPHA_CHANNEL_SEI
4383SEIAlphaChannelInfo* TEncGOP::xCreateSEIAlphaChannelInfo()
4384{
4385  SEIAlphaChannelInfo *sei = new SEIAlphaChannelInfo();
4386  sei->m_alphaChannelCancelFlag = m_pcCfg->getAlphaCancelFlag();
4387  if(!sei->m_alphaChannelCancelFlag)
4388  {
4389    sei->m_alphaChannelUseIdc = m_pcCfg->getAlphaUseIdc();
4390    sei->m_alphaChannelBitDepthMinus8 = m_pcCfg->getAlphaBitDepthMinus8();
4391    sei->m_alphaTransparentValue = m_pcCfg->getAlphaTransparentValue();
4392    sei->m_alphaOpaqueValue = m_pcCfg->getAlphaOpaqueValue();
4393    sei->m_alphaChannelIncrFlag = m_pcCfg->getAlphaIncrementFlag();
4394    sei->m_alphaChannelClipFlag = m_pcCfg->getAlphaClipFlag();
4395    sei->m_alphaChannelClipTypeFlag = m_pcCfg->getAlphaClipTypeFlag();
4396  }
4397  return sei;
4398}
4399#endif
4400#if Q0096_OVERLAY_SEI
4401SEIOverlayInfo* TEncGOP::xCreateSEIOverlayInfo()
4402{ 
4403  SEIOverlayInfo *sei = new SEIOverlayInfo(); 
4404  sei->m_overlayInfoCancelFlag = m_pcCfg->getOverlaySEICancelFlag();   
4405  if ( !sei->m_overlayInfoCancelFlag )
4406  {
4407    sei->m_overlayContentAuxIdMinus128          = m_pcCfg->getOverlaySEIContentAuxIdMinus128(); 
4408    sei->m_overlayLabelAuxIdMinus128            = m_pcCfg->getOverlaySEILabelAuxIdMinus128(); 
4409    sei->m_overlayAlphaAuxIdMinus128            = m_pcCfg->getOverlaySEIAlphaAuxIdMinus128(); 
4410    sei->m_overlayElementLabelValueLengthMinus8 = m_pcCfg->getOverlaySEIElementLabelValueLengthMinus8(); 
4411    sei->m_numOverlaysMinus1                    = m_pcCfg->getOverlaySEINumOverlaysMinus1();     
4412    sei->m_overlayIdx                           = m_pcCfg->getOverlaySEIIdx();           
4413    sei->m_languageOverlayPresentFlag           = m_pcCfg->getOverlaySEILanguagePresentFlag();
4414    sei->m_overlayContentLayerId                = m_pcCfg->getOverlaySEIContentLayerId();   
4415    sei->m_overlayLabelPresentFlag              = m_pcCfg->getOverlaySEILabelPresentFlag();   
4416    sei->m_overlayLabelLayerId                  = m_pcCfg->getOverlaySEILabelLayerId();   
4417    sei->m_overlayAlphaPresentFlag              = m_pcCfg->getOverlaySEIAlphaPresentFlag();   
4418    sei->m_overlayAlphaLayerId                  = m_pcCfg->getOverlaySEIAlphaLayerId();   
4419    sei->m_numOverlayElementsMinus1             = m_pcCfg->getOverlaySEINumElementsMinus1();
4420    sei->m_overlayElementLabelMin               = m_pcCfg->getOverlaySEIElementLabelMin();
4421    sei->m_overlayElementLabelMax               = m_pcCfg->getOverlaySEIElementLabelMax();   
4422    sei->m_overlayLanguage.resize               ( sei->m_numOverlaysMinus1+1, NULL );
4423    sei->m_overlayLanguageLength.resize         ( sei->m_numOverlaysMinus1+1 );
4424    sei->m_overlayName.resize                   ( sei->m_numOverlaysMinus1+1, NULL );
4425    sei->m_overlayNameLength.resize             ( sei->m_numOverlaysMinus1+1 );
4426    sei->m_overlayElementName.resize            ( sei->m_numOverlaysMinus1+1 );
4427    sei->m_overlayElementNameLength.resize      ( sei->m_numOverlaysMinus1+1 ); 
4428
4429    Int i,j;
4430    string strTmp;
4431    Int nBytes;
4432    assert( m_pcCfg->getOverlaySEILanguage().size()    == sei->m_numOverlaysMinus1+1 );
4433    assert( m_pcCfg->getOverlaySEIName().size()        == sei->m_numOverlaysMinus1+1 );
4434    assert( m_pcCfg->getOverlaySEIElementName().size() == sei->m_numOverlaysMinus1+1 );
4435   
4436    for ( i=0 ; i<=sei->m_numOverlaysMinus1; i++ )
4437    {     
4438      //language tag
4439      if ( sei->m_languageOverlayPresentFlag[i] )
4440      {               
4441        strTmp = m_pcCfg->getOverlaySEILanguage()[i];
4442        nBytes = m_pcCfg->getOverlaySEILanguage()[i].size();       
4443        assert( nBytes>0 );
4444        sei->m_overlayLanguage[i] = new UChar[nBytes];
4445        memcpy(sei->m_overlayLanguage[i], strTmp.c_str(), nBytes);       
4446        sei->m_overlayLanguageLength[i] = nBytes;       
4447      }
4448
4449      //overlay name
4450      strTmp = m_pcCfg->getOverlaySEIName()[i];
4451      nBytes = m_pcCfg->getOverlaySEIName()[i].size();       
4452      assert( nBytes>0 );
4453      sei->m_overlayName[i] = new UChar[nBytes];     
4454      memcpy(sei->m_overlayName[i], strTmp.c_str(), nBytes);       
4455      sei->m_overlayNameLength[i] = nBytes;
4456
4457      //overlay element names
4458      if ( sei->m_overlayLabelPresentFlag[i] )
4459      {       
4460        sei->m_overlayElementName[i].resize( sei->m_numOverlayElementsMinus1[i]+1, NULL );
4461        sei->m_overlayElementNameLength[i].resize( sei->m_numOverlayElementsMinus1[i]+1 );
4462        assert( m_pcCfg->getOverlaySEIElementName()[i].size() == sei->m_numOverlayElementsMinus1[i]+1 );       
4463        for ( j=0 ; j<=sei->m_numOverlayElementsMinus1[i] ; j++)
4464        {
4465          strTmp = m_pcCfg->getOverlaySEIElementName()[i][j];
4466          nBytes = m_pcCfg->getOverlaySEIElementName()[i][j].size();       
4467          assert( nBytes>0 );
4468          sei->m_overlayElementName[i][j] = new UChar[nBytes];
4469          memcpy(sei->m_overlayElementName[i][j], strTmp.c_str(), nBytes);       
4470          sei->m_overlayElementNameLength[i][j] = nBytes;
4471        }
4472      }
4473    }
4474  sei->m_overlayInfoPersistenceFlag = true;
4475  }
4476  return sei;
4477}
4478#endif
4479
4480#if Q0074_COLOUR_REMAPPING_SEI
4481SEIColourRemappingInfo*  TEncGOP::xCreateSEIColourRemappingInfo()
4482{
4483  SEIColourRemappingInfo *seiColourRemappingInfo = new SEIColourRemappingInfo();
4484  seiColourRemappingInfo->m_colourRemapId         = m_pcCfg->getCRISEIId();
4485  seiColourRemappingInfo->m_colourRemapCancelFlag = m_pcCfg->getCRISEICancelFlag();
4486  if( !seiColourRemappingInfo->m_colourRemapCancelFlag )
4487  {
4488    seiColourRemappingInfo->m_colourRemapPersistenceFlag            = m_pcCfg->getCRISEIPersistenceFlag();
4489    seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag = m_pcCfg->getCRISEIVideoSignalInfoPresentFlag();
4490    if( seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag )
4491    {
4492      seiColourRemappingInfo->m_colourRemapFullRangeFlag           = m_pcCfg->getCRISEIFullRangeFlag();
4493      seiColourRemappingInfo->m_colourRemapPrimaries               = m_pcCfg->getCRISEIPrimaries();
4494      seiColourRemappingInfo->m_colourRemapTransferFunction        = m_pcCfg->getCRISEITransferFunction();
4495      seiColourRemappingInfo->m_colourRemapMatrixCoefficients      = m_pcCfg->getCRISEIMatrixCoefficients();
4496    }
4497    seiColourRemappingInfo->m_colourRemapInputBitDepth             = m_pcCfg->getCRISEIInputBitDepth();
4498    seiColourRemappingInfo->m_colourRemapBitDepth                  = m_pcCfg->getCRISEIBitDepth();
4499    for( Int c=0 ; c<3 ; c++ )
4500    {
4501      seiColourRemappingInfo->m_preLutNumValMinus1[c] = m_pcCfg->getCRISEIPreLutNumValMinus1(c);
4502      if( seiColourRemappingInfo->m_preLutNumValMinus1[c]>0 )
4503      {
4504        seiColourRemappingInfo->m_preLutCodedValue[c].resize(seiColourRemappingInfo->m_preLutNumValMinus1[c]+1);
4505        seiColourRemappingInfo->m_preLutTargetValue[c].resize(seiColourRemappingInfo->m_preLutNumValMinus1[c]+1);
4506        for( Int i=0 ; i<=seiColourRemappingInfo->m_preLutNumValMinus1[c] ; i++)
4507        {
4508          seiColourRemappingInfo->m_preLutCodedValue[c][i]  = (m_pcCfg->getCRISEIPreLutCodedValue(c))[i];
4509          seiColourRemappingInfo->m_preLutTargetValue[c][i] = (m_pcCfg->getCRISEIPreLutTargetValue(c))[i];
4510        }
4511      }
4512    }
4513    seiColourRemappingInfo->m_colourRemapMatrixPresentFlag = m_pcCfg->getCRISEIMatrixPresentFlag();
4514    if( seiColourRemappingInfo->m_colourRemapMatrixPresentFlag )
4515    {
4516      seiColourRemappingInfo->m_log2MatrixDenom = m_pcCfg->getCRISEILog2MatrixDenom();
4517      for( Int c=0 ; c<3 ; c++ )
4518        for( Int i=0 ; i<3 ; i++ )
4519          seiColourRemappingInfo->m_colourRemapCoeffs[c][i] = (m_pcCfg->getCRISEICoeffs(c))[i];
4520    }
4521    for( Int c=0 ; c<3 ; c++ )
4522    {
4523      seiColourRemappingInfo->m_postLutNumValMinus1[c] = m_pcCfg->getCRISEIPostLutNumValMinus1(c);
4524      if( seiColourRemappingInfo->m_postLutNumValMinus1[c]>0 )
4525      {
4526        seiColourRemappingInfo->m_postLutCodedValue[c].resize(seiColourRemappingInfo->m_postLutNumValMinus1[c]+1);
4527        seiColourRemappingInfo->m_postLutTargetValue[c].resize(seiColourRemappingInfo->m_postLutNumValMinus1[c]+1);
4528        for( Int i=0 ; i<=seiColourRemappingInfo->m_postLutNumValMinus1[c] ; i++)
4529        {
4530          seiColourRemappingInfo->m_postLutCodedValue[c][i]  = (m_pcCfg->getCRISEIPostLutCodedValue(c))[i];
4531          seiColourRemappingInfo->m_postLutTargetValue[c][i] = (m_pcCfg->getCRISEIPostLutTargetValue(c))[i];
4532        }
4533      }
4534    }
4535  }
4536  return seiColourRemappingInfo;
4537}
4538#endif
4539
4540#if SVC_EXTENSION
4541#if LAYERS_NOT_PRESENT_SEI
4542SEILayersNotPresent* TEncGOP::xCreateSEILayersNotPresent ()
4543{
4544  UInt i = 0;
4545  SEILayersNotPresent *seiLayersNotPresent = new SEILayersNotPresent(); 
4546  seiLayersNotPresent->m_activeVpsId = m_pcCfg->getVPS()->getVPSId(); 
4547  seiLayersNotPresent->m_vpsMaxLayers = m_pcCfg->getVPS()->getMaxLayers();
4548  for ( ; i < seiLayersNotPresent->m_vpsMaxLayers; i++)
4549  {
4550    seiLayersNotPresent->m_layerNotPresentFlag[i] = true; 
4551  }
4552  for ( ; i < MAX_LAYERS; i++)
4553  {
4554    seiLayersNotPresent->m_layerNotPresentFlag[i] = false; 
4555  }
4556  return seiLayersNotPresent;
4557}
4558#endif
4559
4560#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
4561SEIInterLayerConstrainedTileSets* TEncGOP::xCreateSEIInterLayerConstrainedTileSets()
4562{
4563  SEIInterLayerConstrainedTileSets *seiInterLayerConstrainedTileSets = new SEIInterLayerConstrainedTileSets();
4564  seiInterLayerConstrainedTileSets->m_ilAllTilesExactSampleValueMatchFlag = false;
4565  seiInterLayerConstrainedTileSets->m_ilOneTilePerTileSetFlag = false;
4566  if (!seiInterLayerConstrainedTileSets->m_ilOneTilePerTileSetFlag)
4567  {
4568    seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1 = m_pcCfg->getIlNumSetsInMessage() - 1;
4569    if (seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1)
4570    {
4571      seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag = m_pcCfg->getSkippedTileSetPresentFlag();
4572    }
4573    else
4574    {
4575      seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag = false;
4576    }
4577    seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1 += seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag ? 1 : 0;
4578    for (UInt i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
4579    {
4580      seiInterLayerConstrainedTileSets->m_ilctsId[i] = i;
4581      seiInterLayerConstrainedTileSets->m_ilNumTileRectsInSetMinus1[i] = 0;
4582      for( UInt j = 0; j <= seiInterLayerConstrainedTileSets->m_ilNumTileRectsInSetMinus1[i]; j++)
4583      {
4584        seiInterLayerConstrainedTileSets->m_ilTopLeftTileIndex[i][j]     = m_pcCfg->getTopLeftTileIndex(i);
4585        seiInterLayerConstrainedTileSets->m_ilBottomRightTileIndex[i][j] = m_pcCfg->getBottomRightTileIndex(i);
4586      }
4587      seiInterLayerConstrainedTileSets->m_ilcIdc[i] = m_pcCfg->getIlcIdc(i);
4588      if (seiInterLayerConstrainedTileSets->m_ilAllTilesExactSampleValueMatchFlag)
4589      {
4590        seiInterLayerConstrainedTileSets->m_ilExactSampleValueMatchFlag[i] = false;
4591      }
4592    }
4593  }
4594
4595  return seiInterLayerConstrainedTileSets;
4596}
4597
4598Void TEncGOP::xBuildTileSetsMap(TComPicSym* picSym)
4599{
4600  Int numCUs = picSym->getFrameWidthInCtus() * picSym->getFrameHeightInCtus();
4601
4602  for (Int i = 0; i < numCUs; i++)
4603  {
4604    picSym->setTileSetIdxMap(i, -1, 0, false);
4605  }
4606
4607  for (Int i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
4608  {
4609    const TComTile* topLeftTile     = picSym->getTComTile(m_pcCfg->getTopLeftTileIndex(i));
4610    TComTile* bottomRightTile = picSym->getTComTile(m_pcCfg->getBottomRightTileIndex(i));
4611    Int tileSetLeftEdgePosInCU = topLeftTile->getRightEdgePosInCtus() - topLeftTile->getTileWidthInCtus() + 1;
4612    Int tileSetRightEdgePosInCU = bottomRightTile->getRightEdgePosInCtus();
4613    Int tileSetTopEdgePosInCU = topLeftTile->getBottomEdgePosInCtus() - topLeftTile->getTileHeightInCtus() + 1;
4614    Int tileSetBottomEdgePosInCU = bottomRightTile->getBottomEdgePosInCtus();
4615    assert(tileSetLeftEdgePosInCU < tileSetRightEdgePosInCU && tileSetTopEdgePosInCU < tileSetBottomEdgePosInCU);
4616    for (Int j = tileSetTopEdgePosInCU; j <= tileSetBottomEdgePosInCU; j++)
4617    {
4618      for (Int k = tileSetLeftEdgePosInCU; k <= tileSetRightEdgePosInCU; k++)
4619      {
4620        picSym->setTileSetIdxMap(j * picSym->getFrameWidthInCtus() + k, i, m_pcCfg->getIlcIdc(i), false);
4621      }
4622    }
4623  }
4624 
4625  if (m_pcCfg->getSkippedTileSetPresentFlag())
4626  {
4627    Int skippedTileSetIdx = m_pcCfg->getIlNumSetsInMessage();
4628    for (Int i = 0; i < numCUs; i++)
4629    {
4630      if (picSym->getTileSetIdxMap(i) < 0)
4631      {
4632        picSym->setTileSetIdxMap(i, skippedTileSetIdx, 0, true);
4633      }
4634    }
4635  }
4636}
4637#endif
4638
4639
4640#if POC_RESET_IDC_ENCODER
4641Void TEncGOP::determinePocResetIdc(Int const pocCurr, TComSlice *const slice)
4642{
4643  // If one picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 1 or 2
4644  // If BL picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 2
4645  // If BL picture is IRAP, and another picture is non-IRAP, then the poc_reset_idc is equal to 1 or 2.
4646#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4647  slice->setPocMsbNeeded(false);
4648#endif
4649  if( slice->getSliceIdx() == 0 ) // First slice - compute, copy for other slices
4650  {
4651    Int needReset = false;
4652    Int resetDueToBL = false;
4653    if( slice->getVPS()->getMaxLayers() > 1 )
4654    {
4655      // If IRAP is refreshed in this access unit for base layer
4656      if( (m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 1 || m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2)
4657        && ( pocCurr % m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
4658        )
4659      {
4660        // Check if the IRAP refresh interval of any layer does not match that of the base layer
4661        for(Int i = 1; i < slice->getVPS()->getMaxLayers(); i++)
4662        {
4663          Bool refreshIntervalFlag = ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 );
4664          Bool refreshTypeFlag     = ( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() );
4665          if( !(refreshIntervalFlag && refreshTypeFlag) )
4666          {
4667            needReset = true;
4668            resetDueToBL = true;
4669            break;
4670          }
4671        }
4672      }
4673    }
4674   
4675    if( !needReset )// No need reset due to base layer IRAP
4676    {
4677      // Check if EL IDRs results in POC Reset
4678      for(Int i = 1; i < slice->getVPS()->getMaxLayers() && !needReset; i++)
4679      {
4680        Bool idrFlag = ( (m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() == 2) 
4681                        && ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
4682                        );
4683        for(Int j = 0; j < slice->getVPS()->getMaxLayers(); j++)
4684        {
4685          if( j == i )
4686          {
4687            continue;
4688          }
4689          Bool idrOtherPicFlag = ( (m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshType() == 2) 
4690                                  && ( pocCurr % m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
4691                                  );
4692
4693          if( idrFlag != idrOtherPicFlag )
4694          {
4695            needReset = true;
4696            break;
4697          }
4698        }
4699      }
4700    }
4701    if( needReset )
4702    {
4703      if( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2 )  // BL IDR refresh, assuming BL picture present
4704      {
4705        if( resetDueToBL )
4706        {
4707          slice->setPocResetIdc( 2 ); // Full reset needed
4708#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4709          if (slice->getVPS()->getVpsPocLsbAlignedFlag() && slice->getVPS()->getNumDirectRefLayers(slice->getLayerId()) == 0)
4710          {
4711            slice->setPocMsbNeeded(true);  // Force msb writing
4712          }
4713#endif
4714        }
4715        else
4716        {
4717          slice->setPocResetIdc( 1 ); // Due to IDR in EL
4718        }
4719      }
4720      else
4721      {
4722        slice->setPocResetIdc( 1 ); // Only MSB reset
4723      }
4724
4725      // Start a new POC reset period
4726      if (m_layerId == 0)   // Assuming BL picture is always present at encoder; for other AU structures, need to change this
4727      {
4728        Int periodId = rand() % 64;
4729        m_lastPocPeriodId = (periodId == m_lastPocPeriodId) ? (periodId + 1) % 64 : periodId ;
4730
4731#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4732        for (UInt i = 0; i < MAX_LAYERS; i++)
4733        {
4734          m_ppcTEncTop[i]->setPocDecrementedInDPBFlag(false);
4735        }
4736#endif
4737      }
4738      else
4739      {
4740        m_lastPocPeriodId = m_ppcTEncTop[0]->getGOPEncoder()->getLastPocPeriodId();
4741      }
4742      slice->setPocResetPeriodId(m_lastPocPeriodId);
4743    }
4744    else
4745    {
4746      slice->setPocResetIdc( 0 );
4747    }
4748  }
4749}
4750
4751Void TEncGOP::updatePocValuesOfPics(Int const pocCurr, TComSlice *const slice)
4752{
4753#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4754  UInt affectedLayerList[MAX_NUM_LAYER_IDS];
4755  Int  numAffectedLayers;
4756
4757  affectedLayerList[0] = m_layerId;
4758  numAffectedLayers = 1;
4759
4760  if (m_pcEncTop->getVPS()->getVpsPocLsbAlignedFlag())
4761  {
4762    for (UInt j = 0; j < m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId); j++)
4763    {
4764      affectedLayerList[j + 1] = m_pcEncTop->getVPS()->getPredictedLayerId(m_layerId, j);
4765    }
4766    numAffectedLayers = m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId) + 1;
4767  }
4768#endif
4769
4770  Int pocAdjustValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4771
4772  // New POC reset period
4773  Int maxPocLsb, pocLsbVal, pocMsbDelta, pocLsbDelta, deltaPocVal;
4774
4775  maxPocLsb   = 1 << slice->getSPS()->getBitsForPOC();
4776
4777#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4778  Int adjustedPocValue = pocCurr;
4779
4780  if (m_pcEncTop->getFirstPicInLayerDecodedFlag())
4781  {
4782#endif
4783
4784  pocLsbVal   = (slice->getPocResetIdc() == 3)
4785                ? slice->getPocLsbVal()
4786                : pocAdjustValue % maxPocLsb; 
4787  pocMsbDelta = pocAdjustValue - pocLsbVal;
4788  pocLsbDelta = (slice->getPocResetIdc() == 2 || ( slice->getPocResetIdc() == 3 && slice->getFullPocResetFlag() )) 
4789                ? pocLsbVal 
4790                : 0; 
4791  deltaPocVal = pocMsbDelta  + pocLsbDelta;
4792
4793#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4794  Int origDeltaPocVal = deltaPocVal;  // original value needed when updating POC adjustment value
4795
4796  if (slice->getPocMsbNeeded())  // IDR picture in base layer, non-IDR picture in other layers, poc_lsb_aligned_flag = 1
4797  {
4798    if (slice->getLayerId() == 0)
4799    {
4800      Int highestPoc = INT_MIN;
4801      // Find greatest POC in DPB for layer 0
4802      for (TComList<TComPic*>::iterator iterPic = m_pcEncTop->getListPic()->begin(); iterPic != m_pcEncTop->getListPic()->end(); ++iterPic)
4803      {
4804        TComPic *dpbPic = *iterPic;
4805        if (dpbPic->getReconMark() && dpbPic->getLayerId() == 0 && dpbPic->getPOC() > highestPoc)
4806        {
4807          highestPoc = dpbPic->getPOC();
4808        }
4809      }
4810      deltaPocVal = (highestPoc - (highestPoc & (maxPocLsb - 1))) + 1*maxPocLsb;
4811      m_pcEncTop->setCurrPocMsb(deltaPocVal);
4812    }
4813    else
4814    {
4815      deltaPocVal = m_ppcTEncTop[0]->getCurrPocMsb();  // copy from base layer
4816    }
4817    slice->setPocMsbVal(deltaPocVal);
4818  }
4819
4820  for (UInt layerIdx = 0; layerIdx < numAffectedLayers; layerIdx++)
4821  {
4822    if (!m_ppcTEncTop[affectedLayerList[layerIdx]]->getPocDecrementedInDPBFlag())
4823    {
4824      m_ppcTEncTop[affectedLayerList[layerIdx]]->setPocDecrementedInDPBFlag(true);
4825
4826      // Decrement value of associatedIrapPoc of the TEncGop object
4827      m_ppcTEncTop[affectedLayerList[layerIdx]]->getGOPEncoder()->m_associatedIRAPPOC -= deltaPocVal;
4828
4829      // Decrememnt the value of m_pocCRA
4830      m_ppcTEncTop[affectedLayerList[layerIdx]]->getGOPEncoder()->m_pocCRA -= deltaPocVal;
4831
4832      TComList<TComPic*>::iterator  iterPic = m_ppcTEncTop[affectedLayerList[layerIdx]]->getListPic()->begin();
4833      while (iterPic != m_ppcTEncTop[affectedLayerList[layerIdx]]->getListPic()->end())
4834#else
4835  // Decrement value of associatedIrapPoc of the TEncGop object
4836  this->m_associatedIRAPPOC -= deltaPocVal;
4837
4838  // Decrememnt the value of m_pocCRA
4839  this->m_pocCRA -= deltaPocVal;
4840
4841  // Iterate through all pictures in the DPB
4842  TComList<TComPic*>::iterator  iterPic = getListPic()->begin(); 
4843  while( iterPic != getListPic()->end() )
4844#endif
4845  {
4846    TComPic *dpbPic = *iterPic;
4847   
4848    if( dpbPic->getReconMark() )
4849    {
4850      for(Int i = dpbPic->getNumAllocatedSlice() - 1; i >= 0; i--)
4851      {
4852        TComSlice *dpbPicSlice = dpbPic->getSlice( i );
4853        TComReferencePictureSet *dpbPicRps = dpbPicSlice->getRPS();
4854
4855        // Decrement POC of slice
4856        dpbPicSlice->setPOC( dpbPicSlice->getPOC() - deltaPocVal );
4857
4858        // Decrement POC value stored in the RPS of each such slice
4859        for( Int j = dpbPicRps->getNumberOfPictures() - 1; j >= 0; j-- )
4860        {
4861          dpbPicRps->setPOC( j, dpbPicRps->getPOC(j) - deltaPocVal );
4862        }
4863
4864        // Decrement value of refPOC
4865        dpbPicSlice->decrementRefPocValues( deltaPocVal );
4866
4867        // Update value of associatedIrapPoc of each slice
4868        dpbPicSlice->setAssociatedIRAPPOC( dpbPicSlice->getAssociatedIRAPPOC() - deltaPocVal );
4869
4870#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4871        if (slice->getPocMsbNeeded())
4872        {
4873          // this delta value is needed when computing delta POCs in reference picture set initialization
4874          dpbPicSlice->setPocResetDeltaPoc(dpbPicSlice->getPocResetDeltaPoc() + (deltaPocVal - pocLsbVal));
4875        }
4876#endif
4877      }
4878    }
4879    iterPic++;
4880  }
4881#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4882    }
4883  }
4884#endif
4885
4886  // Actual POC value before reset
4887#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4888  adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4889#else
4890  Int adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4891#endif
4892
4893  // Set MSB value before reset
4894  Int tempLsbVal = adjustedPocValue & (maxPocLsb - 1);
4895#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4896  if (!slice->getPocMsbNeeded())  // set poc msb normally if special msb handling is not needed
4897  {
4898#endif
4899    slice->setPocMsbVal(adjustedPocValue - tempLsbVal);
4900#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4901  }
4902#endif
4903
4904  // Set LSB value before reset - this is needed in the case of resetIdc = 2
4905  slice->setPicOrderCntLsb( tempLsbVal );
4906
4907  // Cumulative delta
4908#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4909  deltaPocVal = origDeltaPocVal;  // restore deltaPoc for correct adjustment value update
4910#endif
4911  m_pcEncTop->setPocAdjustmentValue( m_pcEncTop->getPocAdjustmentValue() + deltaPocVal );
4912
4913#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4914  }
4915#endif
4916
4917  // New LSB value, after reset
4918  adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4919  Int newLsbVal = adjustedPocValue & (maxPocLsb - 1);
4920
4921  // Set value of POC current picture after RESET
4922  if( slice->getPocResetIdc() == 1 )
4923  {
4924    slice->setPOC( newLsbVal );
4925  }
4926  else if( slice->getPocResetIdc() == 2 )
4927  {
4928    slice->setPOC( 0 );
4929  }
4930  else if( slice->getPocResetIdc() == 3 )
4931  {
4932    Int picOrderCntMsb = slice->getCurrMsb( newLsbVal, 
4933                                        slice->getFullPocResetFlag() ? 0 : slice->getPocLsbVal(), 
4934                                        0,
4935                                        maxPocLsb );
4936    slice->setPOC( picOrderCntMsb + newLsbVal );
4937  }
4938  else
4939  {
4940    assert(0);
4941  }
4942}
4943#endif
4944
4945
4946#if O0164_MULTI_LAYER_HRD
4947#if VPS_VUI_BSP_HRD_PARAMS
4948SEIScalableNesting* TEncGOP::xCreateBspNestingSEI(TComSlice *pcSlice, Int olsIdx, Int partitioningSchemeIdx, Int bspIdx)
4949#else
4950SEIScalableNesting* TEncGOP::xCreateBspNestingSEI(TComSlice *pcSlice)
4951#endif
4952{
4953  SEIScalableNesting *seiScalableNesting = new SEIScalableNesting();
4954  SEIBspInitialArrivalTime *seiBspInitialArrivalTime = new SEIBspInitialArrivalTime();
4955  SEIBspNesting *seiBspNesting = new SEIBspNesting();
4956  SEIBufferingPeriod *seiBufferingPeriod = new SEIBufferingPeriod();
4957
4958  // Scalable nesting SEI
4959
4960  seiScalableNesting->m_bitStreamSubsetFlag           = 1;      // If the nested SEI messages are picture buffereing SEI mesages, picure timing SEI messages or sub-picture timing SEI messages, bitstream_subset_flag shall be equal to 1
4961  seiScalableNesting->m_nestingOpFlag                 = 1;
4962  seiScalableNesting->m_defaultOpFlag                 = 0;
4963  seiScalableNesting->m_nestingNumOpsMinus1           = 0;      //nesting_num_ops_minus1
4964#if VPS_VUI_BSP_HRD_PARAMS
4965  seiScalableNesting->m_nestingOpIdx[0]               = pcSlice->getVPS()->getOutputLayerSetIdx(olsIdx);
4966  seiScalableNesting->m_nestingMaxTemporalIdPlus1[0]  = 6 + 1;
4967#else
4968  seiScalableNesting->m_nestingOpIdx[0]               = 1;
4969#endif
4970  seiScalableNesting->m_allLayersFlag                 = 0;
4971  seiScalableNesting->m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1;  //nesting_no_op_max_temporal_id_plus1
4972  seiScalableNesting->m_nestingNumLayersMinus1        = 1 - 1;  //nesting_num_layers_minus1
4973  seiScalableNesting->m_nestingLayerId[0]             = 0;
4974  seiScalableNesting->m_callerOwnsSEIs                = true;
4975
4976  // Bitstream partition nesting SEI
4977
4978  seiBspNesting->m_bspIdx = 0;
4979  seiBspNesting->m_callerOwnsSEIs = true;
4980
4981  // Buffering period SEI
4982
4983  UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
4984  seiBufferingPeriod->m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
4985  seiBufferingPeriod->m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
4986  seiBufferingPeriod->m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
4987  seiBufferingPeriod->m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
4988
4989  Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
4990
4991  UInt uiTmp = (UInt)( dTmp * 90000.0 ); 
4992  uiInitialCpbRemovalDelay -= uiTmp;
4993  uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
4994  seiBufferingPeriod->m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
4995  seiBufferingPeriod->m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
4996  seiBufferingPeriod->m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
4997  seiBufferingPeriod->m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
4998
4999  seiBufferingPeriod->m_rapCpbParamsPresentFlag              = 0;
5000  //for the concatenation, it can be set to one during splicing.
5001  seiBufferingPeriod->m_concatenationFlag = 0;
5002  //since the temporal layer HRD is not ready, we assumed it is fixed
5003  seiBufferingPeriod->m_auCpbRemovalDelayDelta = 1;
5004  seiBufferingPeriod->m_cpbDelayOffset = 0;
5005  seiBufferingPeriod->m_dpbDelayOffset = 0;
5006
5007  // Intial arrival time SEI message
5008
5009  seiBspInitialArrivalTime->m_nalInitialArrivalDelay[0] = 0;
5010  seiBspInitialArrivalTime->m_vclInitialArrivalDelay[0] = 0;
5011
5012
5013  seiBspNesting->m_nestedSEIs.push_back(seiBufferingPeriod);
5014  seiBspNesting->m_nestedSEIs.push_back(seiBspInitialArrivalTime);
5015#if VPS_VUI_BSP_HRD_PARAMS
5016  seiBspNesting->m_bspIdx = bspIdx;
5017  seiBspNesting->m_seiOlsIdx = olsIdx;
5018  seiBspNesting->m_seiPartitioningSchemeIdx = partitioningSchemeIdx;
5019#endif
5020  seiScalableNesting->m_nestedSEIs.push_back(seiBspNesting); // BSP nesting SEI is contained in scalable nesting SEI
5021
5022  return seiScalableNesting;
5023}
5024#endif
5025
5026#if Q0048_CGS_3D_ASYMLUT
5027Void TEncGOP::xDetermin3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS )
5028{
5029  Int nCGSFlag = pSlice->getPPS()->getCGSFlag();
5030  m_Enc3DAsymLUTPPS.setPPSBit( 0 );
5031  Double dErrorUpdatedPPS = 0 , dErrorPPS = 0;
5032
5033#if R0179_ENC_OPT_3DLUT_SIZE
5034  Int nTLthres = m_pcCfg->getCGSLutSizeRDO() ? 2:7;
5035  Double dFrameLambda; 
5036#if FULL_NBIT
5037  Int    SHIFT_QP = 12 + 6 * (pSlice->getBitDepthY() - 8);
5038#else
5039  Int    SHIFT_QP = 12; 
5040#endif
5041  Int QP = pSlice->getSliceQp();
5042
5043  // set frame lambda
5044  dFrameLambda = 0.68 * pow (2, (QP  - SHIFT_QP) / 3.0) * (m_pcCfg->getGOPSize() > 1 && pSlice->isInterB()? 2 : 1);
5045
5046  if(m_pcCfg->getCGSLutSizeRDO() == 1 && (!bSignalPPS && (pSlice->getDepth() < nTLthres))) 
5047    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB(), dFrameLambda );
5048  else if (pSlice->getDepth() >= nTLthres)
5049    dErrorUpdatedPPS = MAX_DOUBLE;
5050  else // if (m_pcCfg->getCGSLutSizeRDO() = 0 || bSignalPPS)
5051#endif   
5052    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB() );
5053
5054
5055  if( bSignalPPS )
5056  {
5057    m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
5058    pSlice->setCGSOverWritePPS( 1 ); // regular PPS update
5059  }
5060  else if( nCGSFlag )
5061  {
5062#if R0179_ENC_OPT_3DLUT_SIZE
5063    if(pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R || pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N) 
5064    {
5065      pSlice->setCGSOverWritePPS( 0 ); 
5066    }
5067    else if (pSlice->getDepth() >= nTLthres) 
5068    {
5069      pSlice->setCGSOverWritePPS( 0 ); 
5070    }
5071    else
5072    {
5073#endif   
5074      dErrorPPS = m_Enc3DAsymLUTPPS.estimateDistWithCur3DAsymLUT( pCurPic , refLayerIdc );
5075      Double dFactor = pCfg->getIntraPeriod() == 1 ? 0.99 : 0.9;
5076
5077#if R0179_ENC_OPT_3DLUT_SIZE
5078      if( m_pcCfg->getCGSLutSizeRDO() )
5079      {
5080        dErrorPPS = dErrorPPS/m_Enc3DAsymLUTPicUpdate.getDistFactor(pSlice->getSliceType(), pSlice->getDepth()); 
5081      }
5082#endif
5083      pSlice->setCGSOverWritePPS( dErrorUpdatedPPS < dFactor * dErrorPPS );
5084#if R0179_ENC_OPT_3DLUT_SIZE
5085    }
5086#endif
5087    if( pSlice->getCGSOverWritePPS() )
5088    {
5089      m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
5090    }
5091  }
5092  pSlice->getPPS()->setCGSOutputBitDepthY( m_Enc3DAsymLUTPPS.getOutputBitDepthY() );
5093  pSlice->getPPS()->setCGSOutputBitDepthC( m_Enc3DAsymLUTPPS.getOutputBitDepthC() );
5094}
5095
5096Void TEncGOP::downScalePic( TComPicYuv* pcYuvSrc, TComPicYuv* pcYuvDest)
5097{
5098  Int inputBitDepth  = g_bitDepthLayer[CHANNEL_TYPE_LUMA][m_layerId];
5099  Int outputBitDepth = g_bitDepthLayer[CHANNEL_TYPE_CHROMA][m_layerId];
5100  {
5101    pcYuvSrc->setBorderExtension(false);
5102    pcYuvSrc->extendPicBorder   (); // extend the border.
5103    pcYuvSrc->setBorderExtension(false);
5104
5105    Int iWidth  = pcYuvSrc->getWidth(COMPONENT_Y);
5106    Int iHeight = pcYuvSrc->getHeight(COMPONENT_Y); 
5107
5108    if(!m_temp)
5109    {
5110      initDs(iWidth, iHeight, m_pcCfg->getIntraPeriod()>1);
5111    }
5112
5113    filterImg(pcYuvSrc->getAddr(COMPONENT_Y),  pcYuvSrc->getStride(COMPONENT_Y),  pcYuvDest->getAddr(COMPONENT_Y),  pcYuvDest->getStride(COMPONENT_Y),  iHeight,    iWidth,    inputBitDepth-outputBitDepth, 0);
5114    filterImg(pcYuvSrc->getAddr(COMPONENT_Cb), pcYuvSrc->getStride(COMPONENT_Cb), pcYuvDest->getAddr(COMPONENT_Cb), pcYuvDest->getStride(COMPONENT_Cb), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 1);
5115    filterImg(pcYuvSrc->getAddr(COMPONENT_Cr), pcYuvSrc->getStride(COMPONENT_Cr), pcYuvDest->getAddr(COMPONENT_Cr), pcYuvDest->getStride(COMPONENT_Cr), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 2); 
5116  }
5117}
5118const Int TEncGOP::m_phase_filter_0_t0[4][13]={
5119  {0,  2,  -3,  -9,   6,  39,  58,  39,   6,  -9,  -3,  2,  0}, 
5120  {0, 0,  0,  -2,  8,-20, 116, 34, -10,  2,  0, 0,  0},                      //{0,  1,  -1,  -8,  -1,  31,  57,  47,  13,  -7,  -5,  1,  0},  //
5121  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
5122  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
5123};
5124
5125const Int TEncGOP::m_phase_filter_0_t1[4][13]={
5126  {0,  4,  0,  -12, 0,  40,  64,  40, 0, -12,  0,  4,  0},
5127  {0, 0,  0,  -2,  8,-20, 116,34,-10,  2,  0, 0,  0},                      //{0,  1,  -1,  -8,  -1,  31,  57,  47,  13,  -7,  -5,  1,  0},  //
5128  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
5129  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
5130};
5131const Int TEncGOP::m_phase_filter_0_t1_chroma[4][13]={
5132  {0,  0,  0,   0,  0,   0,  128, 0,  0,  0,  0,  0,  0},
5133  {0, 0,  0,  -2,  8,-20, 116,34,-10,  2,  0, 0,  0},                      //{0,  1,  -1,  -8,  -1,  31,  57,  47,  13,  -7,  -5,  1,  0},  //
5134  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
5135  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
5136};
5137
5138const Int TEncGOP::m_phase_filter_1[8][13]={
5139  {0,   0,  5,  -6,  -10,37,  76,  37,-10,   -6, 5,  0,   0},   
5140  {0,  -1,  5,  -3,  -12,29,  75,  45,  -7,   -8, 5,  0,   0},   
5141  {0,  -1,  4,  -1,  -13,22,  73,  52,  -3,  -10, 4,  1,   0},   
5142  {0,  -1,  4,   1,  -13,14,  70,  59,   2,  -12, 3,  2,  -1}, 
5143  {0,  -1,  3,   2,  -13, 8,  65,  65,   8,  -13, 2,  3,  -1},   
5144  {0,  -1,  2,   3,  -12, 2,  59,  70,  14,  -13, 1,  4,  -1},   
5145  {0,   0,  1,   4,  -10,-3,  52,  73,  22,  -13,-1,  4,  -1},   
5146  {0,   0,  0,   5,   -8,-7,  45,  75,  29,  -12,-3,  5,  -1}   
5147};
5148
5149#if CGS_GCC_NO_VECTORIZATION 
5150#ifdef __GNUC__
5151#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
5152#if GCC_VERSION > 40600
5153__attribute__((optimize("no-tree-vectorize")))
5154#endif
5155#endif
5156#endif
5157Void TEncGOP::filterImg(
5158    Pel           *src,
5159    Int           iSrcStride,
5160    Pel           *dst,
5161    Int           iDstStride,
5162    Int           height1, 
5163    Int           width1, 
5164    Int           shift,
5165    Int           plane)
5166{
5167  Int length = m_iTap;
5168  Int height2,width2;
5169  Int k,iSum;
5170  Int i0, div_i0, i1;
5171  Int j0, div_j0, j1;
5172  const Int *p_filter;
5173  Pel *p_src, *p_dst;
5174  Pel *p_src_line, *p_dst_line;
5175  Int **p_temp, *p_tmp;
5176  Int shift2 = 2*7+shift;
5177  Int shift_round = (1 << (shift2 - 1));
5178  Int iMax = (1<<(g_bitDepth[CHANNEL_TYPE_LUMA]-shift))-1;
5179  height2 = (height1 * m_iM) / m_iN;
5180  width2  = (width1  * m_iM) / m_iN;
5181
5182  m_phase_filter = plane? m_phase_filter_chroma : m_phase_filter_luma;
5183
5184  // horizontal filtering
5185  p_src_line = src;
5186  for(j1 = 0; j1 < height1; j1++)
5187  {
5188    i0=-m_iN;
5189    p_tmp = m_temp[j1];
5190   
5191    for(i1 = 0; i1 < width2; i1++)
5192    {
5193      i0      += m_iN;
5194      div_i0   = (i0 / m_iM);
5195      p_src    =  p_src_line + ( div_i0 - (length >> 1));
5196      p_filter = m_phase_filter[i0 - div_i0 * m_iM]; // phase_filter[i0 % M]
5197      iSum     = 0;
5198      for(k = 0; k < length; k++)
5199      {
5200        iSum += (*p_src++) * (*p_filter++);
5201      }
5202      *p_tmp++ = iSum;
5203    }
5204    p_src_line +=  iSrcStride;
5205  }
5206
5207  // pad temp (vertical)
5208  for (k=-(length>>1); k<0; k++)
5209  {
5210    memcpy(m_temp[k], m_temp[0], width2*sizeof(Int));
5211  }
5212  for (k=height1; k<(height1+(length>>1)); k++)
5213  {
5214    memcpy(m_temp[k], m_temp[k-1], (width2)* sizeof(Int));
5215  }
5216
5217  // vertical filtering
5218  j0 = (plane == 0) ? -m_iN : -(m_iN-1);
5219 
5220  p_dst_line = dst;
5221  for(j1 = 0; j1 < height2; j1++)
5222  {
5223    j0      += m_iN;
5224    div_j0   = (j0 / m_iM);
5225    p_dst = p_dst_line;
5226    p_temp   = &m_temp[div_j0 - (length>>1)];
5227    p_filter = m_phase_filter[j0 - div_j0 * m_iM]; // phase_filter[j0 % M]
5228    for(i1 = 0; i1 < width2;i1++)
5229    {
5230      iSum=0;
5231      for(k = 0; k < length; k++)
5232      {
5233        iSum += p_temp[k][i1] * p_filter[k];
5234      }
5235      iSum=((iSum + shift_round) >> shift2);
5236      *p_dst++ = (Short)(iSum > iMax ? iMax : (iSum < 0 ? 0 : iSum));
5237    }
5238    p_dst_line += iDstStride;
5239  }
5240}
5241
5242Void TEncGOP::initDs(Int iWidth, Int iHeight, Int iType)
5243{
5244  m_iTap = 13;
5245  if(g_posScalingFactor[0][0] == (1<<15))
5246  {
5247    m_iM = 4;
5248    m_iN = 8;
5249    m_phase_filter_luma = iType? m_phase_filter_0_t1 : m_phase_filter_0_t0;
5250    m_phase_filter_chroma = m_phase_filter_0_t1_chroma; 
5251  }
5252  else
5253  {
5254    m_iM = 8;
5255    m_iN = 12;
5256    m_phase_filter_luma = m_phase_filter_chroma =  m_phase_filter_1;
5257    m_phase_filter = m_phase_filter_1;
5258  }
5259
5260  get_mem2DintWithPad (&m_temp, iHeight, iWidth*m_iM/m_iN,   m_iTap>>1, 0);
5261}
5262
5263Int TEncGOP::get_mem2DintWithPad(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX)
5264{
5265  Int i;
5266  Int *curr = NULL;
5267  Int iHeight, iWidth;
5268
5269  iHeight = dim0+2*iPadY;
5270  iWidth = dim1+2*iPadX;
5271  (*array2D) = (Int**)malloc(iHeight*sizeof(Int*));
5272  *(*array2D) = (Int* )xMalloc(Int, iHeight*iWidth);
5273
5274  (*array2D)[0] += iPadX;
5275  curr = (*array2D)[0];
5276  for(i = 1 ; i < iHeight; i++)
5277  {
5278    curr += iWidth;
5279    (*array2D)[i] = curr;
5280  }
5281  (*array2D) = &((*array2D)[iPadY]);
5282
5283  return 0;
5284}
5285
5286Void TEncGOP::free_mem2DintWithPad(Int **array2D, Int iPadY, Int iPadX)
5287{
5288  if (array2D)
5289  {
5290    if (*array2D)
5291    {
5292      xFree(array2D[-iPadY]-iPadX);
5293    }
5294    else 
5295    {
5296      printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
5297    }
5298
5299    free (&array2D[-iPadY]);
5300  } 
5301  else
5302  {
5303    printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
5304  }
5305}
5306#endif
5307
5308#if R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
5309Void TEncGOP::xCheckLayerReset(TComSlice *slice)
5310{
5311  Bool layerResetFlag;
5312  Int dolLayerId;
5313
5314  if (slice->isIRAP() && slice->getLayerId() > 0)
5315  {
5316    if (m_prevPicHasEos)
5317    {
5318      layerResetFlag = true;
5319      dolLayerId = slice->getLayerId();
5320    }
5321    else if ((slice->isCRA() && slice->getHandleCraAsBlaFlag()) || (slice->isIDR() && slice->getCrossLayerBLAFlag()) || slice->isBLA())
5322    {
5323      layerResetFlag = true;
5324      dolLayerId = slice->getLayerId();
5325    }
5326    else
5327    {
5328      layerResetFlag = false;
5329    }
5330
5331    if (layerResetFlag)
5332    {
5333      for (Int i = 0; i < slice->getVPS()->getNumPredictedLayers(dolLayerId); i++)
5334      {
5335        Int iLayerId = slice->getVPS()->getPredictedLayerId(dolLayerId, i);
5336        m_ppcTEncTop[iLayerId]->setLayerInitializedFlag(false);
5337        m_ppcTEncTop[iLayerId]->setFirstPicInLayerDecodedFlag(false);
5338      }
5339
5340      // Each picture that is in the DPB and has nuh_layer_id equal to dolLayerId is marked as "unused for reference".
5341      for (TComList<TComPic*>::iterator pic = m_ppcTEncTop[dolLayerId]->getListPic()->begin(); pic != m_ppcTEncTop[dolLayerId]->getListPic()->end(); pic++)
5342      {
5343        if ((*pic)->getSlice(0)->getPOC() != slice->getPOC())
5344        {
5345          (*pic)->getSlice(0)->setReferenced(false);
5346        }
5347      }
5348
5349      // Each picture that is in DPB and has nuh_layer_id equal to any value of IdPredictedLayer[dolLayerId][i]
5350      // for the values of i in range of 0 to NumPredictedLayers[dolLayerId] - 1, inclusive, is marked as "unused for reference"
5351      for (UInt i = 0; i < slice->getVPS()->getNumPredictedLayers(dolLayerId); i++)
5352      {
5353        UInt predLId = slice->getVPS()->getPredictedLayerId(dolLayerId, i);
5354        for (TComList<TComPic*>::iterator pic = m_ppcTEncTop[predLId]->getListPic()->begin(); pic != m_ppcTEncTop[predLId]->getListPic()->end(); pic++)
5355        {
5356          if ((*pic)->getSlice(0)->getPOC() != slice->getPOC())
5357          {
5358            (*pic)->getSlice(0)->setReferenced(false);
5359          }
5360        }
5361      }
5362    }
5363  }
5364}
5365
5366Void TEncGOP::xSetNoRaslOutputFlag(TComSlice *slice)
5367{
5368  if (slice->isIRAP())
5369  {
5370    m_noRaslOutputFlag = slice->getHandleCraAsBlaFlag();  // default value
5371    if (slice->isIDR() || slice->isBLA() || m_bFirst || m_prevPicHasEos)
5372    {
5373      m_noRaslOutputFlag = true;
5374    }
5375    else if (!m_ppcTEncTop[m_layerId]->getLayerInitializedFlag())
5376    {
5377      Bool refLayersInitialized = true;
5378      for (UInt j = 0; j < slice->getVPS()->getNumDirectRefLayers(m_layerId); j++)
5379      {
5380        UInt refLayerId = slice->getVPS()->getRefLayerId(m_layerId, j);
5381        if (!m_ppcTEncTop[refLayerId]->getLayerInitializedFlag())
5382        {
5383          refLayersInitialized = false;
5384        }
5385      }
5386      if (refLayersInitialized)
5387      {
5388        m_noRaslOutputFlag = true;
5389      }
5390    }
5391  }
5392}
5393
5394Void TEncGOP::xSetLayerInitializedFlag(TComSlice *slice)
5395{
5396  if (slice->isIRAP() && m_noRaslOutputFlag)
5397  {
5398    if (m_layerId == 0)
5399    {
5400      m_ppcTEncTop[m_layerId]->setLayerInitializedFlag(true);
5401    }
5402    else if (!m_ppcTEncTop[m_layerId]->getLayerInitializedFlag() && slice->getVPS()->getNumDirectRefLayers(m_layerId) == 0)
5403    {
5404      m_ppcTEncTop[m_layerId]->setLayerInitializedFlag(true);
5405    }
5406    else if (!m_ppcTEncTop[m_layerId]->getLayerInitializedFlag())
5407    {
5408      Bool refLayersInitialized = true;
5409      for (UInt j = 0; j < slice->getVPS()->getNumDirectRefLayers(m_layerId); j++)
5410      {
5411        UInt refLayerId = slice->getVPS()->getRefLayerId(m_layerId, j);
5412        if (!m_ppcTEncTop[refLayerId]->getLayerInitializedFlag())
5413        {
5414          refLayersInitialized = false;
5415        }
5416      }
5417      if (refLayersInitialized)
5418      {
5419        m_ppcTEncTop[m_layerId]->setLayerInitializedFlag(true);
5420      }
5421    }
5422  }
5423}
5424#endif // R0071_IRAP_EOS_CROSS_LAYER_IMPACTS
5425
5426#endif //SVC_EXTENSION
5427
5428//! \}
Note: See TracBrowser for help on using the repository browser.