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

Last change on this file since 937 was 923, checked in by nokia, 11 years ago

Port the STSA bug fix in HM to SHM.

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