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

Last change on this file since 1242 was 1237, checked in by seregin, 9 years ago

port rev 4221

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