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

Last change on this file since 898 was 894, checked in by qualcomm, 11 years ago

JCTVC-R0231: Signalling of VPS VUI BSP HRD parameters and other related changes (Macro: VPS_VUI_BSP_HRD_PARAMS)

This patch includes some of the signalling changes in the VPS VUI BSP HRD parameters in R0231, and related adoptions.

From: Adarsh K. Ramasubramonian <aramasub@…>

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