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

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

fix chroma IDC input

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