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

Last change on this file since 918 was 916, checked in by seregin, 10 years ago

initial porting

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