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

Last change on this file since 1079 was 1077, checked in by seregin, 10 years ago

update the older Visual Studio project files and some fixes to avoid implicit cast warnings, patch was provided by Karsten Sühring <karsten.suehring@…>

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