source: 3DVCSoftware/branches/HTM-8.2-dev0-Cleanup/source/Lib/TLibEncoder/TEncGOP.cpp @ 648

Last change on this file since 648 was 648, checked in by tech, 11 years ago

Macro removal part H_MV5.

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