source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp @ 1171

Last change on this file since 1171 was 1150, checked in by seregin, 9 years ago

macro cleanup: O0149_CROSS_LAYER_BLA_FLAG

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