source: SHVCSoftware/branches/SHM-2.0-dev/source/Lib/TLibEncoder/TEncGOP.cpp @ 583

Last change on this file since 583 was 187, checked in by seregin, 12 years ago

enable zero number of direct references, fix for AVC base YUV input

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