source: SHVCSoftware/branches/SHM-4.0-dev/source/Lib/TLibEncoder/TEncGOP.cpp @ 446

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

copy layerId, reference picture list modification information for the slices in the picture along with performing the upsampling once per picture

  • Property svn:eol-style set to native
File size: 139.1 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2013, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncGOP.cpp
35    \brief    GOP encoder class
36*/
37
38#include <list>
39#include <algorithm>
40#include <functional>
41
42#include "TEncTop.h"
43#include "TEncGOP.h"
44#include "TEncAnalyze.h"
45#include "libmd5/MD5.h"
46#include "TLibCommon/SEI.h"
47#include "TLibCommon/NAL.h"
48#include "NALwrite.h"
49#include <time.h>
50#include <math.h>
51
52using namespace std;
53//! \ingroup TLibEncoder
54//! \{
55
56// ====================================================================================================================
57// Constructor / destructor / initialization / destroy
58// ====================================================================================================================
59Int getLSB(Int poc, Int maxLSB)
60{
61  if (poc >= 0)
62  {
63    return poc % maxLSB;
64  }
65  else
66  {
67    return (maxLSB - ((-poc) % maxLSB)) % maxLSB;
68  }
69}
70
71TEncGOP::TEncGOP()
72{
73  m_iLastIDR            = 0;
74  m_iGopSize            = 0;
75  m_iNumPicCoded        = 0; //Niko
76  m_bFirst              = true;
77 
78  m_pcCfg               = NULL;
79  m_pcSliceEncoder      = NULL;
80  m_pcListPic           = NULL;
81 
82  m_pcEntropyCoder      = NULL;
83  m_pcCavlcCoder        = NULL;
84  m_pcSbacCoder         = NULL;
85  m_pcBinCABAC          = NULL;
86 
87  m_bSeqFirst           = true;
88 
89  m_bRefreshPending     = 0;
90  m_pocCRA            = 0;
91  m_numLongTermRefPicSPS = 0;
92  ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps));
93  ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag));
94  m_cpbRemovalDelay   = 0;
95  m_lastBPSEI         = 0;
96  xResetNonNestedSEIPresentFlags();
97  xResetNestedSEIPresentFlags();
98#if SVC_UPSAMPLING
99  m_pcPredSearch        = NULL;
100#endif
101  return;
102}
103
104TEncGOP::~TEncGOP()
105{
106}
107
108/** Create list to contain pointers to LCU start addresses of slice.
109 */
110#if SVC_EXTENSION
111Void  TEncGOP::create( UInt layerId )
112{
113  m_bLongtermTestPictureHasBeenCoded = 0;
114  m_bLongtermTestPictureHasBeenCoded2 = 0;
115  m_layerId = layerId;
116}
117#else
118Void  TEncGOP::create()
119{
120  m_bLongtermTestPictureHasBeenCoded = 0;
121  m_bLongtermTestPictureHasBeenCoded2 = 0;
122}
123#endif
124
125Void  TEncGOP::destroy()
126{
127}
128
129Void TEncGOP::init ( TEncTop* pcTEncTop )
130{
131  m_pcEncTop     = pcTEncTop;
132  m_pcCfg                = pcTEncTop;
133  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
134  m_pcListPic            = pcTEncTop->getListPic(); 
135 
136  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
137  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
138  m_pcSbacCoder          = pcTEncTop->getSbacCoder();
139  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
140  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
141  m_pcBitCounter         = pcTEncTop->getBitCounter();
142 
143  //--Adaptive Loop filter
144  m_pcSAO                = pcTEncTop->getSAO();
145  m_pcRateCtrl           = pcTEncTop->getRateCtrl();
146  m_lastBPSEI          = 0;
147  m_totalCoded         = 0;
148
149#if SVC_EXTENSION
150  m_ppcTEncTop           = pcTEncTop->getLayerEnc();
151#endif
152#if SVC_UPSAMPLING
153  m_pcPredSearch         = pcTEncTop->getPredSearch();                       ///< encoder search class
154#endif
155}
156
157SEIActiveParameterSets* TEncGOP::xCreateSEIActiveParameterSets (TComSPS *sps)
158{
159  SEIActiveParameterSets *seiActiveParameterSets = new SEIActiveParameterSets(); 
160  seiActiveParameterSets->activeVPSId = m_pcCfg->getVPS()->getVPSId(); 
161  seiActiveParameterSets->m_fullRandomAccessFlag = false;
162  seiActiveParameterSets->m_noParamSetUpdateFlag = false;
163  seiActiveParameterSets->numSpsIdsMinus1 = 0;
164  seiActiveParameterSets->activeSeqParamSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1); 
165  seiActiveParameterSets->activeSeqParamSetId[0] = sps->getSPSId();
166  return seiActiveParameterSets;
167}
168
169#if 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#if SVC_EXTENSION
1610          // copy reference list modification info from the first slice, assuming that this information is the same across all slices in the picture
1611          memcpy( pcSlice->getRefPicListModification(), pcPic->getSlice(0)->getRefPicListModification(), sizeof(TComRefPicListModification) );
1612#endif
1613          uiNumSlices ++;
1614        }
1615      }
1616      else if (pcSlice->isNextSliceSegment() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU))
1617      {
1618        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
1619        m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSliceSegment);
1620        startCUAddrSliceSegmentIdx++;
1621        pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment );
1622      }
1623      else
1624      {
1625        startCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
1626        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
1627      }       
1628
1629      nextCUAddr = (startCUAddrSlice > startCUAddrSliceSegment) ? startCUAddrSlice : startCUAddrSliceSegment;
1630    }
1631    m_storedStartCUAddrForEncodingSlice.push_back( pcSlice->getSliceCurEndCUAddr());
1632    startCUAddrSliceIdx++;
1633    m_storedStartCUAddrForEncodingSliceSegment.push_back(pcSlice->getSliceCurEndCUAddr());
1634    startCUAddrSliceSegmentIdx++;
1635
1636    pcSlice = pcPic->getSlice(0);
1637
1638    // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
1639    if( m_pcCfg->getSaoLcuBasedOptimization() && m_pcCfg->getSaoLcuBoundary() )
1640    {
1641      m_pcSAO->resetStats();
1642      m_pcSAO->calcSaoStatsCu_BeforeDblk( pcPic );
1643    }
1644
1645    //-- Loop filter
1646    Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
1647    m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
1648    if ( m_pcCfg->getDeblockingFilterMetric() )
1649    {
1650      dblMetric(pcPic, uiNumSlices);
1651    }
1652    m_pcLoopFilter->loopFilterPic( pcPic );
1653
1654    pcSlice = pcPic->getSlice(0);
1655    if(pcSlice->getSPS()->getUseSAO())
1656    {
1657      std::vector<Bool> LFCrossSliceBoundaryFlag;
1658      for(Int s=0; s< uiNumSlices; s++)
1659      {
1660        LFCrossSliceBoundaryFlag.push_back(  ((uiNumSlices==1)?true:pcPic->getSlice(s)->getLFCrossSliceBoundaryFlag()) );
1661      }
1662      m_storedStartCUAddrForEncodingSlice.resize(uiNumSlices+1);
1663      pcPic->createNonDBFilterInfo(m_storedStartCUAddrForEncodingSlice, 0, &LFCrossSliceBoundaryFlag ,pcPic->getPicSym()->getNumTiles() ,bLFCrossTileBoundary);
1664    }
1665
1666
1667    pcSlice = pcPic->getSlice(0);
1668
1669    if(pcSlice->getSPS()->getUseSAO())
1670    {
1671      m_pcSAO->createPicSaoInfo(pcPic);
1672    }
1673
1674    /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
1675    // Set entropy coder
1676    m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1677
1678    /* write various header sets. */
1679    if ( m_bSeqFirst )
1680    {
1681#if SVC_EXTENSION
1682#if VPS_NUH_LAYER_ID
1683      OutputNALUnit nalu(NAL_UNIT_VPS, 0, 0        ); // The value of nuh_layer_id of VPS NAL unit shall be equal to 0.
1684#else
1685      OutputNALUnit nalu(NAL_UNIT_VPS, 0, m_layerId);
1686#endif
1687#if AVC_BASE
1688      if( ( m_layerId == 1 && m_pcEncTop->getVPS()->getAvcBaseLayerFlag() ) || ( m_layerId == 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() ) )
1689#else
1690      if( m_layerId == 0 )
1691#endif
1692      {
1693#else
1694      OutputNALUnit nalu(NAL_UNIT_VPS);
1695#endif
1696      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1697      m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());
1698      writeRBSPTrailingBits(nalu.m_Bitstream);
1699      accessUnit.push_back(new NALUnitEBSP(nalu));
1700#if RATE_CONTROL_LAMBDA_DOMAIN
1701      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1702#endif
1703#if SVC_EXTENSION
1704      }
1705#endif
1706
1707#if SVC_EXTENSION
1708      nalu = NALUnit(NAL_UNIT_SPS, 0, m_layerId);
1709#if IL_SL_SIGNALLING_N0371
1710      pcSlice->getSPS()->setVPS( pcSlice->getVPS() );
1711#endif
1712#else
1713      nalu = NALUnit(NAL_UNIT_SPS);
1714#endif
1715      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1716      if (m_bSeqFirst)
1717      {
1718        pcSlice->getSPS()->setNumLongTermRefPicSPS(m_numLongTermRefPicSPS);
1719        for (Int k = 0; k < m_numLongTermRefPicSPS; k++)
1720        {
1721          pcSlice->getSPS()->setLtRefPicPocLsbSps(k, m_ltRefPicPocLsbSps[k]);
1722          pcSlice->getSPS()->setUsedByCurrPicLtSPSFlag(k, m_ltRefPicUsedByCurrPicFlag[k]);
1723        }
1724      }
1725      if( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
1726      {
1727        UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1);
1728        UInt numDU = ( m_pcCfg->getSliceMode() == 1 ) ? ( pcPic->getNumCUsInFrame() / maxCU ) : ( 0 );
1729        if( pcPic->getNumCUsInFrame() % maxCU != 0 || numDU == 0 )
1730        {
1731          numDU ++;
1732        }
1733        pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->setNumDU( numDU );
1734        pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) );
1735      }
1736      if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
1737      {
1738        pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true );
1739      }
1740      m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
1741      writeRBSPTrailingBits(nalu.m_Bitstream);
1742      accessUnit.push_back(new NALUnitEBSP(nalu));
1743#if RATE_CONTROL_LAMBDA_DOMAIN
1744      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1745#endif
1746
1747#if SVC_EXTENSION
1748      nalu = NALUnit(NAL_UNIT_PPS, 0, m_layerId);
1749#else
1750      nalu = NALUnit(NAL_UNIT_PPS);
1751#endif
1752      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1753      m_pcEntropyCoder->encodePPS(pcSlice->getPPS());
1754      writeRBSPTrailingBits(nalu.m_Bitstream);
1755      accessUnit.push_back(new NALUnitEBSP(nalu));
1756#if RATE_CONTROL_LAMBDA_DOMAIN
1757      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1758#endif
1759
1760      xCreateLeadingSEIMessages(accessUnit, pcSlice->getSPS());
1761
1762      m_bSeqFirst = false;
1763    }
1764
1765    if (writeSOP) // write SOP description SEI (if enabled) at the beginning of GOP
1766    {
1767      Int SOPcurrPOC = pocCurr;
1768
1769      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1770      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1771      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1772
1773      SEISOPDescription SOPDescriptionSEI;
1774      SOPDescriptionSEI.m_sopSeqParameterSetId = pcSlice->getSPS()->getSPSId();
1775
1776      UInt i = 0;
1777      UInt prevEntryId = iGOPid;
1778      for (j = iGOPid; j < m_iGopSize; j++)
1779      {
1780        Int deltaPOC = m_pcCfg->getGOPEntry(j).m_POC - m_pcCfg->getGOPEntry(prevEntryId).m_POC;
1781        if ((SOPcurrPOC + deltaPOC) < m_pcCfg->getFramesToBeEncoded())
1782        {
1783          SOPcurrPOC += deltaPOC;
1784          SOPDescriptionSEI.m_sopDescVclNaluType[i] = getNalUnitType(SOPcurrPOC, m_iLastIDR);
1785          SOPDescriptionSEI.m_sopDescTemporalId[i] = m_pcCfg->getGOPEntry(j).m_temporalId;
1786          SOPDescriptionSEI.m_sopDescStRpsIdx[i] = m_pcEncTop->getReferencePictureSetIdxForSOP(pcSlice, SOPcurrPOC, j);
1787          SOPDescriptionSEI.m_sopDescPocDelta[i] = deltaPOC;
1788
1789          prevEntryId = j;
1790          i++;
1791        }
1792      }
1793
1794      SOPDescriptionSEI.m_numPicsInSopMinus1 = i - 1;
1795
1796      m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, pcSlice->getSPS());
1797      writeRBSPTrailingBits(nalu.m_Bitstream);
1798      accessUnit.push_back(new NALUnitEBSP(nalu));
1799
1800      writeSOP = false;
1801    }
1802
1803    if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
1804        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
1805        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
1806       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
1807    {
1808      if( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() )
1809      {
1810        UInt numDU = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumDU();
1811        pictureTimingSEI.m_numDecodingUnitsMinus1     = ( numDU - 1 );
1812        pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = false;
1813
1814        if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL )
1815        {
1816          pictureTimingSEI.m_numNalusInDuMinus1       = new UInt[ numDU ];
1817        }
1818        if( pictureTimingSEI.m_duCpbRemovalDelayMinus1  == NULL )
1819        {
1820          pictureTimingSEI.m_duCpbRemovalDelayMinus1  = new UInt[ numDU ];
1821        }
1822        if( accumBitsDU == NULL )
1823        {
1824          accumBitsDU                                  = new UInt[ numDU ];
1825        }
1826        if( accumNalsDU == NULL )
1827        {
1828          accumNalsDU                                  = new UInt[ numDU ];
1829        }
1830      }
1831      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 .
1832#if POC_RESET_FLAG
1833      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(0) + pocCurr - m_totalCoded;
1834#else
1835      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(0) + pcSlice->getPOC() - m_totalCoded;
1836#endif
1837      Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2;
1838      pictureTimingSEI.m_picDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
1839      if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
1840      {
1841        picSptDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
1842      }
1843    }
1844
1845    if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) &&
1846        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
1847        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
1848       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
1849    {
1850      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1851      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1852      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1853
1854      SEIBufferingPeriod sei_buffering_period;
1855     
1856      UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
1857      sei_buffering_period.m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
1858      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
1859      sei_buffering_period.m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
1860      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
1861
1862      Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
1863
1864      UInt uiTmp = (UInt)( dTmp * 90000.0 ); 
1865      uiInitialCpbRemovalDelay -= uiTmp;
1866      uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
1867      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
1868      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
1869      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
1870      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
1871
1872      sei_buffering_period.m_rapCpbParamsPresentFlag              = 0;
1873      //for the concatenation, it can be set to one during splicing.
1874      sei_buffering_period.m_concatenationFlag = 0;
1875      //since the temporal layer HRD is not ready, we assumed it is fixed
1876      sei_buffering_period.m_auCpbRemovalDelayDelta = 1;
1877      sei_buffering_period.m_cpbDelayOffset = 0;
1878      sei_buffering_period.m_dpbDelayOffset = 0;
1879
1880      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, pcSlice->getSPS());
1881      writeRBSPTrailingBits(nalu.m_Bitstream);
1882      {
1883      UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
1884      UInt offsetPosition = m_activeParameterSetSEIPresentInAU;   // Insert BP SEI after APS SEI
1885      AccessUnit::iterator it;
1886      for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
1887      {
1888        it++;
1889      }
1890      accessUnit.insert(it, new NALUnitEBSP(nalu));
1891      m_bufferingPeriodSEIPresentInAU = true;
1892      }
1893
1894      if (m_pcCfg->getScalableNestingSEIEnabled())
1895      {
1896        OutputNALUnit naluTmp(NAL_UNIT_PREFIX_SEI);
1897        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1898        m_pcEntropyCoder->setBitstream(&naluTmp.m_Bitstream);
1899        scalableNestingSEI.m_nestedSEIs.clear();
1900        scalableNestingSEI.m_nestedSEIs.push_back(&sei_buffering_period);
1901        m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
1902        writeRBSPTrailingBits(naluTmp.m_Bitstream);
1903        UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
1904        UInt offsetPosition = m_activeParameterSetSEIPresentInAU + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU;   // Insert BP SEI after non-nested APS, BP and PT SEIs
1905        AccessUnit::iterator it;
1906        for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
1907        {
1908          it++;
1909        }
1910        accessUnit.insert(it, new NALUnitEBSP(naluTmp));
1911        m_nestedBufferingPeriodSEIPresentInAU = true;
1912      }
1913
1914      m_lastBPSEI = m_totalCoded;
1915      m_cpbRemovalDelay = 0;
1916    }
1917    m_cpbRemovalDelay ++;
1918    if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) )
1919    {
1920      if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !pcSlice->getRapPicFlag() )
1921      {
1922        // Gradual decoding refresh SEI
1923        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1924        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1925        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1926
1927        SEIGradualDecodingRefreshInfo seiGradualDecodingRefreshInfo;
1928        seiGradualDecodingRefreshInfo.m_gdrForegroundFlag = true; // Indicating all "foreground"
1929
1930        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, pcSlice->getSPS() );
1931        writeRBSPTrailingBits(nalu.m_Bitstream);
1932        accessUnit.push_back(new NALUnitEBSP(nalu));
1933      }
1934    // Recovery point SEI
1935      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1936      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1937      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1938
1939      SEIRecoveryPoint sei_recovery_point;
1940      sei_recovery_point.m_recoveryPocCnt    = 0;
1941#if POC_RESET_FLAG
1942      sei_recovery_point.m_exactMatchingFlag = ( pocCurr == 0 ) ? (true) : (false);
1943#else
1944      sei_recovery_point.m_exactMatchingFlag = ( pcSlice->getPOC() == 0 ) ? (true) : (false);
1945#endif
1946      sei_recovery_point.m_brokenLinkFlag    = false;
1947
1948      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, pcSlice->getSPS() );
1949      writeRBSPTrailingBits(nalu.m_Bitstream);
1950      accessUnit.push_back(new NALUnitEBSP(nalu));
1951    }
1952
1953    /* use the main bitstream buffer for storing the marshalled picture */
1954    m_pcEntropyCoder->setBitstream(NULL);
1955
1956    startCUAddrSliceIdx = 0;
1957    startCUAddrSlice    = 0; 
1958
1959    startCUAddrSliceSegmentIdx = 0;
1960    startCUAddrSliceSegment    = 0; 
1961    nextCUAddr                 = 0;
1962    pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
1963
1964    Int processingState = (pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
1965    Bool skippedSlice=false;
1966    while (nextCUAddr < uiRealEndAddress) // Iterate over all slices
1967    {
1968      switch(processingState)
1969      {
1970      case ENCODE_SLICE:
1971        {
1972          pcSlice->setNextSlice       ( false );
1973          pcSlice->setNextSliceSegment( false );
1974          if (nextCUAddr == m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx])
1975          {
1976            pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
1977            if(startCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE)
1978            {
1979              pcSlice->checkColRefIdx(startCUAddrSliceIdx, pcPic);
1980            }
1981            pcPic->setCurrSliceIdx(startCUAddrSliceIdx);
1982            m_pcSliceEncoder->setSliceIdx(startCUAddrSliceIdx);
1983            assert(startCUAddrSliceIdx == pcSlice->getSliceIdx());
1984            // Reconstruction slice
1985            pcSlice->setSliceCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
1986            pcSlice->setSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx+1 ] );
1987            // Dependent slice
1988            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
1989            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
1990
1991            pcSlice->setNextSlice       ( true );
1992
1993            startCUAddrSliceIdx++;
1994            startCUAddrSliceSegmentIdx++;
1995          } 
1996          else if (nextCUAddr == m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx])
1997          {
1998            // Dependent slice
1999            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
2000            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
2001
2002            pcSlice->setNextSliceSegment( true );
2003
2004            startCUAddrSliceSegmentIdx++;
2005          }
2006#if SVC_EXTENSION && M0457_COL_PICTURE_SIGNALING
2007          pcSlice->setNumMotionPredRefLayers(m_pcEncTop->getNumMotionPredRefLayers());
2008#endif
2009          pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
2010          pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
2011          UInt uiDummyStartCUAddr;
2012          UInt uiDummyBoundingCUAddr;
2013          m_pcSliceEncoder->xDetermineStartAndBoundingCUAddr(uiDummyStartCUAddr,uiDummyBoundingCUAddr,pcPic,true);
2014
2015          uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) % pcPic->getNumPartInCU();
2016          uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) / pcPic->getNumPartInCU();
2017          uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2018          uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2019
2020#if REPN_FORMAT_IN_VPS
2021          uiWidth = pcSlice->getPicWidthInLumaSamples();
2022          uiHeight = pcSlice->getPicHeightInLumaSamples();
2023#else
2024          uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
2025          uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
2026#endif
2027          while(uiPosX>=uiWidth||uiPosY>=uiHeight)
2028          {
2029            uiInternalAddress--;
2030            uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2031            uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2032          }
2033          uiInternalAddress++;
2034          if(uiInternalAddress==pcPic->getNumPartInCU())
2035          {
2036            uiInternalAddress = 0;
2037            uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
2038          }
2039          UInt endAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
2040          if(endAddress<=pcSlice->getSliceSegmentCurStartCUAddr()) 
2041          {
2042            UInt boundingAddrSlice, boundingAddrSliceSegment;
2043            boundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
2044            boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
2045            nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
2046            if(pcSlice->isNextSlice())
2047            {
2048              skippedSlice=true;
2049            }
2050            continue;
2051          }
2052          if(skippedSlice) 
2053          {
2054            pcSlice->setNextSlice       ( true );
2055            pcSlice->setNextSliceSegment( false );
2056          }
2057          skippedSlice=false;
2058          pcSlice->allocSubstreamSizes( iNumSubstreams );
2059          for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
2060          {
2061            pcSubstreamsOut[ui].clear();
2062          }
2063
2064          m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
2065          m_pcEntropyCoder->resetEntropy      ();
2066          /* start slice NALunit */
2067#if SVC_EXTENSION
2068          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), m_layerId );
2069#else
2070          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
2071#endif
2072          Bool sliceSegment = (!pcSlice->isNextSlice());
2073          if (!sliceSegment)
2074          {
2075            uiOneBitstreamPerSliceLength = 0; // start of a new slice
2076          }
2077          m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2078#if RATE_CONTROL_LAMBDA_DOMAIN
2079          tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
2080#endif
2081
2082          m_pcEntropyCoder->encodeSliceHeader(pcSlice);
2083
2084#if RATE_CONTROL_LAMBDA_DOMAIN
2085          actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
2086#endif
2087
2088          // is it needed?
2089          {
2090            if (!sliceSegment)
2091            {
2092              pcBitstreamRedirect->writeAlignOne();
2093            }
2094            else
2095            {
2096              // We've not completed our slice header info yet, do the alignment later.
2097            }
2098            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
2099            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
2100            m_pcEntropyCoder->resetEntropy    ();
2101            for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
2102            {
2103              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
2104              m_pcEntropyCoder->resetEntropy    ();
2105            }
2106          }
2107
2108          if(pcSlice->isNextSlice())
2109          {
2110            // set entropy coder for writing
2111            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
2112            {
2113              for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
2114              {
2115                m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
2116                m_pcEntropyCoder->resetEntropy    ();
2117              }
2118              pcSbacCoders[0].load(m_pcSbacCoder);
2119              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[0], pcSlice );  //ALF is written in substream #0 with CABAC coder #0 (see ALF param encoding below)
2120            }
2121            m_pcEntropyCoder->resetEntropy    ();
2122            // File writing
2123            if (!sliceSegment)
2124            {
2125              m_pcEntropyCoder->setBitstream(pcBitstreamRedirect);
2126            }
2127            else
2128            {
2129              m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2130            }
2131            // for now, override the TILES_DECODER setting in order to write substreams.
2132            m_pcEntropyCoder->setBitstream    ( &pcSubstreamsOut[0] );
2133
2134          }
2135          pcSlice->setFinalized(true);
2136
2137          m_pcSbacCoder->load( &pcSbacCoders[0] );
2138
2139          pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength );
2140            pcSlice->setTileLocationCount ( 0 );
2141          m_pcSliceEncoder->encodeSlice(pcPic, pcSubstreamsOut);
2142
2143          {
2144            // Construct the final bitstream by flushing and concatenating substreams.
2145            // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
2146            UInt* puiSubstreamSizes = pcSlice->getSubstreamSizes();
2147            UInt uiTotalCodedSize = 0; // for padding calcs.
2148            UInt uiNumSubstreamsPerTile = iNumSubstreams;
2149            if (iNumSubstreams > 1)
2150            {
2151              uiNumSubstreamsPerTile /= pcPic->getPicSym()->getNumTiles();
2152            }
2153            for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
2154            {
2155              // Flush all substreams -- this includes empty ones.
2156              // Terminating bit and flush.
2157              m_pcEntropyCoder->setEntropyCoder   ( &pcSbacCoders[ui], pcSlice );
2158              m_pcEntropyCoder->setBitstream      (  &pcSubstreamsOut[ui] );
2159              m_pcEntropyCoder->encodeTerminatingBit( 1 );
2160              m_pcEntropyCoder->encodeSliceFinish();
2161
2162              pcSubstreamsOut[ui].writeByteAlignment();   // Byte-alignment in slice_data() at end of sub-stream
2163              // Byte alignment is necessary between tiles when tiles are independent.
2164              uiTotalCodedSize += pcSubstreamsOut[ui].getNumberOfWrittenBits();
2165
2166              Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)&& ((ui+1)%uiNumSubstreamsPerTile == 0);
2167              if (bNextSubstreamInNewTile)
2168              {
2169                pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
2170              }
2171              if (ui+1 < pcSlice->getPPS()->getNumSubstreams())
2172              {
2173                puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits() + (pcSubstreamsOut[ui].countStartCodeEmulations()<<3);
2174              }
2175            }
2176
2177            // Complete the slice header info.
2178            m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
2179            m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2180            m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
2181
2182            // Substreams...
2183            TComOutputBitstream *pcOut = pcBitstreamRedirect;
2184          Int offs = 0;
2185          Int nss = pcSlice->getPPS()->getNumSubstreams();
2186          if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
2187          {
2188            // 1st line present for WPP.
2189            offs = pcSlice->getSliceSegmentCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
2190            nss  = pcSlice->getNumEntryPointOffsets()+1;
2191          }
2192          for ( UInt ui = 0 ; ui < nss; ui++ )
2193          {
2194            pcOut->addSubstream(&pcSubstreamsOut[ui+offs]);
2195            }
2196          }
2197
2198          UInt boundingAddrSlice, boundingAddrSliceSegment;
2199          boundingAddrSlice        = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
2200          boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
2201          nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
2202          // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
2203          // 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.
2204          Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
2205          xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
2206          accessUnit.push_back(new NALUnitEBSP(nalu));
2207#if RATE_CONTROL_LAMBDA_DOMAIN
2208          actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2209#endif
2210          bNALUAlignedWrittenToList = true; 
2211          uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment
2212
2213          if (!bNALUAlignedWrittenToList)
2214          {
2215            {
2216              nalu.m_Bitstream.writeAlignZero();
2217            }
2218            accessUnit.push_back(new NALUnitEBSP(nalu));
2219            uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits() + 24; // length of bitstream after byte-alignment + 3 byte startcode 0x000001
2220          }
2221
2222          if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2223              ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2224              ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
2225             || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
2226              ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
2227          {
2228              UInt numNalus = 0;
2229            UInt numRBSPBytes = 0;
2230            for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2231            {
2232              UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
2233              if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
2234              {
2235                numRBSPBytes += numRBSPBytes_nal;
2236                numNalus ++;
2237              }
2238            }
2239            accumBitsDU[ pcSlice->getSliceIdx() ] = ( numRBSPBytes << 3 );
2240            accumNalsDU[ pcSlice->getSliceIdx() ] = numNalus;   // SEI not counted for bit count; hence shouldn't be counted for # of NALUs - only for consistency
2241          }
2242          processingState = ENCODE_SLICE;
2243          }
2244          break;
2245        case EXECUTE_INLOOPFILTER:
2246          {
2247            // set entropy coder for RD
2248            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
2249            if ( pcSlice->getSPS()->getUseSAO() )
2250            {
2251              m_pcEntropyCoder->resetEntropy();
2252              m_pcEntropyCoder->setBitstream( m_pcBitCounter );
2253              m_pcSAO->startSaoEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), m_pcEncTop->getRDGoOnSbacCoder());
2254              SAOParam& cSaoParam = *pcSlice->getPic()->getPicSym()->getSaoParam();
2255
2256#if SAO_CHROMA_LAMBDA
2257#if SAO_ENCODING_CHOICE
2258              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma(), pcPic->getSlice(0)->getDepth());
2259#else
2260              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma());
2261#endif
2262#else
2263              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambda());
2264#endif
2265              m_pcSAO->endSaoEnc();
2266              m_pcSAO->PCMLFDisableProcess(pcPic);
2267            }
2268#if SAO_RDO
2269            m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
2270#endif
2271            processingState = ENCODE_SLICE;
2272
2273            for(Int s=0; s< uiNumSlices; s++)
2274            {
2275              if (pcSlice->getSPS()->getUseSAO())
2276              {
2277                pcPic->getSlice(s)->setSaoEnabledFlag((pcSlice->getPic()->getPicSym()->getSaoParam()->bSaoFlag[0]==1)?true:false);
2278              }
2279            }
2280          }
2281          break;
2282        default:
2283          {
2284            printf("Not a supported encoding state\n");
2285            assert(0);
2286            exit(-1);
2287          }
2288        }
2289      } // end iteration over slices
2290
2291      if(pcSlice->getSPS()->getUseSAO())
2292      {
2293        if(pcSlice->getSPS()->getUseSAO())
2294        {
2295          m_pcSAO->destroyPicSaoInfo();
2296        }
2297        pcPic->destroyNonDBFilterInfo();
2298      }
2299
2300      pcPic->compressMotion(); 
2301     
2302      //-- For time output for each slice
2303      Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
2304
2305      const Char* digestStr = NULL;
2306      if (m_pcCfg->getDecodedPictureHashSEIEnabled())
2307      {
2308        /* calculate MD5sum for entire reconstructed picture */
2309        SEIDecodedPictureHash sei_recon_picture_digest;
2310        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
2311        {
2312          sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5;
2313          calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2314          digestStr = digestToString(sei_recon_picture_digest.digest, 16);
2315        }
2316        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
2317        {
2318          sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC;
2319          calcCRC(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2320          digestStr = digestToString(sei_recon_picture_digest.digest, 2);
2321        }
2322        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
2323        {
2324          sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM;
2325          calcChecksum(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2326          digestStr = digestToString(sei_recon_picture_digest.digest, 4);
2327        }
2328#if SVC_EXTENSION
2329        OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer(), m_layerId);
2330#else
2331        OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer());
2332#endif
2333
2334        /* write the SEI messages */
2335        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2336        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, pcSlice->getSPS());
2337        writeRBSPTrailingBits(nalu.m_Bitstream);
2338
2339        accessUnit.insert(accessUnit.end(), new NALUnitEBSP(nalu));
2340      }
2341      if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
2342      {
2343        SEITemporalLevel0Index sei_temporal_level0_index;
2344        if (pcSlice->getRapPicFlag())
2345        {
2346          m_tl0Idx = 0;
2347          m_rapIdx = (m_rapIdx + 1) & 0xFF;
2348        }
2349        else
2350        {
2351          m_tl0Idx = (m_tl0Idx + (pcSlice->getTLayer() ? 0 : 1)) & 0xFF;
2352        }
2353        sei_temporal_level0_index.tl0Idx = m_tl0Idx;
2354        sei_temporal_level0_index.rapIdx = m_rapIdx;
2355
2356        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); 
2357
2358        /* write the SEI messages */
2359        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2360        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, pcSlice->getSPS());
2361        writeRBSPTrailingBits(nalu.m_Bitstream);
2362
2363        /* insert the SEI message NALUnit before any Slice NALUnits */
2364        AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
2365        accessUnit.insert(it, new NALUnitEBSP(nalu));
2366      }
2367
2368      xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime );
2369
2370      //In case of field coding, compute the interlaced PSNR for both fields
2371      if (isField && ((!pcPic->isTopField() && isTff) || (pcPic->isTopField() && !isTff)))
2372      {
2373        //get complementary top field
2374        TComPic* pcPicTop;
2375        TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
2376        while ((*iterPic)->getPOC() != pcPic->getPOC()-1)
2377        {
2378          iterPic ++;
2379        }
2380        pcPicTop = *(iterPic);
2381        xCalculateInterlacedAddPSNR(pcPicTop, pcPic, pcPicTop->getPicYuvRec(), pcPic->getPicYuvRec(), accessUnit, dEncTime );
2382      }
2383
2384      if (digestStr)
2385      {
2386        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
2387        {
2388          printf(" [MD5:%s]", digestStr);
2389        }
2390        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
2391        {
2392          printf(" [CRC:%s]", digestStr);
2393        }
2394        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
2395        {
2396          printf(" [Checksum:%s]", digestStr);
2397        }
2398      }
2399#if RATE_CONTROL_LAMBDA_DOMAIN
2400      if ( m_pcCfg->getUseRateCtrl() )
2401      {
2402#if !M0036_RC_IMPROVEMENT
2403        Double effectivePercentage = m_pcRateCtrl->getRCPic()->getEffectivePercentage();
2404#endif
2405        Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
2406        Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
2407        if ( avgLambda < 0.0 )
2408        {
2409          avgLambda = lambda;
2410        }
2411#if M0036_RC_IMPROVEMENT
2412#if RATE_CONTROL_INTRA
2413        m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
2414#else
2415        m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda );
2416#endif
2417#else
2418        m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, effectivePercentage );
2419#endif
2420        m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
2421
2422        m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
2423        if ( pcSlice->getSliceType() != I_SLICE )
2424        {
2425          m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
2426        }
2427        else    // for intra picture, the estimated bits are used to update the current status in the GOP
2428        {
2429          m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
2430        }
2431      }
2432#else
2433      if(m_pcCfg->getUseRateCtrl())
2434      {
2435        UInt  frameBits = m_vRVM_RP[m_vRVM_RP.size()-1];
2436        m_pcRateCtrl->updataRCFrameStatus((Int)frameBits, pcSlice->getSliceType());
2437      }
2438#endif
2439
2440      if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2441          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2442          ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
2443         || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
2444      {
2445        TComVUI *vui = pcSlice->getSPS()->getVuiParameters();
2446        TComHRD *hrd = vui->getHrdParameters();
2447
2448        if( hrd->getSubPicCpbParamsPresentFlag() )
2449        {
2450          Int i;
2451          UInt64 ui64Tmp;
2452          UInt uiPrev = 0;
2453          UInt numDU = ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 );
2454          UInt *pCRD = &pictureTimingSEI.m_duCpbRemovalDelayMinus1[0];
2455          UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
2456
2457          for( i = 0; i < numDU; i ++ )
2458          {
2459            pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] - 1 ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
2460          }
2461
2462          if( numDU == 1 )
2463          {
2464            pCRD[ 0 ] = 0; /* don't care */
2465          }
2466          else
2467          {
2468            pCRD[ numDU - 1 ] = 0;/* by definition */
2469            UInt tmp = 0;
2470            UInt accum = 0;
2471
2472            for( i = ( numDU - 2 ); i >= 0; i -- )
2473            {
2474              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
2475              if( (UInt)ui64Tmp > maxDiff )
2476              {
2477                tmp ++;
2478              }
2479            }
2480            uiPrev = 0;
2481
2482            UInt flag = 0;
2483            for( i = ( numDU - 2 ); i >= 0; i -- )
2484            {
2485              flag = 0;
2486              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
2487
2488              if( (UInt)ui64Tmp > maxDiff )
2489              {
2490                if(uiPrev >= maxDiff - tmp)
2491                {
2492                  ui64Tmp = uiPrev + 1;
2493                  flag = 1;
2494                }
2495                else                            ui64Tmp = maxDiff - tmp + 1;
2496              }
2497              pCRD[ i ] = (UInt)ui64Tmp - uiPrev - 1;
2498              if( (Int)pCRD[ i ] < 0 )
2499              {
2500                pCRD[ i ] = 0;
2501              }
2502              else if (tmp > 0 && flag == 1) 
2503              {
2504                tmp --;
2505              }
2506              accum += pCRD[ i ] + 1;
2507              uiPrev = accum;
2508            }
2509          }
2510        }
2511        if( m_pcCfg->getPictureTimingSEIEnabled() )
2512        {
2513          {
2514            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
2515          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2516          pictureTimingSEI.m_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0;
2517          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, pcSlice->getSPS());
2518          writeRBSPTrailingBits(nalu.m_Bitstream);
2519          UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2520          UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2521                                    + m_bufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
2522          AccessUnit::iterator it;
2523          for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2524          {
2525            it++;
2526          }
2527          accessUnit.insert(it, new NALUnitEBSP(nalu));
2528          m_pictureTimingSEIPresentInAU = true;
2529        }
2530          if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI
2531          {
2532            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
2533            m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2534            scalableNestingSEI.m_nestedSEIs.clear();
2535            scalableNestingSEI.m_nestedSEIs.push_back(&pictureTimingSEI);
2536            m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
2537            writeRBSPTrailingBits(nalu.m_Bitstream);
2538            UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2539            UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2540              + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU + m_nestedBufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
2541            AccessUnit::iterator it;
2542            for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2543            {
2544              it++;
2545            }
2546            accessUnit.insert(it, new NALUnitEBSP(nalu));
2547            m_nestedPictureTimingSEIPresentInAU = true;
2548          }
2549        }
2550        if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
2551        {             
2552          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2553          for( Int i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
2554          {
2555            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
2556
2557            SEIDecodingUnitInfo tempSEI;
2558            tempSEI.m_decodingUnitIdx = i;
2559            tempSEI.m_duSptCpbRemovalDelay = pictureTimingSEI.m_duCpbRemovalDelayMinus1[i] + 1;
2560            tempSEI.m_dpbOutputDuDelayPresentFlag = false;
2561            tempSEI.m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
2562
2563            AccessUnit::iterator it;
2564            // Insert the first one in the right location, before the first slice
2565            if(i == 0)
2566            {
2567              // Insert before the first slice.
2568              m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
2569              writeRBSPTrailingBits(nalu.m_Bitstream);
2570
2571              UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2572              UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2573                                    + m_bufferingPeriodSEIPresentInAU
2574                                    + m_pictureTimingSEIPresentInAU;  // Insert DU info SEI after APS, BP and PT SEI
2575              for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2576              {
2577                it++;
2578              }
2579              accessUnit.insert(it, new NALUnitEBSP(nalu));
2580            }
2581            else
2582            {
2583              Int ctr;
2584              // For the second decoding unit onwards we know how many NALUs are present
2585              for (ctr = 0, it = accessUnit.begin(); it != accessUnit.end(); it++)
2586              {           
2587                if(ctr == accumNalsDU[ i - 1 ])
2588                {
2589                  // Insert before the first slice.
2590                  m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
2591                  writeRBSPTrailingBits(nalu.m_Bitstream);
2592
2593                  accessUnit.insert(it, new NALUnitEBSP(nalu));
2594                  break;
2595                }
2596                if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
2597                {
2598                  ctr++;
2599                }
2600              }
2601            }           
2602          }
2603        }
2604      }
2605      xResetNonNestedSEIPresentFlags();
2606      xResetNestedSEIPresentFlags();
2607      pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
2608
2609#if M0040_ADAPTIVE_RESOLUTION_CHANGE
2610      pcPicYuvRecOut->setReconstructed(true);
2611#endif
2612
2613      pcPic->setReconMark   ( true );
2614      m_bFirst = false;
2615      m_iNumPicCoded++;
2616      m_totalCoded ++;
2617      /* logging: insert a newline at end of picture period */
2618      printf("\n");
2619      fflush(stdout);
2620
2621      delete[] pcSubstreamsOut;
2622  }
2623#if !RATE_CONTROL_LAMBDA_DOMAIN
2624  if(m_pcCfg->getUseRateCtrl())
2625  {
2626    m_pcRateCtrl->updateRCGOPStatus();
2627  }
2628#endif
2629  delete pcBitstreamRedirect;
2630
2631  if( accumBitsDU != NULL) delete accumBitsDU;
2632  if( accumNalsDU != NULL) delete accumNalsDU;
2633
2634#if SVC_EXTENSION
2635  assert ( m_iNumPicCoded <= 1 || (isField && iPOCLast == 1) );
2636#else
2637  assert ( (m_iNumPicCoded == iNumPicRcvd) || (isField && iPOCLast == 1) );
2638#endif
2639}
2640
2641#if !SVC_EXTENSION
2642Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField)
2643{
2644  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
2645 
2646   
2647  //--CFG_KDY
2648  if(isField)
2649  {
2650    m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() * 2);
2651    m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() * 2);
2652    m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() * 2);
2653    m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() * 2);
2654  }
2655   else
2656  {
2657    m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() );
2658    m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() );
2659    m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() );
2660    m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() );
2661  }
2662 
2663  //-- all
2664  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
2665  m_gcAnalyzeAll.printOut('a');
2666 
2667  printf( "\n\nI Slices--------------------------------------------------------\n" );
2668  m_gcAnalyzeI.printOut('i');
2669 
2670  printf( "\n\nP Slices--------------------------------------------------------\n" );
2671  m_gcAnalyzeP.printOut('p');
2672 
2673  printf( "\n\nB Slices--------------------------------------------------------\n" );
2674  m_gcAnalyzeB.printOut('b');
2675 
2676#if _SUMMARY_OUT_
2677  m_gcAnalyzeAll.printSummaryOut();
2678#endif
2679#if _SUMMARY_PIC_
2680  m_gcAnalyzeI.printSummary('I');
2681  m_gcAnalyzeP.printSummary('P');
2682  m_gcAnalyzeB.printSummary('B');
2683#endif
2684
2685  if(isField)
2686  {
2687    //-- interlaced summary
2688    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
2689    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
2690    m_gcAnalyzeAll_in.printOutInterlaced('a',  m_gcAnalyzeAll.getBits());
2691   
2692#if _SUMMARY_OUT_
2693    m_gcAnalyzeAll_in.printSummaryOutInterlaced();
2694#endif
2695  }
2696
2697  printf("\nRVM: %.3lf\n" , xCalculateRVM());
2698}
2699#endif
2700
2701Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
2702{
2703  TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
2704  Bool bCalcDist = false;
2705  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
2706  m_pcLoopFilter->loopFilterPic( pcPic );
2707 
2708  m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
2709  m_pcEntropyCoder->resetEntropy    ();
2710  m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
2711  pcSlice = pcPic->getSlice(0);
2712  if(pcSlice->getSPS()->getUseSAO())
2713  {
2714    std::vector<Bool> LFCrossSliceBoundaryFlag(1, true);
2715    std::vector<Int>  sliceStartAddress;
2716    sliceStartAddress.push_back(0);
2717    sliceStartAddress.push_back(pcPic->getNumCUsInFrame()* pcPic->getNumPartInCU());
2718    pcPic->createNonDBFilterInfo(sliceStartAddress, 0, &LFCrossSliceBoundaryFlag);
2719  }
2720 
2721  if( pcSlice->getSPS()->getUseSAO())
2722  {
2723    pcPic->destroyNonDBFilterInfo();
2724  }
2725 
2726  m_pcEntropyCoder->resetEntropy    ();
2727  ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
2728 
2729  if (!bCalcDist)
2730    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
2731}
2732
2733// ====================================================================================================================
2734// Protected member functions
2735// ====================================================================================================================
2736
2737
2738Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, Bool isField )
2739{
2740  assert( iNumPicRcvd > 0 );
2741  //  Exception for the first frames
2742  if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField  && (iPOCLast == 0))  )
2743  {
2744    m_iGopSize    = 1;
2745  }
2746  else
2747  {
2748    m_iGopSize    = m_pcCfg->getGOPSize();
2749  }
2750  assert (m_iGopSize > 0);
2751 
2752  return;
2753}
2754
2755Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut )
2756{
2757  assert( iNumPicRcvd > 0 );
2758  //  Exception for the first frame
2759  if ( iPOCLast == 0 )
2760  {
2761    m_iGopSize    = 1;
2762  }
2763  else
2764    m_iGopSize    = m_pcCfg->getGOPSize();
2765 
2766  assert (m_iGopSize > 0); 
2767
2768  return;
2769}
2770
2771Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
2772                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
2773                         Int                       iNumPicRcvd,
2774                         Int                       iTimeOffset,
2775                         TComPic*&                 rpcPic,
2776                         TComPicYuv*&              rpcPicYuvRecOut,
2777                         Int                       pocCurr,
2778                         Bool                      isField)
2779{
2780  Int i;
2781  //  Rec. output
2782  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
2783
2784  if (isField)
2785  {
2786    for ( i = 0; i < ( (pocCurr == 0 ) || (pocCurr == 1 ) ? (iNumPicRcvd - iTimeOffset + 1) : (iNumPicRcvd - iTimeOffset + 2) ); i++ )
2787    {
2788      iterPicYuvRec--;
2789    }
2790  }
2791  else
2792  {
2793    for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
2794    {
2795      iterPicYuvRec--;
2796    }
2797  }
2798 
2799  if (isField)
2800  {
2801    if(pocCurr == 1)
2802    {
2803      iterPicYuvRec++;
2804    }
2805  }
2806  rpcPicYuvRecOut = *(iterPicYuvRec);
2807 
2808  //  Current pic.
2809  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
2810  while (iterPic != rcListPic.end())
2811  {
2812    rpcPic = *(iterPic);
2813    rpcPic->setCurrSliceIdx(0);
2814    if (rpcPic->getPOC() == pocCurr)
2815    {
2816      break;
2817    }
2818    iterPic++;
2819  }
2820 
2821  assert( rpcPic != NULL );
2822  assert( rpcPic->getPOC() == pocCurr );
2823 
2824  return;
2825}
2826
2827UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
2828{
2829  Int     x, y;
2830  Pel*  pSrc0   = pcPic0 ->getLumaAddr();
2831  Pel*  pSrc1   = pcPic1 ->getLumaAddr();
2832  UInt  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthY-8);
2833  Int   iTemp;
2834 
2835  Int   iStride = pcPic0->getStride();
2836  Int   iWidth  = pcPic0->getWidth();
2837  Int   iHeight = pcPic0->getHeight();
2838 
2839  UInt64  uiTotalDiff = 0;
2840 
2841  for( y = 0; y < iHeight; y++ )
2842  {
2843    for( x = 0; x < iWidth; x++ )
2844    {
2845      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2846    }
2847    pSrc0 += iStride;
2848    pSrc1 += iStride;
2849  }
2850 
2851  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthC-8);
2852  iHeight >>= 1;
2853  iWidth  >>= 1;
2854  iStride >>= 1;
2855 
2856  pSrc0  = pcPic0->getCbAddr();
2857  pSrc1  = pcPic1->getCbAddr();
2858 
2859  for( y = 0; y < iHeight; y++ )
2860  {
2861    for( x = 0; x < iWidth; x++ )
2862    {
2863      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2864    }
2865    pSrc0 += iStride;
2866    pSrc1 += iStride;
2867  }
2868 
2869  pSrc0  = pcPic0->getCrAddr();
2870  pSrc1  = pcPic1->getCrAddr();
2871 
2872  for( y = 0; y < iHeight; y++ )
2873  {
2874    for( x = 0; x < iWidth; x++ )
2875    {
2876      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2877    }
2878    pSrc0 += iStride;
2879    pSrc1 += iStride;
2880  }
2881 
2882  return uiTotalDiff;
2883}
2884
2885#if VERBOSE_RATE
2886static const Char* nalUnitTypeToString(NalUnitType type)
2887{
2888  switch (type)
2889  {
2890    case NAL_UNIT_CODED_SLICE_TRAIL_R:    return "TRAIL_R";
2891    case NAL_UNIT_CODED_SLICE_TRAIL_N:    return "TRAIL_N";
2892    case NAL_UNIT_CODED_SLICE_TLA_R:      return "TLA_R";
2893    case NAL_UNIT_CODED_SLICE_TSA_N:      return "TSA_N";
2894    case NAL_UNIT_CODED_SLICE_STSA_R:     return "STSA_R";
2895    case NAL_UNIT_CODED_SLICE_STSA_N:     return "STSA_N";
2896    case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
2897    case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
2898    case NAL_UNIT_CODED_SLICE_BLA_N_LP:   return "BLA_N_LP";
2899    case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
2900    case NAL_UNIT_CODED_SLICE_IDR_N_LP:   return "IDR_N_LP";
2901    case NAL_UNIT_CODED_SLICE_CRA:        return "CRA";
2902    case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
2903    case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
2904    case NAL_UNIT_VPS:                    return "VPS";
2905    case NAL_UNIT_SPS:                    return "SPS";
2906    case NAL_UNIT_PPS:                    return "PPS";
2907    case NAL_UNIT_ACCESS_UNIT_DELIMITER:  return "AUD";
2908    case NAL_UNIT_EOS:                    return "EOS";
2909    case NAL_UNIT_EOB:                    return "EOB";
2910    case NAL_UNIT_FILLER_DATA:            return "FILLER";
2911    case NAL_UNIT_PREFIX_SEI:             return "SEI";
2912    case NAL_UNIT_SUFFIX_SEI:             return "SEI";
2913    default:                              return "UNK";
2914  }
2915}
2916#endif
2917
2918Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime )
2919{
2920  Int     x, y;
2921  UInt64 uiSSDY  = 0;
2922  UInt64 uiSSDU  = 0;
2923  UInt64 uiSSDV  = 0;
2924 
2925  Double  dYPSNR  = 0.0;
2926  Double  dUPSNR  = 0.0;
2927  Double  dVPSNR  = 0.0;
2928 
2929  //===== calculate PSNR =====
2930  Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
2931  Pel*  pRec    = pcPicD->getLumaAddr();
2932  Int   iStride = pcPicD->getStride();
2933 
2934  Int   iWidth;
2935  Int   iHeight;
2936 
2937  iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
2938  iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
2939 
2940  Int   iSize   = iWidth*iHeight;
2941 
2942  for( y = 0; y < iHeight; y++ )
2943  {
2944    for( x = 0; x < iWidth; x++ )
2945    {
2946      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2947      uiSSDY   += iDiff * iDiff;
2948    }
2949    pOrg += iStride;
2950    pRec += iStride;
2951  }
2952 
2953  iHeight >>= 1;
2954  iWidth  >>= 1;
2955  iStride >>= 1;
2956  pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
2957  pRec  = pcPicD->getCbAddr();
2958 
2959  for( y = 0; y < iHeight; y++ )
2960  {
2961    for( x = 0; x < iWidth; x++ )
2962    {
2963      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2964      uiSSDU   += iDiff * iDiff;
2965    }
2966    pOrg += iStride;
2967    pRec += iStride;
2968  }
2969 
2970  pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
2971  pRec  = pcPicD->getCrAddr();
2972 
2973  for( y = 0; y < iHeight; y++ )
2974  {
2975    for( x = 0; x < iWidth; x++ )
2976    {
2977      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2978      uiSSDV   += iDiff * iDiff;
2979    }
2980    pOrg += iStride;
2981    pRec += iStride;
2982  }
2983 
2984  Int maxvalY = 255 << (g_bitDepthY-8);
2985  Int maxvalC = 255 << (g_bitDepthC-8);
2986  Double fRefValueY = (Double) maxvalY * maxvalY * iSize;
2987  Double fRefValueC = (Double) maxvalC * maxvalC * iSize / 4.0;
2988  dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
2989  dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
2990  dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
2991
2992  /* calculate the size of the access unit, excluding:
2993   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
2994   *  - SEI NAL units
2995   */
2996  UInt numRBSPBytes = 0;
2997  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2998  {
2999    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3000#if VERBOSE_RATE
3001    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
3002#endif
3003    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3004    {
3005      numRBSPBytes += numRBSPBytes_nal;
3006    }
3007  }
3008
3009  UInt uibits = numRBSPBytes * 8;
3010  m_vRVM_RP.push_back( uibits );
3011
3012  //===== add PSNR =====
3013#if SVC_EXTENSION
3014  m_gcAnalyzeAll[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3015  TComSlice*  pcSlice = pcPic->getSlice(0);
3016  if (pcSlice->isIntra())
3017  {
3018    m_gcAnalyzeI[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3019  }
3020  if (pcSlice->isInterP())
3021  {
3022    m_gcAnalyzeP[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3023  }
3024  if (pcSlice->isInterB())
3025  {
3026    m_gcAnalyzeB[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3027  }
3028#else
3029  m_gcAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3030  TComSlice*  pcSlice = pcPic->getSlice(0);
3031  if (pcSlice->isIntra())
3032  {
3033    m_gcAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3034  }
3035  if (pcSlice->isInterP())
3036  {
3037    m_gcAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3038  }
3039  if (pcSlice->isInterB())
3040  {
3041    m_gcAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3042  }
3043#endif
3044
3045  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
3046  if (!pcSlice->isReferenced()) c += 32;
3047
3048#if SVC_EXTENSION
3049#if ADAPTIVE_QP_SELECTION
3050  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
3051         pcSlice->getPOC(),
3052         pcSlice->getLayerId(),
3053         pcSlice->getTLayer(),
3054         c,
3055         pcSlice->getSliceQpBase(),
3056         pcSlice->getSliceQp(),
3057         uibits );
3058#else
3059  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
3060         pcSlice->getPOC()-pcSlice->getLastIDR(),
3061         pcSlice->getLayerId(),
3062         pcSlice->getTLayer(),
3063         c,
3064         pcSlice->getSliceQp(),
3065         uibits );
3066#endif
3067#else
3068#if ADAPTIVE_QP_SELECTION
3069  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
3070         pcSlice->getPOC(),
3071         pcSlice->getTLayer(),
3072         c,
3073         pcSlice->getSliceQpBase(),
3074         pcSlice->getSliceQp(),
3075         uibits );
3076#else
3077  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
3078         pcSlice->getPOC()-pcSlice->getLastIDR(),
3079         pcSlice->getTLayer(),
3080         c,
3081         pcSlice->getSliceQp(),
3082         uibits );
3083#endif
3084#endif
3085
3086  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dYPSNR, dUPSNR, dVPSNR );
3087  printf(" [ET %5.0f ]", dEncTime );
3088 
3089  for (Int iRefList = 0; iRefList < 2; iRefList++)
3090  {
3091    printf(" [L%d ", iRefList);
3092    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
3093    {
3094#if SVC_EXTENSION
3095#if VPS_EXTN_DIRECT_REF_LAYERS
3096      if( pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->isILR(m_layerId) )
3097      {
3098        printf( "%d(%d)", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR(), pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId() );
3099      }
3100      else
3101      {
3102        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3103      }
3104#endif
3105      if( pcSlice->getEnableTMVPFlag() && iRefList == 1 - pcSlice->getColFromL0Flag() && iRefIndex == pcSlice->getColRefIdx() )
3106      {
3107        printf( "c" );
3108      }
3109
3110      printf( " " );
3111#else
3112      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3113#endif
3114    }
3115    printf("]");
3116  }
3117}
3118
3119
3120Void reinterlace(Pel* top, Pel* bottom, Pel* dst, UInt stride, UInt width, UInt height, Bool isTff)
3121{
3122 
3123  for (Int y = 0; y < height; y++)
3124  {
3125    for (Int x = 0; x < width; x++)
3126    {
3127      dst[x] = isTff ? (UChar) top[x] : (UChar) bottom[x];
3128      dst[stride+x] = isTff ? (UChar) bottom[x] : (UChar) top[x];
3129    }
3130    top += stride;
3131    bottom += stride;
3132    dst += stride*2;
3133  }
3134}
3135
3136Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgTop, TComPic* pcPicOrgBottom, TComPicYuv* pcPicRecTop, TComPicYuv* pcPicRecBottom, const AccessUnit& accessUnit, Double dEncTime )
3137{
3138  Int     x, y;
3139 
3140  UInt64 uiSSDY_in  = 0;
3141  UInt64 uiSSDU_in  = 0;
3142  UInt64 uiSSDV_in  = 0;
3143 
3144  Double  dYPSNR_in  = 0.0;
3145  Double  dUPSNR_in  = 0.0;
3146  Double  dVPSNR_in  = 0.0;
3147 
3148  /*------ INTERLACED PSNR -----------*/
3149 
3150  /* Luma */
3151 
3152  Pel*  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getLumaAddr();
3153  Pel*  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getLumaAddr();
3154  Pel*  pRecTop = pcPicRecTop->getLumaAddr();
3155  Pel*  pRecBottom = pcPicRecBottom->getLumaAddr();
3156 
3157  Int   iWidth;
3158  Int   iHeight;
3159  Int iStride;
3160 
3161  iWidth  = pcPicOrgTop->getPicYuvOrg()->getWidth () - m_pcEncTop->getPad(0);
3162  iHeight = pcPicOrgTop->getPicYuvOrg()->getHeight() - m_pcEncTop->getPad(1);
3163  iStride = pcPicOrgTop->getPicYuvOrg()->getStride();
3164  Int   iSize   = iWidth*iHeight;
3165  bool isTff = pcPicOrgTop->isTopField();
3166 
3167  TComPicYuv* pcOrgInterlaced = new TComPicYuv;
3168  pcOrgInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
3169 
3170  TComPicYuv* pcRecInterlaced = new TComPicYuv;
3171  pcRecInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
3172 
3173  Pel* pOrgInterlaced = pcOrgInterlaced->getLumaAddr();
3174  Pel* pRecInterlaced = pcRecInterlaced->getLumaAddr();
3175 
3176  //=== Interlace fields ====
3177  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
3178  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
3179 
3180  //===== calculate PSNR =====
3181  for( y = 0; y < iHeight << 1; y++ )
3182  {
3183    for( x = 0; x < iWidth; x++ )
3184    {
3185      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
3186      uiSSDY_in   += iDiff * iDiff;
3187    }
3188    pOrgInterlaced += iStride;
3189    pRecInterlaced += iStride;
3190  }
3191 
3192  /*Chroma*/
3193 
3194  iHeight >>= 1;
3195  iWidth  >>= 1;
3196  iStride >>= 1;
3197 
3198  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCbAddr();
3199  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCbAddr();
3200  pRecTop = pcPicRecTop->getCbAddr();
3201  pRecBottom = pcPicRecBottom->getCbAddr();
3202  pOrgInterlaced = pcOrgInterlaced->getCbAddr();
3203  pRecInterlaced = pcRecInterlaced->getCbAddr();
3204 
3205  //=== Interlace fields ====
3206  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
3207  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
3208 
3209  //===== calculate PSNR =====
3210  for( y = 0; y < iHeight << 1; y++ )
3211  {
3212    for( x = 0; x < iWidth; x++ )
3213    {
3214      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
3215      uiSSDU_in   += iDiff * iDiff;
3216    }
3217    pOrgInterlaced += iStride;
3218    pRecInterlaced += iStride;
3219  }
3220 
3221  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCrAddr();
3222  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCrAddr();
3223  pRecTop = pcPicRecTop->getCrAddr();
3224  pRecBottom = pcPicRecBottom->getCrAddr();
3225  pOrgInterlaced = pcOrgInterlaced->getCrAddr();
3226  pRecInterlaced = pcRecInterlaced->getCrAddr();
3227 
3228  //=== Interlace fields ====
3229  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
3230  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
3231 
3232  //===== calculate PSNR =====
3233  for( y = 0; y < iHeight << 1; y++ )
3234  {
3235    for( x = 0; x < iWidth; x++ )
3236    {
3237      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
3238      uiSSDV_in   += iDiff * iDiff;
3239    }
3240    pOrgInterlaced += iStride;
3241    pRecInterlaced += iStride;
3242  }
3243 
3244  Int maxvalY = 255 << (g_bitDepthY-8);
3245  Int maxvalC = 255 << (g_bitDepthC-8);
3246  Double fRefValueY = (Double) maxvalY * maxvalY * iSize*2;
3247  Double fRefValueC = (Double) maxvalC * maxvalC * iSize*2 / 4.0;
3248  dYPSNR_in            = ( uiSSDY_in ? 10.0 * log10( fRefValueY / (Double)uiSSDY_in ) : 99.99 );
3249  dUPSNR_in            = ( uiSSDU_in ? 10.0 * log10( fRefValueC / (Double)uiSSDU_in ) : 99.99 );
3250  dVPSNR_in            = ( uiSSDV_in ? 10.0 * log10( fRefValueC / (Double)uiSSDV_in ) : 99.99 );
3251 
3252  /* calculate the size of the access unit, excluding:
3253   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
3254   *  - SEI NAL units
3255   */
3256  UInt numRBSPBytes = 0;
3257  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3258  {
3259    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3260   
3261    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3262      numRBSPBytes += numRBSPBytes_nal;
3263  }
3264 
3265  UInt uibits = numRBSPBytes * 8 ;
3266 
3267  //===== add PSNR =====
3268  m_gcAnalyzeAll_in.addResult (dYPSNR_in, dUPSNR_in, dVPSNR_in, (Double)uibits);
3269 
3270  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 );
3271 
3272  pcOrgInterlaced->destroy();
3273  delete pcOrgInterlaced;
3274  pcRecInterlaced->destroy();
3275  delete pcRecInterlaced;
3276}
3277
3278/** Function for deciding the nal_unit_type.
3279 * \param pocCurr POC of the current picture
3280 * \returns the nal unit type of the picture
3281 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
3282 */
3283NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR)
3284{
3285  if (pocCurr == 0)
3286  {
3287    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3288  }
3289  if (pocCurr % m_pcCfg->getIntraPeriod() == 0)
3290  {
3291    if (m_pcCfg->getDecodingRefreshType() == 1)
3292    {
3293      return NAL_UNIT_CODED_SLICE_CRA;
3294    }
3295    else if (m_pcCfg->getDecodingRefreshType() == 2)
3296    {
3297      return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3298    }
3299  }
3300  if(m_pocCRA>0)
3301  {
3302    if(pocCurr<m_pocCRA)
3303    {
3304      // All leading pictures are being marked as TFD pictures here since current encoder uses all
3305      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
3306      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
3307      // controlling the reference pictures used for encoding that leading picture. Such a leading
3308      // picture need not be marked as a TFD picture.
3309      return NAL_UNIT_CODED_SLICE_RASL_R;
3310    }
3311  }
3312  if (lastIDR>0)
3313  {
3314    if (pocCurr < lastIDR)
3315    {
3316      return NAL_UNIT_CODED_SLICE_RADL_R;
3317    }
3318  }
3319  return NAL_UNIT_CODED_SLICE_TRAIL_R;
3320}
3321
3322Double TEncGOP::xCalculateRVM()
3323{
3324  Double dRVM = 0;
3325 
3326  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
3327  {
3328    // calculate RVM only for lowdelay configurations
3329    std::vector<Double> vRL , vB;
3330    size_t N = m_vRVM_RP.size();
3331    vRL.resize( N );
3332    vB.resize( N );
3333   
3334    Int i;
3335    Double dRavg = 0 , dBavg = 0;
3336    vB[RVM_VCEGAM10_M] = 0;
3337    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3338    {
3339      vRL[i] = 0;
3340      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
3341        vRL[i] += m_vRVM_RP[j];
3342      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
3343      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
3344      dRavg += m_vRVM_RP[i];
3345      dBavg += vB[i];
3346    }
3347   
3348    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
3349    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
3350   
3351    Double dSigamB = 0;
3352    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3353    {
3354      Double tmp = vB[i] - dBavg;
3355      dSigamB += tmp * tmp;
3356    }
3357    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
3358   
3359    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
3360   
3361    dRVM = dSigamB / dRavg * f;
3362  }
3363 
3364  return( dRVM );
3365}
3366
3367/** Attaches the input bitstream to the stream in the output NAL unit
3368    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
3369 *  \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu
3370 *  \param rNalu          target NAL unit
3371 */
3372Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream*& codedSliceData)
3373{
3374  // Byte-align
3375  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
3376
3377  // Perform bitstream concatenation
3378  if (codedSliceData->getNumberOfWrittenBits() > 0)
3379    {
3380    rNalu.m_Bitstream.addSubstream(codedSliceData);
3381  }
3382
3383  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
3384
3385  codedSliceData->clear();
3386}
3387
3388// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
3389// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
3390Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
3391{
3392  TComReferencePictureSet *rps = pcSlice->getRPS();
3393  if(!rps->getNumberOfLongtermPictures())
3394  {
3395    return;
3396  }
3397
3398  // Arrange long-term reference pictures in the correct order of LSB and MSB,
3399  // and assign values for pocLSBLT and MSB present flag
3400  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
3401  Int longtermPicsMSB[MAX_NUM_REF_PICS];
3402  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
3403  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
3404  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
3405  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
3406  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
3407  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
3408
3409  // Get the long-term reference pictures
3410  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
3411  Int i, ctr = 0;
3412  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
3413  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3414  {
3415    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
3416    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
3417    indices[ctr]      = i; 
3418    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
3419  }
3420  Int numLongPics = rps->getNumberOfLongtermPictures();
3421  assert(ctr == numLongPics);
3422
3423  // Arrange pictures in decreasing order of MSB;
3424  for(i = 0; i < numLongPics; i++)
3425  {
3426    for(Int j = 0; j < numLongPics - 1; j++)
3427    {
3428      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
3429      {
3430        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
3431        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
3432        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
3433        std::swap(indices[j]        , indices[j+1]        );
3434      }
3435    }
3436  }
3437
3438  for(i = 0; i < numLongPics; i++)
3439  {
3440    // Check if MSB present flag should be enabled.
3441    // Check if the buffer contains any pictures that have the same LSB.
3442    TComList<TComPic*>::iterator  iterPic = rcListPic.begin(); 
3443    TComPic*                      pcPic;
3444    while ( iterPic != rcListPic.end() )
3445    {
3446      pcPic = *iterPic;
3447      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
3448                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
3449                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
3450      {
3451        mSBPresentFlag[i] = true;
3452        break;
3453      }
3454      iterPic++;     
3455    }
3456  }
3457
3458  // tempArray for usedByCurr flag
3459  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
3460  for(i = 0; i < numLongPics; i++)
3461  {
3462    tempArray[i] = rps->getUsed(indices[i]);
3463  }
3464  // Now write the final values;
3465  ctr = 0;
3466  Int currMSB = 0, currLSB = 0;
3467  // currPicPoc = currMSB + currLSB
3468  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB); 
3469  currMSB = pcSlice->getPOC() - currLSB;
3470
3471  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3472  {
3473    rps->setPOC                   (i, longtermPicsPoc[ctr]);
3474    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
3475    rps->setUsed                  (i, tempArray[ctr]);
3476    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
3477    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
3478    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);     
3479
3480    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
3481  }
3482  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
3483  {
3484    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
3485    {
3486      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
3487      // don't have to check the MSB present flag values for this constraint.
3488      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
3489    }
3490  }
3491}
3492
3493/** Function for finding the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
3494 * \param accessUnit Access Unit of the current picture
3495 * This function finds the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
3496 */
3497Int TEncGOP::xGetFirstSeiLocation(AccessUnit &accessUnit)
3498{
3499  // Find the location of the first SEI message
3500  AccessUnit::iterator it;
3501  Int seiStartPos = 0;
3502  for(it = accessUnit.begin(); it != accessUnit.end(); it++, seiStartPos++)
3503  {
3504     if ((*it)->isSei() || (*it)->isVcl())
3505     {
3506       break;
3507     }               
3508  }
3509//  assert(it != accessUnit.end());  // Triggers with some legit configurations
3510  return seiStartPos;
3511}
3512
3513#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3514Void TEncGOP::xBuildTileSetsMap(TComPicSym* picSym)
3515{
3516  Int numCUs = picSym->getFrameWidthInCU() * picSym->getFrameHeightInCU();
3517
3518  for (Int i = 0; i < numCUs; i++)
3519  {
3520    picSym->setTileSetIdxMap(i, -1, 0, false);
3521  }
3522
3523  for (Int i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
3524  {
3525    TComTile* topLeftTile     = picSym->getTComTile(m_pcCfg->getTopLeftTileIndex(i));
3526    TComTile* bottomRightTile = picSym->getTComTile(m_pcCfg->getBottomRightTileIndex(i));
3527    Int tileSetLeftEdgePosInCU = topLeftTile->getRightEdgePosInCU() - topLeftTile->getTileWidth() + 1;
3528    Int tileSetRightEdgePosInCU = bottomRightTile->getRightEdgePosInCU();
3529    Int tileSetTopEdgePosInCU = topLeftTile->getBottomEdgePosInCU() - topLeftTile->getTileHeight() + 1;
3530    Int tileSetBottomEdgePosInCU = bottomRightTile->getBottomEdgePosInCU();
3531    assert(tileSetLeftEdgePosInCU < tileSetRightEdgePosInCU && tileSetTopEdgePosInCU < tileSetBottomEdgePosInCU);
3532    for (Int j = tileSetTopEdgePosInCU; j <= tileSetBottomEdgePosInCU; j++)
3533    {
3534      for (Int k = tileSetLeftEdgePosInCU; k <= tileSetRightEdgePosInCU; k++)
3535      {
3536        picSym->setTileSetIdxMap(j * picSym->getFrameWidthInCU() + k, i, m_pcCfg->getIlcIdc(i), false);
3537      }
3538    }
3539  }
3540 
3541  if (m_pcCfg->getSkippedTileSetPresentFlag())
3542  {
3543    Int skippedTileSetIdx = m_pcCfg->getIlNumSetsInMessage();
3544    for (Int i = 0; i < numCUs; i++)
3545    {
3546      if (picSym->getTileSetIdxMap(i) < 0)
3547      {
3548        picSym->setTileSetIdxMap(i, skippedTileSetIdx, 0, true);
3549      }
3550    }
3551  }
3552}
3553#endif
3554
3555Void TEncGOP::dblMetric( TComPic* pcPic, UInt uiNumSlices )
3556{
3557  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
3558  Pel* Rec    = pcPicYuvRec->getLumaAddr( 0 );
3559  Pel* tempRec = Rec;
3560  Int  stride = pcPicYuvRec->getStride();
3561  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
3562  UInt maxTBsize = (1<<log2maxTB);
3563  const UInt minBlockArtSize = 8;
3564  const UInt picWidth = pcPicYuvRec->getWidth();
3565  const UInt picHeight = pcPicYuvRec->getHeight();
3566  const UInt noCol = (picWidth>>log2maxTB);
3567  const UInt noRows = (picHeight>>log2maxTB);
3568  assert(noCol > 1);
3569  assert(noRows > 1);
3570  UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64));
3571  UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64));
3572  UInt colIdx = 0;
3573  UInt rowIdx = 0;
3574  Pel p0, p1, p2, q0, q1, q2;
3575 
3576  Int qp = pcPic->getSlice(0)->getSliceQp();
3577  Int bitdepthScale = 1 << (g_bitDepthY-8);
3578  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
3579  const Int thr2 = (beta>>2);
3580  const Int thr1 = 2*bitdepthScale;
3581  UInt a = 0;
3582 
3583  memset(colSAD, 0, noCol*sizeof(UInt64));
3584  memset(rowSAD, 0, noRows*sizeof(UInt64));
3585 
3586  if (maxTBsize > minBlockArtSize)
3587  {
3588    // Analyze vertical artifact edges
3589    for(Int c = maxTBsize; c < picWidth; c += maxTBsize)
3590    {
3591      for(Int r = 0; r < picHeight; r++)
3592      {
3593        p2 = Rec[c-3];
3594        p1 = Rec[c-2];
3595        p0 = Rec[c-1];
3596        q0 = Rec[c];
3597        q1 = Rec[c+1];
3598        q2 = Rec[c+2];
3599        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3600        if ( thr1 < a && a < thr2)
3601        {
3602          colSAD[colIdx] += abs(p0 - q0);
3603        }
3604        Rec += stride;
3605      }
3606      colIdx++;
3607      Rec = tempRec;
3608    }
3609   
3610    // Analyze horizontal artifact edges
3611    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
3612    {
3613      for(Int c = 0; c < picWidth; c++)
3614      {
3615        p2 = Rec[c + (r-3)*stride];
3616        p1 = Rec[c + (r-2)*stride];
3617        p0 = Rec[c + (r-1)*stride];
3618        q0 = Rec[c + r*stride];
3619        q1 = Rec[c + (r+1)*stride];
3620        q2 = Rec[c + (r+2)*stride];
3621        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3622        if (thr1 < a && a < thr2)
3623        {
3624          rowSAD[rowIdx] += abs(p0 - q0);
3625        }
3626      }
3627      rowIdx++;
3628    }
3629  }
3630 
3631  UInt64 colSADsum = 0;
3632  UInt64 rowSADsum = 0;
3633  for(Int c = 0; c < noCol-1; c++)
3634  {
3635    colSADsum += colSAD[c];
3636  }
3637  for(Int r = 0; r < noRows-1; r++)
3638  {
3639    rowSADsum += rowSAD[r];
3640  }
3641 
3642  colSADsum <<= 10;
3643  rowSADsum <<= 10;
3644  colSADsum /= (noCol-1);
3645  colSADsum /= picHeight;
3646  rowSADsum /= (noRows-1);
3647  rowSADsum /= picWidth;
3648 
3649  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
3650  avgSAD >>= (g_bitDepthY-8);
3651 
3652  if ( avgSAD > 2048 )
3653  {
3654    avgSAD >>= 9;
3655    Int offset = Clip3(2,6,(Int)avgSAD);
3656    for (Int i=0; i<uiNumSlices; i++)
3657    {
3658      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
3659      pcPic->getSlice(i)->setDeblockingFilterDisable(false);
3660      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset );
3661      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset );
3662    }
3663  }
3664  else
3665  {
3666    for (Int i=0; i<uiNumSlices; i++)
3667    {
3668      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
3669      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
3670      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
3671      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
3672    }
3673  }
3674 
3675  free(colSAD);
3676  free(rowSAD);
3677}
3678
3679#if M0457_COL_PICTURE_SIGNALING && !REMOVE_COL_PICTURE_SIGNALING
3680TComPic* TEncGOP::getMotionPredIlp(TComSlice* pcSlice)
3681{
3682  TComPic* ilpPic = NULL;
3683  Int activeMotionPredReflayerIdx = 0;
3684
3685  for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
3686  {
3687    UInt refLayerIdc = pcSlice->getInterLayerPredLayerIdc(i);
3688    if( m_pcEncTop->getMotionPredEnabledFlag( pcSlice->getVPS()->getRefLayerId( m_layerId, refLayerIdc ) ) )
3689    {
3690      if (activeMotionPredReflayerIdx == pcSlice->getColRefLayerIdx())
3691      {
3692        ilpPic = m_pcEncTop->getIlpList()[refLayerIdc];
3693        break;
3694      }
3695      else
3696      {
3697        activeMotionPredReflayerIdx++;
3698      }
3699    }
3700  }
3701
3702  assert(ilpPic != NULL);
3703
3704  return ilpPic;
3705}
3706#endif
3707
3708//! \}
Note: See TracBrowser for help on using the repository browser.