source: 3DVCSoftware/branches/HTM-12.2-dev2-Samsung/source/Lib/TLibEncoder/TEncGOP.cpp @ 1100

Last change on this file since 1100 was 1100, checked in by samsung-htm, 9 years ago

Integration of JCT3V-J0037 (Item1 and Item4)

  • Property svn:eol-style set to native
File size: 126.5 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-2014, 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    Int numDirectRefLayers = vps    ->getNumDirectRefLayers( getLayerId() ); 
883    GOPEntry gopEntry      = m_pcCfg->getGOPEntry( (pcSlice->getRapPicFlag() && getLayerId() > 0) ? MAX_GOP : iGOPid );     
884   
885    Bool interLayerPredLayerIdcPresentFlag = false; 
886    if ( getLayerId() > 0 && !vps->getAllRefLayersActiveFlag() && numDirectRefLayers > 0 )
887    {         
888      pcSlice->setInterLayerPredEnabledFlag ( gopEntry.m_numActiveRefLayerPics > 0 );     
889      if ( pcSlice->getInterLayerPredEnabledFlag() && numDirectRefLayers > 1 )
890      {
891        if ( !vps->getMaxOneActiveRefLayerFlag() )
892        {   
893          pcSlice->setNumInterLayerRefPicsMinus1( gopEntry.m_numActiveRefLayerPics - 1 ); 
894        }
895        if ( gopEntry.m_numActiveRefLayerPics != vps->getNumDirectRefLayers( getLayerId() ) )
896        {       
897          interLayerPredLayerIdcPresentFlag = true; 
898          for (Int i = 0; i < gopEntry.m_numActiveRefLayerPics; i++ )
899          {
900            pcSlice->setInterLayerPredLayerIdc( i, gopEntry.m_interLayerPredLayerIdc[ i ] ); 
901          }
902        }
903      }
904    }
905    if ( !interLayerPredLayerIdcPresentFlag )
906    {
907      for( Int i = 0; i < pcSlice->getNumActiveRefLayerPics(); i++ )   
908      {
909        pcSlice->setInterLayerPredLayerIdc(i, pcSlice->getRefLayerPicIdc( i ) );
910      }
911    }
912
913
914    assert( pcSlice->getNumActiveRefLayerPics() == gopEntry.m_numActiveRefLayerPics ); 
915   
916    pcSlice->createInterLayerReferencePictureSet( m_ivPicLists, m_refPicSetInterLayer0, m_refPicSetInterLayer1 ); 
917    pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(gopEntry.m_numRefPicsActive,( pcSlice->getRPS()->getNumberOfPictures() + (Int) m_refPicSetInterLayer0.size() + (Int) m_refPicSetInterLayer1.size()) ) );
918    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(gopEntry.m_numRefPicsActive,( pcSlice->getRPS()->getNumberOfPictures() + (Int) m_refPicSetInterLayer0.size() + (Int) m_refPicSetInterLayer1.size()) ) );
919
920    std::vector< TComPic* >    tempRefPicLists[2];
921    std::vector< Bool     >    usedAsLongTerm [2];
922    Int       numPocTotalCurr;
923
924    pcSlice->getTempRefPicLists( rcListPic, m_refPicSetInterLayer0, m_refPicSetInterLayer1, tempRefPicLists, usedAsLongTerm, numPocTotalCurr, true );
925   
926
927    xSetRefPicListModificationsMv( tempRefPicLists, pcSlice, iGOPid );   
928#else
929    pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
930    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
931#endif
932
933#if ADAPTIVE_QP_SELECTION
934    pcSlice->setTrQuant( m_pcEncTop->getTrQuant() );
935#endif     
936
937    //  Set reference list
938#if H_MV   
939    pcSlice->setRefPicList( tempRefPicLists, usedAsLongTerm, numPocTotalCurr ); 
940#else
941    pcSlice->setRefPicList ( rcListPic );
942#endif
943#if H_3D_SINGLE_DEPTH
944    TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
945    bool enableSingleDepthMode=false;
946    if(pcEncTop->getUseSingleDepthMode())
947    {
948      if(pcSlice->getIsDepth())
949      {
950        enableSingleDepthMode=true;
951      }
952    }
953    pcSlice->setApplySingleDepthMode(enableSingleDepthMode);
954#endif   
955#if SEC_ARP_VIEW_REF_CHECK_J0037 || SEC_DBBP_VIEW_REF_CHECK_J0037
956    pcSlice->setDefaultRefView();
957#endif
958#if H_3D_ARP
959    //GT: This seems to be broken when layerId in vps is not equal to layerId in nuh
960    pcSlice->setARPStepNum(m_ivPicLists);
961    if(pcSlice->getARPStepNum() > 1)
962    {
963      for(Int iLayerId = 0; iLayerId < getLayerId(); iLayerId ++ )
964      {
965        Int  iViewIdx =   pcSlice->getVPS()->getViewIndex(iLayerId);
966        Bool bIsDepth = ( pcSlice->getVPS()->getDepthId  ( iLayerId ) == 1 );
967        if( iViewIdx<getViewIndex() && !bIsDepth )
968        {
969          pcSlice->setBaseViewRefPicList( m_ivPicLists->getPicList( iLayerId ), iViewIdx );
970        }
971      }
972    }
973#endif
974#if H_3D
975    pcSlice->setIvPicLists( m_ivPicLists );         
976#if H_3D_IV_MERGE   
977    assert( !m_pcEncTop->getIsDepth() || ( pcSlice->getTexturePic() != 0 ) );
978#endif   
979#endif
980#if H_3D_IC
981    pcSlice->setICEnableCandidate( m_aICEnableCandidate );         
982    pcSlice->setICEnableNum( m_aICEnableNum );         
983#endif
984    //  Slice info. refinement
985#if H_MV
986    if ( pcSlice->getSliceType() == B_SLICE )
987    {
988      if( m_pcCfg->getGOPEntry( ( pcSlice->getRapPicFlag() == true && getLayerId() > 0 ) ? MAX_GOP : iGOPid ).m_sliceType == 'P' ) 
989      { 
990        pcSlice->setSliceType( P_SLICE ); 
991      }
992    }
993#else
994    if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
995    {
996      pcSlice->setSliceType ( P_SLICE );
997    }
998#endif
999    if (pcSlice->getSliceType() == B_SLICE)
1000    {
1001      pcSlice->setColFromL0Flag(1-uiColDir);
1002      Bool bLowDelay = true;
1003      Int  iCurrPOC  = pcSlice->getPOC();
1004      Int iRefIdx = 0;
1005
1006      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
1007      {
1008        if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
1009        {
1010          bLowDelay = false;
1011        }
1012      }
1013      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
1014      {
1015        if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
1016        {
1017          bLowDelay = false;
1018        }
1019      }
1020
1021      pcSlice->setCheckLDC(bLowDelay); 
1022    }
1023    else
1024    {
1025      pcSlice->setCheckLDC(true); 
1026    }
1027
1028    uiColDir = 1-uiColDir;
1029
1030    //-------------------------------------------------------------
1031    pcSlice->setRefPOCList();
1032
1033    pcSlice->setList1IdxToList0Idx();
1034#if H_3D_TMVP
1035    if(pcSlice->getLayerId())
1036      pcSlice->generateAlterRefforTMVP();
1037#endif
1038    if (m_pcEncTop->getTMVPModeId() == 2)
1039    {
1040      if (iGOPid == 0) // first picture in SOP (i.e. forward B)
1041      {
1042        pcSlice->setEnableTMVPFlag(0);
1043      }
1044      else
1045      {
1046        // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
1047        pcSlice->setEnableTMVPFlag(1);
1048      }
1049      pcSlice->getSPS()->setTMVPFlagsPresent(1);
1050    }
1051    else if (m_pcEncTop->getTMVPModeId() == 1)
1052    {
1053      pcSlice->getSPS()->setTMVPFlagsPresent(1);
1054      pcSlice->setEnableTMVPFlag(1);
1055    }
1056    else
1057    {
1058      pcSlice->getSPS()->setTMVPFlagsPresent(0);
1059      pcSlice->setEnableTMVPFlag(0);
1060    }
1061#if H_MV
1062    if( pcSlice->getIdrPicFlag() )
1063    {
1064      pcSlice->setEnableTMVPFlag(0);
1065    }
1066#endif
1067
1068#if H_3D_VSO
1069  // Should be moved to TEncTop !!!
1070  Bool bUseVSO = m_pcEncTop->getUseVSO();
1071 
1072  TComRdCost* pcRdCost = m_pcEncTop->getRdCost();   
1073
1074  pcRdCost->setUseVSO( bUseVSO );
1075
1076  // SAIT_VSO_EST_A0033
1077  pcRdCost->setUseEstimatedVSD( m_pcEncTop->getUseEstimatedVSD() );
1078
1079  if ( bUseVSO )
1080  {
1081    Int iVSOMode = m_pcEncTop->getVSOMode();
1082    pcRdCost->setVSOMode( iVSOMode  );
1083    pcRdCost->setAllowNegDist( m_pcEncTop->getAllowNegDist() );
1084
1085    // SAIT_VSO_EST_A0033
1086#if H_3D_FCO
1087    Bool flagRec;
1088    flagRec =  ((m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), false, pcSlice->getPOC(), true) == NULL) ? false: true);
1089    pcRdCost->setVideoRecPicYuv( m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), false, pcSlice->getPOC(), flagRec ) );
1090    pcRdCost->setDepthPicYuv   ( m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), true, pcSlice->getPOC(), false ) );
1091#else
1092    pcRdCost->setVideoRecPicYuv( m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), false , pcSlice->getPOC(), true ) );
1093    pcRdCost->setDepthPicYuv   ( m_pcEncTop->getIvPicLists()->getPicYuv( pcSlice->getViewIndex(), true  , pcSlice->getPOC(), false ) );
1094#endif
1095
1096    // LGE_WVSO_A0119
1097    Bool bUseWVSO  = m_pcEncTop->getUseWVSO();
1098    pcRdCost->setUseWVSO( bUseWVSO );
1099
1100  }
1101#endif
1102    /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
1103    //  Slice compression
1104    if (m_pcCfg->getUseASR())
1105    {
1106      m_pcSliceEncoder->setSearchRange(pcSlice);
1107    }
1108
1109    Bool bGPBcheck=false;
1110    if ( pcSlice->getSliceType() == B_SLICE)
1111    {
1112      if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
1113      {
1114        bGPBcheck=true;
1115        Int i;
1116        for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
1117        {
1118          if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 
1119          {
1120            bGPBcheck=false;
1121            break;
1122          }
1123        }
1124      }
1125    }
1126    if(bGPBcheck)
1127    {
1128      pcSlice->setMvdL1ZeroFlag(true);
1129    }
1130    else
1131    {
1132      pcSlice->setMvdL1ZeroFlag(false);
1133    }
1134    pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
1135
1136    Double lambda            = 0.0;
1137    Int actualHeadBits       = 0;
1138    Int actualTotalBits      = 0;
1139    Int estimatedBits        = 0;
1140    Int tmpBitsBeforeWriting = 0;
1141    if ( m_pcCfg->getUseRateCtrl() )
1142    {
1143      Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
1144      if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )
1145      {
1146        frameLevel = 0;
1147      }
1148      m_pcRateCtrl->initRCPic( frameLevel );
1149
1150#if KWU_RC_MADPRED_E0227
1151      if(m_pcCfg->getLayerId() != 0)
1152      {
1153        m_pcRateCtrl->getRCPic()->setIVPic( m_pcEncTop->getEncTop()->getTEncTop(0)->getRateCtrl()->getRCPic() );
1154      }
1155#endif
1156
1157      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
1158
1159      Int sliceQP = m_pcCfg->getInitialQP();
1160      if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
1161      {
1162        Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
1163        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
1164        Double dQPFactor     = 0.57*dLambda_scale;
1165        Int    SHIFT_QP      = 12;
1166        Int    bitdepth_luma_qp_scale = 0;
1167        Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP;
1168        lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
1169      }
1170      else if ( frameLevel == 0 )   // intra case, but use the model
1171      {
1172        m_pcSliceEncoder->calCostSliceI(pcPic);
1173        if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case
1174        {
1175          Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
1176          bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );
1177          if ( bits < 200 )
1178          {
1179            bits = 200;
1180          }
1181          m_pcRateCtrl->getRCPic()->setTargetBits( bits );
1182        }
1183
1184        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
1185        m_pcRateCtrl->getRCPic()->getLCUInitTargetBits();
1186        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
1187        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
1188      }
1189      else    // normal case
1190      {
1191#if KWU_RC_MADPRED_E0227
1192        if(m_pcRateCtrl->getLayerID() != 0)
1193        {
1194          list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
1195          lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambdaIV( listPreviousPicture, pcSlice->getPOC() );
1196          sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
1197        }
1198        else
1199        {
1200#endif
1201        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
1202        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
1203        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
1204#if KWU_RC_MADPRED_E0227
1205        }
1206#endif
1207      }
1208
1209      sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, sliceQP );
1210      m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );
1211
1212      m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );
1213    }
1214
1215    UInt uiNumSlices = 1;
1216
1217    UInt uiInternalAddress = pcPic->getNumPartInCU()-4;
1218    UInt uiExternalAddress = pcPic->getPicSym()->getNumberOfCUsInFrame()-1;
1219    UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1220    UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1221    UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1222    UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1223    while(uiPosX>=uiWidth||uiPosY>=uiHeight) 
1224    {
1225      uiInternalAddress--;
1226      uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1227      uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1228    }
1229    uiInternalAddress++;
1230    if(uiInternalAddress==pcPic->getNumPartInCU()) 
1231    {
1232      uiInternalAddress = 0;
1233      uiExternalAddress++;
1234    }
1235    UInt uiRealEndAddress = uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress;
1236
1237    Int  p, j;
1238    UInt uiEncCUAddr;
1239
1240    pcPic->getPicSym()->initTiles(pcSlice->getPPS());
1241
1242    // Allocate some coders, now we know how many tiles there are.
1243    Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
1244
1245    //generate the Coding Order Map and Inverse Coding Order Map
1246    for(p=0, uiEncCUAddr=0; p<pcPic->getPicSym()->getNumberOfCUsInFrame(); p++, uiEncCUAddr = pcPic->getPicSym()->xCalculateNxtCUAddr(uiEncCUAddr))
1247    {
1248      pcPic->getPicSym()->setCUOrderMap(p, uiEncCUAddr);
1249      pcPic->getPicSym()->setInverseCUOrderMap(uiEncCUAddr, p);
1250    }
1251    pcPic->getPicSym()->setCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());   
1252    pcPic->getPicSym()->setInverseCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());
1253
1254    // Allocate some coders, now we know how many tiles there are.
1255    m_pcEncTop->createWPPCoders(iNumSubstreams);
1256    pcSbacCoders = m_pcEncTop->getSbacCoders();
1257    pcSubstreamsOut = new TComOutputBitstream[iNumSubstreams];
1258
1259    UInt startCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
1260    UInt startCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
1261    pcSlice->setSliceCurStartCUAddr( startCUAddrSlice ); // Setting "start CU addr" for current slice
1262    m_storedStartCUAddrForEncodingSlice.clear();
1263
1264    UInt startCUAddrSliceSegmentIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
1265    UInt startCUAddrSliceSegment    = 0; // used to keep track of current Dependent slice's starting CU addr.
1266    pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment ); // Setting "start CU addr" for current Dependent slice
1267
1268    m_storedStartCUAddrForEncodingSliceSegment.clear();
1269    UInt nextCUAddr = 0;
1270    m_storedStartCUAddrForEncodingSlice.push_back (nextCUAddr);
1271    startCUAddrSliceIdx++;
1272    m_storedStartCUAddrForEncodingSliceSegment.push_back(nextCUAddr);
1273    startCUAddrSliceSegmentIdx++;
1274#if H_3D_NBDV
1275      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.
1276      {
1277        Int iColPoc = pcSlice->getRefPOC(RefPicList(1-pcSlice->getColFromL0Flag()), pcSlice->getColRefIdx());
1278        pcPic->setNumDdvCandPics(pcPic->getDisCandRefPictures(iColPoc));
1279      }
1280#endif
1281#if H_3D
1282      pcSlice->setDepthToDisparityLUTs(); 
1283
1284#endif
1285
1286#if H_3D_NBDV
1287      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.
1288      {
1289        pcPic->checkTemporalIVRef();
1290      }
1291
1292      if(pcSlice->getIsDepth())
1293      {
1294        pcPic->checkTextureRef();
1295      }
1296#endif
1297    while(nextCUAddr<uiRealEndAddress) // determine slice boundaries
1298    {
1299      pcSlice->setNextSlice       ( false );
1300      pcSlice->setNextSliceSegment( false );
1301      assert(pcPic->getNumAllocatedSlice() == startCUAddrSliceIdx);
1302      m_pcSliceEncoder->precompressSlice( pcPic );
1303      m_pcSliceEncoder->compressSlice   ( pcPic );
1304
1305      Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextSliceSegment());
1306      if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU))
1307      {
1308        startCUAddrSlice = pcSlice->getSliceCurEndCUAddr();
1309        // Reconstruction slice
1310        m_storedStartCUAddrForEncodingSlice.push_back(startCUAddrSlice);
1311        startCUAddrSliceIdx++;
1312        // Dependent slice
1313        if (startCUAddrSliceSegmentIdx>0 && m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx-1] != startCUAddrSlice)
1314        {
1315          m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSlice);
1316          startCUAddrSliceSegmentIdx++;
1317        }
1318
1319        if (startCUAddrSlice < uiRealEndAddress)
1320        {
1321          pcPic->allocateNewSlice();         
1322          pcPic->setCurrSliceIdx                  ( startCUAddrSliceIdx-1 );
1323          m_pcSliceEncoder->setSliceIdx           ( startCUAddrSliceIdx-1 );
1324          pcSlice = pcPic->getSlice               ( startCUAddrSliceIdx-1 );
1325          pcSlice->copySliceInfo                  ( pcPic->getSlice(0)      );
1326          pcSlice->setSliceIdx                    ( startCUAddrSliceIdx-1 );
1327          pcSlice->setSliceCurStartCUAddr         ( startCUAddrSlice      );
1328          pcSlice->setSliceSegmentCurStartCUAddr  ( startCUAddrSlice      );
1329          pcSlice->setSliceBits(0);
1330          uiNumSlices ++;
1331        }
1332      }
1333      else if (pcSlice->isNextSliceSegment() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU))
1334      {
1335        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
1336        m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSliceSegment);
1337        startCUAddrSliceSegmentIdx++;
1338        pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment );
1339      }
1340      else
1341      {
1342        startCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
1343        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
1344      }       
1345
1346      nextCUAddr = (startCUAddrSlice > startCUAddrSliceSegment) ? startCUAddrSlice : startCUAddrSliceSegment;
1347    }
1348    m_storedStartCUAddrForEncodingSlice.push_back( pcSlice->getSliceCurEndCUAddr());
1349    startCUAddrSliceIdx++;
1350    m_storedStartCUAddrForEncodingSliceSegment.push_back(pcSlice->getSliceCurEndCUAddr());
1351    startCUAddrSliceSegmentIdx++;
1352
1353    pcSlice = pcPic->getSlice(0);
1354
1355    // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
1356    if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoLcuBoundary() )
1357    {
1358      m_pcSAO->getPreDBFStatistics(pcPic);
1359    }
1360
1361    //-- Loop filter
1362    Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
1363    m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
1364    if ( m_pcCfg->getDeblockingFilterMetric() )
1365    {
1366      dblMetric(pcPic, uiNumSlices);
1367    }
1368    m_pcLoopFilter->loopFilterPic( pcPic );
1369
1370    /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
1371    // Set entropy coder
1372    m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1373
1374    /* write various header sets. */
1375    if ( m_bSeqFirst )
1376    {
1377      OutputNALUnit nalu(NAL_UNIT_VPS);
1378#if H_MV
1379      if( getLayerId() == 0 )
1380      {
1381#endif
1382      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1383      m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());
1384      writeRBSPTrailingBits(nalu.m_Bitstream);
1385      accessUnit.push_back(new NALUnitEBSP(nalu));
1386      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1387
1388#if H_MV
1389      }
1390      nalu = NALUnit(NAL_UNIT_SPS, 0, getLayerId());
1391#else
1392      nalu = NALUnit(NAL_UNIT_SPS);
1393#endif
1394      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1395      if (m_bSeqFirst)
1396      {
1397        pcSlice->getSPS()->setNumLongTermRefPicSPS(m_numLongTermRefPicSPS);
1398        for (Int k = 0; k < m_numLongTermRefPicSPS; k++)
1399        {
1400          pcSlice->getSPS()->setLtRefPicPocLsbSps(k, m_ltRefPicPocLsbSps[k]);
1401          pcSlice->getSPS()->setUsedByCurrPicLtSPSFlag(k, m_ltRefPicUsedByCurrPicFlag[k]);
1402        }
1403      }
1404      if( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
1405      {
1406        UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1);
1407        UInt numDU = ( m_pcCfg->getSliceMode() == 1 ) ? ( pcPic->getNumCUsInFrame() / maxCU ) : ( 0 );
1408        if( pcPic->getNumCUsInFrame() % maxCU != 0 || numDU == 0 )
1409        {
1410          numDU ++;
1411        }
1412        pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->setNumDU( numDU );
1413        pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) );
1414      }
1415      if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
1416      {
1417        pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true );
1418      }
1419#if !H_3D
1420      m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
1421#else
1422      m_pcEntropyCoder->encodeSPS(pcSlice->getSPS(), pcSlice->getViewIndex(), pcSlice->getIsDepth() );
1423#endif
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      nalu = NALUnit(NAL_UNIT_PPS, 0, getLayerId());
1430#else
1431      nalu = NALUnit(NAL_UNIT_PPS);
1432#endif
1433#if PPS_FIX_DEPTH
1434      if(!pcSlice->getIsDepth() || !pcSlice->getViewIndex() )
1435      {
1436#endif
1437      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1438      m_pcEntropyCoder->encodePPS(pcSlice->getPPS());
1439      writeRBSPTrailingBits(nalu.m_Bitstream);
1440      accessUnit.push_back(new NALUnitEBSP(nalu));
1441      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1442     
1443#if PPS_FIX_DEPTH
1444      }
1445#endif
1446      xCreateLeadingSEIMessages(accessUnit, pcSlice->getSPS());
1447
1448      m_bSeqFirst = false;
1449    }
1450
1451    if (writeSOP) // write SOP description SEI (if enabled) at the beginning of GOP
1452    {
1453      Int SOPcurrPOC = pocCurr;
1454
1455      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1456      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1457      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1458
1459      SEISOPDescription SOPDescriptionSEI;
1460      SOPDescriptionSEI.m_sopSeqParameterSetId = pcSlice->getSPS()->getSPSId();
1461
1462      UInt i = 0;
1463      UInt prevEntryId = iGOPid;
1464      for (j = iGOPid; j < m_iGopSize; j++)
1465      {
1466        Int deltaPOC = m_pcCfg->getGOPEntry(j).m_POC - m_pcCfg->getGOPEntry(prevEntryId).m_POC;
1467        if ((SOPcurrPOC + deltaPOC) < m_pcCfg->getFramesToBeEncoded())
1468        {
1469          SOPcurrPOC += deltaPOC;
1470          SOPDescriptionSEI.m_sopDescVclNaluType[i] = getNalUnitType(SOPcurrPOC, m_iLastIDR, isField);
1471          SOPDescriptionSEI.m_sopDescTemporalId[i] = m_pcCfg->getGOPEntry(j).m_temporalId;
1472          SOPDescriptionSEI.m_sopDescStRpsIdx[i] = m_pcEncTop->getReferencePictureSetIdxForSOP(pcSlice, SOPcurrPOC, j);
1473          SOPDescriptionSEI.m_sopDescPocDelta[i] = deltaPOC;
1474
1475          prevEntryId = j;
1476          i++;
1477        }
1478      }
1479
1480      SOPDescriptionSEI.m_numPicsInSopMinus1 = i - 1;
1481
1482      m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, pcSlice->getSPS());
1483      writeRBSPTrailingBits(nalu.m_Bitstream);
1484      accessUnit.push_back(new NALUnitEBSP(nalu));
1485
1486      writeSOP = false;
1487    }
1488
1489    if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
1490        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
1491        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
1492       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
1493    {
1494      if( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() )
1495      {
1496        UInt numDU = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumDU();
1497        pictureTimingSEI.m_numDecodingUnitsMinus1     = ( numDU - 1 );
1498        pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = false;
1499
1500        if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL )
1501        {
1502          pictureTimingSEI.m_numNalusInDuMinus1       = new UInt[ numDU ];
1503        }
1504        if( pictureTimingSEI.m_duCpbRemovalDelayMinus1  == NULL )
1505        {
1506          pictureTimingSEI.m_duCpbRemovalDelayMinus1  = new UInt[ numDU ];
1507        }
1508        if( accumBitsDU == NULL )
1509        {
1510          accumBitsDU                                  = new UInt[ numDU ];
1511        }
1512        if( accumNalsDU == NULL )
1513        {
1514          accumNalsDU                                  = new UInt[ numDU ];
1515        }
1516      }
1517      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 .
1518      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pcSlice->getPOC() - m_totalCoded;
1519#if EFFICIENT_FIELD_IRAP
1520      if(IRAPGOPid > 0 && IRAPGOPid < m_iGopSize)
1521      {
1522        // if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation
1523        pictureTimingSEI.m_picDpbOutputDelay ++;
1524      }
1525#endif
1526      Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2;
1527      pictureTimingSEI.m_picDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
1528      if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
1529      {
1530        picSptDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
1531      }
1532    }
1533
1534    if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) &&
1535        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
1536        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
1537       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
1538    {
1539      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1540      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1541      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1542
1543      SEIBufferingPeriod sei_buffering_period;
1544     
1545      UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
1546      sei_buffering_period.m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
1547      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
1548      sei_buffering_period.m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
1549      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
1550
1551      Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
1552
1553      UInt uiTmp = (UInt)( dTmp * 90000.0 ); 
1554      uiInitialCpbRemovalDelay -= uiTmp;
1555      uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
1556      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
1557      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
1558      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
1559      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
1560
1561      sei_buffering_period.m_rapCpbParamsPresentFlag              = 0;
1562      //for the concatenation, it can be set to one during splicing.
1563      sei_buffering_period.m_concatenationFlag = 0;
1564      //since the temporal layer HRD is not ready, we assumed it is fixed
1565      sei_buffering_period.m_auCpbRemovalDelayDelta = 1;
1566      sei_buffering_period.m_cpbDelayOffset = 0;
1567      sei_buffering_period.m_dpbDelayOffset = 0;
1568
1569      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, pcSlice->getSPS());
1570      writeRBSPTrailingBits(nalu.m_Bitstream);
1571      {
1572      UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
1573      UInt offsetPosition = m_activeParameterSetSEIPresentInAU;   // Insert BP SEI after APS SEI
1574      AccessUnit::iterator it;
1575      for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
1576      {
1577        it++;
1578      }
1579      accessUnit.insert(it, new NALUnitEBSP(nalu));
1580      m_bufferingPeriodSEIPresentInAU = true;
1581      }
1582
1583      if (m_pcCfg->getScalableNestingSEIEnabled())
1584      {
1585        OutputNALUnit naluTmp(NAL_UNIT_PREFIX_SEI);
1586        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1587        m_pcEntropyCoder->setBitstream(&naluTmp.m_Bitstream);
1588        scalableNestingSEI.m_nestedSEIs.clear();
1589        scalableNestingSEI.m_nestedSEIs.push_back(&sei_buffering_period);
1590        m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
1591        writeRBSPTrailingBits(naluTmp.m_Bitstream);
1592        UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
1593        UInt offsetPosition = m_activeParameterSetSEIPresentInAU + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU;   // Insert BP SEI after non-nested APS, BP and PT SEIs
1594        AccessUnit::iterator it;
1595        for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
1596        {
1597          it++;
1598        }
1599        accessUnit.insert(it, new NALUnitEBSP(naluTmp));
1600        m_nestedBufferingPeriodSEIPresentInAU = true;
1601      }
1602
1603      m_lastBPSEI = m_totalCoded;
1604      m_cpbRemovalDelay = 0;
1605    }
1606    m_cpbRemovalDelay ++;
1607    if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) )
1608    {
1609      if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !pcSlice->getRapPicFlag() )
1610      {
1611        // Gradual decoding refresh SEI
1612        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1613        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1614        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1615
1616        SEIGradualDecodingRefreshInfo seiGradualDecodingRefreshInfo;
1617        seiGradualDecodingRefreshInfo.m_gdrForegroundFlag = true; // Indicating all "foreground"
1618
1619        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, pcSlice->getSPS() );
1620        writeRBSPTrailingBits(nalu.m_Bitstream);
1621        accessUnit.push_back(new NALUnitEBSP(nalu));
1622      }
1623    // Recovery point SEI
1624      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
1625      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1626      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1627
1628      SEIRecoveryPoint sei_recovery_point;
1629      sei_recovery_point.m_recoveryPocCnt    = 0;
1630      sei_recovery_point.m_exactMatchingFlag = ( pcSlice->getPOC() == 0 ) ? (true) : (false);
1631      sei_recovery_point.m_brokenLinkFlag    = false;
1632#if ALLOW_RECOVERY_POINT_AS_RAP
1633      if(m_pcCfg->getDecodingRefreshType() == 3)
1634      {
1635        m_iLastRecoveryPicPOC = pocCurr;
1636      }
1637#endif
1638
1639      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, pcSlice->getSPS() );
1640      writeRBSPTrailingBits(nalu.m_Bitstream);
1641      accessUnit.push_back(new NALUnitEBSP(nalu));
1642    }
1643
1644    /* use the main bitstream buffer for storing the marshalled picture */
1645    m_pcEntropyCoder->setBitstream(NULL);
1646
1647    startCUAddrSliceIdx = 0;
1648    startCUAddrSlice    = 0; 
1649
1650    startCUAddrSliceSegmentIdx = 0;
1651    startCUAddrSliceSegment    = 0; 
1652    nextCUAddr                 = 0;
1653    pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
1654
1655    Int processingState = (pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
1656    Bool skippedSlice=false;
1657    while (nextCUAddr < uiRealEndAddress) // Iterate over all slices
1658    {
1659      switch(processingState)
1660      {
1661      case ENCODE_SLICE:
1662        {
1663          pcSlice->setNextSlice       ( false );
1664          pcSlice->setNextSliceSegment( false );
1665          if (nextCUAddr == m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx])
1666          {
1667            pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
1668            if(startCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE)
1669            {
1670              pcSlice->checkColRefIdx(startCUAddrSliceIdx, pcPic);
1671            }
1672            pcPic->setCurrSliceIdx(startCUAddrSliceIdx);
1673            m_pcSliceEncoder->setSliceIdx(startCUAddrSliceIdx);
1674            assert(startCUAddrSliceIdx == pcSlice->getSliceIdx());
1675            // Reconstruction slice
1676            pcSlice->setSliceCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
1677            pcSlice->setSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx+1 ] );
1678            // Dependent slice
1679            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
1680            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
1681
1682            pcSlice->setNextSlice       ( true );
1683
1684            startCUAddrSliceIdx++;
1685            startCUAddrSliceSegmentIdx++;
1686          } 
1687          else if (nextCUAddr == m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx])
1688          {
1689            // Dependent slice
1690            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
1691            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
1692
1693            pcSlice->setNextSliceSegment( true );
1694
1695            startCUAddrSliceSegmentIdx++;
1696          }
1697
1698          pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
1699          pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
1700          UInt uiDummyStartCUAddr;
1701          UInt uiDummyBoundingCUAddr;
1702          m_pcSliceEncoder->xDetermineStartAndBoundingCUAddr(uiDummyStartCUAddr,uiDummyBoundingCUAddr,pcPic,true);
1703
1704          uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) % pcPic->getNumPartInCU();
1705          uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) / pcPic->getNumPartInCU();
1706          uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1707          uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1708          uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1709          uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1710          while(uiPosX>=uiWidth||uiPosY>=uiHeight)
1711          {
1712            uiInternalAddress--;
1713            uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1714            uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1715          }
1716          uiInternalAddress++;
1717          if(uiInternalAddress==pcPic->getNumPartInCU())
1718          {
1719            uiInternalAddress = 0;
1720            uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
1721          }
1722          UInt endAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
1723          if(endAddress<=pcSlice->getSliceSegmentCurStartCUAddr()) 
1724          {
1725            UInt boundingAddrSlice, boundingAddrSliceSegment;
1726            boundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
1727            boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
1728            nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
1729            if(pcSlice->isNextSlice())
1730            {
1731              skippedSlice=true;
1732            }
1733            continue;
1734          }
1735          if(skippedSlice) 
1736          {
1737            pcSlice->setNextSlice       ( true );
1738            pcSlice->setNextSliceSegment( false );
1739          }
1740          skippedSlice=false;
1741          pcSlice->allocSubstreamSizes( iNumSubstreams );
1742          for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
1743          {
1744            pcSubstreamsOut[ui].clear();
1745          }
1746
1747          m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1748          m_pcEntropyCoder->resetEntropy      ();
1749          /* start slice NALunit */
1750#if H_MV
1751          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), getLayerId() );
1752#else
1753          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
1754#endif
1755          Bool sliceSegment = (!pcSlice->isNextSlice());
1756          if (!sliceSegment)
1757          {
1758            uiOneBitstreamPerSliceLength = 0; // start of a new slice
1759          }
1760          m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1761
1762#if SETTING_NO_OUT_PIC_PRIOR
1763          pcSlice->setNoRaslOutputFlag(false);
1764          if (pcSlice->isIRAP())
1765          {
1766            if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
1767            {
1768              pcSlice->setNoRaslOutputFlag(true);
1769            }
1770            //the inference for NoOutputPriorPicsFlag
1771            // KJS: This cannot happen at the encoder
1772            if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag())
1773            {
1774              if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
1775              {
1776                pcSlice->setNoOutputPriorPicsFlag(true);
1777              }
1778            }
1779          }
1780#endif
1781
1782          tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
1783          m_pcEntropyCoder->encodeSliceHeader(pcSlice);
1784          actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
1785
1786          // is it needed?
1787          {
1788            if (!sliceSegment)
1789            {
1790              pcBitstreamRedirect->writeAlignOne();
1791            }
1792            else
1793            {
1794              // We've not completed our slice header info yet, do the alignment later.
1795            }
1796            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1797            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1798            m_pcEntropyCoder->resetEntropy    ();
1799            for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
1800            {
1801              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
1802              m_pcEntropyCoder->resetEntropy    ();
1803            }
1804          }
1805
1806          if(pcSlice->isNextSlice())
1807          {
1808            // set entropy coder for writing
1809            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1810            {
1811              for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
1812              {
1813                m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
1814                m_pcEntropyCoder->resetEntropy    ();
1815              }
1816              pcSbacCoders[0].load(m_pcSbacCoder);
1817              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[0], pcSlice );  //ALF is written in substream #0 with CABAC coder #0 (see ALF param encoding below)
1818            }
1819            m_pcEntropyCoder->resetEntropy    ();
1820            // File writing
1821            if (!sliceSegment)
1822            {
1823              m_pcEntropyCoder->setBitstream(pcBitstreamRedirect);
1824            }
1825            else
1826            {
1827              m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1828            }
1829            // for now, override the TILES_DECODER setting in order to write substreams.
1830            m_pcEntropyCoder->setBitstream    ( &pcSubstreamsOut[0] );
1831
1832          }
1833          pcSlice->setFinalized(true);
1834
1835          m_pcSbacCoder->load( &pcSbacCoders[0] );
1836
1837          pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength );
1838            pcSlice->setTileLocationCount ( 0 );
1839          m_pcSliceEncoder->encodeSlice(pcPic, pcSubstreamsOut);
1840
1841          {
1842            // Construct the final bitstream by flushing and concatenating substreams.
1843            // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
1844            UInt* puiSubstreamSizes = pcSlice->getSubstreamSizes();
1845            UInt uiTotalCodedSize = 0; // for padding calcs.
1846            UInt uiNumSubstreamsPerTile = iNumSubstreams;
1847            if (iNumSubstreams > 1)
1848            {
1849              uiNumSubstreamsPerTile /= pcPic->getPicSym()->getNumTiles();
1850            }
1851            for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
1852            {
1853              // Flush all substreams -- this includes empty ones.
1854              // Terminating bit and flush.
1855              m_pcEntropyCoder->setEntropyCoder   ( &pcSbacCoders[ui], pcSlice );
1856              m_pcEntropyCoder->setBitstream      (  &pcSubstreamsOut[ui] );
1857              m_pcEntropyCoder->encodeTerminatingBit( 1 );
1858              m_pcEntropyCoder->encodeSliceFinish();
1859
1860              pcSubstreamsOut[ui].writeByteAlignment();   // Byte-alignment in slice_data() at end of sub-stream
1861              // Byte alignment is necessary between tiles when tiles are independent.
1862              uiTotalCodedSize += pcSubstreamsOut[ui].getNumberOfWrittenBits();
1863
1864              Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)&& ((ui+1)%uiNumSubstreamsPerTile == 0);
1865              if (bNextSubstreamInNewTile)
1866              {
1867                pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
1868              }
1869              if (ui+1 < pcSlice->getPPS()->getNumSubstreams())
1870              {
1871                puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits() + (pcSubstreamsOut[ui].countStartCodeEmulations()<<3);
1872              }
1873            }
1874
1875            // Complete the slice header info.
1876            m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1877            m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1878            m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
1879
1880            // Substreams...
1881            TComOutputBitstream *pcOut = pcBitstreamRedirect;
1882          Int offs = 0;
1883          Int nss = pcSlice->getPPS()->getNumSubstreams();
1884          if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
1885          {
1886            // 1st line present for WPP.
1887            offs = pcSlice->getSliceSegmentCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
1888            nss  = pcSlice->getNumEntryPointOffsets()+1;
1889          }
1890          for ( UInt ui = 0 ; ui < nss; ui++ )
1891          {
1892            pcOut->addSubstream(&pcSubstreamsOut[ui+offs]);
1893            }
1894          }
1895
1896          UInt boundingAddrSlice, boundingAddrSliceSegment;
1897          boundingAddrSlice        = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
1898          boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
1899          nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
1900          // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
1901          // 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.
1902          Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
1903          xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
1904          accessUnit.push_back(new NALUnitEBSP(nalu));
1905          actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
1906          bNALUAlignedWrittenToList = true; 
1907          uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment
1908
1909          if (!bNALUAlignedWrittenToList)
1910          {
1911            {
1912              nalu.m_Bitstream.writeAlignZero();
1913            }
1914            accessUnit.push_back(new NALUnitEBSP(nalu));
1915            uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits() + 24; // length of bitstream after byte-alignment + 3 byte startcode 0x000001
1916          }
1917
1918          if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
1919              ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
1920              ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
1921             || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
1922              ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
1923          {
1924              UInt numNalus = 0;
1925            UInt numRBSPBytes = 0;
1926            for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
1927            {
1928              UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
1929              if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
1930              {
1931                numRBSPBytes += numRBSPBytes_nal;
1932                numNalus ++;
1933              }
1934            }
1935            accumBitsDU[ pcSlice->getSliceIdx() ] = ( numRBSPBytes << 3 );
1936            accumNalsDU[ pcSlice->getSliceIdx() ] = numNalus;   // SEI not counted for bit count; hence shouldn't be counted for # of NALUs - only for consistency
1937          }
1938          processingState = ENCODE_SLICE;
1939          }
1940          break;
1941        case EXECUTE_INLOOPFILTER:
1942          {
1943            // set entropy coder for RD
1944            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1945            if ( pcSlice->getSPS()->getUseSAO() )
1946            {
1947              m_pcEntropyCoder->resetEntropy();
1948              m_pcEntropyCoder->setBitstream( m_pcBitCounter );
1949            Bool sliceEnabled[NUM_SAO_COMPONENTS];
1950            m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);
1951            m_pcSAO->SAOProcess(pcPic
1952              , sliceEnabled
1953              , pcPic->getSlice(0)->getLambdas()
1954#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
1955              , m_pcCfg->getSaoLcuBoundary()
1956#endif
1957              );
1958              m_pcSAO->PCMLFDisableProcess(pcPic);
1959
1960            //assign SAO slice header
1961            for(Int s=0; s< uiNumSlices; s++)
1962            {
1963              pcPic->getSlice(s)->setSaoEnabledFlag(sliceEnabled[SAO_Y]);
1964              assert(sliceEnabled[SAO_Cb] == sliceEnabled[SAO_Cr]);
1965              pcPic->getSlice(s)->setSaoEnabledFlagChroma(sliceEnabled[SAO_Cb]);
1966              }
1967            }
1968          processingState = ENCODE_SLICE;
1969          }
1970          break;
1971        default:
1972          {
1973            printf("Not a supported encoding state\n");
1974            assert(0);
1975            exit(-1);
1976          }
1977        }
1978      } // end iteration over slices
1979#if H_3D
1980      pcPic->compressMotion(2); 
1981#endif
1982#if !H_3D
1983      pcPic->compressMotion(); 
1984#endif
1985#if H_MV
1986      m_pocLastCoded = pcPic->getPOC();
1987#endif
1988
1989      //-- For time output for each slice
1990      Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
1991
1992      const Char* digestStr = NULL;
1993      if (m_pcCfg->getDecodedPictureHashSEIEnabled())
1994      {
1995        /* calculate MD5sum for entire reconstructed picture */
1996        SEIDecodedPictureHash sei_recon_picture_digest;
1997        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
1998        {
1999          sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5;
2000          calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2001          digestStr = digestToString(sei_recon_picture_digest.digest, 16);
2002        }
2003        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
2004        {
2005          sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC;
2006          calcCRC(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2007          digestStr = digestToString(sei_recon_picture_digest.digest, 2);
2008        }
2009        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
2010        {
2011          sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM;
2012          calcChecksum(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2013          digestStr = digestToString(sei_recon_picture_digest.digest, 4);
2014        }
2015#if H_MV
2016        OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer(), getLayerId() );
2017#else
2018        OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer());
2019#endif
2020
2021        /* write the SEI messages */
2022        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2023        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, pcSlice->getSPS());
2024        writeRBSPTrailingBits(nalu.m_Bitstream);
2025
2026        accessUnit.insert(accessUnit.end(), new NALUnitEBSP(nalu));
2027      }
2028      if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
2029      {
2030        SEITemporalLevel0Index sei_temporal_level0_index;
2031        if (pcSlice->getRapPicFlag())
2032        {
2033          m_tl0Idx = 0;
2034          m_rapIdx = (m_rapIdx + 1) & 0xFF;
2035        }
2036        else
2037        {
2038          m_tl0Idx = (m_tl0Idx + (pcSlice->getTLayer() ? 0 : 1)) & 0xFF;
2039        }
2040        sei_temporal_level0_index.tl0Idx = m_tl0Idx;
2041        sei_temporal_level0_index.rapIdx = m_rapIdx;
2042
2043        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); 
2044
2045        /* write the SEI messages */
2046        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2047        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, pcSlice->getSPS());
2048        writeRBSPTrailingBits(nalu.m_Bitstream);
2049
2050        /* insert the SEI message NALUnit before any Slice NALUnits */
2051        AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
2052        accessUnit.insert(it, new NALUnitEBSP(nalu));
2053      }
2054
2055      xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime );
2056
2057    //In case of field coding, compute the interlaced PSNR for both fields
2058    if (isField && ((!pcPic->isTopField() && isTff) || (pcPic->isTopField() && !isTff)) && (pcPic->getPOC()%m_iGopSize != 1))
2059    {
2060      //get complementary top field
2061      TComPic* pcPicTop;
2062      TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
2063      while ((*iterPic)->getPOC() != pcPic->getPOC()-1)
2064      {
2065        iterPic ++;
2066      }
2067      pcPicTop = *(iterPic);
2068      xCalculateInterlacedAddPSNR(pcPicTop, pcPic, pcPicTop->getPicYuvRec(), pcPic->getPicYuvRec(), accessUnit, dEncTime );
2069    }
2070    else if (isField && pcPic->getPOC()!= 0 && (pcPic->getPOC()%m_iGopSize == 0))
2071    {
2072      //get complementary bottom field
2073      TComPic* pcPicBottom;
2074      TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
2075      while ((*iterPic)->getPOC() != pcPic->getPOC()+1)
2076      {
2077        iterPic ++;
2078      }
2079      pcPicBottom = *(iterPic);
2080      xCalculateInterlacedAddPSNR(pcPic, pcPicBottom, pcPic->getPicYuvRec(), pcPicBottom->getPicYuvRec(), accessUnit, dEncTime );
2081    }
2082   
2083      if (digestStr)
2084      {
2085        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
2086        {
2087          printf(" [MD5:%s]", digestStr);
2088        }
2089        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
2090        {
2091          printf(" [CRC:%s]", digestStr);
2092        }
2093        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
2094        {
2095          printf(" [Checksum:%s]", digestStr);
2096        }
2097      }
2098      if ( m_pcCfg->getUseRateCtrl() )
2099      {
2100        Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
2101        Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
2102        if ( avgLambda < 0.0 )
2103        {
2104          avgLambda = lambda;
2105        }
2106        m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
2107        m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
2108
2109        m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
2110        if ( pcSlice->getSliceType() != I_SLICE )
2111        {
2112          m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
2113        }
2114        else    // for intra picture, the estimated bits are used to update the current status in the GOP
2115        {
2116          m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
2117        }
2118      }
2119
2120      if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2121          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2122          ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
2123         || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
2124      {
2125        TComVUI *vui = pcSlice->getSPS()->getVuiParameters();
2126        TComHRD *hrd = vui->getHrdParameters();
2127
2128        if( hrd->getSubPicCpbParamsPresentFlag() )
2129        {
2130          Int i;
2131          UInt64 ui64Tmp;
2132          UInt uiPrev = 0;
2133          UInt numDU = ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 );
2134          UInt *pCRD = &pictureTimingSEI.m_duCpbRemovalDelayMinus1[0];
2135          UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
2136
2137          for( i = 0; i < numDU; i ++ )
2138          {
2139            pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] - 1 ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
2140          }
2141
2142          if( numDU == 1 )
2143          {
2144            pCRD[ 0 ] = 0; /* don't care */
2145          }
2146          else
2147          {
2148            pCRD[ numDU - 1 ] = 0;/* by definition */
2149            UInt tmp = 0;
2150            UInt accum = 0;
2151
2152            for( i = ( numDU - 2 ); i >= 0; i -- )
2153            {
2154              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
2155              if( (UInt)ui64Tmp > maxDiff )
2156              {
2157                tmp ++;
2158              }
2159            }
2160            uiPrev = 0;
2161
2162            UInt flag = 0;
2163            for( i = ( numDU - 2 ); i >= 0; i -- )
2164            {
2165              flag = 0;
2166              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
2167
2168              if( (UInt)ui64Tmp > maxDiff )
2169              {
2170                if(uiPrev >= maxDiff - tmp)
2171                {
2172                  ui64Tmp = uiPrev + 1;
2173                  flag = 1;
2174                }
2175                else                            ui64Tmp = maxDiff - tmp + 1;
2176              }
2177              pCRD[ i ] = (UInt)ui64Tmp - uiPrev - 1;
2178              if( (Int)pCRD[ i ] < 0 )
2179              {
2180                pCRD[ i ] = 0;
2181              }
2182              else if (tmp > 0 && flag == 1) 
2183              {
2184                tmp --;
2185              }
2186              accum += pCRD[ i ] + 1;
2187              uiPrev = accum;
2188            }
2189          }
2190        }
2191        if( m_pcCfg->getPictureTimingSEIEnabled() )
2192        {
2193          {
2194            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
2195          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2196          pictureTimingSEI.m_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0;
2197          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, pcSlice->getSPS());
2198          writeRBSPTrailingBits(nalu.m_Bitstream);
2199          UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2200          UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2201                                    + m_bufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
2202          AccessUnit::iterator it;
2203          for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2204          {
2205            it++;
2206          }
2207          accessUnit.insert(it, new NALUnitEBSP(nalu));
2208          m_pictureTimingSEIPresentInAU = true;
2209        }
2210          if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI
2211          {
2212            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
2213            m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2214            scalableNestingSEI.m_nestedSEIs.clear();
2215            scalableNestingSEI.m_nestedSEIs.push_back(&pictureTimingSEI);
2216            m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
2217            writeRBSPTrailingBits(nalu.m_Bitstream);
2218            UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2219            UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2220              + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU + m_nestedBufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
2221            AccessUnit::iterator it;
2222            for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2223            {
2224              it++;
2225            }
2226            accessUnit.insert(it, new NALUnitEBSP(nalu));
2227            m_nestedPictureTimingSEIPresentInAU = true;
2228          }
2229        }
2230        if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
2231        {             
2232          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2233          for( Int i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
2234          {
2235            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
2236
2237            SEIDecodingUnitInfo tempSEI;
2238            tempSEI.m_decodingUnitIdx = i;
2239            tempSEI.m_duSptCpbRemovalDelay = pictureTimingSEI.m_duCpbRemovalDelayMinus1[i] + 1;
2240            tempSEI.m_dpbOutputDuDelayPresentFlag = false;
2241            tempSEI.m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
2242
2243            AccessUnit::iterator it;
2244            // Insert the first one in the right location, before the first slice
2245            if(i == 0)
2246            {
2247              // Insert before the first slice.
2248              m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
2249              writeRBSPTrailingBits(nalu.m_Bitstream);
2250
2251              UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2252              UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2253                                    + m_bufferingPeriodSEIPresentInAU
2254                                    + m_pictureTimingSEIPresentInAU;  // Insert DU info SEI after APS, BP and PT SEI
2255              for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2256              {
2257                it++;
2258              }
2259              accessUnit.insert(it, new NALUnitEBSP(nalu));
2260            }
2261            else
2262            {
2263              Int ctr;
2264              // For the second decoding unit onwards we know how many NALUs are present
2265              for (ctr = 0, it = accessUnit.begin(); it != accessUnit.end(); it++)
2266              {           
2267                if(ctr == accumNalsDU[ i - 1 ])
2268                {
2269                  // Insert before the first slice.
2270                  m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
2271                  writeRBSPTrailingBits(nalu.m_Bitstream);
2272
2273                  accessUnit.insert(it, new NALUnitEBSP(nalu));
2274                  break;
2275                }
2276                if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
2277                {
2278                  ctr++;
2279                }
2280              }
2281            }           
2282          }
2283        }
2284      }
2285      xResetNonNestedSEIPresentFlags();
2286      xResetNestedSEIPresentFlags();
2287      pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
2288
2289      pcPic->setReconMark   ( true );
2290#if H_MV
2291      TComSlice::markIvRefPicsAsShortTerm( m_refPicSetInterLayer0, m_refPicSetInterLayer1 ); 
2292      std::vector<Int> temp; 
2293      TComSlice::markCurrPic( pcPic ); 
2294#endif
2295      m_bFirst = false;
2296      m_iNumPicCoded++;
2297      m_totalCoded ++;
2298      /* logging: insert a newline at end of picture period */
2299      printf("\n");
2300      fflush(stdout);
2301
2302      delete[] pcSubstreamsOut;
2303
2304#if EFFICIENT_FIELD_IRAP
2305    if(IRAPtoReorder)
2306    {
2307      if(swapIRAPForward)
2308      {
2309        if(iGOPid == IRAPGOPid)
2310        {
2311          iGOPid = IRAPGOPid +1;
2312          IRAPtoReorder = false;
2313        }
2314        else if(iGOPid == IRAPGOPid +1)
2315        {
2316          iGOPid --;
2317        }
2318      }
2319      else
2320      {
2321        if(iGOPid == IRAPGOPid)
2322        {
2323          iGOPid = IRAPGOPid -1;
2324        }
2325        else if(iGOPid == IRAPGOPid -1)
2326        {
2327          iGOPid = IRAPGOPid;
2328          IRAPtoReorder = false;
2329        }
2330      }
2331    }
2332#endif
2333  }
2334  delete pcBitstreamRedirect;
2335
2336  if( accumBitsDU != NULL) delete accumBitsDU;
2337  if( accumNalsDU != NULL) delete accumNalsDU;
2338
2339#if !H_MV
2340  assert ( (m_iNumPicCoded == iNumPicRcvd) || (isField && iPOCLast == 1) );
2341#endif
2342}
2343
2344#if !H_MV
2345Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, bool isField)
2346{
2347  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
2348 
2349   
2350  //--CFG_KDY
2351  if(isField)
2352  {
2353    m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() * 2);
2354    m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() * 2);
2355    m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() * 2);
2356    m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() * 2);
2357  }
2358  else
2359  {
2360  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() );
2361  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() );
2362  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() );
2363  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() );
2364  }
2365 
2366  //-- all
2367  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
2368  m_gcAnalyzeAll.printOut('a');
2369 
2370  printf( "\n\nI Slices--------------------------------------------------------\n" );
2371  m_gcAnalyzeI.printOut('i');
2372 
2373  printf( "\n\nP Slices--------------------------------------------------------\n" );
2374  m_gcAnalyzeP.printOut('p');
2375 
2376  printf( "\n\nB Slices--------------------------------------------------------\n" );
2377  m_gcAnalyzeB.printOut('b');
2378 
2379#if _SUMMARY_OUT_
2380  m_gcAnalyzeAll.printSummaryOut();
2381#endif
2382#if _SUMMARY_PIC_
2383  m_gcAnalyzeI.printSummary('I');
2384  m_gcAnalyzeP.printSummary('P');
2385  m_gcAnalyzeB.printSummary('B');
2386#endif
2387
2388  if(isField)
2389  {
2390    //-- interlaced summary
2391    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
2392    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
2393    m_gcAnalyzeAll_in.printOutInterlaced('a',  m_gcAnalyzeAll.getBits());
2394   
2395#if _SUMMARY_OUT_
2396    m_gcAnalyzeAll_in.printSummaryOutInterlaced();
2397#endif
2398  }
2399
2400  printf("\nRVM: %.3lf\n" , xCalculateRVM());
2401}
2402#endif
2403#if H_3D_VSO
2404Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, Dist64& ruiDist, UInt64& ruiBits )
2405#else
2406Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
2407#endif
2408{
2409  TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
2410  Bool bCalcDist = false;
2411  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
2412  m_pcLoopFilter->loopFilterPic( pcPic );
2413 
2414  m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
2415  m_pcEntropyCoder->resetEntropy    ();
2416  m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
2417  m_pcEntropyCoder->resetEntropy    ();
2418  ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
2419 
2420  if (!bCalcDist)
2421    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
2422}
2423
2424// ====================================================================================================================
2425// Protected member functions
2426// ====================================================================================================================
2427
2428
2429Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, bool isField )
2430{
2431  assert( iNumPicRcvd > 0 );
2432  //  Exception for the first frames
2433  if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField  && (iPOCLast == 0))  )
2434  {
2435    m_iGopSize    = 1;
2436  }
2437  else
2438  {
2439    m_iGopSize    = m_pcCfg->getGOPSize();
2440  }
2441  assert (m_iGopSize > 0);
2442 
2443  return;
2444}
2445
2446Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
2447                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
2448                         Int                       iNumPicRcvd,
2449                         Int                       iTimeOffset,
2450                         TComPic*&                 rpcPic,
2451                         TComPicYuv*&              rpcPicYuvRecOut,
2452                         Int                       pocCurr,
2453                         bool                      isField)
2454{
2455  Int i;
2456  //  Rec. output
2457  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
2458 
2459  if (isField)
2460  {
2461    for ( i = 0; i < ( (pocCurr == 0 ) || (pocCurr == 1 ) ? (iNumPicRcvd - iTimeOffset + 1) : (iNumPicRcvd - iTimeOffset + 2) ); i++ )
2462    {
2463      iterPicYuvRec--;
2464    }
2465  }
2466  else
2467  {
2468    for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
2469  {
2470    iterPicYuvRec--;
2471  }
2472 
2473  }
2474 
2475  if (isField)
2476  {
2477    if(pocCurr == 1)
2478    {
2479      iterPicYuvRec++;
2480    }
2481  }
2482  rpcPicYuvRecOut = *(iterPicYuvRec);
2483 
2484  //  Current pic.
2485  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
2486  while (iterPic != rcListPic.end())
2487  {
2488    rpcPic = *(iterPic);
2489    rpcPic->setCurrSliceIdx(0);
2490    if (rpcPic->getPOC() == pocCurr)
2491    {
2492      break;
2493    }
2494    iterPic++;
2495  }
2496
2497#if !H_MV
2498  assert( rpcPic != NULL );
2499#endif
2500  assert (rpcPic->getPOC() == pocCurr);
2501 
2502  return;
2503}
2504
2505#if H_3D_VSO
2506Dist64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
2507#else
2508UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
2509#endif
2510{
2511  Int     x, y;
2512  Pel*  pSrc0   = pcPic0 ->getLumaAddr();
2513  Pel*  pSrc1   = pcPic1 ->getLumaAddr();
2514  UInt  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthY-8);
2515  Int   iTemp;
2516 
2517  Int   iStride = pcPic0->getStride();
2518  Int   iWidth  = pcPic0->getWidth();
2519  Int   iHeight = pcPic0->getHeight();
2520 
2521#if H_3D_VSO
2522  Dist64  uiTotalDiff = 0;
2523#else
2524  UInt64  uiTotalDiff = 0;
2525#endif
2526 
2527  for( y = 0; y < iHeight; y++ )
2528  {
2529    for( x = 0; x < iWidth; x++ )
2530    {
2531      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2532    }
2533    pSrc0 += iStride;
2534    pSrc1 += iStride;
2535  }
2536 
2537  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthC-8);
2538  iHeight >>= 1;
2539  iWidth  >>= 1;
2540  iStride >>= 1;
2541 
2542  pSrc0  = pcPic0->getCbAddr();
2543  pSrc1  = pcPic1->getCbAddr();
2544 
2545  for( y = 0; y < iHeight; y++ )
2546  {
2547    for( x = 0; x < iWidth; x++ )
2548    {
2549      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2550    }
2551    pSrc0 += iStride;
2552    pSrc1 += iStride;
2553  }
2554 
2555  pSrc0  = pcPic0->getCrAddr();
2556  pSrc1  = pcPic1->getCrAddr();
2557 
2558  for( y = 0; y < iHeight; y++ )
2559  {
2560    for( x = 0; x < iWidth; x++ )
2561    {
2562      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
2563    }
2564    pSrc0 += iStride;
2565    pSrc1 += iStride;
2566  }
2567 
2568  return uiTotalDiff;
2569}
2570
2571#if VERBOSE_RATE
2572static const Char* nalUnitTypeToString(NalUnitType type)
2573{
2574  switch (type)
2575  {
2576    case NAL_UNIT_CODED_SLICE_TRAIL_R: return "TRAIL_R";
2577    case NAL_UNIT_CODED_SLICE_TRAIL_N: return "TRAIL_N";
2578    case NAL_UNIT_CODED_SLICE_TSA_R:      return "TSA_R";
2579    case NAL_UNIT_CODED_SLICE_TSA_N: return "TSA_N";
2580    case NAL_UNIT_CODED_SLICE_STSA_R: return "STSA_R";
2581    case NAL_UNIT_CODED_SLICE_STSA_N: return "STSA_N";
2582    case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
2583    case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
2584    case NAL_UNIT_CODED_SLICE_BLA_N_LP: return "BLA_N_LP";
2585    case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
2586    case NAL_UNIT_CODED_SLICE_IDR_N_LP: return "IDR_N_LP";
2587    case NAL_UNIT_CODED_SLICE_CRA: return "CRA";
2588    case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
2589    case NAL_UNIT_CODED_SLICE_RADL_N:     return "RADL_N";
2590    case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
2591    case NAL_UNIT_CODED_SLICE_RASL_N:     return "RASL_N";
2592    case NAL_UNIT_VPS: return "VPS";
2593    case NAL_UNIT_SPS: return "SPS";
2594    case NAL_UNIT_PPS: return "PPS";
2595    case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD";
2596    case NAL_UNIT_EOS: return "EOS";
2597    case NAL_UNIT_EOB: return "EOB";
2598    case NAL_UNIT_FILLER_DATA: return "FILLER";
2599    case NAL_UNIT_PREFIX_SEI:             return "SEI";
2600    case NAL_UNIT_SUFFIX_SEI:             return "SEI";
2601    default: return "UNK";
2602  }
2603}
2604#endif
2605
2606Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime )
2607{
2608  Int     x, y;
2609  UInt64 uiSSDY  = 0;
2610  UInt64 uiSSDU  = 0;
2611  UInt64 uiSSDV  = 0;
2612 
2613  Double  dYPSNR  = 0.0;
2614  Double  dUPSNR  = 0.0;
2615  Double  dVPSNR  = 0.0;
2616 
2617  //===== calculate PSNR =====
2618  Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
2619  Pel*  pRec    = pcPicD->getLumaAddr();
2620  Int   iStride = pcPicD->getStride();
2621 
2622  Int   iWidth;
2623  Int   iHeight;
2624 
2625  iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
2626  iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
2627 
2628  Int   iSize   = iWidth*iHeight;
2629 
2630  for( y = 0; y < iHeight; y++ )
2631  {
2632    for( x = 0; x < iWidth; x++ )
2633    {
2634      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2635      uiSSDY   += iDiff * iDiff;
2636    }
2637    pOrg += iStride;
2638    pRec += iStride;
2639  }
2640 
2641#if H_3D_VSO
2642#if H_3D_VSO_SYNTH_DIST_OUT
2643  if ( m_pcRdCost->getUseRenModel() )
2644  {
2645    unsigned int maxval = 255 * (1<<(g_uiBitDepth + g_uiBitIncrement -8));
2646    Double fRefValueY = (double) maxval * maxval * iSize;
2647    Double fRefValueC = fRefValueY / 4.0;
2648    TRenModel*  pcRenModel = m_pcEncTop->getEncTop()->getRenModel();
2649    Int64 iDistVSOY, iDistVSOU, iDistVSOV;
2650    pcRenModel->getTotalSSE( iDistVSOY, iDistVSOU, iDistVSOV );
2651    dYPSNR = ( iDistVSOY ? 10.0 * log10( fRefValueY / (Double) iDistVSOY ) : 99.99 );
2652    dUPSNR = ( iDistVSOU ? 10.0 * log10( fRefValueC / (Double) iDistVSOU ) : 99.99 );
2653    dVPSNR = ( iDistVSOV ? 10.0 * log10( fRefValueC / (Double) iDistVSOV ) : 99.99 );
2654  }
2655  else
2656  {
2657#endif
2658#endif
2659    iHeight >>= 1;
2660  iWidth  >>= 1;
2661  iStride >>= 1;
2662  pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
2663  pRec  = pcPicD->getCbAddr();
2664 
2665  for( y = 0; y < iHeight; y++ )
2666  {
2667    for( x = 0; x < iWidth; x++ )
2668    {
2669      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2670      uiSSDU   += iDiff * iDiff;
2671    }
2672    pOrg += iStride;
2673    pRec += iStride;
2674  }
2675 
2676  pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
2677  pRec  = pcPicD->getCrAddr();
2678 
2679  for( y = 0; y < iHeight; y++ )
2680  {
2681    for( x = 0; x < iWidth; x++ )
2682    {
2683      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2684      uiSSDV   += iDiff * iDiff;
2685    }
2686    pOrg += iStride;
2687    pRec += iStride;
2688  }
2689 
2690  Int maxvalY = 255 << (g_bitDepthY-8);
2691  Int maxvalC = 255 << (g_bitDepthC-8);
2692  Double fRefValueY = (Double) maxvalY * maxvalY * iSize;
2693  Double fRefValueC = (Double) maxvalC * maxvalC * iSize / 4.0;
2694  dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
2695  dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
2696  dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
2697#if H_3D_VSO
2698#if H_3D_VSO_SYNTH_DIST_OUT
2699}
2700#endif
2701#endif
2702  /* calculate the size of the access unit, excluding:
2703   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
2704   *  - SEI NAL units
2705   */
2706  UInt numRBSPBytes = 0;
2707  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2708  {
2709    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
2710#if VERBOSE_RATE
2711    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
2712#endif
2713    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
2714    {
2715      numRBSPBytes += numRBSPBytes_nal;
2716    }
2717  }
2718
2719  UInt uibits = numRBSPBytes * 8;
2720  m_vRVM_RP.push_back( uibits );
2721
2722  //===== add PSNR =====
2723#if H_MV
2724  m_pcEncTop->getAnalyzeAll()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2725#else
2726  m_gcAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2727#endif
2728  TComSlice*  pcSlice = pcPic->getSlice(0);
2729  if (pcSlice->isIntra())
2730  {
2731#if H_MV
2732    m_pcEncTop->getAnalyzeI()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2733#else
2734    m_gcAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2735#endif
2736  }
2737  if (pcSlice->isInterP())
2738  {
2739#if H_MV
2740    m_pcEncTop->getAnalyzeP()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2741#else
2742    m_gcAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2743#endif
2744  }
2745  if (pcSlice->isInterB())
2746  {
2747#if H_MV
2748    m_pcEncTop->getAnalyzeB()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2749#else
2750    m_gcAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2751#endif
2752  }
2753
2754  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
2755  if (!pcSlice->isReferenced()) c += 32;
2756
2757#if ADAPTIVE_QP_SELECTION
2758#if H_MV
2759  printf("Layer %3d   POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d  bits",
2760    pcSlice->getLayerId(),
2761    pcSlice->getPOC(),
2762    pcSlice->getTLayer(),
2763    c,
2764    pcSlice->getSliceQpBase(),
2765    pcSlice->getSliceQp(),
2766    uibits );
2767#else
2768  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
2769         pcSlice->getPOC(),
2770         pcSlice->getTLayer(),
2771         c,
2772         pcSlice->getSliceQpBase(),
2773         pcSlice->getSliceQp(),
2774         uibits );
2775#endif
2776#else
2777#if H_MV
2778  printf("Layer %3d   POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
2779    pcSlice->getLayerId(),
2780    pcSlice->getPOC()-pcSlice->getLastIDR(),
2781    pcSlice->getTLayer(),
2782    c,
2783    pcSlice->getSliceQp(),
2784    uibits );
2785#else
2786  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
2787         pcSlice->getPOC()-pcSlice->getLastIDR(),
2788         pcSlice->getTLayer(),
2789         c,
2790         pcSlice->getSliceQp(),
2791         uibits );
2792#endif
2793#endif
2794
2795  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dYPSNR, dUPSNR, dVPSNR );
2796  printf(" [ET %5.0f ]", dEncTime );
2797 
2798  for (Int iRefList = 0; iRefList < 2; iRefList++)
2799  {
2800    printf(" [L%d ", iRefList);
2801    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
2802    {
2803#if H_MV
2804      if( pcSlice->getLayerId() != pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) )
2805      {
2806        printf( "V%d ", pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) );
2807      }
2808      else
2809      {
2810#endif
2811      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
2812#if H_MV
2813      }
2814#endif
2815    }
2816    printf("]");
2817  }
2818}
2819
2820
2821Void reinterlace(Pel* top, Pel* bottom, Pel* dst, UInt stride, UInt width, UInt height, bool isTff)
2822{
2823 
2824  for (Int y = 0; y < height; y++)
2825  {
2826    for (Int x = 0; x < width; x++)
2827    {
2828      dst[x] = isTff ? top[x] : bottom[x];
2829      dst[stride+x] = isTff ? bottom[x] : top[x];
2830    }
2831    top += stride;
2832    bottom += stride;
2833    dst += stride*2;
2834  }
2835}
2836
2837
2838Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgTop, TComPic* pcPicOrgBottom, TComPicYuv* pcPicRecTop, TComPicYuv* pcPicRecBottom, const AccessUnit& accessUnit, Double dEncTime )
2839{
2840#if  H_MV
2841  assert( 0 ); // Field coding and MV need to be aligned.
2842#else
2843  Int     x, y;
2844 
2845  UInt64 uiSSDY_in  = 0;
2846  UInt64 uiSSDU_in  = 0;
2847  UInt64 uiSSDV_in  = 0;
2848 
2849  Double  dYPSNR_in  = 0.0;
2850  Double  dUPSNR_in  = 0.0;
2851  Double  dVPSNR_in  = 0.0;
2852 
2853  /*------ INTERLACED PSNR -----------*/
2854 
2855  /* Luma */
2856 
2857  Pel*  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getLumaAddr();
2858  Pel*  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getLumaAddr();
2859  Pel*  pRecTop = pcPicRecTop->getLumaAddr();
2860  Pel*  pRecBottom = pcPicRecBottom->getLumaAddr();
2861 
2862  Int   iWidth;
2863  Int   iHeight;
2864  Int iStride;
2865 
2866  iWidth  = pcPicOrgTop->getPicYuvOrg()->getWidth () - m_pcEncTop->getPad(0);
2867  iHeight = pcPicOrgTop->getPicYuvOrg()->getHeight() - m_pcEncTop->getPad(1);
2868  iStride = pcPicOrgTop->getPicYuvOrg()->getStride();
2869  Int   iSize   = iWidth*iHeight;
2870  bool isTff = pcPicOrgTop->isTopField();
2871 
2872  TComPicYuv* pcOrgInterlaced = new TComPicYuv;
2873  pcOrgInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
2874 
2875  TComPicYuv* pcRecInterlaced = new TComPicYuv;
2876  pcRecInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
2877 
2878  Pel* pOrgInterlaced = pcOrgInterlaced->getLumaAddr();
2879  Pel* pRecInterlaced = pcRecInterlaced->getLumaAddr();
2880 
2881  //=== Interlace fields ====
2882  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
2883  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
2884 
2885  //===== calculate PSNR =====
2886  for( y = 0; y < iHeight << 1; y++ )
2887  {
2888    for( x = 0; x < iWidth; x++ )
2889    {
2890      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
2891      uiSSDY_in   += iDiff * iDiff;
2892    }
2893    pOrgInterlaced += iStride;
2894    pRecInterlaced += iStride;
2895  }
2896 
2897  /*Chroma*/
2898 
2899  iHeight >>= 1;
2900  iWidth  >>= 1;
2901  iStride >>= 1;
2902 
2903  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCbAddr();
2904  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCbAddr();
2905  pRecTop = pcPicRecTop->getCbAddr();
2906  pRecBottom = pcPicRecBottom->getCbAddr();
2907  pOrgInterlaced = pcOrgInterlaced->getCbAddr();
2908  pRecInterlaced = pcRecInterlaced->getCbAddr();
2909 
2910  //=== Interlace fields ====
2911  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
2912  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
2913 
2914  //===== calculate PSNR =====
2915  for( y = 0; y < iHeight << 1; y++ )
2916  {
2917    for( x = 0; x < iWidth; x++ )
2918    {
2919      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
2920      uiSSDU_in   += iDiff * iDiff;
2921    }
2922    pOrgInterlaced += iStride;
2923    pRecInterlaced += iStride;
2924  }
2925 
2926  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCrAddr();
2927  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCrAddr();
2928  pRecTop = pcPicRecTop->getCrAddr();
2929  pRecBottom = pcPicRecBottom->getCrAddr();
2930  pOrgInterlaced = pcOrgInterlaced->getCrAddr();
2931  pRecInterlaced = pcRecInterlaced->getCrAddr();
2932 
2933  //=== Interlace fields ====
2934  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
2935  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
2936 
2937  //===== calculate PSNR =====
2938  for( y = 0; y < iHeight << 1; y++ )
2939  {
2940    for( x = 0; x < iWidth; x++ )
2941    {
2942      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
2943      uiSSDV_in   += iDiff * iDiff;
2944    }
2945    pOrgInterlaced += iStride;
2946    pRecInterlaced += iStride;
2947  }
2948 
2949  Int maxvalY = 255 << (g_bitDepthY-8);
2950  Int maxvalC = 255 << (g_bitDepthC-8);
2951  Double fRefValueY = (Double) maxvalY * maxvalY * iSize*2;
2952  Double fRefValueC = (Double) maxvalC * maxvalC * iSize*2 / 4.0;
2953  dYPSNR_in            = ( uiSSDY_in ? 10.0 * log10( fRefValueY / (Double)uiSSDY_in ) : 99.99 );
2954  dUPSNR_in            = ( uiSSDU_in ? 10.0 * log10( fRefValueC / (Double)uiSSDU_in ) : 99.99 );
2955  dVPSNR_in            = ( uiSSDV_in ? 10.0 * log10( fRefValueC / (Double)uiSSDV_in ) : 99.99 );
2956 
2957  /* calculate the size of the access unit, excluding:
2958   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
2959   *  - SEI NAL units
2960   */
2961  UInt numRBSPBytes = 0;
2962  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2963  {
2964    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
2965   
2966    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
2967      numRBSPBytes += numRBSPBytes_nal;
2968  }
2969 
2970  UInt uibits = numRBSPBytes * 8 ;
2971 
2972  //===== add PSNR =====
2973  m_gcAnalyzeAll_in.addResult (dYPSNR_in, dUPSNR_in, dVPSNR_in, (Double)uibits);
2974 
2975  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 );
2976 
2977  pcOrgInterlaced->destroy();
2978  delete pcOrgInterlaced;
2979  pcRecInterlaced->destroy();
2980  delete pcRecInterlaced;
2981#endif
2982}
2983/** Function for deciding the nal_unit_type.
2984 * \param pocCurr POC of the current picture
2985 * \returns the nal unit type of the picture
2986 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
2987 */
2988NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR, Bool isField)
2989{
2990  if (pocCurr == 0)
2991  {
2992    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
2993  }
2994#if EFFICIENT_FIELD_IRAP
2995  if(isField && pocCurr == 1)
2996  {
2997    // to avoid the picture becoming an IRAP
2998    return NAL_UNIT_CODED_SLICE_TRAIL_R;
2999  }
3000#endif
3001
3002#if ALLOW_RECOVERY_POINT_AS_RAP
3003  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3004#else
3005  if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3006#endif
3007  {
3008    if (m_pcCfg->getDecodingRefreshType() == 1)
3009    {
3010      return NAL_UNIT_CODED_SLICE_CRA;
3011    }
3012    else if (m_pcCfg->getDecodingRefreshType() == 2)
3013    {
3014      return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3015    }
3016  }
3017  if(m_pocCRA>0)
3018  {
3019    if(pocCurr<m_pocCRA)
3020    {
3021      // All leading pictures are being marked as TFD pictures here since current encoder uses all
3022      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
3023      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
3024      // controlling the reference pictures used for encoding that leading picture. Such a leading
3025      // picture need not be marked as a TFD picture.
3026      return NAL_UNIT_CODED_SLICE_RASL_R;
3027    }
3028  }
3029  if (lastIDR>0)
3030  {
3031    if (pocCurr < lastIDR)
3032    {
3033      return NAL_UNIT_CODED_SLICE_RADL_R;
3034    }
3035  }
3036  return NAL_UNIT_CODED_SLICE_TRAIL_R;
3037}
3038
3039Double TEncGOP::xCalculateRVM()
3040{
3041  Double dRVM = 0;
3042 
3043  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
3044  {
3045    // calculate RVM only for lowdelay configurations
3046    std::vector<Double> vRL , vB;
3047    size_t N = m_vRVM_RP.size();
3048    vRL.resize( N );
3049    vB.resize( N );
3050   
3051    Int i;
3052    Double dRavg = 0 , dBavg = 0;
3053    vB[RVM_VCEGAM10_M] = 0;
3054    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3055    {
3056      vRL[i] = 0;
3057      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
3058        vRL[i] += m_vRVM_RP[j];
3059      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
3060      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
3061      dRavg += m_vRVM_RP[i];
3062      dBavg += vB[i];
3063    }
3064   
3065    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
3066    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
3067   
3068    Double dSigamB = 0;
3069    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3070    {
3071      Double tmp = vB[i] - dBavg;
3072      dSigamB += tmp * tmp;
3073    }
3074    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
3075   
3076    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
3077   
3078    dRVM = dSigamB / dRavg * f;
3079  }
3080 
3081  return( dRVM );
3082}
3083
3084/** Attaches the input bitstream to the stream in the output NAL unit
3085    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
3086 *  \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu
3087 *  \param rNalu          target NAL unit
3088 */
3089Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream*& codedSliceData)
3090{
3091  // Byte-align
3092  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
3093
3094  // Perform bitstream concatenation
3095  if (codedSliceData->getNumberOfWrittenBits() > 0)
3096    {
3097    rNalu.m_Bitstream.addSubstream(codedSliceData);
3098  }
3099
3100  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
3101
3102  codedSliceData->clear();
3103}
3104
3105// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
3106// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
3107Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
3108{
3109  TComReferencePictureSet *rps = pcSlice->getRPS();
3110  if(!rps->getNumberOfLongtermPictures())
3111  {
3112    return;
3113  }
3114
3115  // Arrange long-term reference pictures in the correct order of LSB and MSB,
3116  // and assign values for pocLSBLT and MSB present flag
3117  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
3118  Int longtermPicsMSB[MAX_NUM_REF_PICS];
3119  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
3120  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
3121  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
3122  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
3123  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
3124  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
3125
3126  // Get the long-term reference pictures
3127  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
3128  Int i, ctr = 0;
3129  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
3130  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3131  {
3132    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
3133    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
3134    indices[ctr]      = i; 
3135    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
3136  }
3137  Int numLongPics = rps->getNumberOfLongtermPictures();
3138  assert(ctr == numLongPics);
3139
3140  // Arrange pictures in decreasing order of MSB;
3141  for(i = 0; i < numLongPics; i++)
3142  {
3143    for(Int j = 0; j < numLongPics - 1; j++)
3144    {
3145      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
3146      {
3147        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
3148        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
3149        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
3150        std::swap(indices[j]        , indices[j+1]        );
3151      }
3152    }
3153  }
3154
3155  for(i = 0; i < numLongPics; i++)
3156  {
3157    // Check if MSB present flag should be enabled.
3158    // Check if the buffer contains any pictures that have the same LSB.
3159    TComList<TComPic*>::iterator  iterPic = rcListPic.begin(); 
3160    TComPic*                      pcPic;
3161    while ( iterPic != rcListPic.end() )
3162    {
3163      pcPic = *iterPic;
3164      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
3165                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
3166                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
3167      {
3168        mSBPresentFlag[i] = true;
3169        break;
3170      }
3171      iterPic++;     
3172    }
3173  }
3174
3175  // tempArray for usedByCurr flag
3176  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
3177  for(i = 0; i < numLongPics; i++)
3178  {
3179    tempArray[i] = rps->getUsed(indices[i]);
3180  }
3181  // Now write the final values;
3182  ctr = 0;
3183  Int currMSB = 0, currLSB = 0;
3184  // currPicPoc = currMSB + currLSB
3185  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB); 
3186  currMSB = pcSlice->getPOC() - currLSB;
3187
3188  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3189  {
3190    rps->setPOC                   (i, longtermPicsPoc[ctr]);
3191    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
3192    rps->setUsed                  (i, tempArray[ctr]);
3193    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
3194    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
3195    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);     
3196
3197    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
3198  }
3199  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
3200  {
3201    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
3202    {
3203      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
3204      // don't have to check the MSB present flag values for this constraint.
3205      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
3206    }
3207  }
3208}
3209
3210/** Function for finding the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
3211 * \param accessUnit Access Unit of the current picture
3212 * This function finds the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
3213 */
3214Int TEncGOP::xGetFirstSeiLocation(AccessUnit &accessUnit)
3215{
3216  // Find the location of the first SEI message
3217  AccessUnit::iterator it;
3218  Int seiStartPos = 0;
3219  for(it = accessUnit.begin(); it != accessUnit.end(); it++, seiStartPos++)
3220  {
3221     if ((*it)->isSei() || (*it)->isVcl())
3222     {
3223       break;
3224     }               
3225  }
3226//  assert(it != accessUnit.end());  // Triggers with some legit configurations
3227  return seiStartPos;
3228}
3229
3230Void TEncGOP::dblMetric( TComPic* pcPic, UInt uiNumSlices )
3231{
3232  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
3233  Pel* Rec    = pcPicYuvRec->getLumaAddr( 0 );
3234  Pel* tempRec = Rec;
3235  Int  stride = pcPicYuvRec->getStride();
3236  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
3237  UInt maxTBsize = (1<<log2maxTB);
3238  const UInt minBlockArtSize = 8;
3239  const UInt picWidth = pcPicYuvRec->getWidth();
3240  const UInt picHeight = pcPicYuvRec->getHeight();
3241  const UInt noCol = (picWidth>>log2maxTB);
3242  const UInt noRows = (picHeight>>log2maxTB);
3243  assert(noCol > 1);
3244  assert(noRows > 1);
3245  UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64));
3246  UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64));
3247  UInt colIdx = 0;
3248  UInt rowIdx = 0;
3249  Pel p0, p1, p2, q0, q1, q2;
3250 
3251  Int qp = pcPic->getSlice(0)->getSliceQp();
3252  Int bitdepthScale = 1 << (g_bitDepthY-8);
3253  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
3254  const Int thr2 = (beta>>2);
3255  const Int thr1 = 2*bitdepthScale;
3256  UInt a = 0;
3257 
3258  memset(colSAD, 0, noCol*sizeof(UInt64));
3259  memset(rowSAD, 0, noRows*sizeof(UInt64));
3260 
3261  if (maxTBsize > minBlockArtSize)
3262  {
3263    // Analyze vertical artifact edges
3264    for(Int c = maxTBsize; c < picWidth; c += maxTBsize)
3265    {
3266      for(Int r = 0; r < picHeight; r++)
3267      {
3268        p2 = Rec[c-3];
3269        p1 = Rec[c-2];
3270        p0 = Rec[c-1];
3271        q0 = Rec[c];
3272        q1 = Rec[c+1];
3273        q2 = Rec[c+2];
3274        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3275        if ( thr1 < a && a < thr2)
3276        {
3277          colSAD[colIdx] += abs(p0 - q0);
3278        }
3279        Rec += stride;
3280      }
3281      colIdx++;
3282      Rec = tempRec;
3283    }
3284   
3285    // Analyze horizontal artifact edges
3286    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
3287    {
3288      for(Int c = 0; c < picWidth; c++)
3289      {
3290        p2 = Rec[c + (r-3)*stride];
3291        p1 = Rec[c + (r-2)*stride];
3292        p0 = Rec[c + (r-1)*stride];
3293        q0 = Rec[c + r*stride];
3294        q1 = Rec[c + (r+1)*stride];
3295        q2 = Rec[c + (r+2)*stride];
3296        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3297        if (thr1 < a && a < thr2)
3298        {
3299          rowSAD[rowIdx] += abs(p0 - q0);
3300        }
3301      }
3302      rowIdx++;
3303    }
3304  }
3305 
3306  UInt64 colSADsum = 0;
3307  UInt64 rowSADsum = 0;
3308  for(Int c = 0; c < noCol-1; c++)
3309  {
3310    colSADsum += colSAD[c];
3311  }
3312  for(Int r = 0; r < noRows-1; r++)
3313  {
3314    rowSADsum += rowSAD[r];
3315  }
3316 
3317  colSADsum <<= 10;
3318  rowSADsum <<= 10;
3319  colSADsum /= (noCol-1);
3320  colSADsum /= picHeight;
3321  rowSADsum /= (noRows-1);
3322  rowSADsum /= picWidth;
3323 
3324  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
3325  avgSAD >>= (g_bitDepthY-8);
3326 
3327  if ( avgSAD > 2048 )
3328  {
3329    avgSAD >>= 9;
3330    Int offset = Clip3(2,6,(Int)avgSAD);
3331    for (Int i=0; i<uiNumSlices; i++)
3332    {
3333      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
3334      pcPic->getSlice(i)->setDeblockingFilterDisable(false);
3335      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset );
3336      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset );
3337    }
3338  }
3339  else
3340  {
3341    for (Int i=0; i<uiNumSlices; i++)
3342    {
3343      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
3344      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
3345      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
3346      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
3347    }
3348  }
3349 
3350  free(colSAD);
3351  free(rowSAD);
3352}
3353
3354#if H_MV
3355Void TEncGOP::xSetRefPicListModificationsMv( std::vector<TComPic*> tempPicLists[2], TComSlice* pcSlice, UInt iGOPid )
3356{ 
3357 
3358  if( pcSlice->getSliceType() == I_SLICE || !(pcSlice->getPPS()->getListsModificationPresentFlag()) || pcSlice->getNumActiveRefLayerPics() == 0 )
3359  {
3360    return;
3361  }
3362 
3363  GOPEntry ge = m_pcCfg->getGOPEntry( (pcSlice->getRapPicFlag() && ( pcSlice->getLayerId( ) > 0) ) ? MAX_GOP : iGOPid );
3364  assert( ge.m_numActiveRefLayerPics == pcSlice->getNumActiveRefLayerPics() ); 
3365
3366  Int numPicsInTempList     = pcSlice->getNumRpsCurrTempList(); 
3367
3368  // GT: check if SliceType should be checked here.
3369  for (Int li = 0; li < 2; li ++) // Loop over lists L0 and L1
3370  {
3371    Int numPicsInFinalRefList = pcSlice->getNumRefIdx( ( li == 0 ) ? REF_PIC_LIST_0 : REF_PIC_LIST_1 ); 
3372           
3373    Int finalIdxToTempIdxMap[16];
3374    for( Int k = 0; k < 16; k++ )
3375    {
3376      finalIdxToTempIdxMap[ k ] = -1;
3377    }
3378
3379    Bool isModified = false;
3380    if ( numPicsInTempList > 1 )
3381    {
3382      for( Int k = 0; k < pcSlice->getNumActiveRefLayerPics(); k++ )
3383      {
3384        // get position in temp. list
3385        Int refPicLayerId = pcSlice->getRefPicLayerId(k);
3386        Int idxInTempList = 0; 
3387        for (; idxInTempList < numPicsInTempList; idxInTempList++)
3388        {
3389          if ( (tempPicLists[li][idxInTempList])->getLayerId() == refPicLayerId )
3390          {
3391            break; 
3392          }
3393        }
3394
3395        Int idxInFinalList = ge.m_interViewRefPosL[ li ][ k ];
3396       
3397        // Add negative from behind
3398        idxInFinalList = ( idxInFinalList < 0 )? ( numPicsInTempList + idxInFinalList ) : idxInFinalList; 
3399       
3400        Bool curIsModified = ( idxInFinalList != idxInTempList ) && ( ( idxInTempList < numPicsInFinalRefList ) || ( idxInFinalList < numPicsInFinalRefList ) ) ;
3401        if ( curIsModified )
3402        {
3403          isModified = true; 
3404          assert( finalIdxToTempIdxMap[ idxInFinalList ] == -1 ); // Assert when two inter layer reference pictures are sorted to the same position
3405        }
3406        finalIdxToTempIdxMap[ idxInFinalList ] = idxInTempList;             
3407      }
3408    }
3409
3410    TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
3411    refPicListModification->setRefPicListModificationFlagL( li, isModified ); 
3412
3413    if( isModified )
3414    {
3415      Int refIdx = 0;
3416     
3417      for( Int i = 0; i < numPicsInFinalRefList; i++ )
3418      {
3419        if( finalIdxToTempIdxMap[i] >= 0 ) 
3420        {
3421          refPicListModification->setRefPicSetIdxL( li, i, finalIdxToTempIdxMap[i] );
3422        }
3423        else
3424        {
3425          ///* Fill gaps with temporal references *///
3426          // Forward inter layer reference pictures
3427          while( ( refIdx < numPicsInTempList ) && ( tempPicLists[li][refIdx]->getLayerId() != getLayerId())  )
3428          {
3429            refIdx++; 
3430          }
3431          refPicListModification->setRefPicSetIdxL( li, i, refIdx );
3432          refIdx++;
3433        }
3434      }
3435    }
3436  }
3437}
3438#endif
3439//! \}
Note: See TracBrowser for help on using the repository browser.