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

Last change on this file since 571 was 568, checked in by qualcomm, 12 years ago

JCTVC-P0125 -- Revert vps_extension_offset back to vps_reserved_0xffff_16bits

One macro (P0125_REVERT_VPS_EXTN_OFFSET_TO_RESERVED) is defined and it negate the following two macros (VPS_EXTN_OFFSET & VPS_EXTN_OFFSET_CALC).

Contact fhendry@…

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