source: 3DVCSoftware/branches/HTM-DEV-0.3-dev2/source/Lib/TLibEncoder/TEncGOP.cpp @ 534

Last change on this file since 534 was 534, checked in by tech, 11 years ago

MergeMerged tags/HTM-DEV-1.0.

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