source: SHVCSoftware/branches/SHM-2.1-dev/source/Lib/TLibEncoder/TEncGOP.cpp @ 288

Last change on this file since 288 was 288, checked in by qualcomm, 11 years ago

Changes made to signaling of scaled reference layer offsets.

Patch incorporating changes made to signaling of scaled reference layer offsets during SHVC editing. The number of sets of scaled reference layer offsets is signaled. Changes to configuration files also included.

From: Adarsh K. Ramasubramonian <aramasub@…>

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