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

Last change on this file since 899 was 437, checked in by nokia, 11 years ago

fix spec inconsistencies and a typo (tileIdx -> tileSetIdx) in tile sets implementation

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