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

Last change on this file since 880 was 880, checked in by seregin, 11 years ago

port rev 4061 from RExt to solve WPP problem related to ticket #35, macro is WPP_FIX

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