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

Last change on this file since 226 was 195, checked in by sharp, 12 years ago

JCTVC-M0208 proposal 1— A restriction on inter-layer reference pictures
From Sachin Deshpande <sdeshpande@…>

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