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

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

Minor clean ups.

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