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

Last change on this file since 980 was 978, checked in by nokia, 11 years ago

Implementation of JCTVC-R0071 - IRAP and EOS cross-layer impacts

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