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

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

Macro removal part 2.

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