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

Last change on this file since 851 was 815, checked in by seregin, 10 years ago

merge with SHM-6-dev branch

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