source: SHVCSoftware/branches/SHM-3.1-dev/source/Lib/TLibEncoder/TEncGOP.cpp @ 421

Last change on this file since 421 was 418, checked in by seregin, 12 years ago

formatting the code

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