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

Last change on this file since 1263 was 1260, checked in by seregin, 9 years ago

port rev 4257

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