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

Last change on this file since 1222 was 1213, checked in by seregin, 10 years ago

macro cleanup: R0150_CGS_SIGNAL_CONSTRAINTS

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