source: SHVCSoftware/branches/SHM-upgrade/source/Lib/TLibEncoder/TEncGOP.cpp @ 1311

Last change on this file since 1311 was 985, checked in by seregin, 10 years ago

port a fix for Temporal ID for EOS nal unit in the encoder (rev 984)

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