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

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

remove macro ALIGN_TSA_STSA_PICS

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