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

Last change on this file since 928 was 926, checked in by seregin, 11 years ago

fix compiler warnings, rep format

  • Property svn:eol-style set to native
File size: 199.1 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#if REPN_FORMAT_IN_VPS
2958      const Int paddedWidth = ((pcSlice->getPicWidthInLumaSamples()  + minCuWidth  - 1) / minCuWidth) * minCuWidth;
2959      const Int paddedHeight= ((pcSlice->getPicHeightInLumaSamples() + minCuHeight - 1) / minCuHeight) * minCuHeight;
2960#else
2961      const Int paddedWidth = ((pcSlice->getSPS()->getPicWidthInLumaSamples()  + minCuWidth  - 1) / minCuWidth) * minCuWidth;
2962      const Int paddedHeight= ((pcSlice->getSPS()->getPicHeightInLumaSamples() + minCuHeight - 1) / minCuHeight) * minCuHeight;
2963#endif
2964      const Int rawBits = paddedWidth * paddedHeight *
2965                             (g_bitDepth[CHANNEL_TYPE_LUMA] + 2*(g_bitDepth[CHANNEL_TYPE_CHROMA]>>log2subWidthCxsubHeightC));
2966      const Int64 threshold = (32LL/3)*numBytesInVclNalUnits + (rawBits/32);
2967      if (binCountsInNalUnits >= threshold)
2968      {
2969        // need to add additional cabac zero words (each one accounts for 3 bytes (=00 00 03)) to increase numBytesInVclNalUnits
2970        const Int64 targetNumBytesInVclNalUnits = ((binCountsInNalUnits - (rawBits/32))*3+31)/32;
2971        const Int64 numberOfAdditionalBytesNeeded=targetNumBytesInVclNalUnits - numBytesInVclNalUnits;
2972
2973        if (numberOfAdditionalBytesNeeded>0) // It should be!
2974        {
2975          const Int64 numberOfAdditionalCabacZeroWords=(numberOfAdditionalBytesNeeded+2)/3;
2976          const Int64 numberOfAdditionalCabacZeroBytes=numberOfAdditionalCabacZeroWords*3;
2977          if (m_pcCfg->getCabacZeroWordPaddingEnabled())
2978          {
2979            std::vector<Char> zeroBytesPadding(numberOfAdditionalCabacZeroBytes, Char(0));
2980            for(Int64 i=0; i<numberOfAdditionalCabacZeroWords; i++)
2981            {
2982              zeroBytesPadding[i*3+2]=3;  // 00 00 03
2983            }
2984            accessUnit.back()->m_nalUnitData.write(&(zeroBytesPadding[0]), numberOfAdditionalCabacZeroBytes);
2985            printf("Adding %lld bytes of padding\n", numberOfAdditionalCabacZeroWords*3);
2986          }
2987          else
2988          {
2989            printf("Standard would normally require adding %lld bytes of padding\n", numberOfAdditionalCabacZeroWords*3);
2990          }
2991        }
2992      }
2993    }
2994
2995    pcPic->compressMotion();
2996
2997    //-- For time output for each slice
2998    Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
2999
3000    std::string digestStr;
3001    if (m_pcCfg->getDecodedPictureHashSEIEnabled())
3002    {
3003      /* calculate MD5sum for entire reconstructed picture */
3004      SEIDecodedPictureHash sei_recon_picture_digest;
3005      if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
3006      {
3007        sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5;
3008        UInt numChar=calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.m_digest);
3009        digestStr = digestToString(sei_recon_picture_digest.m_digest, numChar);
3010      }
3011      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
3012      {
3013        sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC;
3014        UInt numChar=calcCRC(*pcPic->getPicYuvRec(), sei_recon_picture_digest.m_digest);
3015        digestStr = digestToString(sei_recon_picture_digest.m_digest, numChar);
3016      }
3017      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
3018      {
3019        sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM;
3020        UInt numChar=calcChecksum(*pcPic->getPicYuvRec(), sei_recon_picture_digest.m_digest);
3021        digestStr = digestToString(sei_recon_picture_digest.m_digest, numChar);
3022      }
3023
3024#if SVC_EXTENSION
3025      OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer(), m_layerId);
3026#else
3027      OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer());
3028#endif
3029
3030      /* write the SEI messages */
3031      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3032#if O0164_MULTI_LAYER_HRD
3033      m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, m_pcEncTop->getVPS(), pcSlice->getSPS());
3034#else
3035      m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, pcSlice->getSPS());
3036#endif
3037      writeRBSPTrailingBits(nalu.m_Bitstream);
3038
3039      accessUnit.insert(accessUnit.end(), new NALUnitEBSP(nalu));
3040    }
3041    if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
3042    {
3043      SEITemporalLevel0Index sei_temporal_level0_index;
3044      if (pcSlice->getRapPicFlag())
3045      {
3046        m_tl0Idx = 0;
3047        m_rapIdx = (m_rapIdx + 1) & 0xFF;
3048      }
3049      else
3050      {
3051        m_tl0Idx = (m_tl0Idx + (pcSlice->getTLayer() ? 0 : 1)) & 0xFF;
3052      }
3053      sei_temporal_level0_index.tl0Idx = m_tl0Idx;
3054      sei_temporal_level0_index.rapIdx = m_rapIdx;
3055
3056      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
3057
3058      /* write the SEI messages */
3059      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3060#if O0164_MULTI_LAYER_HRD
3061      m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, m_pcEncTop->getVPS(), pcSlice->getSPS());
3062#else
3063      m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, pcSlice->getSPS());     
3064#endif
3065      writeRBSPTrailingBits(nalu.m_Bitstream);
3066
3067      /* insert the SEI message NALUnit before any Slice NALUnits */
3068      AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
3069      accessUnit.insert(it, new NALUnitEBSP(nalu));
3070    }
3071
3072    m_pcCfg->setEncodedFlag(iGOPid, true);
3073    xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
3074
3075    //In case of field coding, compute the interlaced PSNR for both fields
3076    if(isField)
3077    {
3078      Bool bothFieldsAreEncoded = false;
3079      Int correspondingFieldPOC = pcPic->getPOC();
3080      Int currentPicGOPPoc = m_pcCfg->getGOPEntry(iGOPid).m_POC;
3081      if(pcPic->getPOC() == 0)
3082      {
3083        // particular case for POC 0 and 1.
3084        // If they are not encoded first and separately from other pictures, we need to change this
3085        // POC 0 is always encoded first then POC 1 is encoded
3086        bothFieldsAreEncoded = false;
3087      }
3088      else if(pcPic->getPOC() == 1)
3089      {
3090        // if we are at POC 1, POC 0 has been encoded for sure
3091        correspondingFieldPOC = 0;
3092        bothFieldsAreEncoded = true;
3093      }
3094      else 
3095      {
3096        if(pcPic->getPOC()%2 == 1)
3097        {
3098          correspondingFieldPOC -= 1; // all odd POC are associated with the preceding even POC (e.g poc 1 is associated to poc 0)
3099          currentPicGOPPoc      -= 1;
3100        }
3101        else
3102        {
3103          correspondingFieldPOC += 1; // all even POC are associated with the following odd POC (e.g poc 0 is associated to poc 1)
3104          currentPicGOPPoc      += 1;
3105        }
3106        for(Int i = 0; i < m_iGopSize; i ++)
3107        {
3108          if(m_pcCfg->getGOPEntry(i).m_POC == currentPicGOPPoc)
3109          {
3110            bothFieldsAreEncoded = m_pcCfg->getGOPEntry(i).m_isEncoded;
3111            break;
3112          }
3113        }
3114      }
3115
3116      if(bothFieldsAreEncoded)
3117      {       
3118        //get complementary top field
3119        TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
3120        while ((*iterPic)->getPOC() != correspondingFieldPOC)
3121        {
3122          iterPic ++;
3123        }
3124        TComPic* correspondingFieldPic = *(iterPic);
3125
3126        if( (pcPic->isTopField() && isTff) || (!pcPic->isTopField() && !isTff))
3127        {
3128          xCalculateInterlacedAddPSNR(pcPic, correspondingFieldPic, pcPic->getPicYuvRec(), correspondingFieldPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
3129        }
3130        else
3131        {
3132          xCalculateInterlacedAddPSNR(correspondingFieldPic, pcPic, correspondingFieldPic->getPicYuvRec(), pcPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
3133        }
3134      }
3135    }
3136
3137    if (!digestStr.empty())
3138    {
3139      if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
3140      {
3141        printf(" [MD5:%s]", digestStr.c_str());
3142      }
3143      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
3144      {
3145        printf(" [CRC:%s]", digestStr.c_str());
3146      }
3147      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
3148      {
3149        printf(" [Checksum:%s]", digestStr.c_str());
3150      }
3151    }
3152
3153    if ( m_pcCfg->getUseRateCtrl() )
3154    {
3155      Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
3156      Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
3157      if ( avgLambda < 0.0 )
3158      {
3159        avgLambda = lambda;
3160      }
3161
3162      m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
3163      m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
3164
3165      m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
3166      if ( pcSlice->getSliceType() != I_SLICE )
3167      {
3168        m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
3169      }
3170      else    // for intra picture, the estimated bits are used to update the current status in the GOP
3171      {
3172        m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
3173      }
3174    }
3175
3176    if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
3177        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
3178        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
3179        || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
3180    {
3181      TComVUI *vui = pcSlice->getSPS()->getVuiParameters();
3182      TComHRD *hrd = vui->getHrdParameters();
3183
3184      if( hrd->getSubPicCpbParamsPresentFlag() )
3185      {
3186        Int i;
3187        UInt64 ui64Tmp;
3188        UInt uiPrev = 0;
3189        UInt numDU = ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 );
3190        UInt *pCRD = &pictureTimingSEI.m_duCpbRemovalDelayMinus1[0];
3191        UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
3192
3193        for( i = 0; i < numDU; i ++ )
3194        {
3195          pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] - 1 ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
3196        }
3197
3198        if( numDU == 1 )
3199        {
3200          pCRD[ 0 ] = 0; /* don't care */
3201        }
3202        else
3203        {
3204          pCRD[ numDU - 1 ] = 0;/* by definition */
3205          UInt tmp = 0;
3206          UInt accum = 0;
3207
3208          for( i = ( numDU - 2 ); i >= 0; i -- )
3209          {
3210            ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
3211            if( (UInt)ui64Tmp > maxDiff )
3212            {
3213              tmp ++;
3214            }
3215          }
3216          uiPrev = 0;
3217
3218          UInt flag = 0;
3219          for( i = ( numDU - 2 ); i >= 0; i -- )
3220          {
3221            flag = 0;
3222            ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
3223
3224            if( (UInt)ui64Tmp > maxDiff )
3225            {
3226              if(uiPrev >= maxDiff - tmp)
3227              {
3228                ui64Tmp = uiPrev + 1;
3229                flag = 1;
3230              }
3231              else                            ui64Tmp = maxDiff - tmp + 1;
3232            }
3233            pCRD[ i ] = (UInt)ui64Tmp - uiPrev - 1;
3234            if( (Int)pCRD[ i ] < 0 )
3235            {
3236              pCRD[ i ] = 0;
3237            }
3238            else if (tmp > 0 && flag == 1)
3239            {
3240              tmp --;
3241            }
3242            accum += pCRD[ i ] + 1;
3243            uiPrev = accum;
3244          }
3245        }
3246      }
3247
3248      if( m_pcCfg->getPictureTimingSEIEnabled() )
3249      {
3250        {
3251          OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
3252          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3253          pictureTimingSEI.m_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0;
3254#if O0164_MULTI_LAYER_HRD
3255          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3256#else
3257          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, pcSlice->getSPS());
3258#endif
3259          writeRBSPTrailingBits(nalu.m_Bitstream);
3260          UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
3261          UInt offsetPosition = m_activeParameterSetSEIPresentInAU
3262                                    + m_bufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
3263          AccessUnit::iterator it = accessUnit.begin();
3264          for(Int j = 0; j < seiPositionInAu + offsetPosition; j++)
3265          {
3266            it++;
3267          }
3268          accessUnit.insert(it, new NALUnitEBSP(nalu));
3269          m_pictureTimingSEIPresentInAU = true;
3270        }
3271
3272        if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI
3273        {
3274          OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
3275          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3276          scalableNestingSEI.m_nestedSEIs.clear();
3277          scalableNestingSEI.m_nestedSEIs.push_back(&pictureTimingSEI);
3278#if O0164_MULTI_LAYER_HRD
3279          m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3280#else
3281          m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
3282#endif
3283          writeRBSPTrailingBits(nalu.m_Bitstream);
3284          UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
3285          UInt offsetPosition = m_activeParameterSetSEIPresentInAU
3286            + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU + m_nestedBufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
3287          AccessUnit::iterator it = accessUnit.begin();
3288          for(Int j = 0; j < seiPositionInAu + offsetPosition; j++)
3289          {
3290            it++;
3291          }
3292          accessUnit.insert(it, new NALUnitEBSP(nalu));
3293          m_nestedPictureTimingSEIPresentInAU = true;
3294        }
3295      }
3296
3297      if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
3298      {
3299        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3300        for( Int i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
3301        {
3302          OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
3303
3304          SEIDecodingUnitInfo tempSEI;
3305          tempSEI.m_decodingUnitIdx = i;
3306          tempSEI.m_duSptCpbRemovalDelay = pictureTimingSEI.m_duCpbRemovalDelayMinus1[i] + 1;
3307          tempSEI.m_dpbOutputDuDelayPresentFlag = false;
3308          tempSEI.m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
3309
3310          // Insert the first one in the right location, before the first slice
3311          if(i == 0)
3312          {
3313            // Insert before the first slice.
3314#if O0164_MULTI_LAYER_HRD
3315            m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3316#else
3317            m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
3318#endif
3319            writeRBSPTrailingBits(nalu.m_Bitstream);
3320
3321            UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
3322            UInt offsetPosition = m_activeParameterSetSEIPresentInAU
3323                                  + m_bufferingPeriodSEIPresentInAU
3324                                  + m_pictureTimingSEIPresentInAU;  // Insert DU info SEI after APS, BP and PT SEI
3325            AccessUnit::iterator it = accessUnit.begin();
3326            for(Int j = 0; j < seiPositionInAu + offsetPosition; j++)
3327            {
3328              it++;
3329            }
3330            accessUnit.insert(it, new NALUnitEBSP(nalu));
3331          }
3332          else
3333          {
3334            // For the second decoding unit onwards we know how many NALUs are present
3335            AccessUnit::iterator it = accessUnit.begin();
3336            for (Int ctr = 0; it != accessUnit.end(); it++)
3337            {
3338              if(ctr == accumNalsDU[ i - 1 ])
3339              {
3340                // Insert before the first slice.
3341#if O0164_MULTI_LAYER_HRD
3342                m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3343#else
3344                m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
3345#endif
3346                writeRBSPTrailingBits(nalu.m_Bitstream);
3347
3348                accessUnit.insert(it, new NALUnitEBSP(nalu));
3349                break;
3350              }
3351              if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3352              {
3353                ctr++;
3354              }
3355            }
3356          }
3357        }
3358      }
3359    }
3360
3361    xResetNonNestedSEIPresentFlags();
3362    xResetNestedSEIPresentFlags();
3363
3364    pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
3365
3366#if M0040_ADAPTIVE_RESOLUTION_CHANGE
3367    pcPicYuvRecOut->setReconstructed(true);
3368#endif
3369#if P0297_VPS_POC_LSB_ALIGNED_FLAG
3370    m_pcEncTop->setFirstPicInLayerDecodedFlag(true);
3371#endif
3372    pcPic->setReconMark   ( true );
3373    m_bFirst = false;
3374    m_iNumPicCoded++;
3375    m_totalCoded ++;
3376    /* logging: insert a newline at end of picture period */
3377    printf("\n");
3378    fflush(stdout);
3379
3380#if EFFICIENT_FIELD_IRAP
3381    if(IRAPtoReorder)
3382    {
3383      if(swapIRAPForward)
3384      {
3385        if(iGOPid == IRAPGOPid)
3386        {
3387          iGOPid = IRAPGOPid +1;
3388          IRAPtoReorder = false;
3389        }
3390        else if(iGOPid == IRAPGOPid +1)
3391        {
3392          iGOPid --;
3393        }
3394      }
3395      else
3396      {
3397        if(iGOPid == IRAPGOPid)
3398        {
3399          iGOPid = IRAPGOPid -1;
3400        }
3401        else if(iGOPid == IRAPGOPid -1)
3402        {
3403          iGOPid = IRAPGOPid;
3404          IRAPtoReorder = false;
3405        }
3406      }
3407    }
3408#endif
3409  } // iGOPid-loop
3410
3411  delete pcBitstreamRedirect;
3412
3413  if( accumBitsDU != NULL) delete accumBitsDU;
3414  if( accumNalsDU != NULL) delete accumNalsDU;
3415
3416#if SVC_EXTENSION
3417  assert ( m_iNumPicCoded <= 1 );
3418#else
3419  assert ( (m_iNumPicCoded == iNumPicRcvd) );
3420#endif
3421}
3422
3423#if !SVC_EXTENSION
3424Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField, const Bool printMSEBasedSNR, const Bool printSequenceMSE)
3425{
3426  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
3427
3428
3429  //--CFG_KDY
3430  const Int rateMultiplier=(isField?2:1);
3431  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
3432  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
3433  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
3434  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
3435  const ChromaFormat chFmt = m_pcCfg->getChromaFormatIdc();
3436
3437  //-- all
3438  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
3439  m_gcAnalyzeAll.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE);
3440
3441  printf( "\n\nI Slices--------------------------------------------------------\n" );
3442  m_gcAnalyzeI.printOut('i', chFmt, printMSEBasedSNR, printSequenceMSE);
3443
3444  printf( "\n\nP Slices--------------------------------------------------------\n" );
3445  m_gcAnalyzeP.printOut('p', chFmt, printMSEBasedSNR, printSequenceMSE);
3446
3447  printf( "\n\nB Slices--------------------------------------------------------\n" );
3448  m_gcAnalyzeB.printOut('b', chFmt, printMSEBasedSNR, printSequenceMSE);
3449
3450#if _SUMMARY_OUT_
3451  m_gcAnalyzeAll.printSummary(chFmt, printSequenceMSE);
3452#endif
3453#if _SUMMARY_PIC_
3454  m_gcAnalyzeI.printSummary(chFmt, printSequenceMSE,'I');
3455  m_gcAnalyzeP.printSummary(chFmt, printSequenceMSE,'P');
3456  m_gcAnalyzeB.printSummary(chFmt, printSequenceMSE,'B');
3457#endif
3458
3459  if(isField)
3460  {
3461    //-- interlaced summary
3462    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
3463    m_gcAnalyzeAll_in.setBits(m_gcAnalyzeAll.getBits());
3464    // prior to the above statement, the interlace analyser does not contain the correct total number of bits.
3465
3466    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
3467    m_gcAnalyzeAll_in.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE);
3468
3469#if _SUMMARY_OUT_
3470    m_gcAnalyzeAll_in.printSummary(chFmt, printSequenceMSE);
3471#endif
3472  }
3473
3474  printf("\nRVM: %.3lf\n" , xCalculateRVM());
3475}
3476#endif
3477
3478Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist )
3479{
3480  Bool bCalcDist = false;
3481  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
3482  m_pcLoopFilter->loopFilterPic( pcPic );
3483
3484  if (!bCalcDist)
3485    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
3486}
3487
3488// ====================================================================================================================
3489// Protected member functions
3490// ====================================================================================================================
3491
3492
3493Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, Bool isField )
3494{
3495  assert( iNumPicRcvd > 0 );
3496  //  Exception for the first frames
3497  if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField  && (iPOCLast == 0))  )
3498  {
3499    m_iGopSize    = 1;
3500  }
3501  else
3502  {
3503    m_iGopSize    = m_pcCfg->getGOPSize();
3504  }
3505  assert (m_iGopSize > 0);
3506
3507  return;
3508}
3509
3510
3511Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
3512                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
3513                         Int                       iNumPicRcvd,
3514                         Int                       iTimeOffset,
3515                         TComPic*&                 rpcPic,
3516                         TComPicYuv*&              rpcPicYuvRecOut,
3517                         Int                       pocCurr,
3518                         Bool                      isField)
3519{
3520  Int i;
3521  //  Rec. output
3522  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
3523
3524  if (isField && pocCurr > 1 && m_iGopSize!=1)
3525  {
3526    iTimeOffset--;
3527  }
3528
3529  for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
3530  {
3531    iterPicYuvRec--;
3532  }
3533
3534  rpcPicYuvRecOut = *(iterPicYuvRec);
3535
3536  //  Current pic.
3537  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
3538  while (iterPic != rcListPic.end())
3539  {
3540    rpcPic = *(iterPic);
3541    rpcPic->setCurrSliceIdx(0);
3542    if (rpcPic->getPOC() == pocCurr)
3543    {
3544      break;
3545    }
3546    iterPic++;
3547  }
3548
3549  assert (rpcPic != NULL);
3550  assert (rpcPic->getPOC() == pocCurr);
3551
3552  return;
3553}
3554
3555UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
3556{
3557  UInt64  uiTotalDiff = 0;
3558
3559  for(Int chan=0; chan<pcPic0 ->getNumberValidComponents(); chan++)
3560  {
3561    const ComponentID ch=ComponentID(chan);
3562    Pel*  pSrc0   = pcPic0 ->getAddr(ch);
3563    Pel*  pSrc1   = pcPic1 ->getAddr(ch);
3564    UInt  uiShift     = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepth[toChannelType(ch)]-8);
3565
3566    const Int   iStride = pcPic0->getStride(ch);
3567    const Int   iWidth  = pcPic0->getWidth(ch);
3568    const Int   iHeight = pcPic0->getHeight(ch);
3569
3570    for(Int y = 0; y < iHeight; y++ )
3571    {
3572      for(Int x = 0; x < iWidth; x++ )
3573      {
3574        Intermediate_Int iTemp = pSrc0[x] - pSrc1[x];
3575        uiTotalDiff += UInt64((iTemp*iTemp) >> uiShift);
3576      }
3577      pSrc0 += iStride;
3578      pSrc1 += iStride;
3579    }
3580  }
3581
3582  return uiTotalDiff;
3583}
3584
3585#if VERBOSE_RATE
3586static const Char* nalUnitTypeToString(NalUnitType type)
3587{
3588  switch (type)
3589  {
3590    case NAL_UNIT_CODED_SLICE_TRAIL_R:    return "TRAIL_R";
3591    case NAL_UNIT_CODED_SLICE_TRAIL_N:    return "TRAIL_N";
3592    case NAL_UNIT_CODED_SLICE_TSA_R:      return "TSA_R";
3593    case NAL_UNIT_CODED_SLICE_TSA_N:      return "TSA_N";
3594    case NAL_UNIT_CODED_SLICE_STSA_R:     return "STSA_R";
3595    case NAL_UNIT_CODED_SLICE_STSA_N:     return "STSA_N";
3596    case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
3597    case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
3598    case NAL_UNIT_CODED_SLICE_BLA_N_LP:   return "BLA_N_LP";
3599    case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
3600    case NAL_UNIT_CODED_SLICE_IDR_N_LP:   return "IDR_N_LP";
3601    case NAL_UNIT_CODED_SLICE_CRA:        return "CRA";
3602    case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
3603    case NAL_UNIT_CODED_SLICE_RADL_N:     return "RADL_N";
3604    case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
3605    case NAL_UNIT_CODED_SLICE_RASL_N:     return "RASL_N";
3606    case NAL_UNIT_VPS:                    return "VPS";
3607    case NAL_UNIT_SPS:                    return "SPS";
3608    case NAL_UNIT_PPS:                    return "PPS";
3609    case NAL_UNIT_ACCESS_UNIT_DELIMITER:  return "AUD";
3610    case NAL_UNIT_EOS:                    return "EOS";
3611    case NAL_UNIT_EOB:                    return "EOB";
3612    case NAL_UNIT_FILLER_DATA:            return "FILLER";
3613    case NAL_UNIT_PREFIX_SEI:             return "SEI";
3614    case NAL_UNIT_SUFFIX_SEI:             return "SEI";
3615    default:                              return "UNK";
3616  }
3617}
3618#endif
3619
3620Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime, const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3621{
3622  Double  dPSNR[MAX_NUM_COMPONENT];
3623
3624  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3625  {
3626    dPSNR[i]=0.0;
3627  }
3628
3629  TComPicYuv cscd;
3630  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3631  {
3632    cscd.create(pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), pcPicD->getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
3633    TVideoIOYuv::ColourSpaceConvert(*pcPicD, cscd, conversion, g_bitDepth, false);
3634  }
3635  TComPicYuv &picd=(conversion==IPCOLOURSPACE_UNCHANGED)?*pcPicD : cscd;
3636
3637  //===== calculate PSNR =====
3638  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3639
3640  for(Int chan=0; chan<pcPicD->getNumberValidComponents(); chan++)
3641  {
3642    const ComponentID ch=ComponentID(chan);
3643    const Pel*  pOrg    = (conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg()->getAddr(ch) : pcPic ->getPicYuvOrg()->getAddr(ch);
3644    Pel*  pRec    = picd.getAddr(ch);
3645    const Int   iStride = pcPicD->getStride(ch);
3646
3647    const Int   iWidth  = pcPicD->getWidth (ch) - (m_pcEncTop->getPad(0) >> pcPic->getComponentScaleX(ch));
3648    const Int   iHeight = pcPicD->getHeight(ch) - ((m_pcEncTop->getPad(1) >> (pcPic->isField()?1:0)) >> pcPic->getComponentScaleY(ch));
3649
3650    Int   iSize   = iWidth*iHeight;
3651
3652    UInt64 uiSSDtemp=0;
3653    for(Int y = 0; y < iHeight; y++ )
3654    {
3655      for(Int x = 0; x < iWidth; x++ )
3656      {
3657        Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3658        uiSSDtemp   += iDiff * iDiff;
3659      }
3660      pOrg += iStride;
3661      pRec += iStride;
3662    }
3663    const Int maxval = 255 << (g_bitDepth[toChannelType(ch)] - 8);
3664    const Double fRefValue = (Double) maxval * maxval * iSize;
3665    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3666    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize);
3667  }
3668
3669
3670  /* calculate the size of the access unit, excluding:
3671   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
3672   *  - SEI NAL units
3673   */
3674  UInt numRBSPBytes = 0;
3675  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3676  {
3677    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3678#if VERBOSE_RATE
3679    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
3680#endif
3681    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3682    {
3683      numRBSPBytes += numRBSPBytes_nal;
3684    }
3685  }
3686
3687  UInt uibits = numRBSPBytes * 8;
3688  m_vRVM_RP.push_back( uibits );
3689
3690  //===== add PSNR =====
3691#if SVC_EXTENSION
3692  m_gcAnalyzeAll[m_layerId].addResult (dPSNR, (Double)uibits, MSEyuvframe);
3693  TComSlice*  pcSlice = pcPic->getSlice(0);
3694  if (pcSlice->isIntra())
3695  {
3696    m_gcAnalyzeI[m_layerId].addResult (dPSNR, (Double)uibits, MSEyuvframe);
3697  }
3698  if (pcSlice->isInterP())
3699  {
3700    m_gcAnalyzeP[m_layerId].addResult (dPSNR, (Double)uibits, MSEyuvframe);
3701  }
3702  if (pcSlice->isInterB())
3703  {
3704    m_gcAnalyzeB[m_layerId].addResult (dPSNR, (Double)uibits, MSEyuvframe);
3705  }
3706#else
3707  m_gcAnalyzeAll.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3708  TComSlice*  pcSlice = pcPic->getSlice(0);
3709  if (pcSlice->isIntra())
3710  {
3711    m_gcAnalyzeI.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3712  }
3713  if (pcSlice->isInterP())
3714  {
3715    m_gcAnalyzeP.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3716  }
3717  if (pcSlice->isInterB())
3718  {
3719    m_gcAnalyzeB.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3720  }
3721#endif
3722
3723  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
3724  if (!pcSlice->isReferenced()) c += 32;
3725
3726#if SVC_EXTENSION
3727#if ADAPTIVE_QP_SELECTION 
3728  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, nQP %d QP %d ) %10d bits",
3729         pcSlice->getPOC(),
3730         pcSlice->getLayerId(),
3731         pcSlice->getTLayer(),
3732         c,
3733         NaluToStr( pcSlice->getNalUnitType() ).data(),
3734         pcSlice->getSliceQpBase(),
3735         pcSlice->getSliceQp(),
3736         uibits );
3737#else
3738  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, QP %d ) %10d bits",
3739         pcSlice->getPOC()-pcSlice->getLastIDR(),
3740         pcSlice->getLayerId(),
3741         pcSlice->getTLayer(),
3742         c,
3743         NaluToStr( pcSlice->getNalUnitType() ).data(),
3744         pcSlice->getSliceQp(),
3745         uibits );
3746#endif
3747#else
3748#if ADAPTIVE_QP_SELECTION
3749  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
3750         pcSlice->getPOC(),
3751         pcSlice->getTLayer(),
3752         c,
3753         pcSlice->getSliceQpBase(),
3754         pcSlice->getSliceQp(),
3755         uibits );
3756#else
3757  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
3758         pcSlice->getPOC()-pcSlice->getLastIDR(),
3759         pcSlice->getTLayer(),
3760         c,
3761         pcSlice->getSliceQp(),
3762         uibits );
3763#endif
3764#endif
3765
3766  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
3767  if (printFrameMSE)
3768  {
3769    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3770  }
3771  printf(" [ET %5.0f ]", dEncTime );
3772
3773  for (Int iRefList = 0; iRefList < 2; iRefList++)
3774  {
3775    printf(" [L%d ", iRefList);
3776    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
3777    {
3778#if SVC_EXTENSION
3779#if VPS_EXTN_DIRECT_REF_LAYERS
3780      if( pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->isILR(m_layerId) )
3781      {
3782#if POC_RESET_IDC_ENCODER
3783        UInt refLayerId = pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId();
3784        UInt refLayerIdc = pcSlice->getReferenceLayerIdc(refLayerId);
3785        assert( g_posScalingFactor[refLayerIdc][0] );
3786        assert( g_posScalingFactor[refLayerIdc][1] );
3787
3788        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] );
3789#else
3790        printf( "%d(%d)", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR(), pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId() );
3791#endif
3792      }
3793      else
3794      {
3795#if POC_RESET_IDC_ENCODER
3796        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
3797#else
3798        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3799#endif
3800      }
3801#endif
3802      if( pcSlice->getEnableTMVPFlag() && iRefList == 1 - pcSlice->getColFromL0Flag() && iRefIndex == pcSlice->getColRefIdx() )
3803      {
3804        printf( "c" );
3805      }
3806
3807      printf( " " );
3808#else
3809      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3810#endif
3811    }
3812    printf("]");
3813  }
3814#if Q0048_CGS_3D_ASYMLUT
3815  pcPic->setFrameBit( (Int)uibits );
3816  if( m_layerId && pcSlice->getPPS()->getCGSFlag() )
3817  {
3818#if R0179_ENC_OPT_3DLUT_SIZE
3819      m_Enc3DAsymLUTPicUpdate.update3DAsymLUTParam( &m_Enc3DAsymLUTPPS );
3820#else
3821    if( m_Enc3DAsymLUTPPS.getPPSBit() > 0 )
3822      m_Enc3DAsymLUTPicUpdate.copy3DAsymLUT( &m_Enc3DAsymLUTPPS );
3823#endif
3824    m_Enc3DAsymLUTPicUpdate.updatePicCGSBits( pcSlice , m_Enc3DAsymLUTPPS.getPPSBit() );
3825  }
3826#endif
3827
3828  cscd.destroy();
3829}
3830
3831Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgFirstField, TComPic* pcPicOrgSecondField,
3832                                           TComPicYuv* pcPicRecFirstField, TComPicYuv* pcPicRecSecondField,
3833                                           const AccessUnit& accessUnit, Double dEncTime, const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3834{
3835  Double  dPSNR[MAX_NUM_COMPONENT];
3836  TComPic    *apcPicOrgFields[2]={pcPicOrgFirstField, pcPicOrgSecondField};
3837  TComPicYuv *apcPicRecFields[2]={pcPicRecFirstField, pcPicRecSecondField};
3838
3839  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3840  {
3841    dPSNR[i]=0.0;
3842  }
3843
3844  TComPicYuv cscd[2 /* first/second field */];
3845  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3846  {
3847    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3848    {
3849      TComPicYuv &reconField=*(apcPicRecFields[fieldNum]);
3850      cscd[fieldNum].create(reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), reconField.getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
3851      TVideoIOYuv::ColourSpaceConvert(reconField, cscd[fieldNum], conversion, g_bitDepth, false);
3852      apcPicRecFields[fieldNum]=cscd+fieldNum;
3853    }
3854  }
3855
3856  //===== calculate PSNR =====
3857  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3858
3859  assert(apcPicRecFields[0]->getChromaFormat()==apcPicRecFields[1]->getChromaFormat());
3860  const UInt numValidComponents=apcPicRecFields[0]->getNumberValidComponents();
3861
3862  for(Int chan=0; chan<numValidComponents; chan++)
3863  {
3864    const ComponentID ch=ComponentID(chan);
3865    assert(apcPicRecFields[0]->getWidth(ch)==apcPicRecFields[1]->getWidth(ch));
3866    assert(apcPicRecFields[0]->getHeight(ch)==apcPicRecFields[1]->getHeight(ch));
3867
3868    UInt64 uiSSDtemp=0;
3869    const Int   iWidth  = apcPicRecFields[0]->getWidth (ch) - (m_pcEncTop->getPad(0) >> apcPicRecFields[0]->getComponentScaleX(ch));
3870    const Int   iHeight = apcPicRecFields[0]->getHeight(ch) - ((m_pcEncTop->getPad(1) >> 1) >> apcPicRecFields[0]->getComponentScaleY(ch));
3871
3872    Int   iSize   = iWidth*iHeight;
3873
3874    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3875    {
3876      TComPic *pcPic=apcPicOrgFields[fieldNum];
3877      TComPicYuv *pcPicD=apcPicRecFields[fieldNum];
3878
3879      const Pel*  pOrg    = (conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg()->getAddr(ch) : pcPic ->getPicYuvOrg()->getAddr(ch);
3880      Pel*  pRec    = pcPicD->getAddr(ch);
3881      const Int   iStride = pcPicD->getStride(ch);
3882
3883
3884      for(Int y = 0; y < iHeight; y++ )
3885      {
3886        for(Int x = 0; x < iWidth; x++ )
3887        {
3888          Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3889          uiSSDtemp   += iDiff * iDiff;
3890        }
3891        pOrg += iStride;
3892        pRec += iStride;
3893      }
3894    }
3895    const Int maxval = 255 << (g_bitDepth[toChannelType(ch)] - 8);
3896    const Double fRefValue = (Double) maxval * maxval * iSize*2;
3897    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3898    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize*2);
3899  }
3900
3901  UInt uibits = 0; // the number of bits for the pair is not calculated here - instead the overall total is used elsewhere.
3902
3903  //===== add PSNR =====
3904  m_gcAnalyzeAll_in.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3905
3906  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] );
3907  if (printFrameMSE)
3908  {
3909    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3910  }
3911
3912  for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3913  {
3914    cscd[fieldNum].destroy();
3915  }
3916}
3917
3918/** Function for deciding the nal_unit_type.
3919 * \param pocCurr POC of the current picture
3920 * \returns the nal unit type of the picture
3921 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
3922 */
3923NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR, Bool isField)
3924{
3925  if (pocCurr == 0)
3926  {
3927    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3928  }
3929
3930#if EFFICIENT_FIELD_IRAP
3931  if(isField && pocCurr == 1)
3932  {
3933    // to avoid the picture becoming an IRAP
3934    return NAL_UNIT_CODED_SLICE_TRAIL_R;
3935  }
3936#endif
3937
3938#if ALLOW_RECOVERY_POINT_AS_RAP
3939  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3940#else
3941  if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3942#endif
3943  {
3944    if (m_pcCfg->getDecodingRefreshType() == 1)
3945    {
3946      return NAL_UNIT_CODED_SLICE_CRA;
3947    }
3948    else if (m_pcCfg->getDecodingRefreshType() == 2)
3949    {
3950      return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3951    }
3952  }
3953
3954#if POC_RESET_IDC_ENCODER
3955  if(m_pocCraWithoutReset > 0 && this->m_associatedIRAPType == NAL_UNIT_CODED_SLICE_CRA)
3956  {
3957    if(pocCurr < m_pocCraWithoutReset)
3958#else
3959  if(m_pocCRA>0)
3960  {
3961    if(pocCurr<m_pocCRA)
3962#endif
3963    {
3964      // All leading pictures are being marked as TFD pictures here since current encoder uses all
3965      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
3966      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
3967      // controlling the reference pictures used for encoding that leading picture. Such a leading
3968      // picture need not be marked as a TFD picture.
3969      return NAL_UNIT_CODED_SLICE_RASL_R;
3970    }
3971  }
3972  if (lastIDR>0)
3973  {
3974    if (pocCurr < lastIDR)
3975    {
3976      return NAL_UNIT_CODED_SLICE_RADL_R;
3977    }
3978  }
3979  return NAL_UNIT_CODED_SLICE_TRAIL_R;
3980}
3981
3982Double TEncGOP::xCalculateRVM()
3983{
3984  Double dRVM = 0;
3985
3986  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
3987  {
3988    // calculate RVM only for lowdelay configurations
3989    std::vector<Double> vRL , vB;
3990    size_t N = m_vRVM_RP.size();
3991    vRL.resize( N );
3992    vB.resize( N );
3993
3994    Int i;
3995    Double dRavg = 0 , dBavg = 0;
3996    vB[RVM_VCEGAM10_M] = 0;
3997    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3998    {
3999      vRL[i] = 0;
4000      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
4001        vRL[i] += m_vRVM_RP[j];
4002      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
4003      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
4004      dRavg += m_vRVM_RP[i];
4005      dBavg += vB[i];
4006    }
4007
4008    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
4009    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
4010
4011    Double dSigamB = 0;
4012    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
4013    {
4014      Double tmp = vB[i] - dBavg;
4015      dSigamB += tmp * tmp;
4016    }
4017    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
4018
4019    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
4020
4021    dRVM = dSigamB / dRavg * f;
4022  }
4023
4024  return( dRVM );
4025}
4026
4027/** Attaches the input bitstream to the stream in the output NAL unit
4028    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
4029 *  \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu
4030 *  \param rNalu          target NAL unit
4031 */
4032Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream* codedSliceData)
4033{
4034  // Byte-align
4035  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
4036
4037  // Perform bitstream concatenation
4038  if (codedSliceData->getNumberOfWrittenBits() > 0)
4039  {
4040    rNalu.m_Bitstream.addSubstream(codedSliceData);
4041  }
4042
4043  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
4044
4045  codedSliceData->clear();
4046}
4047
4048// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
4049// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
4050Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
4051{
4052  TComReferencePictureSet *rps = pcSlice->getRPS();
4053  if(!rps->getNumberOfLongtermPictures())
4054  {
4055    return;
4056  }
4057
4058  // Arrange long-term reference pictures in the correct order of LSB and MSB,
4059  // and assign values for pocLSBLT and MSB present flag
4060  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
4061  Int longtermPicsMSB[MAX_NUM_REF_PICS];
4062  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
4063  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
4064  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
4065  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
4066  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
4067  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
4068
4069  // Get the long-term reference pictures
4070  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
4071  Int i, ctr = 0;
4072  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
4073  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
4074  {
4075    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
4076    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
4077    indices[ctr]      = i;
4078    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
4079  }
4080  Int numLongPics = rps->getNumberOfLongtermPictures();
4081  assert(ctr == numLongPics);
4082
4083  // Arrange pictures in decreasing order of MSB;
4084  for(i = 0; i < numLongPics; i++)
4085  {
4086    for(Int j = 0; j < numLongPics - 1; j++)
4087    {
4088      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
4089      {
4090        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
4091        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
4092        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
4093        std::swap(indices[j]        , indices[j+1]        );
4094      }
4095    }
4096  }
4097
4098  for(i = 0; i < numLongPics; i++)
4099  {
4100    // Check if MSB present flag should be enabled.
4101    // Check if the buffer contains any pictures that have the same LSB.
4102    TComList<TComPic*>::iterator  iterPic = rcListPic.begin();
4103    TComPic*                      pcPic;
4104    while ( iterPic != rcListPic.end() )
4105    {
4106      pcPic = *iterPic;
4107      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
4108                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
4109                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
4110      {
4111        mSBPresentFlag[i] = true;
4112        break;
4113      }
4114      iterPic++;
4115    }
4116  }
4117
4118  // tempArray for usedByCurr flag
4119  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
4120  for(i = 0; i < numLongPics; i++)
4121  {
4122    tempArray[i] = rps->getUsed(indices[i]);
4123  }
4124  // Now write the final values;
4125  ctr = 0;
4126  Int currMSB = 0, currLSB = 0;
4127  // currPicPoc = currMSB + currLSB
4128  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB);
4129  currMSB = pcSlice->getPOC() - currLSB;
4130
4131  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
4132  {
4133    rps->setPOC                   (i, longtermPicsPoc[ctr]);
4134    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
4135    rps->setUsed                  (i, tempArray[ctr]);
4136    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
4137    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
4138    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);
4139
4140    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
4141  }
4142  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
4143  {
4144    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
4145    {
4146      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
4147      // don't have to check the MSB present flag values for this constraint.
4148      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
4149    }
4150  }
4151}
4152
4153/** Function for finding the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
4154 * \param accessUnit Access Unit of the current picture
4155 * This function finds the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
4156 */
4157Int TEncGOP::xGetFirstSeiLocation(AccessUnit &accessUnit)
4158{
4159  // Find the location of the first SEI message
4160  Int seiStartPos = 0;
4161  for(AccessUnit::iterator it = accessUnit.begin(); it != accessUnit.end(); it++, seiStartPos++)
4162  {
4163     if ((*it)->isSei() || (*it)->isVcl())
4164     {
4165       break;
4166     }
4167  }
4168  //  assert(it != accessUnit.end());  // Triggers with some legit configurations
4169  return seiStartPos;
4170}
4171
4172Void TEncGOP::dblMetric( TComPic* pcPic, UInt uiNumSlices )
4173{
4174  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
4175  Pel* Rec    = pcPicYuvRec->getAddr(COMPONENT_Y);
4176  Pel* tempRec = Rec;
4177  Int  stride = pcPicYuvRec->getStride(COMPONENT_Y);
4178  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
4179  UInt maxTBsize = (1<<log2maxTB);
4180  const UInt minBlockArtSize = 8;
4181  const UInt picWidth = pcPicYuvRec->getWidth(COMPONENT_Y);
4182  const UInt picHeight = pcPicYuvRec->getHeight(COMPONENT_Y);
4183  const UInt noCol = (picWidth>>log2maxTB);
4184  const UInt noRows = (picHeight>>log2maxTB);
4185  assert(noCol > 1);
4186  assert(noRows > 1);
4187  UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64));
4188  UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64));
4189  UInt colIdx = 0;
4190  UInt rowIdx = 0;
4191  Pel p0, p1, p2, q0, q1, q2;
4192
4193  Int qp = pcPic->getSlice(0)->getSliceQp();
4194  Int bitdepthScale = 1 << (g_bitDepth[CHANNEL_TYPE_LUMA]-8);
4195  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
4196  const Int thr2 = (beta>>2);
4197  const Int thr1 = 2*bitdepthScale;
4198  UInt a = 0;
4199
4200  memset(colSAD, 0, noCol*sizeof(UInt64));
4201  memset(rowSAD, 0, noRows*sizeof(UInt64));
4202
4203  if (maxTBsize > minBlockArtSize)
4204  {
4205    // Analyze vertical artifact edges
4206    for(Int c = maxTBsize; c < picWidth; c += maxTBsize)
4207    {
4208      for(Int r = 0; r < picHeight; r++)
4209      {
4210        p2 = Rec[c-3];
4211        p1 = Rec[c-2];
4212        p0 = Rec[c-1];
4213        q0 = Rec[c];
4214        q1 = Rec[c+1];
4215        q2 = Rec[c+2];
4216        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
4217        if ( thr1 < a && a < thr2)
4218        {
4219          colSAD[colIdx] += abs(p0 - q0);
4220        }
4221        Rec += stride;
4222      }
4223      colIdx++;
4224      Rec = tempRec;
4225    }
4226
4227    // Analyze horizontal artifact edges
4228    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
4229    {
4230      for(Int c = 0; c < picWidth; c++)
4231      {
4232        p2 = Rec[c + (r-3)*stride];
4233        p1 = Rec[c + (r-2)*stride];
4234        p0 = Rec[c + (r-1)*stride];
4235        q0 = Rec[c + r*stride];
4236        q1 = Rec[c + (r+1)*stride];
4237        q2 = Rec[c + (r+2)*stride];
4238        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
4239        if (thr1 < a && a < thr2)
4240        {
4241          rowSAD[rowIdx] += abs(p0 - q0);
4242        }
4243      }
4244      rowIdx++;
4245    }
4246  }
4247
4248  UInt64 colSADsum = 0;
4249  UInt64 rowSADsum = 0;
4250  for(Int c = 0; c < noCol-1; c++)
4251  {
4252    colSADsum += colSAD[c];
4253  }
4254  for(Int r = 0; r < noRows-1; r++)
4255  {
4256    rowSADsum += rowSAD[r];
4257  }
4258
4259  colSADsum <<= 10;
4260  rowSADsum <<= 10;
4261  colSADsum /= (noCol-1);
4262  colSADsum /= picHeight;
4263  rowSADsum /= (noRows-1);
4264  rowSADsum /= picWidth;
4265
4266  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
4267  avgSAD >>= (g_bitDepth[CHANNEL_TYPE_LUMA]-8);
4268
4269  if ( avgSAD > 2048 )
4270  {
4271    avgSAD >>= 9;
4272    Int offset = Clip3(2,6,(Int)avgSAD);
4273    for (Int i=0; i<uiNumSlices; i++)
4274    {
4275      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
4276      pcPic->getSlice(i)->setDeblockingFilterDisable(false);
4277      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset );
4278      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset );
4279    }
4280  }
4281  else
4282  {
4283    for (Int i=0; i<uiNumSlices; i++)
4284    {
4285      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
4286      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
4287      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
4288      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
4289    }
4290  }
4291
4292  free(colSAD);
4293  free(rowSAD);
4294}
4295
4296#if Q0096_OVERLAY_SEI
4297SEIOverlayInfo* TEncGOP::xCreateSEIOverlayInfo()
4298{ 
4299  SEIOverlayInfo *sei = new SEIOverlayInfo(); 
4300  sei->m_overlayInfoCancelFlag = m_pcCfg->getOverlaySEICancelFlag();   
4301  if ( !sei->m_overlayInfoCancelFlag )
4302  {
4303    sei->m_overlayContentAuxIdMinus128          = m_pcCfg->getOverlaySEIContentAuxIdMinus128(); 
4304    sei->m_overlayLabelAuxIdMinus128            = m_pcCfg->getOverlaySEILabelAuxIdMinus128(); 
4305    sei->m_overlayAlphaAuxIdMinus128            = m_pcCfg->getOverlaySEIAlphaAuxIdMinus128(); 
4306    sei->m_overlayElementLabelValueLengthMinus8 = m_pcCfg->getOverlaySEIElementLabelValueLengthMinus8(); 
4307    sei->m_numOverlaysMinus1                    = m_pcCfg->getOverlaySEINumOverlaysMinus1();     
4308    sei->m_overlayIdx                           = m_pcCfg->getOverlaySEIIdx();           
4309    sei->m_languageOverlayPresentFlag           = m_pcCfg->getOverlaySEILanguagePresentFlag();
4310    sei->m_overlayContentLayerId                = m_pcCfg->getOverlaySEIContentLayerId();   
4311    sei->m_overlayLabelPresentFlag              = m_pcCfg->getOverlaySEILabelPresentFlag();   
4312    sei->m_overlayLabelLayerId                  = m_pcCfg->getOverlaySEILabelLayerId();   
4313    sei->m_overlayAlphaPresentFlag              = m_pcCfg->getOverlaySEIAlphaPresentFlag();   
4314    sei->m_overlayAlphaLayerId                  = m_pcCfg->getOverlaySEIAlphaLayerId();   
4315    sei->m_numOverlayElementsMinus1             = m_pcCfg->getOverlaySEINumElementsMinus1();
4316    sei->m_overlayElementLabelMin               = m_pcCfg->getOverlaySEIElementLabelMin();
4317    sei->m_overlayElementLabelMax               = m_pcCfg->getOverlaySEIElementLabelMax();   
4318    sei->m_overlayLanguage.resize               ( sei->m_numOverlaysMinus1+1, NULL );
4319    sei->m_overlayLanguageLength.resize         ( sei->m_numOverlaysMinus1+1 );
4320    sei->m_overlayName.resize                   ( sei->m_numOverlaysMinus1+1, NULL );
4321    sei->m_overlayNameLength.resize             ( sei->m_numOverlaysMinus1+1 );
4322    sei->m_overlayElementName.resize            ( sei->m_numOverlaysMinus1+1 );
4323    sei->m_overlayElementNameLength.resize      ( sei->m_numOverlaysMinus1+1 ); 
4324
4325    Int i,j;
4326    string strTmp;
4327    Int nBytes;
4328    assert( m_pcCfg->getOverlaySEILanguage().size()    == sei->m_numOverlaysMinus1+1 );
4329    assert( m_pcCfg->getOverlaySEIName().size()        == sei->m_numOverlaysMinus1+1 );
4330    assert( m_pcCfg->getOverlaySEIElementName().size() == sei->m_numOverlaysMinus1+1 );
4331   
4332    for ( i=0 ; i<=sei->m_numOverlaysMinus1; i++ )
4333    {     
4334      //language tag
4335      if ( sei->m_languageOverlayPresentFlag[i] )
4336      {               
4337        strTmp = m_pcCfg->getOverlaySEILanguage()[i];
4338        nBytes = m_pcCfg->getOverlaySEILanguage()[i].size();       
4339        assert( nBytes>0 );
4340        sei->m_overlayLanguage[i] = new UChar[nBytes];
4341        memcpy(sei->m_overlayLanguage[i], strTmp.c_str(), nBytes);       
4342        sei->m_overlayLanguageLength[i] = nBytes;       
4343      }
4344
4345      //overlay name
4346      strTmp = m_pcCfg->getOverlaySEIName()[i];
4347      nBytes = m_pcCfg->getOverlaySEIName()[i].size();       
4348      assert( nBytes>0 );
4349      sei->m_overlayName[i] = new UChar[nBytes];     
4350      memcpy(sei->m_overlayName[i], strTmp.c_str(), nBytes);       
4351      sei->m_overlayNameLength[i] = nBytes;
4352
4353      //overlay element names
4354      if ( sei->m_overlayLabelPresentFlag[i] )
4355      {       
4356        sei->m_overlayElementName[i].resize( sei->m_numOverlayElementsMinus1[i]+1, NULL );
4357        sei->m_overlayElementNameLength[i].resize( sei->m_numOverlayElementsMinus1[i]+1 );
4358        assert( m_pcCfg->getOverlaySEIElementName()[i].size() == sei->m_numOverlayElementsMinus1[i]+1 );       
4359        for ( j=0 ; j<=sei->m_numOverlayElementsMinus1[i] ; j++)
4360        {
4361          strTmp = m_pcCfg->getOverlaySEIElementName()[i][j];
4362          nBytes = m_pcCfg->getOverlaySEIElementName()[i][j].size();       
4363          assert( nBytes>0 );
4364          sei->m_overlayElementName[i][j] = new UChar[nBytes];
4365          memcpy(sei->m_overlayElementName[i][j], strTmp.c_str(), nBytes);       
4366          sei->m_overlayElementNameLength[i][j] = nBytes;
4367        }
4368      }
4369    }
4370  sei->m_overlayInfoPersistenceFlag = true;
4371  }
4372  return sei;
4373}
4374#endif
4375
4376#if Q0074_COLOUR_REMAPPING_SEI
4377SEIColourRemappingInfo*  TEncGOP::xCreateSEIColourRemappingInfo()
4378{
4379  SEIColourRemappingInfo *seiColourRemappingInfo = new SEIColourRemappingInfo();
4380  seiColourRemappingInfo->m_colourRemapId         = m_pcCfg->getCRISEIId();
4381  seiColourRemappingInfo->m_colourRemapCancelFlag = m_pcCfg->getCRISEICancelFlag();
4382  if( !seiColourRemappingInfo->m_colourRemapCancelFlag )
4383  {
4384    seiColourRemappingInfo->m_colourRemapPersistenceFlag            = m_pcCfg->getCRISEIPersistenceFlag();
4385    seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag = m_pcCfg->getCRISEIVideoSignalInfoPresentFlag();
4386    if( seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag )
4387    {
4388      seiColourRemappingInfo->m_colourRemapFullRangeFlag           = m_pcCfg->getCRISEIFullRangeFlag();
4389      seiColourRemappingInfo->m_colourRemapPrimaries               = m_pcCfg->getCRISEIPrimaries();
4390      seiColourRemappingInfo->m_colourRemapTransferFunction        = m_pcCfg->getCRISEITransferFunction();
4391      seiColourRemappingInfo->m_colourRemapMatrixCoefficients      = m_pcCfg->getCRISEIMatrixCoefficients();
4392    }
4393    seiColourRemappingInfo->m_colourRemapInputBitDepth             = m_pcCfg->getCRISEIInputBitDepth();
4394    seiColourRemappingInfo->m_colourRemapBitDepth                  = m_pcCfg->getCRISEIBitDepth();
4395    for( Int c=0 ; c<3 ; c++ )
4396    {
4397      seiColourRemappingInfo->m_preLutNumValMinus1[c] = m_pcCfg->getCRISEIPreLutNumValMinus1(c);
4398      if( seiColourRemappingInfo->m_preLutNumValMinus1[c]>0 )
4399      {
4400        seiColourRemappingInfo->m_preLutCodedValue[c].resize(seiColourRemappingInfo->m_preLutNumValMinus1[c]+1);
4401        seiColourRemappingInfo->m_preLutTargetValue[c].resize(seiColourRemappingInfo->m_preLutNumValMinus1[c]+1);
4402        for( Int i=0 ; i<=seiColourRemappingInfo->m_preLutNumValMinus1[c] ; i++)
4403        {
4404          seiColourRemappingInfo->m_preLutCodedValue[c][i]  = (m_pcCfg->getCRISEIPreLutCodedValue(c))[i];
4405          seiColourRemappingInfo->m_preLutTargetValue[c][i] = (m_pcCfg->getCRISEIPreLutTargetValue(c))[i];
4406        }
4407      }
4408    }
4409    seiColourRemappingInfo->m_colourRemapMatrixPresentFlag = m_pcCfg->getCRISEIMatrixPresentFlag();
4410    if( seiColourRemappingInfo->m_colourRemapMatrixPresentFlag )
4411    {
4412      seiColourRemappingInfo->m_log2MatrixDenom = m_pcCfg->getCRISEILog2MatrixDenom();
4413      for( Int c=0 ; c<3 ; c++ )
4414        for( Int i=0 ; i<3 ; i++ )
4415          seiColourRemappingInfo->m_colourRemapCoeffs[c][i] = (m_pcCfg->getCRISEICoeffs(c))[i];
4416    }
4417    for( Int c=0 ; c<3 ; c++ )
4418    {
4419      seiColourRemappingInfo->m_postLutNumValMinus1[c] = m_pcCfg->getCRISEIPostLutNumValMinus1(c);
4420      if( seiColourRemappingInfo->m_postLutNumValMinus1[c]>0 )
4421      {
4422        seiColourRemappingInfo->m_postLutCodedValue[c].resize(seiColourRemappingInfo->m_postLutNumValMinus1[c]+1);
4423        seiColourRemappingInfo->m_postLutTargetValue[c].resize(seiColourRemappingInfo->m_postLutNumValMinus1[c]+1);
4424        for( Int i=0 ; i<=seiColourRemappingInfo->m_postLutNumValMinus1[c] ; i++)
4425        {
4426          seiColourRemappingInfo->m_postLutCodedValue[c][i]  = (m_pcCfg->getCRISEIPostLutCodedValue(c))[i];
4427          seiColourRemappingInfo->m_postLutTargetValue[c][i] = (m_pcCfg->getCRISEIPostLutTargetValue(c))[i];
4428        }
4429      }
4430    }
4431  }
4432  return seiColourRemappingInfo;
4433}
4434#endif
4435
4436#if SVC_EXTENSION
4437#if LAYERS_NOT_PRESENT_SEI
4438SEILayersNotPresent* TEncGOP::xCreateSEILayersNotPresent ()
4439{
4440  UInt i = 0;
4441  SEILayersNotPresent *seiLayersNotPresent = new SEILayersNotPresent(); 
4442  seiLayersNotPresent->m_activeVpsId = m_pcCfg->getVPS()->getVPSId(); 
4443  seiLayersNotPresent->m_vpsMaxLayers = m_pcCfg->getVPS()->getMaxLayers();
4444  for ( ; i < seiLayersNotPresent->m_vpsMaxLayers; i++)
4445  {
4446    seiLayersNotPresent->m_layerNotPresentFlag[i] = true; 
4447  }
4448  for ( ; i < MAX_LAYERS; i++)
4449  {
4450    seiLayersNotPresent->m_layerNotPresentFlag[i] = false; 
4451  }
4452  return seiLayersNotPresent;
4453}
4454#endif
4455
4456#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
4457SEIInterLayerConstrainedTileSets* TEncGOP::xCreateSEIInterLayerConstrainedTileSets()
4458{
4459  SEIInterLayerConstrainedTileSets *seiInterLayerConstrainedTileSets = new SEIInterLayerConstrainedTileSets();
4460  seiInterLayerConstrainedTileSets->m_ilAllTilesExactSampleValueMatchFlag = false;
4461  seiInterLayerConstrainedTileSets->m_ilOneTilePerTileSetFlag = false;
4462  if (!seiInterLayerConstrainedTileSets->m_ilOneTilePerTileSetFlag)
4463  {
4464    seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1 = m_pcCfg->getIlNumSetsInMessage() - 1;
4465    if (seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1)
4466    {
4467      seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag = m_pcCfg->getSkippedTileSetPresentFlag();
4468    }
4469    else
4470    {
4471      seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag = false;
4472    }
4473    seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1 += seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag ? 1 : 0;
4474    for (UInt i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
4475    {
4476      seiInterLayerConstrainedTileSets->m_ilctsId[i] = i;
4477      seiInterLayerConstrainedTileSets->m_ilNumTileRectsInSetMinus1[i] = 0;
4478      for( UInt j = 0; j <= seiInterLayerConstrainedTileSets->m_ilNumTileRectsInSetMinus1[i]; j++)
4479      {
4480        seiInterLayerConstrainedTileSets->m_ilTopLeftTileIndex[i][j]     = m_pcCfg->getTopLeftTileIndex(i);
4481        seiInterLayerConstrainedTileSets->m_ilBottomRightTileIndex[i][j] = m_pcCfg->getBottomRightTileIndex(i);
4482      }
4483      seiInterLayerConstrainedTileSets->m_ilcIdc[i] = m_pcCfg->getIlcIdc(i);
4484      if (seiInterLayerConstrainedTileSets->m_ilAllTilesExactSampleValueMatchFlag)
4485      {
4486        seiInterLayerConstrainedTileSets->m_ilExactSampleValueMatchFlag[i] = false;
4487      }
4488    }
4489  }
4490
4491  return seiInterLayerConstrainedTileSets;
4492}
4493
4494Void TEncGOP::xBuildTileSetsMap(TComPicSym* picSym)
4495{
4496  Int numCUs = picSym->getFrameWidthInCtus() * picSym->getFrameHeightInCtus();
4497
4498  for (Int i = 0; i < numCUs; i++)
4499  {
4500    picSym->setTileSetIdxMap(i, -1, 0, false);
4501  }
4502
4503  for (Int i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
4504  {
4505    const TComTile* topLeftTile     = picSym->getTComTile(m_pcCfg->getTopLeftTileIndex(i));
4506    TComTile* bottomRightTile = picSym->getTComTile(m_pcCfg->getBottomRightTileIndex(i));
4507    Int tileSetLeftEdgePosInCU = topLeftTile->getRightEdgePosInCtus() - topLeftTile->getTileWidthInCtus() + 1;
4508    Int tileSetRightEdgePosInCU = bottomRightTile->getRightEdgePosInCtus();
4509    Int tileSetTopEdgePosInCU = topLeftTile->getBottomEdgePosInCtus() - topLeftTile->getTileHeightInCtus() + 1;
4510    Int tileSetBottomEdgePosInCU = bottomRightTile->getBottomEdgePosInCtus();
4511    assert(tileSetLeftEdgePosInCU < tileSetRightEdgePosInCU && tileSetTopEdgePosInCU < tileSetBottomEdgePosInCU);
4512    for (Int j = tileSetTopEdgePosInCU; j <= tileSetBottomEdgePosInCU; j++)
4513    {
4514      for (Int k = tileSetLeftEdgePosInCU; k <= tileSetRightEdgePosInCU; k++)
4515      {
4516        picSym->setTileSetIdxMap(j * picSym->getFrameWidthInCtus() + k, i, m_pcCfg->getIlcIdc(i), false);
4517      }
4518    }
4519  }
4520 
4521  if (m_pcCfg->getSkippedTileSetPresentFlag())
4522  {
4523    Int skippedTileSetIdx = m_pcCfg->getIlNumSetsInMessage();
4524    for (Int i = 0; i < numCUs; i++)
4525    {
4526      if (picSym->getTileSetIdxMap(i) < 0)
4527      {
4528        picSym->setTileSetIdxMap(i, skippedTileSetIdx, 0, true);
4529      }
4530    }
4531  }
4532}
4533#endif
4534
4535
4536#if POC_RESET_IDC_ENCODER
4537Void TEncGOP::determinePocResetIdc(Int const pocCurr, TComSlice *const slice)
4538{
4539  // If one picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 1 or 2
4540  // If BL picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 2
4541  // If BL picture is IRAP, and another picture is non-IRAP, then the poc_reset_idc is equal to 1 or 2.
4542#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4543  slice->setPocMsbNeeded(false);
4544#endif
4545  if( slice->getSliceIdx() == 0 ) // First slice - compute, copy for other slices
4546  {
4547    Int needReset = false;
4548    Int resetDueToBL = false;
4549    if( slice->getVPS()->getMaxLayers() > 1 )
4550    {
4551      // If IRAP is refreshed in this access unit for base layer
4552      if( (m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 1 || m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2)
4553        && ( pocCurr % m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
4554        )
4555      {
4556        // Check if the IRAP refresh interval of any layer does not match that of the base layer
4557        for(Int i = 1; i < slice->getVPS()->getMaxLayers(); i++)
4558        {
4559          Bool refreshIntervalFlag = ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 );
4560          Bool refreshTypeFlag     = ( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() );
4561          if( !(refreshIntervalFlag && refreshTypeFlag) )
4562          {
4563            needReset = true;
4564            resetDueToBL = true;
4565            break;
4566          }
4567        }
4568      }
4569    }
4570   
4571    if( !needReset )// No need reset due to base layer IRAP
4572    {
4573      // Check if EL IDRs results in POC Reset
4574      for(Int i = 1; i < slice->getVPS()->getMaxLayers() && !needReset; i++)
4575      {
4576        Bool idrFlag = ( (m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() == 2) 
4577                        && ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
4578                        );
4579        for(Int j = 0; j < slice->getVPS()->getMaxLayers(); j++)
4580        {
4581          if( j == i )
4582          {
4583            continue;
4584          }
4585          Bool idrOtherPicFlag = ( (m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshType() == 2) 
4586                                  && ( pocCurr % m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
4587                                  );
4588
4589          if( idrFlag != idrOtherPicFlag )
4590          {
4591            needReset = true;
4592            break;
4593          }
4594        }
4595      }
4596    }
4597    if( needReset )
4598    {
4599      if( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2 )  // BL IDR refresh, assuming BL picture present
4600      {
4601        if( resetDueToBL )
4602        {
4603          slice->setPocResetIdc( 2 ); // Full reset needed
4604#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4605          if (slice->getVPS()->getVpsPocLsbAlignedFlag() && slice->getVPS()->getNumDirectRefLayers(slice->getLayerId()) == 0)
4606          {
4607            slice->setPocMsbNeeded(true);  // Force msb writing
4608          }
4609#endif
4610        }
4611        else
4612        {
4613          slice->setPocResetIdc( 1 ); // Due to IDR in EL
4614        }
4615      }
4616      else
4617      {
4618        slice->setPocResetIdc( 1 ); // Only MSB reset
4619      }
4620
4621      // Start a new POC reset period
4622      if (m_layerId == 0)   // Assuming BL picture is always present at encoder; for other AU structures, need to change this
4623      {
4624        Int periodId = rand() % 64;
4625        m_lastPocPeriodId = (periodId == m_lastPocPeriodId) ? (periodId + 1) % 64 : periodId ;
4626
4627#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4628        for (UInt i = 0; i < MAX_LAYERS; i++)
4629        {
4630          m_ppcTEncTop[i]->setPocDecrementedInDPBFlag(false);
4631        }
4632#endif
4633      }
4634      else
4635      {
4636        m_lastPocPeriodId = m_ppcTEncTop[0]->getGOPEncoder()->getLastPocPeriodId();
4637      }
4638      slice->setPocResetPeriodId(m_lastPocPeriodId);
4639    }
4640    else
4641    {
4642      slice->setPocResetIdc( 0 );
4643    }
4644  }
4645}
4646
4647Void TEncGOP::updatePocValuesOfPics(Int const pocCurr, TComSlice *const slice)
4648{
4649#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4650  UInt affectedLayerList[MAX_NUM_LAYER_IDS];
4651  Int  numAffectedLayers;
4652
4653  affectedLayerList[0] = m_layerId;
4654  numAffectedLayers = 1;
4655
4656  if (m_pcEncTop->getVPS()->getVpsPocLsbAlignedFlag())
4657  {
4658    for (UInt j = 0; j < m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId); j++)
4659    {
4660      affectedLayerList[j + 1] = m_pcEncTop->getVPS()->getPredictedLayerId(m_layerId, j);
4661    }
4662    numAffectedLayers = m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId) + 1;
4663  }
4664#endif
4665
4666  Int pocAdjustValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4667
4668  // New POC reset period
4669  Int maxPocLsb, pocLsbVal, pocMsbDelta, pocLsbDelta, deltaPocVal;
4670
4671  maxPocLsb   = 1 << slice->getSPS()->getBitsForPOC();
4672
4673#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4674  Int adjustedPocValue = pocCurr;
4675
4676  if (m_pcEncTop->getFirstPicInLayerDecodedFlag())
4677  {
4678#endif
4679
4680  pocLsbVal   = (slice->getPocResetIdc() == 3)
4681                ? slice->getPocLsbVal()
4682                : pocAdjustValue % maxPocLsb; 
4683  pocMsbDelta = pocAdjustValue - pocLsbVal;
4684  pocLsbDelta = (slice->getPocResetIdc() == 2 || ( slice->getPocResetIdc() == 3 && slice->getFullPocResetFlag() )) 
4685                ? pocLsbVal 
4686                : 0; 
4687  deltaPocVal = pocMsbDelta  + pocLsbDelta;
4688
4689#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4690  Int origDeltaPocVal = deltaPocVal;  // original value needed when updating POC adjustment value
4691
4692  if (slice->getPocMsbNeeded())  // IDR picture in base layer, non-IDR picture in other layers, poc_lsb_aligned_flag = 1
4693  {
4694    if (slice->getLayerId() == 0)
4695    {
4696      Int highestPoc = INT_MIN;
4697      // Find greatest POC in DPB for layer 0
4698      for (TComList<TComPic*>::iterator iterPic = m_pcEncTop->getListPic()->begin(); iterPic != m_pcEncTop->getListPic()->end(); ++iterPic)
4699      {
4700        TComPic *dpbPic = *iterPic;
4701        if (dpbPic->getReconMark() && dpbPic->getLayerId() == 0 && dpbPic->getPOC() > highestPoc)
4702        {
4703          highestPoc = dpbPic->getPOC();
4704        }
4705      }
4706      deltaPocVal = (highestPoc - (highestPoc & (maxPocLsb - 1))) + 1*maxPocLsb;
4707      m_pcEncTop->setCurrPocMsb(deltaPocVal);
4708    }
4709    else
4710    {
4711      deltaPocVal = m_ppcTEncTop[0]->getCurrPocMsb();  // copy from base layer
4712    }
4713    slice->setPocMsbVal(deltaPocVal);
4714  }
4715
4716  for (UInt layerIdx = 0; layerIdx < numAffectedLayers; layerIdx++)
4717  {
4718    if (!m_ppcTEncTop[affectedLayerList[layerIdx]]->getPocDecrementedInDPBFlag())
4719    {
4720      m_ppcTEncTop[affectedLayerList[layerIdx]]->setPocDecrementedInDPBFlag(true);
4721
4722      // Decrement value of associatedIrapPoc of the TEncGop object
4723      m_ppcTEncTop[affectedLayerList[layerIdx]]->getGOPEncoder()->m_associatedIRAPPOC -= deltaPocVal;
4724
4725      // Decrememnt the value of m_pocCRA
4726      m_ppcTEncTop[affectedLayerList[layerIdx]]->getGOPEncoder()->m_pocCRA -= deltaPocVal;
4727
4728      TComList<TComPic*>::iterator  iterPic = m_ppcTEncTop[affectedLayerList[layerIdx]]->getListPic()->begin();
4729      while (iterPic != m_ppcTEncTop[affectedLayerList[layerIdx]]->getListPic()->end())
4730#else
4731  // Decrement value of associatedIrapPoc of the TEncGop object
4732  this->m_associatedIRAPPOC -= deltaPocVal;
4733
4734  // Decrememnt the value of m_pocCRA
4735  this->m_pocCRA -= deltaPocVal;
4736
4737  // Iterate through all pictures in the DPB
4738  TComList<TComPic*>::iterator  iterPic = getListPic()->begin(); 
4739  while( iterPic != getListPic()->end() )
4740#endif
4741  {
4742    TComPic *dpbPic = *iterPic;
4743   
4744    if( dpbPic->getReconMark() )
4745    {
4746      for(Int i = dpbPic->getNumAllocatedSlice() - 1; i >= 0; i--)
4747      {
4748        TComSlice *dpbPicSlice = dpbPic->getSlice( i );
4749        TComReferencePictureSet *dpbPicRps = dpbPicSlice->getRPS();
4750
4751        // Decrement POC of slice
4752        dpbPicSlice->setPOC( dpbPicSlice->getPOC() - deltaPocVal );
4753
4754        // Decrement POC value stored in the RPS of each such slice
4755        for( Int j = dpbPicRps->getNumberOfPictures() - 1; j >= 0; j-- )
4756        {
4757          dpbPicRps->setPOC( j, dpbPicRps->getPOC(j) - deltaPocVal );
4758        }
4759
4760        // Decrement value of refPOC
4761        dpbPicSlice->decrementRefPocValues( deltaPocVal );
4762
4763        // Update value of associatedIrapPoc of each slice
4764        dpbPicSlice->setAssociatedIRAPPOC( dpbPicSlice->getAssociatedIRAPPOC() - deltaPocVal );
4765
4766#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4767        if (slice->getPocMsbNeeded())
4768        {
4769          // this delta value is needed when computing delta POCs in reference picture set initialization
4770          dpbPicSlice->setPocResetDeltaPoc(dpbPicSlice->getPocResetDeltaPoc() + (deltaPocVal - pocLsbVal));
4771        }
4772#endif
4773      }
4774    }
4775    iterPic++;
4776  }
4777#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4778    }
4779  }
4780#endif
4781
4782  // Actual POC value before reset
4783#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4784  adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4785#else
4786  Int adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4787#endif
4788
4789  // Set MSB value before reset
4790  Int tempLsbVal = adjustedPocValue & (maxPocLsb - 1);
4791#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4792  if (!slice->getPocMsbNeeded())  // set poc msb normally if special msb handling is not needed
4793  {
4794#endif
4795    slice->setPocMsbVal(adjustedPocValue - tempLsbVal);
4796#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4797  }
4798#endif
4799
4800  // Set LSB value before reset - this is needed in the case of resetIdc = 2
4801  slice->setPicOrderCntLsb( tempLsbVal );
4802
4803  // Cumulative delta
4804#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4805  deltaPocVal = origDeltaPocVal;  // restore deltaPoc for correct adjustment value update
4806#endif
4807  m_pcEncTop->setPocAdjustmentValue( m_pcEncTop->getPocAdjustmentValue() + deltaPocVal );
4808
4809#if P0297_VPS_POC_LSB_ALIGNED_FLAG
4810  }
4811#endif
4812
4813  // New LSB value, after reset
4814  adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4815  Int newLsbVal = adjustedPocValue & (maxPocLsb - 1);
4816
4817  // Set value of POC current picture after RESET
4818  if( slice->getPocResetIdc() == 1 )
4819  {
4820    slice->setPOC( newLsbVal );
4821  }
4822  else if( slice->getPocResetIdc() == 2 )
4823  {
4824    slice->setPOC( 0 );
4825  }
4826  else if( slice->getPocResetIdc() == 3 )
4827  {
4828    Int picOrderCntMsb = slice->getCurrMsb( newLsbVal, 
4829                                        slice->getFullPocResetFlag() ? 0 : slice->getPocLsbVal(), 
4830                                        0,
4831                                        maxPocLsb );
4832    slice->setPOC( picOrderCntMsb + newLsbVal );
4833  }
4834  else
4835  {
4836    assert(0);
4837  }
4838}
4839#endif
4840
4841
4842#if O0164_MULTI_LAYER_HRD
4843#if VPS_VUI_BSP_HRD_PARAMS
4844SEIScalableNesting* TEncGOP::xCreateBspNestingSEI(TComSlice *pcSlice, Int olsIdx, Int partitioningSchemeIdx, Int bspIdx)
4845#else
4846SEIScalableNesting* TEncGOP::xCreateBspNestingSEI(TComSlice *pcSlice)
4847#endif
4848{
4849  SEIScalableNesting *seiScalableNesting = new SEIScalableNesting();
4850  SEIBspInitialArrivalTime *seiBspInitialArrivalTime = new SEIBspInitialArrivalTime();
4851  SEIBspNesting *seiBspNesting = new SEIBspNesting();
4852  SEIBufferingPeriod *seiBufferingPeriod = new SEIBufferingPeriod();
4853
4854  // Scalable nesting SEI
4855
4856  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
4857  seiScalableNesting->m_nestingOpFlag                 = 1;
4858  seiScalableNesting->m_defaultOpFlag                 = 0;
4859  seiScalableNesting->m_nestingNumOpsMinus1           = 0;      //nesting_num_ops_minus1
4860#if VPS_VUI_BSP_HRD_PARAMS
4861  seiScalableNesting->m_nestingOpIdx[0]               = pcSlice->getVPS()->getOutputLayerSetIdx(olsIdx);
4862  seiScalableNesting->m_nestingMaxTemporalIdPlus1[0]  = 6 + 1;
4863#else
4864  seiScalableNesting->m_nestingOpIdx[0]               = 1;
4865#endif
4866  seiScalableNesting->m_allLayersFlag                 = 0;
4867  seiScalableNesting->m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1;  //nesting_no_op_max_temporal_id_plus1
4868  seiScalableNesting->m_nestingNumLayersMinus1        = 1 - 1;  //nesting_num_layers_minus1
4869  seiScalableNesting->m_nestingLayerId[0]             = 0;
4870  seiScalableNesting->m_callerOwnsSEIs                = true;
4871
4872  // Bitstream partition nesting SEI
4873
4874  seiBspNesting->m_bspIdx = 0;
4875  seiBspNesting->m_callerOwnsSEIs = true;
4876
4877  // Buffering period SEI
4878
4879  UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
4880  seiBufferingPeriod->m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
4881  seiBufferingPeriod->m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
4882  seiBufferingPeriod->m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
4883  seiBufferingPeriod->m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
4884
4885  Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
4886
4887  UInt uiTmp = (UInt)( dTmp * 90000.0 ); 
4888  uiInitialCpbRemovalDelay -= uiTmp;
4889  uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
4890  seiBufferingPeriod->m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
4891  seiBufferingPeriod->m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
4892  seiBufferingPeriod->m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
4893  seiBufferingPeriod->m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
4894
4895  seiBufferingPeriod->m_rapCpbParamsPresentFlag              = 0;
4896  //for the concatenation, it can be set to one during splicing.
4897  seiBufferingPeriod->m_concatenationFlag = 0;
4898  //since the temporal layer HRD is not ready, we assumed it is fixed
4899  seiBufferingPeriod->m_auCpbRemovalDelayDelta = 1;
4900  seiBufferingPeriod->m_cpbDelayOffset = 0;
4901  seiBufferingPeriod->m_dpbDelayOffset = 0;
4902
4903  // Intial arrival time SEI message
4904
4905  seiBspInitialArrivalTime->m_nalInitialArrivalDelay[0] = 0;
4906  seiBspInitialArrivalTime->m_vclInitialArrivalDelay[0] = 0;
4907
4908
4909  seiBspNesting->m_nestedSEIs.push_back(seiBufferingPeriod);
4910  seiBspNesting->m_nestedSEIs.push_back(seiBspInitialArrivalTime);
4911#if VPS_VUI_BSP_HRD_PARAMS
4912  seiBspNesting->m_bspIdx = bspIdx;
4913  seiBspNesting->m_seiOlsIdx = olsIdx;
4914  seiBspNesting->m_seiPartitioningSchemeIdx = partitioningSchemeIdx;
4915#endif
4916  seiScalableNesting->m_nestedSEIs.push_back(seiBspNesting); // BSP nesting SEI is contained in scalable nesting SEI
4917
4918  return seiScalableNesting;
4919}
4920#endif
4921
4922#if Q0048_CGS_3D_ASYMLUT
4923Void TEncGOP::xDetermin3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS )
4924{
4925  Int nCGSFlag = pSlice->getPPS()->getCGSFlag();
4926  m_Enc3DAsymLUTPPS.setPPSBit( 0 );
4927  Double dErrorUpdatedPPS = 0 , dErrorPPS = 0;
4928
4929#if R0179_ENC_OPT_3DLUT_SIZE
4930  Int nTLthres = m_pcCfg->getCGSLutSizeRDO() ? 2:7;
4931  Double dFrameLambda; 
4932#if FULL_NBIT
4933  Int    SHIFT_QP = 12 + 6 * (pSlice->getBitDepthY() - 8);
4934#else
4935  Int    SHIFT_QP = 12; 
4936#endif
4937  Int QP = pSlice->getSliceQp();
4938
4939  // set frame lambda
4940  dFrameLambda = 0.68 * pow (2, (QP  - SHIFT_QP) / 3.0) * (m_pcCfg->getGOPSize() > 1 && pSlice->isInterB()? 2 : 1);
4941
4942  if(m_pcCfg->getCGSLutSizeRDO() == 1 && (!bSignalPPS && (pSlice->getDepth() < nTLthres))) 
4943    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB(), dFrameLambda );
4944  else if (pSlice->getDepth() >= nTLthres)
4945    dErrorUpdatedPPS = MAX_DOUBLE;
4946  else // if (m_pcCfg->getCGSLutSizeRDO() = 0 || bSignalPPS)
4947#endif   
4948    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB() );
4949
4950
4951  if( bSignalPPS )
4952  {
4953    m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4954    pSlice->setCGSOverWritePPS( 1 ); // regular PPS update
4955  }
4956  else if( nCGSFlag )
4957  {
4958#if R0179_ENC_OPT_3DLUT_SIZE
4959    if(pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R || pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N) 
4960    {
4961      pSlice->setCGSOverWritePPS( 0 ); 
4962    }
4963    else if (pSlice->getDepth() >= nTLthres) 
4964    {
4965      pSlice->setCGSOverWritePPS( 0 ); 
4966    }
4967    else
4968    {
4969#endif   
4970      dErrorPPS = m_Enc3DAsymLUTPPS.estimateDistWithCur3DAsymLUT( pCurPic , refLayerIdc );
4971      Double dFactor = pCfg->getIntraPeriod() == 1 ? 0.99 : 0.9;
4972
4973#if R0179_ENC_OPT_3DLUT_SIZE
4974      if( m_pcCfg->getCGSLutSizeRDO() )
4975      {
4976        dErrorPPS = dErrorPPS/m_Enc3DAsymLUTPicUpdate.getDistFactor(pSlice->getSliceType(), pSlice->getDepth()); 
4977      }
4978#endif
4979      pSlice->setCGSOverWritePPS( dErrorUpdatedPPS < dFactor * dErrorPPS );
4980#if R0179_ENC_OPT_3DLUT_SIZE
4981    }
4982#endif
4983    if( pSlice->getCGSOverWritePPS() )
4984    {
4985      m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4986    }
4987  }
4988  pSlice->getPPS()->setCGSOutputBitDepthY( m_Enc3DAsymLUTPPS.getOutputBitDepthY() );
4989  pSlice->getPPS()->setCGSOutputBitDepthC( m_Enc3DAsymLUTPPS.getOutputBitDepthC() );
4990}
4991
4992Void TEncGOP::downScalePic( TComPicYuv* pcYuvSrc, TComPicYuv* pcYuvDest)
4993{
4994  Int inputBitDepth  = g_bitDepthLayer[CHANNEL_TYPE_LUMA][m_layerId];
4995  Int outputBitDepth = g_bitDepthLayer[CHANNEL_TYPE_CHROMA][m_layerId];
4996  {
4997    pcYuvSrc->setBorderExtension(false);
4998    pcYuvSrc->extendPicBorder   (); // extend the border.
4999    pcYuvSrc->setBorderExtension(false);
5000
5001    Int iWidth  = pcYuvSrc->getWidth(COMPONENT_Y);
5002    Int iHeight = pcYuvSrc->getHeight(COMPONENT_Y); 
5003
5004    if(!m_temp)
5005    {
5006      initDs(iWidth, iHeight, m_pcCfg->getIntraPeriod()>1);
5007    }
5008
5009    filterImg(pcYuvSrc->getAddr(COMPONENT_Y),  pcYuvSrc->getStride(COMPONENT_Y),  pcYuvDest->getAddr(COMPONENT_Y),  pcYuvDest->getStride(COMPONENT_Y),  iHeight,    iWidth,    inputBitDepth-outputBitDepth, 0);
5010    filterImg(pcYuvSrc->getAddr(COMPONENT_Cb), pcYuvSrc->getStride(COMPONENT_Cb), pcYuvDest->getAddr(COMPONENT_Cb), pcYuvDest->getStride(COMPONENT_Cb), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 1);
5011    filterImg(pcYuvSrc->getAddr(COMPONENT_Cr), pcYuvSrc->getStride(COMPONENT_Cr), pcYuvDest->getAddr(COMPONENT_Cr), pcYuvDest->getStride(COMPONENT_Cr), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 2); 
5012  }
5013}
5014const Int TEncGOP::m_phase_filter_0_t0[4][13]={
5015  {0,  2,  -3,  -9,   6,  39,  58,  39,   6,  -9,  -3,  2,  0}, 
5016  {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},  //
5017  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
5018  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
5019};
5020
5021const Int TEncGOP::m_phase_filter_0_t1[4][13]={
5022  {0,  4,  0,  -12, 0,  40,  64,  40, 0, -12,  0,  4,  0},
5023  {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},  //
5024  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
5025  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
5026};
5027const Int TEncGOP::m_phase_filter_0_t1_chroma[4][13]={
5028  {0,  0,  0,   0,  0,   0,  128, 0,  0,  0,  0,  0,  0},
5029  {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},  //
5030  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
5031  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
5032};
5033
5034const Int TEncGOP::m_phase_filter_1[8][13]={
5035  {0,   0,  5,  -6,  -10,37,  76,  37,-10,   -6, 5,  0,   0},   
5036  {0,  -1,  5,  -3,  -12,29,  75,  45,  -7,   -8, 5,  0,   0},   
5037  {0,  -1,  4,  -1,  -13,22,  73,  52,  -3,  -10, 4,  1,   0},   
5038  {0,  -1,  4,   1,  -13,14,  70,  59,   2,  -12, 3,  2,  -1}, 
5039  {0,  -1,  3,   2,  -13, 8,  65,  65,   8,  -13, 2,  3,  -1},   
5040  {0,  -1,  2,   3,  -12, 2,  59,  70,  14,  -13, 1,  4,  -1},   
5041  {0,   0,  1,   4,  -10,-3,  52,  73,  22,  -13,-1,  4,  -1},   
5042  {0,   0,  0,   5,   -8,-7,  45,  75,  29,  -12,-3,  5,  -1}   
5043};
5044
5045#if CGS_GCC_NO_VECTORIZATION 
5046#ifdef __GNUC__
5047#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
5048#if GCC_VERSION > 40600
5049__attribute__((optimize("no-tree-vectorize")))
5050#endif
5051#endif
5052#endif
5053Void TEncGOP::filterImg(
5054    Pel           *src,
5055    Int           iSrcStride,
5056    Pel           *dst,
5057    Int           iDstStride,
5058    Int           height1, 
5059    Int           width1, 
5060    Int           shift,
5061    Int           plane)
5062{
5063  Int length = m_iTap;
5064  Int height2,width2;
5065  Int k,iSum;
5066  Int i0, div_i0, i1;
5067  Int j0, div_j0, j1;
5068  const Int *p_filter;
5069  Pel *p_src, *p_dst;
5070  Pel *p_src_line, *p_dst_line;
5071  Int **p_temp, *p_tmp;
5072  Int shift2 = 2*7+shift;
5073  Int shift_round = (1 << (shift2 - 1));
5074  Int iMax = (1<<(g_bitDepth[CHANNEL_TYPE_LUMA]-shift))-1;
5075  height2 = (height1 * m_iM) / m_iN;
5076  width2  = (width1  * m_iM) / m_iN;
5077
5078  m_phase_filter = plane? m_phase_filter_chroma : m_phase_filter_luma;
5079
5080  // horizontal filtering
5081  p_src_line = src;
5082  for(j1 = 0; j1 < height1; j1++)
5083  {
5084    i0=-m_iN;
5085    p_tmp = m_temp[j1];
5086   
5087    for(i1 = 0; i1 < width2; i1++)
5088    {
5089      i0      += m_iN;
5090      div_i0   = (i0 / m_iM);
5091      p_src    =  p_src_line + ( div_i0 - (length >> 1));
5092      p_filter = m_phase_filter[i0 - div_i0 * m_iM]; // phase_filter[i0 % M]
5093      iSum     = 0;
5094      for(k = 0; k < length; k++)
5095      {
5096        iSum += (*p_src++) * (*p_filter++);
5097      }
5098      *p_tmp++ = iSum;
5099    }
5100    p_src_line +=  iSrcStride;
5101  }
5102
5103  // pad temp (vertical)
5104  for (k=-(length>>1); k<0; k++)
5105  {
5106    memcpy(m_temp[k], m_temp[0], width2*sizeof(Int));
5107  }
5108  for (k=height1; k<(height1+(length>>1)); k++)
5109  {
5110    memcpy(m_temp[k], m_temp[k-1], (width2)* sizeof(Int));
5111  }
5112
5113  // vertical filtering
5114  j0 = (plane == 0) ? -m_iN : -(m_iN-1);
5115 
5116  p_dst_line = dst;
5117  for(j1 = 0; j1 < height2; j1++)
5118  {
5119    j0      += m_iN;
5120    div_j0   = (j0 / m_iM);
5121    p_dst = p_dst_line;
5122    p_temp   = &m_temp[div_j0 - (length>>1)];
5123    p_filter = m_phase_filter[j0 - div_j0 * m_iM]; // phase_filter[j0 % M]
5124    for(i1 = 0; i1 < width2;i1++)
5125    {
5126      iSum=0;
5127      for(k = 0; k < length; k++)
5128      {
5129        iSum += p_temp[k][i1] * p_filter[k];
5130      }
5131      iSum=((iSum + shift_round) >> shift2);
5132      *p_dst++ = (Short)(iSum > iMax ? iMax : (iSum < 0 ? 0 : iSum));
5133    }
5134    p_dst_line += iDstStride;
5135  }
5136}
5137
5138Void TEncGOP::initDs(Int iWidth, Int iHeight, Int iType)
5139{
5140  m_iTap = 13;
5141  if(g_posScalingFactor[0][0] == (1<<15))
5142  {
5143    m_iM = 4;
5144    m_iN = 8;
5145    m_phase_filter_luma = iType? m_phase_filter_0_t1 : m_phase_filter_0_t0;
5146    m_phase_filter_chroma = m_phase_filter_0_t1_chroma; 
5147  }
5148  else
5149  {
5150    m_iM = 8;
5151    m_iN = 12;
5152    m_phase_filter_luma = m_phase_filter_chroma =  m_phase_filter_1;
5153    m_phase_filter = m_phase_filter_1;
5154  }
5155
5156  get_mem2DintWithPad (&m_temp, iHeight, iWidth*m_iM/m_iN,   m_iTap>>1, 0);
5157}
5158
5159Int TEncGOP::get_mem2DintWithPad(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX)
5160{
5161  Int i;
5162  Int *curr = NULL;
5163  Int iHeight, iWidth;
5164
5165  iHeight = dim0+2*iPadY;
5166  iWidth = dim1+2*iPadX;
5167  (*array2D) = (Int**)malloc(iHeight*sizeof(Int*));
5168  *(*array2D) = (Int* )xMalloc(Int, iHeight*iWidth);
5169
5170  (*array2D)[0] += iPadX;
5171  curr = (*array2D)[0];
5172  for(i = 1 ; i < iHeight; i++)
5173  {
5174    curr += iWidth;
5175    (*array2D)[i] = curr;
5176  }
5177  (*array2D) = &((*array2D)[iPadY]);
5178
5179  return 0;
5180}
5181
5182Void TEncGOP::free_mem2DintWithPad(Int **array2D, Int iPadY, Int iPadX)
5183{
5184  if (array2D)
5185  {
5186    if (*array2D)
5187    {
5188      xFree(array2D[-iPadY]-iPadX);
5189    }
5190    else 
5191    {
5192      printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
5193    }
5194
5195    free (&array2D[-iPadY]);
5196  } 
5197  else
5198  {
5199    printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
5200  }
5201}
5202#endif
5203#endif //SVC_EXTENSION
5204
5205//! \}
Note: See TracBrowser for help on using the repository browser.