source: 3DVCSoftware/branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncGOP.cpp @ 465

Last change on this file since 465 was 465, checked in by tech, 12 years ago

Fixed some minor memory leaks.

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