source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncGOP.cpp @ 1497

Last change on this file since 1497 was 906, checked in by seregin, 10 years ago

merge SHM-dev

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