source: SHVCSoftware/trunk/source/Lib/TLibEncoder/TEncGOP.cpp @ 372

Last change on this file since 372 was 352, checked in by seregin, 11 years ago

merge SHM-3.0-dev branch

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