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

Last change on this file since 674 was 673, checked in by etri, 11 years ago

Add a condition to the derivation of refLayerPicIdc of (TemporalId == 0) : JCTVC-Q0060 proposal 2

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