source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncGOP.cpp @ 1179

Last change on this file since 1179 was 1179, checked in by tech, 9 years ago

Merged branch 13.1-dev0@1178.

  • Property svn:eol-style set to native
File size: 127.9 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-2015, 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#if ALLOW_RECOVERY_POINT_AS_RAP
78  m_iLastRecoveryPicPOC = 0;
79#endif
80 
81  m_pcCfg               = NULL;
82  m_pcSliceEncoder      = NULL;
83  m_pcListPic           = NULL;
84 
85  m_pcEntropyCoder      = NULL;
86  m_pcCavlcCoder        = NULL;
87  m_pcSbacCoder         = NULL;
88  m_pcBinCABAC          = NULL;
89 
90  m_bSeqFirst           = true;
91 
92  m_bRefreshPending     = 0;
93  m_pocCRA            = 0;
94  m_numLongTermRefPicSPS = 0;
95  ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps));
96  ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag));
97  m_cpbRemovalDelay   = 0;
98  m_lastBPSEI         = 0;
99  xResetNonNestedSEIPresentFlags();
100  xResetNestedSEIPresentFlags();
101#if H_MV
102  m_layerId      = 0;
103  m_viewId       = 0;
104  m_pocLastCoded = -1; 
105#if H_3D
106  m_viewIndex  =   0; 
107  m_isDepth = false;
108#endif
109#endif
110#if FIX1172
111  m_associatedIRAPType = NAL_UNIT_CODED_SLICE_IDR_N_LP;
112  m_associatedIRAPPOC  = 0;
113#endif
114  return;
115}
116
117TEncGOP::~TEncGOP()
118{
119}
120
121/** Create list to contain pointers to LCU start addresses of slice.
122 */
123Void  TEncGOP::create()
124{
125  m_bLongtermTestPictureHasBeenCoded = 0;
126  m_bLongtermTestPictureHasBeenCoded2 = 0;
127}
128
129Void  TEncGOP::destroy()
130{
131}
132
133Void TEncGOP::init ( TEncTop* pcTEncTop )
134{
135  m_pcEncTop     = pcTEncTop;
136  m_pcCfg                = pcTEncTop;
137  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
138  m_pcListPic            = pcTEncTop->getListPic();
139 
140  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
141  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
142  m_pcSbacCoder          = pcTEncTop->getSbacCoder();
143  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
144  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
145  m_pcBitCounter         = pcTEncTop->getBitCounter();
146 
147  //--Adaptive Loop filter
148  m_pcSAO                = pcTEncTop->getSAO();
149  m_pcRateCtrl           = pcTEncTop->getRateCtrl();
150  m_lastBPSEI          = 0;
151  m_totalCoded         = 0;
152
153#if H_MV
154  m_ivPicLists           = pcTEncTop->getIvPicLists(); 
155  m_layerId              = pcTEncTop->getLayerId();
156  m_viewId               = pcTEncTop->getViewId();
157#if H_3D
158  m_viewIndex            = pcTEncTop->getViewIndex();
159  m_isDepth              = pcTEncTop->getIsDepth();
160#endif
161#endif
162#if H_3D_IC
163  m_aICEnableCandidate   = pcTEncTop->getICEnableCandidate(); 
164  m_aICEnableNum         = pcTEncTop->getICEnableNum(); 
165#endif
166#if KWU_FIX_URQ
167  m_pcRateCtrl           = pcTEncTop->getRateCtrl();
168#endif
169}
170
171SEIActiveParameterSets* TEncGOP::xCreateSEIActiveParameterSets (TComSPS *sps)
172{
173  SEIActiveParameterSets *seiActiveParameterSets = new SEIActiveParameterSets(); 
174  seiActiveParameterSets->activeVPSId = m_pcCfg->getVPS()->getVPSId(); 
175  seiActiveParameterSets->m_selfContainedCvsFlag = false;
176  seiActiveParameterSets->m_noParameterSetUpdateFlag = false;
177  seiActiveParameterSets->numSpsIdsMinus1 = 0;
178  seiActiveParameterSets->activeSeqParameterSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1); 
179  seiActiveParameterSets->activeSeqParameterSetId[0] = sps->getSPSId();
180  return seiActiveParameterSets;
181}
182
183SEIFramePacking* TEncGOP::xCreateSEIFramePacking()
184{
185  SEIFramePacking *seiFramePacking = new SEIFramePacking();
186  seiFramePacking->m_arrangementId = m_pcCfg->getFramePackingArrangementSEIId();
187  seiFramePacking->m_arrangementCancelFlag = 0;
188  seiFramePacking->m_arrangementType = m_pcCfg->getFramePackingArrangementSEIType();
189  assert((seiFramePacking->m_arrangementType > 2) && (seiFramePacking->m_arrangementType < 6) );
190  seiFramePacking->m_quincunxSamplingFlag = m_pcCfg->getFramePackingArrangementSEIQuincunx();
191  seiFramePacking->m_contentInterpretationType = m_pcCfg->getFramePackingArrangementSEIInterpretation();
192  seiFramePacking->m_spatialFlippingFlag = 0;
193  seiFramePacking->m_frame0FlippedFlag = 0;
194  seiFramePacking->m_fieldViewsFlag = (seiFramePacking->m_arrangementType == 2);
195  seiFramePacking->m_currentFrameIsFrame0Flag = ((seiFramePacking->m_arrangementType == 5) && m_iNumPicCoded&1);
196  seiFramePacking->m_frame0SelfContainedFlag = 0;
197  seiFramePacking->m_frame1SelfContainedFlag = 0;
198  seiFramePacking->m_frame0GridPositionX = 0;
199  seiFramePacking->m_frame0GridPositionY = 0;
200  seiFramePacking->m_frame1GridPositionX = 0;
201  seiFramePacking->m_frame1GridPositionY = 0;
202  seiFramePacking->m_arrangementReservedByte = 0;
203  seiFramePacking->m_arrangementPersistenceFlag = true;
204  seiFramePacking->m_upsampledAspectRatio = 0;
205  return seiFramePacking;
206}
207
208SEIDisplayOrientation* TEncGOP::xCreateSEIDisplayOrientation()
209{
210  SEIDisplayOrientation *seiDisplayOrientation = new SEIDisplayOrientation();
211  seiDisplayOrientation->cancelFlag = false;
212  seiDisplayOrientation->horFlip = false;
213  seiDisplayOrientation->verFlip = false;
214  seiDisplayOrientation->anticlockwiseRotation = m_pcCfg->getDisplayOrientationSEIAngle();
215  return seiDisplayOrientation;
216}
217
218SEIToneMappingInfo*  TEncGOP::xCreateSEIToneMappingInfo()
219{
220  SEIToneMappingInfo *seiToneMappingInfo = new SEIToneMappingInfo();
221  seiToneMappingInfo->m_toneMapId = m_pcCfg->getTMISEIToneMapId();
222  seiToneMappingInfo->m_toneMapCancelFlag = m_pcCfg->getTMISEIToneMapCancelFlag();
223  seiToneMappingInfo->m_toneMapPersistenceFlag = m_pcCfg->getTMISEIToneMapPersistenceFlag();
224
225  seiToneMappingInfo->m_codedDataBitDepth = m_pcCfg->getTMISEICodedDataBitDepth();
226  assert(seiToneMappingInfo->m_codedDataBitDepth >= 8 && seiToneMappingInfo->m_codedDataBitDepth <= 14);
227  seiToneMappingInfo->m_targetBitDepth = m_pcCfg->getTMISEITargetBitDepth();
228  assert( seiToneMappingInfo->m_targetBitDepth >= 1 && seiToneMappingInfo->m_targetBitDepth <= 17 );
229  seiToneMappingInfo->m_modelId = m_pcCfg->getTMISEIModelID();
230  assert(seiToneMappingInfo->m_modelId >=0 &&seiToneMappingInfo->m_modelId<=4);
231
232  switch( seiToneMappingInfo->m_modelId)
233  {
234  case 0:
235    {
236      seiToneMappingInfo->m_minValue = m_pcCfg->getTMISEIMinValue();
237      seiToneMappingInfo->m_maxValue = m_pcCfg->getTMISEIMaxValue();
238      break;
239    }
240  case 1:
241    {
242      seiToneMappingInfo->m_sigmoidMidpoint = m_pcCfg->getTMISEISigmoidMidpoint();
243      seiToneMappingInfo->m_sigmoidWidth = m_pcCfg->getTMISEISigmoidWidth();
244      break;
245    }
246  case 2:
247    {
248      UInt num = 1u<<(seiToneMappingInfo->m_targetBitDepth);
249      seiToneMappingInfo->m_startOfCodedInterval.resize(num);
250      Int* ptmp = m_pcCfg->getTMISEIStartOfCodedInterva();
251      if(ptmp)
252      {
253        for(int i=0; i<num;i++)
254        {
255          seiToneMappingInfo->m_startOfCodedInterval[i] = ptmp[i];
256        }
257      }
258      break;
259    }
260  case 3:
261    {
262      seiToneMappingInfo->m_numPivots = m_pcCfg->getTMISEINumPivots();
263      seiToneMappingInfo->m_codedPivotValue.resize(seiToneMappingInfo->m_numPivots);
264      seiToneMappingInfo->m_targetPivotValue.resize(seiToneMappingInfo->m_numPivots);
265      Int* ptmpcoded = m_pcCfg->getTMISEICodedPivotValue();
266      Int* ptmptarget = m_pcCfg->getTMISEITargetPivotValue();
267      if(ptmpcoded&&ptmptarget)
268      {
269        for(int i=0; i<(seiToneMappingInfo->m_numPivots);i++)
270        {
271          seiToneMappingInfo->m_codedPivotValue[i]=ptmpcoded[i];
272          seiToneMappingInfo->m_targetPivotValue[i]=ptmptarget[i];
273         }
274       }
275       break;
276     }
277  case 4:
278     {
279       seiToneMappingInfo->m_cameraIsoSpeedIdc = m_pcCfg->getTMISEICameraIsoSpeedIdc();
280       seiToneMappingInfo->m_cameraIsoSpeedValue = m_pcCfg->getTMISEICameraIsoSpeedValue();
281       assert( seiToneMappingInfo->m_cameraIsoSpeedValue !=0 );
282       seiToneMappingInfo->m_exposureIndexIdc = m_pcCfg->getTMISEIExposurIndexIdc();
283       seiToneMappingInfo->m_exposureIndexValue = m_pcCfg->getTMISEIExposurIndexValue();
284       assert( seiToneMappingInfo->m_exposureIndexValue !=0 );
285       seiToneMappingInfo->m_exposureCompensationValueSignFlag = m_pcCfg->getTMISEIExposureCompensationValueSignFlag();
286       seiToneMappingInfo->m_exposureCompensationValueNumerator = m_pcCfg->getTMISEIExposureCompensationValueNumerator();
287       seiToneMappingInfo->m_exposureCompensationValueDenomIdc = m_pcCfg->getTMISEIExposureCompensationValueDenomIdc();
288       seiToneMappingInfo->m_refScreenLuminanceWhite = m_pcCfg->getTMISEIRefScreenLuminanceWhite();
289       seiToneMappingInfo->m_extendedRangeWhiteLevel = m_pcCfg->getTMISEIExtendedRangeWhiteLevel();
290       assert( seiToneMappingInfo->m_extendedRangeWhiteLevel >= 100 );
291       seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue = m_pcCfg->getTMISEINominalBlackLevelLumaCodeValue();
292       seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue = m_pcCfg->getTMISEINominalWhiteLevelLumaCodeValue();
293       assert( seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue > seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue );
294       seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue = m_pcCfg->getTMISEIExtendedWhiteLevelLumaCodeValue();
295       assert( seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue >= seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue );
296       break;
297    }
298  default:
299    {
300      assert(!"Undefined SEIToneMapModelId");
301      break;
302    }
303  }
304  return seiToneMappingInfo;
305}
306
307#if H_MV
308SEISubBitstreamProperty *TEncGOP::xCreateSEISubBitstreamProperty( TComSPS *sps)
309{
310  SEISubBitstreamProperty *seiSubBitstreamProperty = new SEISubBitstreamProperty();
311
312  seiSubBitstreamProperty->m_activeVpsId = sps->getVPSId();
313  /* These values can be determined by the encoder; for now we will use the input parameter */
314  TEncTop *encTop = this->m_pcEncTop;
315  seiSubBitstreamProperty->m_numAdditionalSubStreams = encTop->getNumAdditionalSubStreams();
316  seiSubBitstreamProperty->m_subBitstreamMode        = encTop->getSubBitstreamMode();
317  seiSubBitstreamProperty->m_outputLayerSetIdxToVps  = encTop->getOutputLayerSetIdxToVps();
318  seiSubBitstreamProperty->m_highestSublayerId       = encTop->getHighestSublayerId();
319  seiSubBitstreamProperty->m_avgBitRate              = encTop->getAvgBitRate();
320  seiSubBitstreamProperty->m_maxBitRate              = encTop->getMaxBitRate();
321
322  return seiSubBitstreamProperty;
323}
324#endif
325
326Void TEncGOP::xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps)
327{
328  OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
329
330  if(m_pcCfg->getActiveParameterSetsSEIEnabled())
331  {
332    SEIActiveParameterSets *sei = xCreateSEIActiveParameterSets (sps);
333
334    //nalu = NALUnit(NAL_UNIT_SEI);
335    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
336    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
337    writeRBSPTrailingBits(nalu.m_Bitstream);
338    accessUnit.push_back(new NALUnitEBSP(nalu));
339    delete sei;
340    m_activeParameterSetSEIPresentInAU = true;
341  }
342
343  if(m_pcCfg->getFramePackingArrangementSEIEnabled())
344  {
345    SEIFramePacking *sei = xCreateSEIFramePacking ();
346
347    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
348    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
349    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
350    writeRBSPTrailingBits(nalu.m_Bitstream);
351    accessUnit.push_back(new NALUnitEBSP(nalu));
352    delete sei;
353  }
354  if (m_pcCfg->getDisplayOrientationSEIAngle())
355  {
356    SEIDisplayOrientation *sei = xCreateSEIDisplayOrientation();
357
358    nalu = NALUnit(NAL_UNIT_PREFIX_SEI); 
359    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
360    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
361    writeRBSPTrailingBits(nalu.m_Bitstream);
362    accessUnit.push_back(new NALUnitEBSP(nalu));
363    delete sei;
364  }
365  if(m_pcCfg->getToneMappingInfoSEIEnabled())
366  {
367    SEIToneMappingInfo *sei = xCreateSEIToneMappingInfo ();
368     
369    nalu = NALUnit(NAL_UNIT_PREFIX_SEI); 
370    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
371    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
372    writeRBSPTrailingBits(nalu.m_Bitstream);
373    accessUnit.push_back(new NALUnitEBSP(nalu));
374    delete sei;
375  }
376#if H_MV
377  if( m_pcCfg->getSubBitstreamPropSEIEnabled() )
378  {
379    SEISubBitstreamProperty *sei = xCreateSEISubBitstreamProperty ( sps );
380
381    nalu = NALUnit(NAL_UNIT_PREFIX_SEI); 
382    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
383    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
384    writeRBSPTrailingBits(nalu.m_Bitstream);
385    accessUnit.push_back(new NALUnitEBSP(nalu));
386    delete sei;
387  }
388#endif
389}
390
391// ====================================================================================================================
392// Public member functions
393// ====================================================================================================================
394#if H_MV
395Void TEncGOP::initGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP)
396{
397#if H_MV_ALIGN_HM_15
398  xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut, false );
399#else
400  xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut );
401#endif
402  m_iNumPicCoded = 0;
403}
404#endif
405#if H_MV
406Void TEncGOP::compressPicInGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP, Int iGOPid, bool isField, bool isTff)
407#else
408Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP, bool isField, bool isTff)
409#endif
410{
411  TComPic*        pcPic;
412  TComPicYuv*     pcPicYuvRecOut;
413  TComSlice*      pcSlice;
414  TComOutputBitstream  *pcBitstreamRedirect;
415  pcBitstreamRedirect = new TComOutputBitstream;
416  AccessUnit::iterator  itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted
417  UInt                  uiOneBitstreamPerSliceLength = 0;
418  TEncSbac* pcSbacCoders = NULL;
419  TComOutputBitstream* pcSubstreamsOut = NULL;
420
421#if !H_MV
422  xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut, isField );
423
424 
425  m_iNumPicCoded = 0;
426#endif
427  SEIPictureTiming pictureTimingSEI;
428  Bool writeSOP = m_pcCfg->getSOPDescriptionSEIEnabled();
429  // Initialize Scalable Nesting SEI with single layer values
430  SEIScalableNesting scalableNestingSEI;
431  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
432  scalableNestingSEI.m_nestingOpFlag                 = 0;
433  scalableNestingSEI.m_nestingNumOpsMinus1           = 0;      //nesting_num_ops_minus1
434  scalableNestingSEI.m_allLayersFlag                 = 0;
435  scalableNestingSEI.m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1;  //nesting_no_op_max_temporal_id_plus1
436  scalableNestingSEI.m_nestingNumLayersMinus1        = 1 - 1;  //nesting_num_layers_minus1
437  scalableNestingSEI.m_nestingLayerId[0]             = 0;
438  scalableNestingSEI.m_callerOwnsSEIs                = true;
439  Int picSptDpbOutputDuDelay = 0;
440  UInt *accumBitsDU = NULL;
441  UInt *accumNalsDU = NULL;
442  SEIDecodingUnitInfo decodingUnitInfoSEI;
443#if EFFICIENT_FIELD_IRAP
444  Int IRAPGOPid = -1;
445  Bool IRAPtoReorder = false;
446  Bool swapIRAPForward = false;
447  if(isField)
448  {
449    Int pocCurr;
450#if !H_MV
451    for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
452#endif
453    {
454      // determine actual POC
455      if(iPOCLast == 0) //case first frame or first top field
456      {
457        pocCurr=0;
458      }
459      else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
460      {
461        pocCurr = 1;
462      }
463      else
464      {
465        pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField;
466      }
467
468      // check if POC corresponds to IRAP
469      NalUnitType tmpUnitType = getNalUnitType(pocCurr, m_iLastIDR, isField);
470      if(tmpUnitType >= NAL_UNIT_CODED_SLICE_BLA_W_LP && tmpUnitType <= NAL_UNIT_CODED_SLICE_CRA) // if picture is an IRAP
471      {
472        if(pocCurr%2 == 0 && iGOPid < m_iGopSize-1 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid+1).m_POC-1)
473        { // if top field and following picture in enc order is associated bottom field
474          IRAPGOPid = iGOPid;
475          IRAPtoReorder = true;
476          swapIRAPForward = true; 
477          break;
478        }
479        if(pocCurr%2 != 0 && iGOPid > 0 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid-1).m_POC+1)
480        {
481          // if picture is an IRAP remember to process it first
482          IRAPGOPid = iGOPid;
483          IRAPtoReorder = true;
484          swapIRAPForward = false; 
485          break;
486        }
487      }
488    }
489  }
490#endif
491#if !H_MV
492  for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
493#endif
494  {
495#if EFFICIENT_FIELD_IRAP
496    if(IRAPtoReorder)
497    {
498      if(swapIRAPForward)
499      {
500        if(iGOPid == IRAPGOPid)
501        {
502          iGOPid = IRAPGOPid +1;
503        }
504        else if(iGOPid == IRAPGOPid +1)
505        {
506          iGOPid = IRAPGOPid;
507        }
508      }
509      else
510      {
511        if(iGOPid == IRAPGOPid -1)
512        {
513          iGOPid = IRAPGOPid;
514        }
515        else if(iGOPid == IRAPGOPid)
516        {
517          iGOPid = IRAPGOPid -1;
518        }
519      }
520    }
521#endif
522    UInt uiColDir = 1;
523    //-- For time output for each slice
524    long iBeforeTime = clock();
525
526    //select uiColDir
527    Int iCloseLeft=1, iCloseRight=-1;
528    for(Int i = 0; i<m_pcCfg->getGOPEntry(iGOPid).m_numRefPics; i++) 
529    {
530      Int iRef = m_pcCfg->getGOPEntry(iGOPid).m_referencePics[i];
531      if(iRef>0&&(iRef<iCloseRight||iCloseRight==-1))
532      {
533        iCloseRight=iRef;
534      }
535      else if(iRef<0&&(iRef>iCloseLeft||iCloseLeft==1))
536      {
537        iCloseLeft=iRef;
538      }
539    }
540    if(iCloseRight>-1)
541    {
542      iCloseRight=iCloseRight+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
543    }
544    if(iCloseLeft<1) 
545    {
546      iCloseLeft=iCloseLeft+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
547      while(iCloseLeft<0)
548      {
549        iCloseLeft+=m_iGopSize;
550      }
551    }
552    Int iLeftQP=0, iRightQP=0;
553    for(Int i=0; i<m_iGopSize; i++)
554    {
555      if(m_pcCfg->getGOPEntry(i).m_POC==(iCloseLeft%m_iGopSize)+1)
556      {
557        iLeftQP= m_pcCfg->getGOPEntry(i).m_QPOffset;
558      }
559      if (m_pcCfg->getGOPEntry(i).m_POC==(iCloseRight%m_iGopSize)+1)
560      {
561        iRightQP=m_pcCfg->getGOPEntry(i).m_QPOffset;
562      }
563    }
564    if(iCloseRight>-1&&iRightQP<iLeftQP)
565    {
566      uiColDir=0;
567    }
568
569    /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
570    Int iTimeOffset;
571    Int pocCurr;
572   
573    if(iPOCLast == 0) //case first frame or first top field
574    {
575      pocCurr=0;
576      iTimeOffset = 1;
577    }
578    else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
579    {
580      pocCurr = 1;
581      iTimeOffset = 1;
582    }
583    else
584    {
585      pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField;
586      iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;
587    }
588    if(pocCurr>=m_pcCfg->getFramesToBeEncoded())
589    {
590#if EFFICIENT_FIELD_IRAP
591      if(IRAPtoReorder)
592      {
593        if(swapIRAPForward)
594        {
595          if(iGOPid == IRAPGOPid)
596          {
597            iGOPid = IRAPGOPid +1;
598            IRAPtoReorder = false;
599          }
600          else if(iGOPid == IRAPGOPid +1)
601          {
602            iGOPid --;
603          }
604        }
605        else
606        {
607          if(iGOPid == IRAPGOPid)
608          {
609            iGOPid = IRAPGOPid -1;
610          }
611          else if(iGOPid == IRAPGOPid -1)
612          {
613            iGOPid = IRAPGOPid;
614            IRAPtoReorder = false;
615          }
616        }
617      }
618#endif
619#if H_MV
620      delete pcBitstreamRedirect;
621      return;
622#else
623      continue;
624#endif
625    }
626
627    if( getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType(pocCurr, m_iLastIDR, isField) == NAL_UNIT_CODED_SLICE_IDR_N_LP )
628    {
629      m_iLastIDR = pocCurr;
630    }       
631    // start a new access unit: create an entry in the list of output access units
632    accessUnitsInGOP.push_back(AccessUnit());
633    AccessUnit& accessUnit = accessUnitsInGOP.back();
634    xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField);
635
636    //  Slice data initialization
637    pcPic->clearSliceBuffer();
638    assert(pcPic->getNumAllocatedSlice() == 1);
639    m_pcSliceEncoder->setSliceIdx(0);
640    pcPic->setCurrSliceIdx(0);
641
642
643#if H_MV
644    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getVPS(), m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), getLayerId(), isField  );     
645#else
646    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), isField  );
647#endif
648   
649    //Set Frame/Field coding
650    pcSlice->getPic()->setField(isField);
651
652    pcSlice->setLastIDR(m_iLastIDR);
653    pcSlice->setSliceIdx(0);
654#if H_MV
655    pcSlice->setRefPicSetInterLayer ( &m_refPicSetInterLayer0, &m_refPicSetInterLayer1 ); 
656    pcPic  ->setLayerId     ( getLayerId()   );
657    pcPic  ->setViewId      ( getViewId()    );   
658#if !H_3D
659    pcSlice->setLayerId     ( getLayerId() );
660    pcSlice->setViewId      ( getViewId()  );   
661    pcSlice->setVPS         ( m_pcEncTop->getVPS() );
662#else
663    pcPic  ->setViewIndex   ( getViewIndex() ); 
664    pcPic  ->setIsDepth( getIsDepth() );
665    pcSlice->setCamparaSlice( pcPic->getCodedScale(), pcPic->getCodedOffset() );   
666#endif
667#endif
668    //set default slice level flag to the same as SPS level flag
669    pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag()  );
670    pcSlice->setScalingList ( m_pcEncTop->getScalingList()  );
671    if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_OFF)
672    {
673      m_pcEncTop->getTrQuant()->setFlatScalingList();
674      m_pcEncTop->getTrQuant()->setUseScalingList(false);
675      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
676      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
677    }
678    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_DEFAULT)
679    {
680      pcSlice->setDefaultScalingList ();
681      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
682      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
683      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
684      m_pcEncTop->getTrQuant()->setUseScalingList(true);
685    }
686    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_FILE_READ)
687    {
688      if(pcSlice->getScalingList()->xParseScalingList(m_pcCfg->getScalingListFile()))
689      {
690        pcSlice->setDefaultScalingList ();
691      }
692      pcSlice->getScalingList()->checkDcOfMatrix();
693      m_pcEncTop->getSPS()->setScalingListPresentFlag(pcSlice->checkDefaultScalingList());
694      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
695      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
696      m_pcEncTop->getTrQuant()->setUseScalingList(true);
697    }
698    else
699    {
700      printf("error : ScalingList == %d no support\n",m_pcEncTop->getUseScalingListId());
701      assert(0);
702    }
703
704#if H_MV
705    // Set the nal unit type
706    pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
707    if( pcSlice->getSliceType() == B_SLICE )
708    {
709      if( m_pcCfg->getGOPEntry( ( pcSlice->getRapPicFlag() && getLayerId() > 0 ) ? MAX_GOP : iGOPid ).m_sliceType == 'P' ) 
710      { 
711        pcSlice->setSliceType( P_SLICE );
712      }
713    }
714
715// To be checked!
716    if( pcSlice->getSliceType() == B_SLICE )
717    {
718      if( m_pcCfg->getGOPEntry( ( pcSlice->getRapPicFlag() && getLayerId() > 0 ) ? MAX_GOP : iGOPid ).m_sliceType == 'I' ) 
719      { 
720        pcSlice->setSliceType( I_SLICE );
721      }
722    }
723#else
724    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P')
725    {
726      pcSlice->setSliceType(P_SLICE);
727    }
728    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='I')
729    {
730      pcSlice->setSliceType(I_SLICE);
731    }
732   
733    // Set the nal unit type
734    pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
735#endif
736    if(pcSlice->getTemporalLayerNonReferenceFlag())
737    {
738      if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_TRAIL_R &&
739          !(m_iGopSize == 1 && pcSlice->getSliceType() == I_SLICE))
740        // Add this condition to avoid POC issues with encoder_intra_main.cfg configuration (see #1127 in bug tracker)
741      {
742        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TRAIL_N);
743      }
744      if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RADL_R)
745      {
746        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RADL_N);
747      }
748      if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RASL_R)
749      {
750        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RASL_N);
751      }
752    }
753
754#if EFFICIENT_FIELD_IRAP
755#if FIX1172
756    if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
757      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
758      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
759      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
760      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
761      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
762    {
763      m_associatedIRAPType = pcSlice->getNalUnitType();
764      m_associatedIRAPPOC = pocCurr;
765    }
766    pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
767    pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
768#endif
769#endif
770    // Do decoding refresh marking if any
771    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic);
772    m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid);
773    pcSlice->getRPS()->setNumberOfLongtermPictures(0);
774#if EFFICIENT_FIELD_IRAP
775#else
776#if FIX1172
777    if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
778      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
779      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
780      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
781      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
782      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
783    {
784      m_associatedIRAPType = pcSlice->getNalUnitType();
785      m_associatedIRAPPOC = pocCurr;
786    }
787    pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
788    pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
789#endif
790#endif
791
792#if ALLOW_RECOVERY_POINT_AS_RAP
793    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP()) 
794#if EFFICIENT_FIELD_IRAP
795      || (isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1)
796#endif
797      )
798    {
799      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3);
800    }
801#else
802    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false) != 0) || (pcSlice->isIRAP()))
803    {
804      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP());
805    }
806#endif
807    pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS());
808
809    if(pcSlice->getTLayer() > 0 
810      &&  !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N     // Check if not a leading picture
811          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R
812          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N
813          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R )
814        )
815    {
816      if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic) || pcSlice->getSPS()->getTemporalIdNestingFlag())
817      {
818        if(pcSlice->getTemporalLayerNonReferenceFlag())
819        {
820          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
821        }
822        else
823        {
824          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R);
825        }
826      }
827      else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
828      {
829        Bool isSTSA=true;
830        for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
831        {
832          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
833          if(lTid==pcSlice->getTLayer()) 
834          {
835            TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
836            for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++)
837            {
838              if(nRPS->getUsed(jj)) 
839              {
840                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
841                Int kk=0;
842                for(kk=0;kk<m_pcCfg->getGOPSize();kk++)
843                {
844                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
845                    break;
846                }
847                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
848                if(tTid >= pcSlice->getTLayer())
849                {
850                  isSTSA=false;
851                  break;
852                }
853              }
854            }
855          }
856        }
857        if(isSTSA==true)
858        {   
859          if(pcSlice->getTemporalLayerNonReferenceFlag())
860          {
861            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
862          }
863          else
864          {
865            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
866          }
867        }
868      }
869    }
870    arrangeLongtermPicturesInRPS(pcSlice, rcListPic);
871    TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
872    refPicListModification->setRefPicListModificationFlagL0(0);
873    refPicListModification->setRefPicListModificationFlagL1(0);
874#if H_MV
875    if ( pcSlice->getPPS()->getNumExtraSliceHeaderBits() > 0 )
876    {
877      // Some more sophisticated algorithm to determine discardable_flag might be added here.
878      pcSlice->setDiscardableFlag           ( false );     
879    }   
880
881    TComVPS*           vps = pcSlice->getVPS();     
882#if H_3D
883    Int numDirectRefLayers = vps    ->getNumRefListLayers( getLayerId() ); 
884#else
885    Int numDirectRefLayers = vps    ->getNumDirectRefLayers( getLayerId() ); 
886#endif
887#if HHI_INTER_COMP_PRED_K0052
888    pcSlice->setIvPicLists( m_ivPicLists );         
889
890    Int gopNum = (pcSlice->getRapPicFlag() && getLayerId() > 0) ? MAX_GOP : iGOPid;
891    GOPEntry gopEntry      = m_pcCfg->getGOPEntry( gopNum );     
892#else
893    GOPEntry gopEntry      = m_pcCfg->getGOPEntry( (pcSlice->getRapPicFlag() && getLayerId() > 0) ? MAX_GOP : iGOPid );     
894#endif
895   
896    Bool interLayerPredLayerIdcPresentFlag = false; 
897    if ( getLayerId() > 0 && !vps->getAllRefLayersActiveFlag() && numDirectRefLayers > 0 )
898    {         
899      pcSlice->setInterLayerPredEnabledFlag ( gopEntry.m_numActiveRefLayerPics > 0 );     
900      if ( pcSlice->getInterLayerPredEnabledFlag() && numDirectRefLayers > 1 )
901      {
902        if ( !vps->getMaxOneActiveRefLayerFlag() )
903        {   
904          pcSlice->setNumInterLayerRefPicsMinus1( gopEntry.m_numActiveRefLayerPics - 1 ); 
905        }
906#if H_3D
907        if ( gopEntry.m_numActiveRefLayerPics != vps->getNumRefListLayers( getLayerId() ) )
908#else
909        if ( gopEntry.m_numActiveRefLayerPics != vps->getNumDirectRefLayers( getLayerId() ) )
910#endif
911        {       
912          interLayerPredLayerIdcPresentFlag = true; 
913          for (Int i = 0; i < gopEntry.m_numActiveRefLayerPics; i++ )
914          {
915            pcSlice->setInterLayerPredLayerIdc( i, gopEntry.m_interLayerPredLayerIdc[ i ] ); 
916          }
917        }
918      }
919    }
920    if ( !interLayerPredLayerIdcPresentFlag )
921    {
922      for( Int i = 0; i < pcSlice->getNumActiveRefLayerPics(); i++ )   
923      {
924        pcSlice->setInterLayerPredLayerIdc(i, pcSlice->getRefLayerPicIdc( i ) );
925      }
926    }
927
928
929    assert( pcSlice->getNumActiveRefLayerPics() == gopEntry.m_numActiveRefLayerPics ); 
930   
931#if HHI_INTER_COMP_PRED_K0052
932#if H_3D
933    if ( m_pcEncTop->decProcAnnexI() )
934    {   
935      pcSlice->deriveInCmpPredAndCpAvailFlag(); 
936      if ( pcSlice->getInCmpPredAvailFlag() )
937      {     
938        pcSlice->setInCompPredFlag( gopEntry.m_interCompPredFlag ); 
939      }
940      else
941      {
942        if (gopEntry.m_interCompPredFlag )
943        {
944          if ( gopNum == MAX_GOP)
945          {
946            printf( "\nError: FrameI_l%d cannot enable inter-component prediction.\n", pcSlice->getVPS()->getLayerIdInVps( getLayerId() ) );
947          }
948          else
949          {
950            printf( "\nError: Frame%d_l%d cannot enable inter-component prediction.\n", gopNum, pcSlice->getVPS()->getLayerIdInVps( getLayerId() ) );
951          }
952         
953          exit(EXIT_FAILURE);
954        }
955      }
956      pcSlice->init3dToolParameters(); 
957      pcSlice->checkInCompPredRefLayers(); 
958    }
959   
960
961    // This needs to be done after initilizaiton of 3D tool parameters.
962    pcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()   + ( ( pcSlice->getMpiFlag( ) || pcSlice->getIvMvPredFlag( ) || pcSlice->getViewSynthesisPredFlag( )   ) ? 1 : 0 ));
963#endif
964#endif
965
966    pcSlice->createInterLayerReferencePictureSet( m_ivPicLists, m_refPicSetInterLayer0, m_refPicSetInterLayer1 ); 
967    pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(gopEntry.m_numRefPicsActive,( pcSlice->getRPS()->getNumberOfPictures() + (Int) m_refPicSetInterLayer0.size() + (Int) m_refPicSetInterLayer1.size()) ) );
968    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(gopEntry.m_numRefPicsActive,( pcSlice->getRPS()->getNumberOfPictures() + (Int) m_refPicSetInterLayer0.size() + (Int) m_refPicSetInterLayer1.size()) ) );
969
970    std::vector< TComPic* >    tempRefPicLists[2];
971    std::vector< Bool     >    usedAsLongTerm [2];
972    Int       numPocTotalCurr;
973
974    pcSlice->getTempRefPicLists( rcListPic, m_refPicSetInterLayer0, m_refPicSetInterLayer1, tempRefPicLists, usedAsLongTerm, numPocTotalCurr, true );
975   
976
977    xSetRefPicListModificationsMv( tempRefPicLists, pcSlice, iGOPid );   
978#else
979    pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
980    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
981#endif
982
983#if ADAPTIVE_QP_SELECTION
984    pcSlice->setTrQuant( m_pcEncTop->getTrQuant() );
985#endif     
986
987    //  Set reference list
988#if H_MV   
989    pcSlice->setRefPicList( tempRefPicLists, usedAsLongTerm, numPocTotalCurr ); 
990#else
991    pcSlice->setRefPicList ( rcListPic );
992#endif
993#if H_3D
994    pcSlice->setDefaultRefView();
995#endif
996#if H_3D_ARP
997    //GT: This seems to be broken when layerId in vps is not equal to layerId in nuh
998    pcSlice->setARPStepNum(m_ivPicLists);
999    if(pcSlice->getARPStepNum() > 1)
1000    {
1001      for(Int iLayerId = 0; iLayerId < getLayerId(); iLayerId ++ )
1002      {
1003        Int  iViewIdx =   pcSlice->getVPS()->getViewIndex(iLayerId);
1004        Bool bIsDepth = ( pcSlice->getVPS()->getDepthId  ( iLayerId ) == 1 );
1005        if( iViewIdx<getViewIndex() && !bIsDepth )
1006        {
1007          pcSlice->setBaseViewRefPicList( m_ivPicLists->getPicList( iLayerId ), iViewIdx );
1008        }
1009      }
1010    }
1011#endif
1012#if !HHI_INTER_COMP_PRED_K0052
1013#if H_3D
1014    pcSlice->setIvPicLists( m_ivPicLists );         
1015#if H_3D_IV_MERGE   
1016    assert( !m_pcEncTop->getIsDepth() || ( pcSlice->getTexturePic() != 0 ) );
1017#endif   
1018#endif
1019#endif
1020#if H_3D_IC
1021    pcSlice->setICEnableCandidate( m_aICEnableCandidate );         
1022    pcSlice->setICEnableNum( m_aICEnableNum );         
1023#endif
1024    //  Slice info. refinement
1025#if H_MV
1026    if ( pcSlice->getSliceType() == B_SLICE )
1027    {
1028      if( m_pcCfg->getGOPEntry( ( pcSlice->getRapPicFlag() == true && getLayerId() > 0 ) ? MAX_GOP : iGOPid ).m_sliceType == 'P' ) 
1029      { 
1030        pcSlice->setSliceType( P_SLICE ); 
1031      }
1032    }
1033#else
1034    if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
1035    {
1036      pcSlice->setSliceType ( P_SLICE );
1037    }
1038#endif
1039    if (pcSlice->getSliceType() == B_SLICE)
1040    {
1041      pcSlice->setColFromL0Flag(1-uiColDir);
1042      Bool bLowDelay = true;
1043      Int  iCurrPOC  = pcSlice->getPOC();
1044      Int iRefIdx = 0;
1045
1046      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
1047      {
1048        if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
1049        {
1050          bLowDelay = false;
1051        }
1052      }
1053      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
1054      {
1055        if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
1056        {
1057          bLowDelay = false;
1058        }
1059      }
1060
1061      pcSlice->setCheckLDC(bLowDelay); 
1062    }
1063    else
1064    {
1065      pcSlice->setCheckLDC(true); 
1066    }
1067
1068    uiColDir = 1-uiColDir;
1069
1070    //-------------------------------------------------------------
1071    pcSlice->setRefPOCList();
1072
1073    pcSlice->setList1IdxToList0Idx();
1074#if H_3D_TMVP
1075    if(pcSlice->getLayerId())
1076      pcSlice->generateAlterRefforTMVP();
1077#endif
1078    if (m_pcEncTop->getTMVPModeId() == 2)
1079    {
1080      if (iGOPid == 0) // first picture in SOP (i.e. forward B)
1081      {
1082        pcSlice->setEnableTMVPFlag(0);
1083      }
1084      else
1085      {
1086        // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
1087        pcSlice->setEnableTMVPFlag(1);
1088      }
1089      pcSlice->getSPS()->setTMVPFlagsPresent(1);
1090    }
1091    else if (m_pcEncTop->getTMVPModeId() == 1)
1092    {
1093      pcSlice->getSPS()->setTMVPFlagsPresent(1);
1094      pcSlice->setEnableTMVPFlag(1);
1095    }
1096    else
1097    {
1098      pcSlice->getSPS()->setTMVPFlagsPresent(0);
1099      pcSlice->setEnableTMVPFlag(0);
1100    }
1101#if H_MV
1102    if( pcSlice->getIdrPicFlag() )
1103    {
1104      pcSlice->setEnableTMVPFlag(0);
1105    }
1106#endif
1107
1108#if H_3D_VSO
1109  // Should be moved to TEncTop !!!
1110  Bool bUseVSO = m_pcEncTop->getUseVSO();
1111 
1112  TComRdCost* pcRdCost = m_pcEncTop->getRdCost();   
1113
1114  pcRdCost->setUseVSO( bUseVSO );
1115
1116  // SAIT_VSO_EST_A0033
1117  pcRdCost->setUseEstimatedVSD( m_pcEncTop->getUseEstimatedVSD() );
1118
1119  if ( bUseVSO )
1120  {
1121    Int iVSOMode = m_pcEncTop->getVSOMode();
1122    pcRdCost->setVSOMode( iVSOMode  );
1123    pcRdCost->setAllowNegDist( m_pcEncTop->getAllowNegDist() );
1124
1125    // SAIT_VSO_EST_A0033
1126#if H_3D_FCO
1127    Bool flagRec;
1128    flagRec =  ((m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), false, pcSlice->getPOC(), true) == NULL) ? false: true);
1129    pcRdCost->setVideoRecPicYuv( m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), false, pcSlice->getPOC(), flagRec ) );
1130    pcRdCost->setDepthPicYuv   ( m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), true, pcSlice->getPOC(), false ) );
1131#else
1132    pcRdCost->setVideoRecPicYuv( m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), false , pcSlice->getPOC(), true ) );
1133    pcRdCost->setDepthPicYuv   ( m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), true  , pcSlice->getPOC(), false ) );
1134#endif
1135
1136    // LGE_WVSO_A0119
1137    Bool bUseWVSO  = m_pcEncTop->getUseWVSO();
1138    pcRdCost->setUseWVSO( bUseWVSO );
1139
1140  }
1141#endif
1142    /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
1143    //  Slice compression
1144    if (m_pcCfg->getUseASR())
1145    {
1146      m_pcSliceEncoder->setSearchRange(pcSlice);
1147    }
1148
1149    Bool bGPBcheck=false;
1150    if ( pcSlice->getSliceType() == B_SLICE)
1151    {
1152      if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
1153      {
1154        bGPBcheck=true;
1155        Int i;
1156        for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
1157        {
1158          if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 
1159          {
1160            bGPBcheck=false;
1161            break;
1162          }
1163        }
1164      }
1165    }
1166    if(bGPBcheck)
1167    {
1168      pcSlice->setMvdL1ZeroFlag(true);
1169    }
1170    else
1171    {
1172      pcSlice->setMvdL1ZeroFlag(false);
1173    }
1174    pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
1175
1176    Double lambda            = 0.0;
1177    Int actualHeadBits       = 0;
1178    Int actualTotalBits      = 0;
1179    Int estimatedBits        = 0;
1180    Int tmpBitsBeforeWriting = 0;
1181    if ( m_pcCfg->getUseRateCtrl() )
1182    {
1183      Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
1184      if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )
1185      {
1186        frameLevel = 0;
1187      }
1188      m_pcRateCtrl->initRCPic( frameLevel );
1189
1190#if KWU_RC_MADPRED_E0227
1191      if(m_pcCfg->getLayerId() != 0)
1192      {
1193        m_pcRateCtrl->getRCPic()->setIVPic( m_pcEncTop->getEncTop()->getTEncTop(0)->getRateCtrl()->getRCPic() );
1194      }
1195#endif
1196
1197      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
1198
1199      Int sliceQP = m_pcCfg->getInitialQP();
1200      if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
1201      {
1202        Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
1203        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
1204        Double dQPFactor     = 0.57*dLambda_scale;
1205        Int    SHIFT_QP      = 12;
1206        Int    bitdepth_luma_qp_scale = 0;
1207        Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP;
1208        lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
1209      }
1210      else if ( frameLevel == 0 )   // intra case, but use the model
1211      {
1212        m_pcSliceEncoder->calCostSliceI(pcPic);
1213        if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case
1214        {
1215          Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
1216          bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );
1217          if ( bits < 200 )
1218          {
1219            bits = 200;
1220          }
1221          m_pcRateCtrl->getRCPic()->setTargetBits( bits );
1222        }
1223
1224        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
1225        m_pcRateCtrl->getRCPic()->getLCUInitTargetBits();
1226        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
1227        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
1228      }
1229      else    // normal case
1230      {
1231#if KWU_RC_MADPRED_E0227
1232        if(m_pcRateCtrl->getLayerID() != 0)
1233        {
1234          list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
1235          lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambdaIV( listPreviousPicture, pcSlice->getPOC() );
1236          sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
1237        }
1238        else
1239        {
1240#endif
1241        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
1242        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
1243        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
1244#if KWU_RC_MADPRED_E0227
1245        }
1246#endif
1247      }
1248
1249      sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, sliceQP );
1250      m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );
1251
1252      m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );
1253    }
1254
1255    UInt uiNumSlices = 1;
1256
1257    UInt uiInternalAddress = pcPic->getNumPartInCU()-4;
1258    UInt uiExternalAddress = pcPic->getPicSym()->getNumberOfCUsInFrame()-1;
1259    UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1260    UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1261    UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1262    UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1263    while(uiPosX>=uiWidth||uiPosY>=uiHeight) 
1264    {
1265      uiInternalAddress--;
1266      uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1267      uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1268    }
1269    uiInternalAddress++;
1270    if(uiInternalAddress==pcPic->getNumPartInCU()) 
1271    {
1272      uiInternalAddress = 0;
1273      uiExternalAddress++;
1274    }
1275    UInt uiRealEndAddress = uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress;
1276
1277    Int  p, j;
1278    UInt uiEncCUAddr;
1279
1280    pcPic->getPicSym()->initTiles(pcSlice->getPPS());
1281
1282    // Allocate some coders, now we know how many tiles there are.
1283    Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1284
1285    //generate the Coding Order Map and Inverse Coding Order Map
1286    for(p=0, uiEncCUAddr=0; p<pcPic->getPicSym()->getNumberOfCUsInFrame(); p++, uiEncCUAddr = pcPic->getPicSym()->xCalculateNxtCUAddr(uiEncCUAddr))
1287    {
1288      pcPic->getPicSym()->setCUOrderMap(p, uiEncCUAddr);
1289      pcPic->getPicSym()->setInverseCUOrderMap(uiEncCUAddr, p);
1290    }
1291    pcPic->getPicSym()->setCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());   
1292    pcPic->getPicSym()->setInverseCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());
1293
1294    // Allocate some coders, now we know how many tiles there are.
1295    m_pcEncTop->createWPPCoders(iNumSubstreams);
1296    pcSbacCoders = m_pcEncTop->getSbacCoders();
1297    pcSubstreamsOut = new TComOutputBitstream[iNumSubstreams];
1298
1299    UInt startCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
1300    UInt startCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
1301    pcSlice->setSliceCurStartCUAddr( startCUAddrSlice ); // Setting "start CU addr" for current slice
1302    m_storedStartCUAddrForEncodingSlice.clear();
1303
1304    UInt startCUAddrSliceSegmentIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
1305    UInt startCUAddrSliceSegment    = 0; // used to keep track of current Dependent slice's starting CU addr.
1306    pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment ); // Setting "start CU addr" for current Dependent slice
1307
1308    m_storedStartCUAddrForEncodingSliceSegment.clear();
1309    UInt nextCUAddr = 0;
1310    m_storedStartCUAddrForEncodingSlice.push_back (nextCUAddr);
1311    startCUAddrSliceIdx++;
1312    m_storedStartCUAddrForEncodingSliceSegment.push_back(nextCUAddr);
1313    startCUAddrSliceSegmentIdx++;
1314#if H_3D_NBDV
1315      if(pcSlice->getViewIndex() && !pcSlice->getIsDepth()) //Notes from QC: this condition shall be changed once the configuration is completed, e.g. in pcSlice->getSPS()->getMultiviewMvPredMode() || ARP in prev. HTM. Remove this comment once it is done.
1316      {
1317        Int iColPoc = pcSlice->getRefPOC(RefPicList(1-pcSlice->getColFromL0Flag()), pcSlice->getColRefIdx());
1318        pcPic->setNumDdvCandPics(pcPic->getDisCandRefPictures(iColPoc));
1319      }
1320#endif
1321#if H_3D
1322      pcSlice->setDepthToDisparityLUTs(); 
1323
1324#endif
1325
1326#if H_3D_NBDV
1327      if(pcSlice->getViewIndex() && !pcSlice->getIsDepth() && !pcSlice->isIntra()) //Notes from QC: this condition shall be changed once the configuration is completed, e.g. in pcSlice->getSPS()->getMultiviewMvPredMode() || ARP in prev. HTM. Remove this comment once it is done.
1328      {
1329        pcPic->checkTemporalIVRef();
1330      }
1331
1332      if(pcSlice->getIsDepth())
1333      {
1334        pcPic->checkTextureRef();
1335      }
1336#endif
1337    while(nextCUAddr<uiRealEndAddress) // determine slice boundaries
1338    {
1339      pcSlice->setNextSlice       ( false );
1340      pcSlice->setNextSliceSegment( false );
1341      assert(pcPic->getNumAllocatedSlice() == startCUAddrSliceIdx);
1342      m_pcSliceEncoder->precompressSlice( pcPic );
1343      m_pcSliceEncoder->compressSlice   ( pcPic );
1344
1345      Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextSliceSegment());
1346      if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU))
1347      {
1348        startCUAddrSlice = pcSlice->getSliceCurEndCUAddr();
1349        // Reconstruction slice
1350        m_storedStartCUAddrForEncodingSlice.push_back(startCUAddrSlice);
1351        startCUAddrSliceIdx++;
1352        // Dependent slice
1353        if (startCUAddrSliceSegmentIdx>0 && m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx-1] != startCUAddrSlice)
1354        {
1355          m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSlice);
1356          startCUAddrSliceSegmentIdx++;
1357        }
1358
1359        if (startCUAddrSlice < uiRealEndAddress)
1360        {
1361          pcPic->allocateNewSlice();         
1362          pcPic->setCurrSliceIdx                  ( startCUAddrSliceIdx-1 );
1363          m_pcSliceEncoder->setSliceIdx           ( startCUAddrSliceIdx-1 );
1364          pcSlice = pcPic->getSlice               ( startCUAddrSliceIdx-1 );
1365          pcSlice->copySliceInfo                  ( pcPic->getSlice(0)      );
1366          pcSlice->setSliceIdx                    ( startCUAddrSliceIdx-1 );
1367          pcSlice->setSliceCurStartCUAddr         ( startCUAddrSlice      );
1368          pcSlice->setSliceSegmentCurStartCUAddr  ( startCUAddrSlice      );
1369          pcSlice->setSliceBits(0);
1370          uiNumSlices ++;
1371        }
1372      }
1373      else if (pcSlice->isNextSliceSegment() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU))
1374      {
1375        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
1376        m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSliceSegment);
1377        startCUAddrSliceSegmentIdx++;
1378        pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment );
1379      }
1380      else
1381      {
1382        startCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
1383        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
1384      }       
1385
1386      nextCUAddr = (startCUAddrSlice > startCUAddrSliceSegment) ? startCUAddrSlice : startCUAddrSliceSegment;
1387    }
1388    m_storedStartCUAddrForEncodingSlice.push_back( pcSlice->getSliceCurEndCUAddr());
1389    startCUAddrSliceIdx++;
1390    m_storedStartCUAddrForEncodingSliceSegment.push_back(pcSlice->getSliceCurEndCUAddr());
1391    startCUAddrSliceSegmentIdx++;
1392
1393    pcSlice = pcPic->getSlice(0);
1394
1395    // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
1396    if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoLcuBoundary() )
1397    {
1398      m_pcSAO->getPreDBFStatistics(pcPic);
1399    }
1400
1401    //-- Loop filter
1402    Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
1403    m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
1404    if ( m_pcCfg->getDeblockingFilterMetric() )
1405    {
1406      dblMetric(pcPic, uiNumSlices);
1407    }
1408    m_pcLoopFilter->loopFilterPic( pcPic );
1409
1410    /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
1411    // Set entropy coder
1412    m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1413
1414    /* write various header sets. */
1415    if ( m_bSeqFirst )
1416    {
1417      OutputNALUnit nalu(NAL_UNIT_VPS);
1418#if H_MV
1419      if( getLayerId() == 0 )
1420      {
1421#endif
1422      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1423      m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());
1424      writeRBSPTrailingBits(nalu.m_Bitstream);
1425      accessUnit.push_back(new NALUnitEBSP(nalu));
1426      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1427
1428#if H_MV
1429      }
1430      nalu = NALUnit(NAL_UNIT_SPS, 0, getLayerId());
1431#else
1432      nalu = NALUnit(NAL_UNIT_SPS);
1433#endif
1434      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1435      if (m_bSeqFirst)
1436      {
1437        pcSlice->getSPS()->setNumLongTermRefPicSPS(m_numLongTermRefPicSPS);
1438        for (Int k = 0; k < m_numLongTermRefPicSPS; k++)
1439        {
1440          pcSlice->getSPS()->setLtRefPicPocLsbSps(k, m_ltRefPicPocLsbSps[k]);
1441          pcSlice->getSPS()->setUsedByCurrPicLtSPSFlag(k, m_ltRefPicUsedByCurrPicFlag[k]);
1442        }
1443      }
1444      if( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
1445      {
1446        UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1);
1447        UInt numDU = ( m_pcCfg->getSliceMode() == 1 ) ? ( pcPic->getNumCUsInFrame() / maxCU ) : ( 0 );
1448        if( pcPic->getNumCUsInFrame() % maxCU != 0 || numDU == 0 )
1449        {
1450          numDU ++;
1451        }
1452        pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->setNumDU( numDU );
1453        pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) );
1454      }
1455      if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
1456      {
1457        pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true );
1458      }
1459      m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
1460      writeRBSPTrailingBits(nalu.m_Bitstream);
1461      accessUnit.push_back(new NALUnitEBSP(nalu));
1462      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1463
1464#if H_MV
1465      nalu = NALUnit(NAL_UNIT_PPS, 0, getLayerId());
1466#else
1467      nalu = NALUnit(NAL_UNIT_PPS);
1468#endif
1469#if PPS_FIX_DEPTH
1470      if(!pcSlice->getIsDepth() || !pcSlice->getViewIndex() )
1471      {
1472#endif
1473      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1474      m_pcEntropyCoder->encodePPS(pcSlice->getPPS());
1475      writeRBSPTrailingBits(nalu.m_Bitstream);
1476      accessUnit.push_back(new NALUnitEBSP(nalu));
1477      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1478     
1479#if PPS_FIX_DEPTH
1480      }
1481#endif
1482      xCreateLeadingSEIMessages(accessUnit, pcSlice->getSPS());
1483
1484      m_bSeqFirst = false;
1485    }
1486
1487    if (writeSOP) // write SOP description SEI (if enabled) at the beginning of GOP
1488    {
1489      Int SOPcurrPOC = pocCurr;
1490
1491      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1492      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1493      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1494
1495      SEISOPDescription SOPDescriptionSEI;
1496      SOPDescriptionSEI.m_sopSeqParameterSetId = pcSlice->getSPS()->getSPSId();
1497
1498      UInt i = 0;
1499      UInt prevEntryId = iGOPid;
1500      for (j = iGOPid; j < m_iGopSize; j++)
1501      {
1502        Int deltaPOC = m_pcCfg->getGOPEntry(j).m_POC - m_pcCfg->getGOPEntry(prevEntryId).m_POC;
1503        if ((SOPcurrPOC + deltaPOC) < m_pcCfg->getFramesToBeEncoded())
1504        {
1505          SOPcurrPOC += deltaPOC;
1506          SOPDescriptionSEI.m_sopDescVclNaluType[i] = getNalUnitType(SOPcurrPOC, m_iLastIDR, isField);
1507          SOPDescriptionSEI.m_sopDescTemporalId[i] = m_pcCfg->getGOPEntry(j).m_temporalId;
1508          SOPDescriptionSEI.m_sopDescStRpsIdx[i] = m_pcEncTop->getReferencePictureSetIdxForSOP(pcSlice, SOPcurrPOC, j);
1509          SOPDescriptionSEI.m_sopDescPocDelta[i] = deltaPOC;
1510
1511          prevEntryId = j;
1512          i++;
1513        }
1514      }
1515
1516      SOPDescriptionSEI.m_numPicsInSopMinus1 = i - 1;
1517
1518      m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, pcSlice->getSPS());
1519      writeRBSPTrailingBits(nalu.m_Bitstream);
1520      accessUnit.push_back(new NALUnitEBSP(nalu));
1521
1522      writeSOP = false;
1523    }
1524
1525    if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
1526        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
1527        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
1528       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
1529    {
1530      if( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() )
1531      {
1532        UInt numDU = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumDU();
1533        pictureTimingSEI.m_numDecodingUnitsMinus1     = ( numDU - 1 );
1534        pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = false;
1535
1536        if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL )
1537        {
1538          pictureTimingSEI.m_numNalusInDuMinus1       = new UInt[ numDU ];
1539        }
1540        if( pictureTimingSEI.m_duCpbRemovalDelayMinus1  == NULL )
1541        {
1542          pictureTimingSEI.m_duCpbRemovalDelayMinus1  = new UInt[ numDU ];
1543        }
1544        if( accumBitsDU == NULL )
1545        {
1546          accumBitsDU                                  = new UInt[ numDU ];
1547        }
1548        if( accumNalsDU == NULL )
1549        {
1550          accumNalsDU                                  = new UInt[ numDU ];
1551        }
1552      }
1553      pictureTimingSEI.m_auCpbRemovalDelay = std::min<Int>(std::max<Int>(1, m_totalCoded - m_lastBPSEI), static_cast<Int>(pow(2, static_cast<double>(pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getCpbRemovalDelayLengthMinus1()+1)))); // Syntax element signalled as minus, hence the .
1554      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pcSlice->getPOC() - m_totalCoded;
1555#if EFFICIENT_FIELD_IRAP
1556      if(IRAPGOPid > 0 && IRAPGOPid < m_iGopSize)
1557      {
1558        // if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation
1559        pictureTimingSEI.m_picDpbOutputDelay ++;
1560      }
1561#endif
1562      Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2;
1563      pictureTimingSEI.m_picDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
1564      if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
1565      {
1566        picSptDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
1567      }
1568    }
1569
1570    if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) &&
1571        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
1572        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
1573       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
1574    {
1575      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1576      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1577      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1578
1579      SEIBufferingPeriod sei_buffering_period;
1580     
1581      UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
1582      sei_buffering_period.m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
1583      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
1584      sei_buffering_period.m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
1585      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
1586
1587      Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
1588
1589      UInt uiTmp = (UInt)( dTmp * 90000.0 ); 
1590      uiInitialCpbRemovalDelay -= uiTmp;
1591      uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
1592      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
1593      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
1594      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
1595      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
1596
1597      sei_buffering_period.m_rapCpbParamsPresentFlag              = 0;
1598      //for the concatenation, it can be set to one during splicing.
1599      sei_buffering_period.m_concatenationFlag = 0;
1600      //since the temporal layer HRD is not ready, we assumed it is fixed
1601      sei_buffering_period.m_auCpbRemovalDelayDelta = 1;
1602      sei_buffering_period.m_cpbDelayOffset = 0;
1603      sei_buffering_period.m_dpbDelayOffset = 0;
1604
1605      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, pcSlice->getSPS());
1606      writeRBSPTrailingBits(nalu.m_Bitstream);
1607      {
1608      UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
1609      UInt offsetPosition = m_activeParameterSetSEIPresentInAU;   // Insert BP SEI after APS SEI
1610      AccessUnit::iterator it;
1611      for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
1612      {
1613        it++;
1614      }
1615      accessUnit.insert(it, new NALUnitEBSP(nalu));
1616      m_bufferingPeriodSEIPresentInAU = true;
1617      }
1618
1619      if (m_pcCfg->getScalableNestingSEIEnabled())
1620      {
1621        OutputNALUnit naluTmp(NAL_UNIT_PREFIX_SEI);
1622        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1623        m_pcEntropyCoder->setBitstream(&naluTmp.m_Bitstream);
1624        scalableNestingSEI.m_nestedSEIs.clear();
1625        scalableNestingSEI.m_nestedSEIs.push_back(&sei_buffering_period);
1626        m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
1627        writeRBSPTrailingBits(naluTmp.m_Bitstream);
1628        UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
1629        UInt offsetPosition = m_activeParameterSetSEIPresentInAU + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU;   // Insert BP SEI after non-nested APS, BP and PT SEIs
1630        AccessUnit::iterator it;
1631        for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
1632        {
1633          it++;
1634        }
1635        accessUnit.insert(it, new NALUnitEBSP(naluTmp));
1636        m_nestedBufferingPeriodSEIPresentInAU = true;
1637      }
1638
1639      m_lastBPSEI = m_totalCoded;
1640      m_cpbRemovalDelay = 0;
1641    }
1642    m_cpbRemovalDelay ++;
1643    if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) )
1644    {
1645      if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !pcSlice->getRapPicFlag() )
1646      {
1647        // Gradual decoding refresh SEI
1648        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1649        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1650        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1651
1652        SEIGradualDecodingRefreshInfo seiGradualDecodingRefreshInfo;
1653        seiGradualDecodingRefreshInfo.m_gdrForegroundFlag = true; // Indicating all "foreground"
1654
1655        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, pcSlice->getSPS() );
1656        writeRBSPTrailingBits(nalu.m_Bitstream);
1657        accessUnit.push_back(new NALUnitEBSP(nalu));
1658      }
1659    // Recovery point SEI
1660      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1661      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1662      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1663
1664      SEIRecoveryPoint sei_recovery_point;
1665      sei_recovery_point.m_recoveryPocCnt    = 0;
1666      sei_recovery_point.m_exactMatchingFlag = ( pcSlice->getPOC() == 0 ) ? (true) : (false);
1667      sei_recovery_point.m_brokenLinkFlag    = false;
1668#if ALLOW_RECOVERY_POINT_AS_RAP
1669      if(m_pcCfg->getDecodingRefreshType() == 3)
1670      {
1671        m_iLastRecoveryPicPOC = pocCurr;
1672      }
1673#endif
1674
1675      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, pcSlice->getSPS() );
1676      writeRBSPTrailingBits(nalu.m_Bitstream);
1677      accessUnit.push_back(new NALUnitEBSP(nalu));
1678    }
1679
1680    /* use the main bitstream buffer for storing the marshalled picture */
1681    m_pcEntropyCoder->setBitstream(NULL);
1682
1683    startCUAddrSliceIdx = 0;
1684    startCUAddrSlice    = 0; 
1685
1686    startCUAddrSliceSegmentIdx = 0;
1687    startCUAddrSliceSegment    = 0; 
1688    nextCUAddr                 = 0;
1689    pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
1690
1691    Int processingState = (pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
1692    Bool skippedSlice=false;
1693    while (nextCUAddr < uiRealEndAddress) // Iterate over all slices
1694    {
1695      switch(processingState)
1696      {
1697      case ENCODE_SLICE:
1698        {
1699          pcSlice->setNextSlice       ( false );
1700          pcSlice->setNextSliceSegment( false );
1701          if (nextCUAddr == m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx])
1702          {
1703            pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
1704            if(startCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE)
1705            {
1706              pcSlice->checkColRefIdx(startCUAddrSliceIdx, pcPic);
1707            }
1708            pcPic->setCurrSliceIdx(startCUAddrSliceIdx);
1709            m_pcSliceEncoder->setSliceIdx(startCUAddrSliceIdx);
1710            assert(startCUAddrSliceIdx == pcSlice->getSliceIdx());
1711            // Reconstruction slice
1712            pcSlice->setSliceCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
1713            pcSlice->setSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx+1 ] );
1714            // Dependent slice
1715            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
1716            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
1717
1718            pcSlice->setNextSlice       ( true );
1719
1720            startCUAddrSliceIdx++;
1721            startCUAddrSliceSegmentIdx++;
1722          } 
1723          else if (nextCUAddr == m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx])
1724          {
1725            // Dependent slice
1726            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
1727            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
1728
1729            pcSlice->setNextSliceSegment( true );
1730
1731            startCUAddrSliceSegmentIdx++;
1732          }
1733
1734          pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
1735          pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
1736          UInt uiDummyStartCUAddr;
1737          UInt uiDummyBoundingCUAddr;
1738          m_pcSliceEncoder->xDetermineStartAndBoundingCUAddr(uiDummyStartCUAddr,uiDummyBoundingCUAddr,pcPic,true);
1739
1740          uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) % pcPic->getNumPartInCU();
1741          uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) / pcPic->getNumPartInCU();
1742          uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1743          uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1744          uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1745          uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1746          while(uiPosX>=uiWidth||uiPosY>=uiHeight)
1747          {
1748            uiInternalAddress--;
1749            uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1750            uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1751          }
1752          uiInternalAddress++;
1753          if(uiInternalAddress==pcPic->getNumPartInCU())
1754          {
1755            uiInternalAddress = 0;
1756            uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1757          }
1758          UInt endAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
1759          if(endAddress<=pcSlice->getSliceSegmentCurStartCUAddr()) 
1760          {
1761            UInt boundingAddrSlice, boundingAddrSliceSegment;
1762            boundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
1763            boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
1764            nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
1765            if(pcSlice->isNextSlice())
1766            {
1767              skippedSlice=true;
1768            }
1769            continue;
1770          }
1771          if(skippedSlice) 
1772          {
1773            pcSlice->setNextSlice       ( true );
1774            pcSlice->setNextSliceSegment( false );
1775          }
1776          skippedSlice=false;
1777          pcSlice->allocSubstreamSizes( iNumSubstreams );
1778          for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
1779          {
1780            pcSubstreamsOut[ui].clear();
1781          }
1782
1783          m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1784          m_pcEntropyCoder->resetEntropy      ();
1785          /* start slice NALunit */
1786#if H_MV
1787          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), getLayerId() );
1788#else
1789          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
1790#endif
1791          Bool sliceSegment = (!pcSlice->isNextSlice());
1792          if (!sliceSegment)
1793          {
1794            uiOneBitstreamPerSliceLength = 0; // start of a new slice
1795          }
1796          m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1797
1798#if SETTING_NO_OUT_PIC_PRIOR
1799          pcSlice->setNoRaslOutputFlag(false);
1800          if (pcSlice->isIRAP())
1801          {
1802            if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
1803            {
1804              pcSlice->setNoRaslOutputFlag(true);
1805            }
1806            //the inference for NoOutputPriorPicsFlag
1807            // KJS: This cannot happen at the encoder
1808            if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag())
1809            {
1810              if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
1811              {
1812                pcSlice->setNoOutputPriorPicsFlag(true);
1813              }
1814            }
1815          }
1816#endif
1817
1818          tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
1819          m_pcEntropyCoder->encodeSliceHeader(pcSlice);
1820          actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
1821
1822          // is it needed?
1823          {
1824            if (!sliceSegment)
1825            {
1826              pcBitstreamRedirect->writeAlignOne();
1827            }
1828            else
1829            {
1830              // We've not completed our slice header info yet, do the alignment later.
1831            }
1832            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1833            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1834            m_pcEntropyCoder->resetEntropy    ();
1835            for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
1836            {
1837              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
1838              m_pcEntropyCoder->resetEntropy    ();
1839            }
1840          }
1841
1842          if(pcSlice->isNextSlice())
1843          {
1844            // set entropy coder for writing
1845            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1846            {
1847              for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
1848              {
1849                m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
1850                m_pcEntropyCoder->resetEntropy    ();
1851              }
1852              pcSbacCoders[0].load(m_pcSbacCoder);
1853              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[0], pcSlice );  //ALF is written in substream #0 with CABAC coder #0 (see ALF param encoding below)
1854            }
1855            m_pcEntropyCoder->resetEntropy    ();
1856            // File writing
1857            if (!sliceSegment)
1858            {
1859              m_pcEntropyCoder->setBitstream(pcBitstreamRedirect);
1860            }
1861            else
1862            {
1863              m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1864            }
1865            // for now, override the TILES_DECODER setting in order to write substreams.
1866            m_pcEntropyCoder->setBitstream    ( &pcSubstreamsOut[0] );
1867
1868          }
1869          pcSlice->setFinalized(true);
1870
1871          m_pcSbacCoder->load( &pcSbacCoders[0] );
1872
1873          pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength );
1874            pcSlice->setTileLocationCount ( 0 );
1875          m_pcSliceEncoder->encodeSlice(pcPic, pcSubstreamsOut);
1876
1877          {
1878            // Construct the final bitstream by flushing and concatenating substreams.
1879            // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
1880            UInt* puiSubstreamSizes = pcSlice->getSubstreamSizes();
1881            UInt uiTotalCodedSize = 0; // for padding calcs.
1882            UInt uiNumSubstreamsPerTile = iNumSubstreams;
1883            if (iNumSubstreams > 1)
1884            {
1885              uiNumSubstreamsPerTile /= pcPic->getPicSym()->getNumTiles();
1886            }
1887            for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
1888            {
1889              // Flush all substreams -- this includes empty ones.
1890              // Terminating bit and flush.
1891              m_pcEntropyCoder->setEntropyCoder   ( &pcSbacCoders[ui], pcSlice );
1892              m_pcEntropyCoder->setBitstream      (  &pcSubstreamsOut[ui] );
1893              m_pcEntropyCoder->encodeTerminatingBit( 1 );
1894              m_pcEntropyCoder->encodeSliceFinish();
1895
1896              pcSubstreamsOut[ui].writeByteAlignment();   // Byte-alignment in slice_data() at end of sub-stream
1897              // Byte alignment is necessary between tiles when tiles are independent.
1898              uiTotalCodedSize += pcSubstreamsOut[ui].getNumberOfWrittenBits();
1899
1900              Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)&& ((ui+1)%uiNumSubstreamsPerTile == 0);
1901              if (bNextSubstreamInNewTile)
1902              {
1903                pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
1904              }
1905              if (ui+1 < pcSlice->getPPS()->getNumSubstreams())
1906              {
1907                puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits() + (pcSubstreamsOut[ui].countStartCodeEmulations()<<3);
1908              }
1909            }
1910
1911            // Complete the slice header info.
1912            m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1913            m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1914            m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
1915
1916            // Substreams...
1917            TComOutputBitstream *pcOut = pcBitstreamRedirect;
1918          Int offs = 0;
1919          Int nss = pcSlice->getPPS()->getNumSubstreams();
1920          if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
1921          {
1922            // 1st line present for WPP.
1923            offs = pcSlice->getSliceSegmentCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
1924            nss  = pcSlice->getNumEntryPointOffsets()+1;
1925          }
1926          for ( UInt ui = 0 ; ui < nss; ui++ )
1927          {
1928            pcOut->addSubstream(&pcSubstreamsOut[ui+offs]);
1929            }
1930          }
1931
1932          UInt boundingAddrSlice, boundingAddrSliceSegment;
1933          boundingAddrSlice        = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
1934          boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
1935          nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
1936          // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
1937          // 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.
1938          Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
1939          xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
1940          accessUnit.push_back(new NALUnitEBSP(nalu));
1941          actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1942          bNALUAlignedWrittenToList = true; 
1943          uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment
1944
1945          if (!bNALUAlignedWrittenToList)
1946          {
1947            {
1948              nalu.m_Bitstream.writeAlignZero();
1949            }
1950            accessUnit.push_back(new NALUnitEBSP(nalu));
1951            uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits() + 24; // length of bitstream after byte-alignment + 3 byte startcode 0x000001
1952          }
1953
1954          if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
1955              ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
1956              ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
1957             || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
1958              ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
1959          {
1960              UInt numNalus = 0;
1961            UInt numRBSPBytes = 0;
1962            for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
1963            {
1964              UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
1965              if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
1966              {
1967                numRBSPBytes += numRBSPBytes_nal;
1968                numNalus ++;
1969              }
1970            }
1971            accumBitsDU[ pcSlice->getSliceIdx() ] = ( numRBSPBytes << 3 );
1972            accumNalsDU[ pcSlice->getSliceIdx() ] = numNalus;   // SEI not counted for bit count; hence shouldn't be counted for # of NALUs - only for consistency
1973          }
1974          processingState = ENCODE_SLICE;
1975          }
1976          break;
1977        case EXECUTE_INLOOPFILTER:
1978          {
1979            // set entropy coder for RD
1980            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1981            if ( pcSlice->getSPS()->getUseSAO() )
1982            {
1983              m_pcEntropyCoder->resetEntropy();
1984              m_pcEntropyCoder->setBitstream( m_pcBitCounter );
1985            Bool sliceEnabled[NUM_SAO_COMPONENTS];
1986            m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);
1987            m_pcSAO->SAOProcess(pcPic
1988              , sliceEnabled
1989              , pcPic->getSlice(0)->getLambdas()
1990#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
1991              , m_pcCfg->getSaoLcuBoundary()
1992#endif
1993              );
1994              m_pcSAO->PCMLFDisableProcess(pcPic);
1995
1996#if H_3D_DISABLE_CHROMA
1997            if (pcSlice->getIsDepth())
1998            {
1999              sliceEnabled[SAO_Cb] = false; 
2000              sliceEnabled[SAO_Cr] = false; 
2001            }
2002#endif
2003            //assign SAO slice header
2004            for(Int s=0; s< uiNumSlices; s++)
2005            {
2006              pcPic->getSlice(s)->setSaoEnabledFlag(sliceEnabled[SAO_Y]);
2007              assert(sliceEnabled[SAO_Cb] == sliceEnabled[SAO_Cr]);
2008              pcPic->getSlice(s)->setSaoEnabledFlagChroma(sliceEnabled[SAO_Cb]);
2009              }
2010            }
2011          processingState = ENCODE_SLICE;
2012          }
2013          break;
2014        default:
2015          {
2016            printf("Not a supported encoding state\n");
2017            assert(0);
2018            exit(-1);
2019          }
2020        }
2021      } // end iteration over slices
2022#if H_3D
2023      pcPic->compressMotion(2); 
2024#endif
2025#if !H_3D
2026      pcPic->compressMotion(); 
2027#endif
2028#if H_MV
2029      m_pocLastCoded = pcPic->getPOC();
2030#endif
2031
2032      //-- For time output for each slice
2033      Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
2034
2035      const Char* digestStr = NULL;
2036      if (m_pcCfg->getDecodedPictureHashSEIEnabled())
2037      {
2038        /* calculate MD5sum for entire reconstructed picture */
2039        SEIDecodedPictureHash sei_recon_picture_digest;
2040        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
2041        {
2042          sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5;
2043          calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2044          digestStr = digestToString(sei_recon_picture_digest.digest, 16);
2045        }
2046        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
2047        {
2048          sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC;
2049          calcCRC(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2050          digestStr = digestToString(sei_recon_picture_digest.digest, 2);
2051        }
2052        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
2053        {
2054          sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM;
2055          calcChecksum(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2056          digestStr = digestToString(sei_recon_picture_digest.digest, 4);
2057        }
2058#if H_MV
2059        OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer(), getLayerId() );
2060#else
2061        OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer());
2062#endif
2063
2064        /* write the SEI messages */
2065        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2066        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, pcSlice->getSPS());
2067        writeRBSPTrailingBits(nalu.m_Bitstream);
2068
2069        accessUnit.insert(accessUnit.end(), new NALUnitEBSP(nalu));
2070      }
2071      if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
2072      {
2073        SEITemporalLevel0Index sei_temporal_level0_index;
2074        if (pcSlice->getRapPicFlag())
2075        {
2076          m_tl0Idx = 0;
2077          m_rapIdx = (m_rapIdx + 1) & 0xFF;
2078        }
2079        else
2080        {
2081          m_tl0Idx = (m_tl0Idx + (pcSlice->getTLayer() ? 0 : 1)) & 0xFF;
2082        }
2083        sei_temporal_level0_index.tl0Idx = m_tl0Idx;
2084        sei_temporal_level0_index.rapIdx = m_rapIdx;
2085
2086        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); 
2087
2088        /* write the SEI messages */
2089        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2090        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, pcSlice->getSPS());
2091        writeRBSPTrailingBits(nalu.m_Bitstream);
2092
2093        /* insert the SEI message NALUnit before any Slice NALUnits */
2094        AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
2095        accessUnit.insert(it, new NALUnitEBSP(nalu));
2096      }
2097
2098      xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime );
2099
2100    //In case of field coding, compute the interlaced PSNR for both fields
2101    if (isField && ((!pcPic->isTopField() && isTff) || (pcPic->isTopField() && !isTff)) && (pcPic->getPOC()%m_iGopSize != 1))
2102    {
2103      //get complementary top field
2104      TComPic* pcPicTop;
2105      TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
2106      while ((*iterPic)->getPOC() != pcPic->getPOC()-1)
2107      {
2108        iterPic ++;
2109      }
2110      pcPicTop = *(iterPic);
2111      xCalculateInterlacedAddPSNR(pcPicTop, pcPic, pcPicTop->getPicYuvRec(), pcPic->getPicYuvRec(), accessUnit, dEncTime );
2112    }
2113    else if (isField && pcPic->getPOC()!= 0 && (pcPic->getPOC()%m_iGopSize == 0))
2114    {
2115      //get complementary bottom field
2116      TComPic* pcPicBottom;
2117      TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
2118      while ((*iterPic)->getPOC() != pcPic->getPOC()+1)
2119      {
2120        iterPic ++;
2121      }
2122      pcPicBottom = *(iterPic);
2123      xCalculateInterlacedAddPSNR(pcPic, pcPicBottom, pcPic->getPicYuvRec(), pcPicBottom->getPicYuvRec(), accessUnit, dEncTime );
2124    }
2125   
2126      if (digestStr)
2127      {
2128        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
2129        {
2130          printf(" [MD5:%s]", digestStr);
2131        }
2132        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
2133        {
2134          printf(" [CRC:%s]", digestStr);
2135        }
2136        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
2137        {
2138          printf(" [Checksum:%s]", digestStr);
2139        }
2140      }
2141      if ( m_pcCfg->getUseRateCtrl() )
2142      {
2143        Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
2144        Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
2145        if ( avgLambda < 0.0 )
2146        {
2147          avgLambda = lambda;
2148        }
2149        m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
2150        m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
2151
2152        m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
2153        if ( pcSlice->getSliceType() != I_SLICE )
2154        {
2155          m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
2156        }
2157        else    // for intra picture, the estimated bits are used to update the current status in the GOP
2158        {
2159          m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
2160        }
2161      }
2162
2163      if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2164          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2165          ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
2166         || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
2167      {
2168        TComVUI *vui = pcSlice->getSPS()->getVuiParameters();
2169        TComHRD *hrd = vui->getHrdParameters();
2170
2171        if( hrd->getSubPicCpbParamsPresentFlag() )
2172        {
2173          Int i;
2174          UInt64 ui64Tmp;
2175          UInt uiPrev = 0;
2176          UInt numDU = ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 );
2177          UInt *pCRD = &pictureTimingSEI.m_duCpbRemovalDelayMinus1[0];
2178          UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
2179
2180          for( i = 0; i < numDU; i ++ )
2181          {
2182            pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] - 1 ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
2183          }
2184
2185          if( numDU == 1 )
2186          {
2187            pCRD[ 0 ] = 0; /* don't care */
2188          }
2189          else
2190          {
2191            pCRD[ numDU - 1 ] = 0;/* by definition */
2192            UInt tmp = 0;
2193            UInt accum = 0;
2194
2195            for( i = ( numDU - 2 ); i >= 0; i -- )
2196            {
2197              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
2198              if( (UInt)ui64Tmp > maxDiff )
2199              {
2200                tmp ++;
2201              }
2202            }
2203            uiPrev = 0;
2204
2205            UInt flag = 0;
2206            for( i = ( numDU - 2 ); i >= 0; i -- )
2207            {
2208              flag = 0;
2209              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
2210
2211              if( (UInt)ui64Tmp > maxDiff )
2212              {
2213                if(uiPrev >= maxDiff - tmp)
2214                {
2215                  ui64Tmp = uiPrev + 1;
2216                  flag = 1;
2217                }
2218                else                            ui64Tmp = maxDiff - tmp + 1;
2219              }
2220              pCRD[ i ] = (UInt)ui64Tmp - uiPrev - 1;
2221              if( (Int)pCRD[ i ] < 0 )
2222              {
2223                pCRD[ i ] = 0;
2224              }
2225              else if (tmp > 0 && flag == 1) 
2226              {
2227                tmp --;
2228              }
2229              accum += pCRD[ i ] + 1;
2230              uiPrev = accum;
2231            }
2232          }
2233        }
2234        if( m_pcCfg->getPictureTimingSEIEnabled() )
2235        {
2236          {
2237            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
2238          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2239          pictureTimingSEI.m_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0;
2240          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, pcSlice->getSPS());
2241          writeRBSPTrailingBits(nalu.m_Bitstream);
2242          UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2243          UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2244                                    + m_bufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
2245          AccessUnit::iterator it;
2246          for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2247          {
2248            it++;
2249          }
2250          accessUnit.insert(it, new NALUnitEBSP(nalu));
2251          m_pictureTimingSEIPresentInAU = true;
2252        }
2253          if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI
2254          {
2255            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
2256            m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2257            scalableNestingSEI.m_nestedSEIs.clear();
2258            scalableNestingSEI.m_nestedSEIs.push_back(&pictureTimingSEI);
2259            m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
2260            writeRBSPTrailingBits(nalu.m_Bitstream);
2261            UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2262            UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2263              + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU + m_nestedBufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
2264            AccessUnit::iterator it;
2265            for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2266            {
2267              it++;
2268            }
2269            accessUnit.insert(it, new NALUnitEBSP(nalu));
2270            m_nestedPictureTimingSEIPresentInAU = true;
2271          }
2272        }
2273        if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
2274        {             
2275          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2276          for( Int i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
2277          {
2278            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
2279
2280            SEIDecodingUnitInfo tempSEI;
2281            tempSEI.m_decodingUnitIdx = i;
2282            tempSEI.m_duSptCpbRemovalDelay = pictureTimingSEI.m_duCpbRemovalDelayMinus1[i] + 1;
2283            tempSEI.m_dpbOutputDuDelayPresentFlag = false;
2284            tempSEI.m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
2285
2286            AccessUnit::iterator it;
2287            // Insert the first one in the right location, before the first slice
2288            if(i == 0)
2289            {
2290              // Insert before the first slice.
2291              m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
2292              writeRBSPTrailingBits(nalu.m_Bitstream);
2293
2294              UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2295              UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2296                                    + m_bufferingPeriodSEIPresentInAU
2297                                    + m_pictureTimingSEIPresentInAU;  // Insert DU info SEI after APS, BP and PT SEI
2298              for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2299              {
2300                it++;
2301              }
2302              accessUnit.insert(it, new NALUnitEBSP(nalu));
2303            }
2304            else
2305            {
2306              Int ctr;
2307              // For the second decoding unit onwards we know how many NALUs are present
2308              for (ctr = 0, it = accessUnit.begin(); it != accessUnit.end(); it++)
2309              {           
2310                if(ctr == accumNalsDU[ i - 1 ])
2311                {
2312                  // Insert before the first slice.
2313                  m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
2314                  writeRBSPTrailingBits(nalu.m_Bitstream);
2315
2316                  accessUnit.insert(it, new NALUnitEBSP(nalu));
2317                  break;
2318                }
2319                if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
2320                {
2321                  ctr++;
2322                }
2323              }
2324            }           
2325          }
2326        }
2327      }
2328      xResetNonNestedSEIPresentFlags();
2329      xResetNestedSEIPresentFlags();
2330      pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
2331
2332      pcPic->setReconMark   ( true );
2333#if H_MV
2334      TComSlice::markIvRefPicsAsShortTerm( m_refPicSetInterLayer0, m_refPicSetInterLayer1 ); 
2335      std::vector<Int> temp; 
2336      TComSlice::markCurrPic( pcPic ); 
2337#endif
2338      m_bFirst = false;
2339      m_iNumPicCoded++;
2340      m_totalCoded ++;
2341      /* logging: insert a newline at end of picture period */
2342      printf("\n");
2343      fflush(stdout);
2344
2345      delete[] pcSubstreamsOut;
2346
2347#if EFFICIENT_FIELD_IRAP
2348    if(IRAPtoReorder)
2349    {
2350      if(swapIRAPForward)
2351      {
2352        if(iGOPid == IRAPGOPid)
2353        {
2354          iGOPid = IRAPGOPid +1;
2355          IRAPtoReorder = false;
2356        }
2357        else if(iGOPid == IRAPGOPid +1)
2358        {
2359          iGOPid --;
2360        }
2361      }
2362      else
2363      {
2364        if(iGOPid == IRAPGOPid)
2365        {
2366          iGOPid = IRAPGOPid -1;
2367        }
2368        else if(iGOPid == IRAPGOPid -1)
2369        {
2370          iGOPid = IRAPGOPid;
2371          IRAPtoReorder = false;
2372        }
2373      }
2374    }
2375#endif
2376  }
2377  delete pcBitstreamRedirect;
2378
2379  if( accumBitsDU != NULL) delete accumBitsDU;
2380  if( accumNalsDU != NULL) delete accumNalsDU;
2381
2382#if !H_MV
2383  assert ( (m_iNumPicCoded == iNumPicRcvd) || (isField && iPOCLast == 1) );
2384#endif
2385}
2386
2387#if !H_MV
2388Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, bool isField)
2389{
2390  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
2391 
2392   
2393  //--CFG_KDY
2394  if(isField)
2395  {
2396    m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() * 2);
2397    m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() * 2);
2398    m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() * 2);
2399    m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() * 2);
2400  }
2401  else
2402  {
2403  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() );
2404  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() );
2405  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() );
2406  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() );
2407  }
2408 
2409  //-- all
2410  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
2411  m_gcAnalyzeAll.printOut('a');
2412 
2413  printf( "\n\nI Slices--------------------------------------------------------\n" );
2414  m_gcAnalyzeI.printOut('i');
2415 
2416  printf( "\n\nP Slices--------------------------------------------------------\n" );
2417  m_gcAnalyzeP.printOut('p');
2418 
2419  printf( "\n\nB Slices--------------------------------------------------------\n" );
2420  m_gcAnalyzeB.printOut('b');
2421 
2422#if _SUMMARY_OUT_
2423  m_gcAnalyzeAll.printSummaryOut();
2424#endif
2425#if _SUMMARY_PIC_
2426  m_gcAnalyzeI.printSummary('I');
2427  m_gcAnalyzeP.printSummary('P');
2428  m_gcAnalyzeB.printSummary('B');
2429#endif
2430
2431  if(isField)
2432  {
2433    //-- interlaced summary
2434    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
2435    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
2436    m_gcAnalyzeAll_in.printOutInterlaced('a',  m_gcAnalyzeAll.getBits());
2437   
2438#if _SUMMARY_OUT_
2439    m_gcAnalyzeAll_in.printSummaryOutInterlaced();
2440#endif
2441  }
2442
2443  printf("\nRVM: %.3lf\n" , xCalculateRVM());
2444}
2445#endif
2446#if H_3D_VSO
2447Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, Dist64& ruiDist, UInt64& ruiBits )
2448#else
2449Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
2450#endif
2451{
2452  TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
2453  Bool bCalcDist = false;
2454  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
2455  m_pcLoopFilter->loopFilterPic( pcPic );
2456 
2457  m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
2458  m_pcEntropyCoder->resetEntropy    ();
2459  m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
2460  m_pcEntropyCoder->resetEntropy    ();
2461  ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
2462 
2463  if (!bCalcDist)
2464    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
2465}
2466
2467// ====================================================================================================================
2468// Protected member functions
2469// ====================================================================================================================
2470
2471
2472Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, bool isField )
2473{
2474  assert( iNumPicRcvd > 0 );
2475  //  Exception for the first frames
2476  if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField  && (iPOCLast == 0))  )
2477  {
2478    m_iGopSize    = 1;
2479  }
2480  else
2481  {
2482    m_iGopSize    = m_pcCfg->getGOPSize();
2483  }
2484  assert (m_iGopSize > 0);
2485 
2486  return;
2487}
2488
2489Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
2490                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
2491                         Int                       iNumPicRcvd,
2492                         Int                       iTimeOffset,
2493                         TComPic*&                 rpcPic,
2494                         TComPicYuv*&              rpcPicYuvRecOut,
2495                         Int                       pocCurr,
2496                         bool                      isField)
2497{
2498  Int i;
2499  //  Rec. output
2500  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
2501 
2502  if (isField)
2503  {
2504    for ( i = 0; i < ( (pocCurr == 0 ) || (pocCurr == 1 ) ? (iNumPicRcvd - iTimeOffset + 1) : (iNumPicRcvd - iTimeOffset + 2) ); i++ )
2505    {
2506      iterPicYuvRec--;
2507    }
2508  }
2509  else
2510  {
2511    for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
2512  {
2513    iterPicYuvRec--;
2514  }
2515 
2516  }
2517 
2518  if (isField)
2519  {
2520    if(pocCurr == 1)
2521    {
2522      iterPicYuvRec++;
2523    }
2524  }
2525  rpcPicYuvRecOut = *(iterPicYuvRec);
2526 
2527  //  Current pic.
2528  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
2529  while (iterPic != rcListPic.end())
2530  {
2531    rpcPic = *(iterPic);
2532    rpcPic->setCurrSliceIdx(0);
2533    if (rpcPic->getPOC() == pocCurr)
2534    {
2535      break;
2536    }
2537    iterPic++;
2538  }
2539
2540#if !H_MV
2541  assert( rpcPic != NULL );
2542#endif
2543  assert (rpcPic->getPOC() == pocCurr);
2544 
2545  return;
2546}
2547
2548#if H_3D_VSO
2549Dist64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
2550#else
2551UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
2552#endif
2553{
2554  Int     x, y;
2555  Pel*  pSrc0   = pcPic0 ->getLumaAddr();
2556  Pel*  pSrc1   = pcPic1 ->getLumaAddr();
2557  UInt  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthY-8);
2558  Int   iTemp;
2559 
2560  Int   iStride = pcPic0->getStride();
2561  Int   iWidth  = pcPic0->getWidth();
2562  Int   iHeight = pcPic0->getHeight();
2563 
2564#if H_3D_VSO
2565  Dist64  uiTotalDiff = 0;
2566#else
2567  UInt64  uiTotalDiff = 0;
2568#endif
2569 
2570  for( y = 0; y < iHeight; y++ )
2571  {
2572    for( x = 0; x < iWidth; x++ )
2573    {
2574      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2575    }
2576    pSrc0 += iStride;
2577    pSrc1 += iStride;
2578  }
2579 
2580  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthC-8);
2581  iHeight >>= 1;
2582  iWidth  >>= 1;
2583  iStride >>= 1;
2584 
2585  pSrc0  = pcPic0->getCbAddr();
2586  pSrc1  = pcPic1->getCbAddr();
2587 
2588  for( y = 0; y < iHeight; y++ )
2589  {
2590    for( x = 0; x < iWidth; x++ )
2591    {
2592      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2593    }
2594    pSrc0 += iStride;
2595    pSrc1 += iStride;
2596  }
2597 
2598  pSrc0  = pcPic0->getCrAddr();
2599  pSrc1  = pcPic1->getCrAddr();
2600 
2601  for( y = 0; y < iHeight; y++ )
2602  {
2603    for( x = 0; x < iWidth; x++ )
2604    {
2605      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2606    }
2607    pSrc0 += iStride;
2608    pSrc1 += iStride;
2609  }
2610 
2611  return uiTotalDiff;
2612}
2613
2614#if VERBOSE_RATE
2615static const Char* nalUnitTypeToString(NalUnitType type)
2616{
2617  switch (type)
2618  {
2619    case NAL_UNIT_CODED_SLICE_TRAIL_R: return "TRAIL_R";
2620    case NAL_UNIT_CODED_SLICE_TRAIL_N: return "TRAIL_N";
2621    case NAL_UNIT_CODED_SLICE_TSA_R:      return "TSA_R";
2622    case NAL_UNIT_CODED_SLICE_TSA_N: return "TSA_N";
2623    case NAL_UNIT_CODED_SLICE_STSA_R: return "STSA_R";
2624    case NAL_UNIT_CODED_SLICE_STSA_N: return "STSA_N";
2625    case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
2626    case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
2627    case NAL_UNIT_CODED_SLICE_BLA_N_LP: return "BLA_N_LP";
2628    case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
2629    case NAL_UNIT_CODED_SLICE_IDR_N_LP: return "IDR_N_LP";
2630    case NAL_UNIT_CODED_SLICE_CRA: return "CRA";
2631    case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
2632    case NAL_UNIT_CODED_SLICE_RADL_N:     return "RADL_N";
2633    case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
2634    case NAL_UNIT_CODED_SLICE_RASL_N:     return "RASL_N";
2635    case NAL_UNIT_VPS: return "VPS";
2636    case NAL_UNIT_SPS: return "SPS";
2637    case NAL_UNIT_PPS: return "PPS";
2638    case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD";
2639    case NAL_UNIT_EOS: return "EOS";
2640    case NAL_UNIT_EOB: return "EOB";
2641    case NAL_UNIT_FILLER_DATA: return "FILLER";
2642    case NAL_UNIT_PREFIX_SEI:             return "SEI";
2643    case NAL_UNIT_SUFFIX_SEI:             return "SEI";
2644    default: return "UNK";
2645  }
2646}
2647#endif
2648
2649Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime )
2650{
2651  Int     x, y;
2652  UInt64 uiSSDY  = 0;
2653  UInt64 uiSSDU  = 0;
2654  UInt64 uiSSDV  = 0;
2655 
2656  Double  dYPSNR  = 0.0;
2657  Double  dUPSNR  = 0.0;
2658  Double  dVPSNR  = 0.0;
2659 
2660  //===== calculate PSNR =====
2661  Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
2662  Pel*  pRec    = pcPicD->getLumaAddr();
2663  Int   iStride = pcPicD->getStride();
2664 
2665  Int   iWidth;
2666  Int   iHeight;
2667 
2668  iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
2669  iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
2670 
2671  Int   iSize   = iWidth*iHeight;
2672 
2673  for( y = 0; y < iHeight; y++ )
2674  {
2675    for( x = 0; x < iWidth; x++ )
2676    {
2677      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2678      uiSSDY   += iDiff * iDiff;
2679    }
2680    pOrg += iStride;
2681    pRec += iStride;
2682  }
2683 
2684#if H_3D_VSO
2685#if H_3D_VSO_SYNTH_DIST_OUT
2686  if ( m_pcRdCost->getUseRenModel() )
2687  {
2688    unsigned int maxval = 255 * (1<<(g_uiBitDepth + g_uiBitIncrement -8));
2689    Double fRefValueY = (double) maxval * maxval * iSize;
2690    Double fRefValueC = fRefValueY / 4.0;
2691    TRenModel*  pcRenModel = m_pcEncTop->getEncTop()->getRenModel();
2692    Int64 iDistVSOY, iDistVSOU, iDistVSOV;
2693    pcRenModel->getTotalSSE( iDistVSOY, iDistVSOU, iDistVSOV );
2694    dYPSNR = ( iDistVSOY ? 10.0 * log10( fRefValueY / (Double) iDistVSOY ) : 99.99 );
2695    dUPSNR = ( iDistVSOU ? 10.0 * log10( fRefValueC / (Double) iDistVSOU ) : 99.99 );
2696    dVPSNR = ( iDistVSOV ? 10.0 * log10( fRefValueC / (Double) iDistVSOV ) : 99.99 );
2697  }
2698  else
2699  {
2700#endif
2701#endif
2702    iHeight >>= 1;
2703  iWidth  >>= 1;
2704  iStride >>= 1;
2705  pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
2706  pRec  = pcPicD->getCbAddr();
2707 
2708  for( y = 0; y < iHeight; y++ )
2709  {
2710    for( x = 0; x < iWidth; x++ )
2711    {
2712      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2713      uiSSDU   += iDiff * iDiff;
2714    }
2715    pOrg += iStride;
2716    pRec += iStride;
2717  }
2718 
2719  pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
2720  pRec  = pcPicD->getCrAddr();
2721 
2722  for( y = 0; y < iHeight; y++ )
2723  {
2724    for( x = 0; x < iWidth; x++ )
2725    {
2726      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2727      uiSSDV   += iDiff * iDiff;
2728    }
2729    pOrg += iStride;
2730    pRec += iStride;
2731  }
2732 
2733  Int maxvalY = 255 << (g_bitDepthY-8);
2734  Int maxvalC = 255 << (g_bitDepthC-8);
2735  Double fRefValueY = (Double) maxvalY * maxvalY * iSize;
2736  Double fRefValueC = (Double) maxvalC * maxvalC * iSize / 4.0;
2737  dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
2738  dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
2739  dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
2740#if H_3D_VSO
2741#if H_3D_VSO_SYNTH_DIST_OUT
2742}
2743#endif
2744#endif
2745  /* calculate the size of the access unit, excluding:
2746   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
2747   *  - SEI NAL units
2748   */
2749  UInt numRBSPBytes = 0;
2750  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2751  {
2752    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
2753#if VERBOSE_RATE
2754    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
2755#endif
2756    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
2757    {
2758      numRBSPBytes += numRBSPBytes_nal;
2759    }
2760  }
2761
2762  UInt uibits = numRBSPBytes * 8;
2763  m_vRVM_RP.push_back( uibits );
2764
2765  //===== add PSNR =====
2766#if H_MV
2767  m_pcEncTop->getAnalyzeAll()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2768#else
2769  m_gcAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2770#endif
2771  TComSlice*  pcSlice = pcPic->getSlice(0);
2772  if (pcSlice->isIntra())
2773  {
2774#if H_MV
2775    m_pcEncTop->getAnalyzeI()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2776#else
2777    m_gcAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2778#endif
2779  }
2780  if (pcSlice->isInterP())
2781  {
2782#if H_MV
2783    m_pcEncTop->getAnalyzeP()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2784#else
2785    m_gcAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2786#endif
2787  }
2788  if (pcSlice->isInterB())
2789  {
2790#if H_MV
2791    m_pcEncTop->getAnalyzeB()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2792#else
2793    m_gcAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2794#endif
2795  }
2796
2797  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
2798  if (!pcSlice->isReferenced()) c += 32;
2799
2800#if ADAPTIVE_QP_SELECTION
2801#if H_MV
2802  printf("Layer %3d   POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d  bits",
2803    pcSlice->getLayerId(),
2804    pcSlice->getPOC(),
2805    pcSlice->getTLayer(),
2806    c,
2807    pcSlice->getSliceQpBase(),
2808    pcSlice->getSliceQp(),
2809    uibits );
2810#else
2811  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
2812         pcSlice->getPOC(),
2813         pcSlice->getTLayer(),
2814         c,
2815         pcSlice->getSliceQpBase(),
2816         pcSlice->getSliceQp(),
2817         uibits );
2818#endif
2819#else
2820#if H_MV
2821  printf("Layer %3d   POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
2822    pcSlice->getLayerId(),
2823    pcSlice->getPOC()-pcSlice->getLastIDR(),
2824    pcSlice->getTLayer(),
2825    c,
2826    pcSlice->getSliceQp(),
2827    uibits );
2828#else
2829  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
2830         pcSlice->getPOC()-pcSlice->getLastIDR(),
2831         pcSlice->getTLayer(),
2832         c,
2833         pcSlice->getSliceQp(),
2834         uibits );
2835#endif
2836#endif
2837
2838  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dYPSNR, dUPSNR, dVPSNR );
2839  printf(" [ET %5.0f ]", dEncTime );
2840 
2841  for (Int iRefList = 0; iRefList < 2; iRefList++)
2842  {
2843    printf(" [L%d ", iRefList);
2844    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
2845    {
2846#if H_MV
2847      if( pcSlice->getLayerId() != pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) )
2848      {
2849        printf( "V%d ", pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) );
2850      }
2851      else
2852      {
2853#endif
2854      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
2855#if H_MV
2856      }
2857#endif
2858    }
2859    printf("]");
2860  }
2861}
2862
2863
2864Void reinterlace(Pel* top, Pel* bottom, Pel* dst, UInt stride, UInt width, UInt height, bool isTff)
2865{
2866 
2867  for (Int y = 0; y < height; y++)
2868  {
2869    for (Int x = 0; x < width; x++)
2870    {
2871      dst[x] = isTff ? top[x] : bottom[x];
2872      dst[stride+x] = isTff ? bottom[x] : top[x];
2873    }
2874    top += stride;
2875    bottom += stride;
2876    dst += stride*2;
2877  }
2878}
2879
2880
2881Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgTop, TComPic* pcPicOrgBottom, TComPicYuv* pcPicRecTop, TComPicYuv* pcPicRecBottom, const AccessUnit& accessUnit, Double dEncTime )
2882{
2883#if  H_MV
2884  assert( 0 ); // Field coding and MV need to be aligned.
2885#else
2886  Int     x, y;
2887 
2888  UInt64 uiSSDY_in  = 0;
2889  UInt64 uiSSDU_in  = 0;
2890  UInt64 uiSSDV_in  = 0;
2891 
2892  Double  dYPSNR_in  = 0.0;
2893  Double  dUPSNR_in  = 0.0;
2894  Double  dVPSNR_in  = 0.0;
2895 
2896  /*------ INTERLACED PSNR -----------*/
2897 
2898  /* Luma */
2899 
2900  Pel*  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getLumaAddr();
2901  Pel*  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getLumaAddr();
2902  Pel*  pRecTop = pcPicRecTop->getLumaAddr();
2903  Pel*  pRecBottom = pcPicRecBottom->getLumaAddr();
2904 
2905  Int   iWidth;
2906  Int   iHeight;
2907  Int iStride;
2908 
2909  iWidth  = pcPicOrgTop->getPicYuvOrg()->getWidth () - m_pcEncTop->getPad(0);
2910  iHeight = pcPicOrgTop->getPicYuvOrg()->getHeight() - m_pcEncTop->getPad(1);
2911  iStride = pcPicOrgTop->getPicYuvOrg()->getStride();
2912  Int   iSize   = iWidth*iHeight;
2913  bool isTff = pcPicOrgTop->isTopField();
2914 
2915  TComPicYuv* pcOrgInterlaced = new TComPicYuv;
2916  pcOrgInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
2917 
2918  TComPicYuv* pcRecInterlaced = new TComPicYuv;
2919  pcRecInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
2920 
2921  Pel* pOrgInterlaced = pcOrgInterlaced->getLumaAddr();
2922  Pel* pRecInterlaced = pcRecInterlaced->getLumaAddr();
2923 
2924  //=== Interlace fields ====
2925  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
2926  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
2927 
2928  //===== calculate PSNR =====
2929  for( y = 0; y < iHeight << 1; y++ )
2930  {
2931    for( x = 0; x < iWidth; x++ )
2932    {
2933      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
2934      uiSSDY_in   += iDiff * iDiff;
2935    }
2936    pOrgInterlaced += iStride;
2937    pRecInterlaced += iStride;
2938  }
2939 
2940  /*Chroma*/
2941 
2942  iHeight >>= 1;
2943  iWidth  >>= 1;
2944  iStride >>= 1;
2945 
2946  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCbAddr();
2947  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCbAddr();
2948  pRecTop = pcPicRecTop->getCbAddr();
2949  pRecBottom = pcPicRecBottom->getCbAddr();
2950  pOrgInterlaced = pcOrgInterlaced->getCbAddr();
2951  pRecInterlaced = pcRecInterlaced->getCbAddr();
2952 
2953  //=== Interlace fields ====
2954  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
2955  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
2956 
2957  //===== calculate PSNR =====
2958  for( y = 0; y < iHeight << 1; y++ )
2959  {
2960    for( x = 0; x < iWidth; x++ )
2961    {
2962      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
2963      uiSSDU_in   += iDiff * iDiff;
2964    }
2965    pOrgInterlaced += iStride;
2966    pRecInterlaced += iStride;
2967  }
2968 
2969  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCrAddr();
2970  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCrAddr();
2971  pRecTop = pcPicRecTop->getCrAddr();
2972  pRecBottom = pcPicRecBottom->getCrAddr();
2973  pOrgInterlaced = pcOrgInterlaced->getCrAddr();
2974  pRecInterlaced = pcRecInterlaced->getCrAddr();
2975 
2976  //=== Interlace fields ====
2977  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
2978  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
2979 
2980  //===== calculate PSNR =====
2981  for( y = 0; y < iHeight << 1; y++ )
2982  {
2983    for( x = 0; x < iWidth; x++ )
2984    {
2985      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
2986      uiSSDV_in   += iDiff * iDiff;
2987    }
2988    pOrgInterlaced += iStride;
2989    pRecInterlaced += iStride;
2990  }
2991 
2992  Int maxvalY = 255 << (g_bitDepthY-8);
2993  Int maxvalC = 255 << (g_bitDepthC-8);
2994  Double fRefValueY = (Double) maxvalY * maxvalY * iSize*2;
2995  Double fRefValueC = (Double) maxvalC * maxvalC * iSize*2 / 4.0;
2996  dYPSNR_in            = ( uiSSDY_in ? 10.0 * log10( fRefValueY / (Double)uiSSDY_in ) : 99.99 );
2997  dUPSNR_in            = ( uiSSDU_in ? 10.0 * log10( fRefValueC / (Double)uiSSDU_in ) : 99.99 );
2998  dVPSNR_in            = ( uiSSDV_in ? 10.0 * log10( fRefValueC / (Double)uiSSDV_in ) : 99.99 );
2999 
3000  /* calculate the size of the access unit, excluding:
3001   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
3002   *  - SEI NAL units
3003   */
3004  UInt numRBSPBytes = 0;
3005  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3006  {
3007    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3008   
3009    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3010      numRBSPBytes += numRBSPBytes_nal;
3011  }
3012 
3013  UInt uibits = numRBSPBytes * 8 ;
3014 
3015  //===== add PSNR =====
3016  m_gcAnalyzeAll_in.addResult (dYPSNR_in, dUPSNR_in, dVPSNR_in, (Double)uibits);
3017 
3018  printf("\n                                      Interlaced frame %d: [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", pcPicOrgBottom->getPOC()/2 , dYPSNR_in, dUPSNR_in, dVPSNR_in );
3019 
3020  pcOrgInterlaced->destroy();
3021  delete pcOrgInterlaced;
3022  pcRecInterlaced->destroy();
3023  delete pcRecInterlaced;
3024#endif
3025}
3026/** Function for deciding the nal_unit_type.
3027 * \param pocCurr POC of the current picture
3028 * \returns the nal unit type of the picture
3029 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
3030 */
3031NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR, Bool isField)
3032{
3033  if (pocCurr == 0)
3034  {
3035    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3036  }
3037#if EFFICIENT_FIELD_IRAP
3038  if(isField && pocCurr == 1)
3039  {
3040    // to avoid the picture becoming an IRAP
3041    return NAL_UNIT_CODED_SLICE_TRAIL_R;
3042  }
3043#endif
3044
3045#if ALLOW_RECOVERY_POINT_AS_RAP
3046  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3047#else
3048  if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3049#endif
3050  {
3051    if (m_pcCfg->getDecodingRefreshType() == 1)
3052    {
3053      return NAL_UNIT_CODED_SLICE_CRA;
3054    }
3055    else if (m_pcCfg->getDecodingRefreshType() == 2)
3056    {
3057      return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3058    }
3059  }
3060  if(m_pocCRA>0)
3061  {
3062    if(pocCurr<m_pocCRA)
3063    {
3064      // All leading pictures are being marked as TFD pictures here since current encoder uses all
3065      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
3066      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
3067      // controlling the reference pictures used for encoding that leading picture. Such a leading
3068      // picture need not be marked as a TFD picture.
3069      return NAL_UNIT_CODED_SLICE_RASL_R;
3070    }
3071  }
3072  if (lastIDR>0)
3073  {
3074    if (pocCurr < lastIDR)
3075    {
3076      return NAL_UNIT_CODED_SLICE_RADL_R;
3077    }
3078  }
3079  return NAL_UNIT_CODED_SLICE_TRAIL_R;
3080}
3081
3082Double TEncGOP::xCalculateRVM()
3083{
3084  Double dRVM = 0;
3085 
3086  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
3087  {
3088    // calculate RVM only for lowdelay configurations
3089    std::vector<Double> vRL , vB;
3090    size_t N = m_vRVM_RP.size();
3091    vRL.resize( N );
3092    vB.resize( N );
3093   
3094    Int i;
3095    Double dRavg = 0 , dBavg = 0;
3096    vB[RVM_VCEGAM10_M] = 0;
3097    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3098    {
3099      vRL[i] = 0;
3100      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
3101        vRL[i] += m_vRVM_RP[j];
3102      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
3103      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
3104      dRavg += m_vRVM_RP[i];
3105      dBavg += vB[i];
3106    }
3107   
3108    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
3109    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
3110   
3111    Double dSigamB = 0;
3112    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3113    {
3114      Double tmp = vB[i] - dBavg;
3115      dSigamB += tmp * tmp;
3116    }
3117    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
3118   
3119    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
3120   
3121    dRVM = dSigamB / dRavg * f;
3122  }
3123 
3124  return( dRVM );
3125}
3126
3127/** Attaches the input bitstream to the stream in the output NAL unit
3128    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
3129 *  \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu
3130 *  \param rNalu          target NAL unit
3131 */
3132Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream*& codedSliceData)
3133{
3134  // Byte-align
3135  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
3136
3137  // Perform bitstream concatenation
3138  if (codedSliceData->getNumberOfWrittenBits() > 0)
3139    {
3140    rNalu.m_Bitstream.addSubstream(codedSliceData);
3141  }
3142
3143  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
3144
3145  codedSliceData->clear();
3146}
3147
3148// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
3149// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
3150Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
3151{
3152  TComReferencePictureSet *rps = pcSlice->getRPS();
3153  if(!rps->getNumberOfLongtermPictures())
3154  {
3155    return;
3156  }
3157
3158  // Arrange long-term reference pictures in the correct order of LSB and MSB,
3159  // and assign values for pocLSBLT and MSB present flag
3160  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
3161  Int longtermPicsMSB[MAX_NUM_REF_PICS];
3162  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
3163  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
3164  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
3165  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
3166  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
3167  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
3168
3169  // Get the long-term reference pictures
3170  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
3171  Int i, ctr = 0;
3172  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
3173  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3174  {
3175    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
3176    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
3177    indices[ctr]      = i; 
3178    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
3179  }
3180  Int numLongPics = rps->getNumberOfLongtermPictures();
3181  assert(ctr == numLongPics);
3182
3183  // Arrange pictures in decreasing order of MSB;
3184  for(i = 0; i < numLongPics; i++)
3185  {
3186    for(Int j = 0; j < numLongPics - 1; j++)
3187    {
3188      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
3189      {
3190        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
3191        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
3192        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
3193        std::swap(indices[j]        , indices[j+1]        );
3194      }
3195    }
3196  }
3197
3198  for(i = 0; i < numLongPics; i++)
3199  {
3200    // Check if MSB present flag should be enabled.
3201    // Check if the buffer contains any pictures that have the same LSB.
3202    TComList<TComPic*>::iterator  iterPic = rcListPic.begin(); 
3203    TComPic*                      pcPic;
3204    while ( iterPic != rcListPic.end() )
3205    {
3206      pcPic = *iterPic;
3207      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
3208                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
3209                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
3210      {
3211        mSBPresentFlag[i] = true;
3212        break;
3213      }
3214      iterPic++;     
3215    }
3216  }
3217
3218  // tempArray for usedByCurr flag
3219  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
3220  for(i = 0; i < numLongPics; i++)
3221  {
3222    tempArray[i] = rps->getUsed(indices[i]);
3223  }
3224  // Now write the final values;
3225  ctr = 0;
3226  Int currMSB = 0, currLSB = 0;
3227  // currPicPoc = currMSB + currLSB
3228  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB); 
3229  currMSB = pcSlice->getPOC() - currLSB;
3230
3231  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3232  {
3233    rps->setPOC                   (i, longtermPicsPoc[ctr]);
3234    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
3235    rps->setUsed                  (i, tempArray[ctr]);
3236    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
3237    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
3238    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);     
3239
3240    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
3241  }
3242  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
3243  {
3244    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
3245    {
3246      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
3247      // don't have to check the MSB present flag values for this constraint.
3248      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
3249    }
3250  }
3251}
3252
3253/** Function for finding the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
3254 * \param accessUnit Access Unit of the current picture
3255 * This function finds the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
3256 */
3257Int TEncGOP::xGetFirstSeiLocation(AccessUnit &accessUnit)
3258{
3259  // Find the location of the first SEI message
3260  AccessUnit::iterator it;
3261  Int seiStartPos = 0;
3262  for(it = accessUnit.begin(); it != accessUnit.end(); it++, seiStartPos++)
3263  {
3264     if ((*it)->isSei() || (*it)->isVcl())
3265     {
3266       break;
3267     }               
3268  }
3269//  assert(it != accessUnit.end());  // Triggers with some legit configurations
3270  return seiStartPos;
3271}
3272
3273Void TEncGOP::dblMetric( TComPic* pcPic, UInt uiNumSlices )
3274{
3275  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
3276  Pel* Rec    = pcPicYuvRec->getLumaAddr( 0 );
3277  Pel* tempRec = Rec;
3278  Int  stride = pcPicYuvRec->getStride();
3279  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
3280  UInt maxTBsize = (1<<log2maxTB);
3281  const UInt minBlockArtSize = 8;
3282  const UInt picWidth = pcPicYuvRec->getWidth();
3283  const UInt picHeight = pcPicYuvRec->getHeight();
3284  const UInt noCol = (picWidth>>log2maxTB);
3285  const UInt noRows = (picHeight>>log2maxTB);
3286  assert(noCol > 1);
3287  assert(noRows > 1);
3288  UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64));
3289  UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64));
3290  UInt colIdx = 0;
3291  UInt rowIdx = 0;
3292  Pel p0, p1, p2, q0, q1, q2;
3293 
3294  Int qp = pcPic->getSlice(0)->getSliceQp();
3295  Int bitdepthScale = 1 << (g_bitDepthY-8);
3296  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
3297  const Int thr2 = (beta>>2);
3298  const Int thr1 = 2*bitdepthScale;
3299  UInt a = 0;
3300 
3301  memset(colSAD, 0, noCol*sizeof(UInt64));
3302  memset(rowSAD, 0, noRows*sizeof(UInt64));
3303 
3304  if (maxTBsize > minBlockArtSize)
3305  {
3306    // Analyze vertical artifact edges
3307    for(Int c = maxTBsize; c < picWidth; c += maxTBsize)
3308    {
3309      for(Int r = 0; r < picHeight; r++)
3310      {
3311        p2 = Rec[c-3];
3312        p1 = Rec[c-2];
3313        p0 = Rec[c-1];
3314        q0 = Rec[c];
3315        q1 = Rec[c+1];
3316        q2 = Rec[c+2];
3317        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3318        if ( thr1 < a && a < thr2)
3319        {
3320          colSAD[colIdx] += abs(p0 - q0);
3321        }
3322        Rec += stride;
3323      }
3324      colIdx++;
3325      Rec = tempRec;
3326    }
3327   
3328    // Analyze horizontal artifact edges
3329    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
3330    {
3331      for(Int c = 0; c < picWidth; c++)
3332      {
3333        p2 = Rec[c + (r-3)*stride];
3334        p1 = Rec[c + (r-2)*stride];
3335        p0 = Rec[c + (r-1)*stride];
3336        q0 = Rec[c + r*stride];
3337        q1 = Rec[c + (r+1)*stride];
3338        q2 = Rec[c + (r+2)*stride];
3339        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3340        if (thr1 < a && a < thr2)
3341        {
3342          rowSAD[rowIdx] += abs(p0 - q0);
3343        }
3344      }
3345      rowIdx++;
3346    }
3347  }
3348 
3349  UInt64 colSADsum = 0;
3350  UInt64 rowSADsum = 0;
3351  for(Int c = 0; c < noCol-1; c++)
3352  {
3353    colSADsum += colSAD[c];
3354  }
3355  for(Int r = 0; r < noRows-1; r++)
3356  {
3357    rowSADsum += rowSAD[r];
3358  }
3359 
3360  colSADsum <<= 10;
3361  rowSADsum <<= 10;
3362  colSADsum /= (noCol-1);
3363  colSADsum /= picHeight;
3364  rowSADsum /= (noRows-1);
3365  rowSADsum /= picWidth;
3366 
3367  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
3368  avgSAD >>= (g_bitDepthY-8);
3369 
3370  if ( avgSAD > 2048 )
3371  {
3372    avgSAD >>= 9;
3373    Int offset = Clip3(2,6,(Int)avgSAD);
3374    for (Int i=0; i<uiNumSlices; i++)
3375    {
3376      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
3377      pcPic->getSlice(i)->setDeblockingFilterDisable(false);
3378      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset );
3379      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset );
3380    }
3381  }
3382  else
3383  {
3384    for (Int i=0; i<uiNumSlices; i++)
3385    {
3386      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
3387      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
3388      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
3389      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
3390    }
3391  }
3392 
3393  free(colSAD);
3394  free(rowSAD);
3395}
3396
3397#if H_MV
3398Void TEncGOP::xSetRefPicListModificationsMv( std::vector<TComPic*> tempPicLists[2], TComSlice* pcSlice, UInt iGOPid )
3399{ 
3400 
3401  if( pcSlice->getSliceType() == I_SLICE || !(pcSlice->getPPS()->getListsModificationPresentFlag()) || pcSlice->getNumActiveRefLayerPics() == 0 )
3402  {
3403    return;
3404  }
3405 
3406  GOPEntry ge = m_pcCfg->getGOPEntry( (pcSlice->getRapPicFlag() && ( pcSlice->getLayerId( ) > 0) ) ? MAX_GOP : iGOPid );
3407  assert( ge.m_numActiveRefLayerPics == pcSlice->getNumActiveRefLayerPics() ); 
3408
3409  Int numPicsInTempList     = pcSlice->getNumRpsCurrTempList(); 
3410
3411  // GT: check if SliceType should be checked here.
3412  for (Int li = 0; li < 2; li ++) // Loop over lists L0 and L1
3413  {
3414    Int numPicsInFinalRefList = pcSlice->getNumRefIdx( ( li == 0 ) ? REF_PIC_LIST_0 : REF_PIC_LIST_1 ); 
3415           
3416    Int finalIdxToTempIdxMap[16];
3417    for( Int k = 0; k < 16; k++ )
3418    {
3419      finalIdxToTempIdxMap[ k ] = -1;
3420    }
3421
3422    Bool isModified = false;
3423    if ( numPicsInTempList > 1 )
3424    {
3425      for( Int k = 0; k < pcSlice->getNumActiveRefLayerPics(); k++ )
3426      {
3427        // get position in temp. list
3428        Int refPicLayerId = pcSlice->getRefPicLayerId(k);
3429        Int idxInTempList = 0; 
3430        for (; idxInTempList < numPicsInTempList; idxInTempList++)
3431        {
3432          if ( (tempPicLists[li][idxInTempList])->getLayerId() == refPicLayerId )
3433          {
3434            break; 
3435          }
3436        }
3437
3438        Int idxInFinalList = ge.m_interViewRefPosL[ li ][ k ];
3439       
3440        // Add negative from behind
3441        idxInFinalList = ( idxInFinalList < 0 )? ( numPicsInTempList + idxInFinalList ) : idxInFinalList; 
3442       
3443        Bool curIsModified = ( idxInFinalList != idxInTempList ) && ( ( idxInTempList < numPicsInFinalRefList ) || ( idxInFinalList < numPicsInFinalRefList ) ) ;
3444        if ( curIsModified )
3445        {
3446          isModified = true; 
3447          assert( finalIdxToTempIdxMap[ idxInFinalList ] == -1 ); // Assert when two inter layer reference pictures are sorted to the same position
3448        }
3449        finalIdxToTempIdxMap[ idxInFinalList ] = idxInTempList;             
3450      }
3451    }
3452
3453    TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
3454    refPicListModification->setRefPicListModificationFlagL( li, isModified ); 
3455
3456    if( isModified )
3457    {
3458      Int refIdx = 0;
3459     
3460      for( Int i = 0; i < numPicsInFinalRefList; i++ )
3461      {
3462        if( finalIdxToTempIdxMap[i] >= 0 ) 
3463        {
3464          refPicListModification->setRefPicSetIdxL( li, i, finalIdxToTempIdxMap[i] );
3465        }
3466        else
3467        {
3468          ///* Fill gaps with temporal references *///
3469          // Forward inter layer reference pictures
3470          while( ( refIdx < numPicsInTempList ) && ( tempPicLists[li][refIdx]->getLayerId() != getLayerId())  )
3471          {
3472            refIdx++; 
3473          }
3474          refPicListModification->setRefPicSetIdxL( li, i, refIdx );
3475          refIdx++;
3476        }
3477      }
3478    }
3479  }
3480}
3481#endif
3482//! \}
Note: See TracBrowser for help on using the repository browser.