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

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

update to HM-13.0

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