Changeset 1313 in 3DVCSoftware for trunk/source/Lib/TLibEncoder/TEncGOP.cpp


Ignore:
Timestamp:
13 Aug 2015, 17:38:13 (9 years ago)
Author:
tech
Message:

Merged 14.1-update-dev1@1312.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/Lib/TLibEncoder/TEncGOP.cpp

    r1196 r1313  
    22 * License, included below. This software may be subject to other third party
    33 * and contributor rights, including patent rights, and no such rights are
    4  * granted under this license. 
     4 * granted under this license.
    55 *
    6 * Copyright (c) 2010-2015, ITU/ISO/IEC
     6 * Copyright (c) 2010-2015, ITU/ISO/IEC
    77 * All rights reserved.
    88 *
     
    5050#include <math.h>
    5151
     52#include <deque>
    5253using namespace std;
     54
    5355//! \ingroup TLibEncoder
    5456//! \{
     
    7577  m_iNumPicCoded        = 0; //Niko
    7678  m_bFirst              = true;
    77 #if ALLOW_RECOVERY_POINT_AS_RAP
    7879  m_iLastRecoveryPicPOC = 0;
    79 #endif
    80  
     80
    8181  m_pcCfg               = NULL;
    8282  m_pcSliceEncoder      = NULL;
    8383  m_pcListPic           = NULL;
    84  
     84
    8585  m_pcEntropyCoder      = NULL;
    8686  m_pcCavlcCoder        = NULL;
    8787  m_pcSbacCoder         = NULL;
    8888  m_pcBinCABAC          = NULL;
    89  
     89
    9090  m_bSeqFirst           = true;
    91  
     91
    9292  m_bRefreshPending     = 0;
    9393  m_pocCRA            = 0;
     
    9595  ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps));
    9696  ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag));
    97   m_cpbRemovalDelay   = 0;
    9897  m_lastBPSEI         = 0;
    99   xResetNonNestedSEIPresentFlags();
    100   xResetNestedSEIPresentFlags();
    101 #if H_MV
     98  m_bufferingPeriodSEIPresentInAU = false;
     99#if NH_MV
    102100  m_layerId      = 0;
    103101  m_viewId       = 0;
    104102  m_pocLastCoded = -1;
    105 #if H_3D
     103#if NH_3D
    106104  m_viewIndex  =   0;
    107105  m_isDepth = false;
    108106#endif
    109107#endif
    110 #if FIX1172
    111108  m_associatedIRAPType = NAL_UNIT_CODED_SLICE_IDR_N_LP;
    112109  m_associatedIRAPPOC  = 0;
    113 #endif
    114110  return;
    115111}
     
    119115}
    120116
    121 /** Create list to contain pointers to LCU start addresses of slice.
     117/** Create list to contain pointers to CTU start addresses of slice.
    122118 */
    123119Void  TEncGOP::create()
     
    135131  m_pcEncTop     = pcTEncTop;
    136132  m_pcCfg                = pcTEncTop;
     133  m_seiEncoder.init(m_pcCfg, pcTEncTop, this);
    137134  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
    138135  m_pcListPic            = pcTEncTop->getListPic();
    139  
     136
    140137  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
    141138  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
     
    143140  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
    144141  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
    145   m_pcBitCounter         = pcTEncTop->getBitCounter();
    146  
    147   //--Adaptive Loop filter
     142
    148143  m_pcSAO                = pcTEncTop->getSAO();
    149144  m_pcRateCtrl           = pcTEncTop->getRateCtrl();
     
    151146  m_totalCoded         = 0;
    152147
    153 #if H_MV
     148#if NH_MV
    154149  m_ivPicLists           = pcTEncTop->getIvPicLists();
    155150  m_layerId              = pcTEncTop->getLayerId();
    156151  m_viewId               = pcTEncTop->getViewId();
    157 #if H_3D
     152#if NH_3D
    158153  m_viewIndex            = pcTEncTop->getViewIndex();
    159154  m_isDepth              = pcTEncTop->getIsDepth();
    160155#endif
    161156#endif
    162 #if H_3D_IC
     157#if NH_3D_IC
    163158  m_aICEnableCandidate   = pcTEncTop->getICEnableCandidate();
    164159  m_aICEnableNum         = pcTEncTop->getICEnableNum();
     
    169164}
    170165
    171 SEIActiveParameterSets* TEncGOP::xCreateSEIActiveParameterSets (TComSPS *sps)
    172 {
    173   SEIActiveParameterSets *seiActiveParameterSets = new SEIActiveParameterSets();
    174   seiActiveParameterSets->activeVPSId = m_pcCfg->getVPS()->getVPSId();
    175   seiActiveParameterSets->m_selfContainedCvsFlag = false;
    176   seiActiveParameterSets->m_noParameterSetUpdateFlag = false;
    177   seiActiveParameterSets->numSpsIdsMinus1 = 0;
    178   seiActiveParameterSets->activeSeqParameterSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1);
    179   seiActiveParameterSets->activeSeqParameterSetId[0] = sps->getSPSId();
    180   return seiActiveParameterSets;
    181 }
    182 
    183 SEIFramePacking* TEncGOP::xCreateSEIFramePacking()
    184 {
    185   SEIFramePacking *seiFramePacking = new SEIFramePacking();
    186   seiFramePacking->m_arrangementId = m_pcCfg->getFramePackingArrangementSEIId();
    187   seiFramePacking->m_arrangementCancelFlag = 0;
    188   seiFramePacking->m_arrangementType = m_pcCfg->getFramePackingArrangementSEIType();
    189   assert((seiFramePacking->m_arrangementType > 2) && (seiFramePacking->m_arrangementType < 6) );
    190   seiFramePacking->m_quincunxSamplingFlag = m_pcCfg->getFramePackingArrangementSEIQuincunx();
    191   seiFramePacking->m_contentInterpretationType = m_pcCfg->getFramePackingArrangementSEIInterpretation();
    192   seiFramePacking->m_spatialFlippingFlag = 0;
    193   seiFramePacking->m_frame0FlippedFlag = 0;
    194   seiFramePacking->m_fieldViewsFlag = (seiFramePacking->m_arrangementType == 2);
    195   seiFramePacking->m_currentFrameIsFrame0Flag = ((seiFramePacking->m_arrangementType == 5) && m_iNumPicCoded&1);
    196   seiFramePacking->m_frame0SelfContainedFlag = 0;
    197   seiFramePacking->m_frame1SelfContainedFlag = 0;
    198   seiFramePacking->m_frame0GridPositionX = 0;
    199   seiFramePacking->m_frame0GridPositionY = 0;
    200   seiFramePacking->m_frame1GridPositionX = 0;
    201   seiFramePacking->m_frame1GridPositionY = 0;
    202   seiFramePacking->m_arrangementReservedByte = 0;
    203   seiFramePacking->m_arrangementPersistenceFlag = true;
    204   seiFramePacking->m_upsampledAspectRatio = 0;
    205   return seiFramePacking;
    206 }
    207 
    208 SEIDisplayOrientation* TEncGOP::xCreateSEIDisplayOrientation()
    209 {
    210   SEIDisplayOrientation *seiDisplayOrientation = new SEIDisplayOrientation();
    211   seiDisplayOrientation->cancelFlag = false;
    212   seiDisplayOrientation->horFlip = false;
    213   seiDisplayOrientation->verFlip = false;
    214   seiDisplayOrientation->anticlockwiseRotation = m_pcCfg->getDisplayOrientationSEIAngle();
    215   return seiDisplayOrientation;
    216 }
    217 
    218 SEIToneMappingInfo*  TEncGOP::xCreateSEIToneMappingInfo()
    219 {
    220   SEIToneMappingInfo *seiToneMappingInfo = new SEIToneMappingInfo();
    221   seiToneMappingInfo->m_toneMapId = m_pcCfg->getTMISEIToneMapId();
    222   seiToneMappingInfo->m_toneMapCancelFlag = m_pcCfg->getTMISEIToneMapCancelFlag();
    223   seiToneMappingInfo->m_toneMapPersistenceFlag = m_pcCfg->getTMISEIToneMapPersistenceFlag();
    224 
    225   seiToneMappingInfo->m_codedDataBitDepth = m_pcCfg->getTMISEICodedDataBitDepth();
    226   assert(seiToneMappingInfo->m_codedDataBitDepth >= 8 && seiToneMappingInfo->m_codedDataBitDepth <= 14);
    227   seiToneMappingInfo->m_targetBitDepth = m_pcCfg->getTMISEITargetBitDepth();
    228   assert( seiToneMappingInfo->m_targetBitDepth >= 1 && seiToneMappingInfo->m_targetBitDepth <= 17 );
    229   seiToneMappingInfo->m_modelId = m_pcCfg->getTMISEIModelID();
    230   assert(seiToneMappingInfo->m_modelId >=0 &&seiToneMappingInfo->m_modelId<=4);
    231 
    232   switch( seiToneMappingInfo->m_modelId)
    233   {
    234   case 0:
    235     {
    236       seiToneMappingInfo->m_minValue = m_pcCfg->getTMISEIMinValue();
    237       seiToneMappingInfo->m_maxValue = m_pcCfg->getTMISEIMaxValue();
    238       break;
    239     }
    240   case 1:
    241     {
    242       seiToneMappingInfo->m_sigmoidMidpoint = m_pcCfg->getTMISEISigmoidMidpoint();
    243       seiToneMappingInfo->m_sigmoidWidth = m_pcCfg->getTMISEISigmoidWidth();
    244       break;
    245     }
    246   case 2:
    247     {
    248       UInt num = 1u<<(seiToneMappingInfo->m_targetBitDepth);
    249       seiToneMappingInfo->m_startOfCodedInterval.resize(num);
    250       Int* ptmp = m_pcCfg->getTMISEIStartOfCodedInterva();
    251       if(ptmp)
    252       {
    253         for(int i=0; i<num;i++)
    254         {
    255           seiToneMappingInfo->m_startOfCodedInterval[i] = ptmp[i];
    256         }
    257       }
    258       break;
    259     }
    260   case 3:
    261     {
    262       seiToneMappingInfo->m_numPivots = m_pcCfg->getTMISEINumPivots();
    263       seiToneMappingInfo->m_codedPivotValue.resize(seiToneMappingInfo->m_numPivots);
    264       seiToneMappingInfo->m_targetPivotValue.resize(seiToneMappingInfo->m_numPivots);
    265       Int* ptmpcoded = m_pcCfg->getTMISEICodedPivotValue();
    266       Int* ptmptarget = m_pcCfg->getTMISEITargetPivotValue();
    267       if(ptmpcoded&&ptmptarget)
    268       {
    269         for(int i=0; i<(seiToneMappingInfo->m_numPivots);i++)
    270         {
    271           seiToneMappingInfo->m_codedPivotValue[i]=ptmpcoded[i];
    272           seiToneMappingInfo->m_targetPivotValue[i]=ptmptarget[i];
    273          }
    274        }
    275        break;
    276      }
    277   case 4:
    278      {
    279        seiToneMappingInfo->m_cameraIsoSpeedIdc = m_pcCfg->getTMISEICameraIsoSpeedIdc();
    280        seiToneMappingInfo->m_cameraIsoSpeedValue = m_pcCfg->getTMISEICameraIsoSpeedValue();
    281        assert( seiToneMappingInfo->m_cameraIsoSpeedValue !=0 );
    282        seiToneMappingInfo->m_exposureIndexIdc = m_pcCfg->getTMISEIExposurIndexIdc();
    283        seiToneMappingInfo->m_exposureIndexValue = m_pcCfg->getTMISEIExposurIndexValue();
    284        assert( seiToneMappingInfo->m_exposureIndexValue !=0 );
    285        seiToneMappingInfo->m_exposureCompensationValueSignFlag = m_pcCfg->getTMISEIExposureCompensationValueSignFlag();
    286        seiToneMappingInfo->m_exposureCompensationValueNumerator = m_pcCfg->getTMISEIExposureCompensationValueNumerator();
    287        seiToneMappingInfo->m_exposureCompensationValueDenomIdc = m_pcCfg->getTMISEIExposureCompensationValueDenomIdc();
    288        seiToneMappingInfo->m_refScreenLuminanceWhite = m_pcCfg->getTMISEIRefScreenLuminanceWhite();
    289        seiToneMappingInfo->m_extendedRangeWhiteLevel = m_pcCfg->getTMISEIExtendedRangeWhiteLevel();
    290        assert( seiToneMappingInfo->m_extendedRangeWhiteLevel >= 100 );
    291        seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue = m_pcCfg->getTMISEINominalBlackLevelLumaCodeValue();
    292        seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue = m_pcCfg->getTMISEINominalWhiteLevelLumaCodeValue();
    293        assert( seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue > seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue );
    294        seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue = m_pcCfg->getTMISEIExtendedWhiteLevelLumaCodeValue();
    295        assert( seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue >= seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue );
    296        break;
    297     }
    298   default:
    299     {
    300       assert(!"Undefined SEIToneMapModelId");
    301       break;
    302     }
    303   }
    304   return seiToneMappingInfo;
    305 }
    306 
    307 #if H_MV
    308 SEISubBitstreamProperty *TEncGOP::xCreateSEISubBitstreamProperty( TComSPS *sps)
    309 {
    310   SEISubBitstreamProperty *seiSubBitstreamProperty = new SEISubBitstreamProperty();
    311 
    312   seiSubBitstreamProperty->m_activeVpsId = sps->getVPSId();
    313   /* These values can be determined by the encoder; for now we will use the input parameter */
    314   TEncTop *encTop = this->m_pcEncTop;
    315   seiSubBitstreamProperty->m_numAdditionalSubStreams = encTop->getNumAdditionalSubStreams();
    316   seiSubBitstreamProperty->m_subBitstreamMode        = encTop->getSubBitstreamMode();
    317   seiSubBitstreamProperty->m_outputLayerSetIdxToVps  = encTop->getOutputLayerSetIdxToVps();
    318   seiSubBitstreamProperty->m_highestSublayerId       = encTop->getHighestSublayerId();
    319   seiSubBitstreamProperty->m_avgBitRate              = encTop->getAvgBitRate();
    320   seiSubBitstreamProperty->m_maxBitRate              = encTop->getMaxBitRate();
    321 
    322   return seiSubBitstreamProperty;
    323 }
    324 #endif
    325 
    326 Void TEncGOP::xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps)
    327 {
     166Int TEncGOP::xWriteVPS (AccessUnit &accessUnit, const TComVPS *vps)
     167{
     168  OutputNALUnit nalu(NAL_UNIT_VPS);
     169  m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
     170  m_pcEntropyCoder->encodeVPS(vps);
     171  accessUnit.push_back(new NALUnitEBSP(nalu));
     172  return (Int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
     173}
     174
     175Int TEncGOP::xWriteSPS (AccessUnit &accessUnit, const TComSPS *sps)
     176{
     177#if NH_MV
     178  OutputNALUnit nalu(NAL_UNIT_SPS, 0, getLayerId() );
     179#else
     180  OutputNALUnit nalu(NAL_UNIT_SPS);
     181#endif
     182  m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
     183  m_pcEntropyCoder->encodeSPS(sps);
     184  accessUnit.push_back(new NALUnitEBSP(nalu));
     185  return (Int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
     186
     187}
     188
     189Int TEncGOP::xWritePPS (AccessUnit &accessUnit, const TComPPS *pps)
     190{
     191#if NH_MV
     192  OutputNALUnit nalu(NAL_UNIT_PPS, 0, getLayerId() );
     193#else
     194  OutputNALUnit nalu(NAL_UNIT_PPS);
     195#endif
     196  m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
     197  m_pcEntropyCoder->encodePPS(pps);
     198  accessUnit.push_back(new NALUnitEBSP(nalu));
     199  return (Int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
     200}
     201
     202
     203Int TEncGOP::xWriteParameterSets (AccessUnit &accessUnit, TComSlice *slice)
     204{
     205  Int actualTotalBits = 0;
     206
     207#if NH_MV
     208  if ( getLayerId() == 0 )
     209  { 
     210    actualTotalBits += xWriteVPS(accessUnit, m_pcEncTop->getVPS());
     211  }
     212#else
     213  actualTotalBits += xWriteVPS(accessUnit, m_pcEncTop->getVPS());
     214#endif
     215  actualTotalBits += xWriteSPS(accessUnit, slice->getSPS());
     216  actualTotalBits += xWritePPS(accessUnit, slice->getPPS());
     217
     218  return actualTotalBits;
     219}
     220
     221// write SEI list into one NAL unit and add it to the Access unit at auPos
     222Void TEncGOP::xWriteSEI (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, Int temporalId, const TComSPS *sps)
     223{
     224  // don't do anything, if we get an empty list
     225  if (seiMessages.empty())
     226  {
     227    return;
     228  }
     229#if NH_MV
     230  OutputNALUnit nalu(naluType, temporalId, getLayerId() );
     231#else
     232  OutputNALUnit nalu(naluType, temporalId);
     233#endif
     234  m_seiWriter.writeSEImessages(nalu.m_Bitstream, seiMessages, sps, false);
     235  auPos = accessUnit.insert(auPos, new NALUnitEBSP(nalu));
     236  auPos++;
     237}
     238
     239Void TEncGOP::xWriteSEISeparately (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, Int temporalId, const TComSPS *sps)
     240{
     241  // don't do anything, if we get an empty list
     242  if (seiMessages.empty())
     243  {
     244    return;
     245  }
     246  for (SEIMessages::const_iterator sei = seiMessages.begin(); sei!=seiMessages.end(); sei++ )
     247  {
     248    SEIMessages tmpMessages;
     249    tmpMessages.push_back(*sei);
     250#if NH_MV
     251    OutputNALUnit nalu(naluType, temporalId, getLayerId() );
     252#else
     253    OutputNALUnit nalu(naluType, temporalId);
     254#endif
     255    m_seiWriter.writeSEImessages(nalu.m_Bitstream, tmpMessages, sps, false);
     256    auPos = accessUnit.insert(auPos, new NALUnitEBSP(nalu));
     257    auPos++;
     258  }
     259}
     260
     261Void TEncGOP::xClearSEIs(SEIMessages& seiMessages, Bool deleteMessages)
     262{
     263  if (deleteMessages)
     264  {
     265    deleteSEIs(seiMessages);
     266  }
     267  else
     268  {
     269    seiMessages.clear();
     270  }
     271}
     272
     273// write SEI messages as separate NAL units ordered
     274Void TEncGOP::xWriteLeadingSEIOrdered (SEIMessages& seiMessages, SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, Int temporalId, const TComSPS *sps, Bool testWrite)
     275{
     276  AccessUnit::iterator itNalu = accessUnit.begin();
     277
     278  while ( (itNalu!=accessUnit.end())&&
     279    ( (*itNalu)->m_nalUnitType==NAL_UNIT_ACCESS_UNIT_DELIMITER
     280    || (*itNalu)->m_nalUnitType==NAL_UNIT_VPS
     281    || (*itNalu)->m_nalUnitType==NAL_UNIT_SPS
     282    || (*itNalu)->m_nalUnitType==NAL_UNIT_PPS
     283    ))
     284  {
     285    itNalu++;
     286  }
     287
     288  SEIMessages localMessages = seiMessages;
     289  SEIMessages currentMessages;
     290 
     291#if ENC_DEC_TRACE
     292  g_HLSTraceEnable = !testWrite;
     293#endif
     294  // The case that a specific SEI is not present is handled in xWriteSEI (empty list)
     295
     296  // Active parameter sets SEI must always be the first SEI
     297  currentMessages = extractSeisByType(localMessages, SEI::ACTIVE_PARAMETER_SETS);
     298  assert (currentMessages.size() <= 1);
     299  xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
     300  xClearSEIs(currentMessages, !testWrite);
     301 
     302  // Buffering period SEI must always be following active parameter sets
     303  currentMessages = extractSeisByType(localMessages, SEI::BUFFERING_PERIOD);
     304  assert (currentMessages.size() <= 1);
     305  xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
     306  xClearSEIs(currentMessages, !testWrite);
     307
     308  // Picture timing SEI must always be following buffering period
     309  currentMessages = extractSeisByType(localMessages, SEI::PICTURE_TIMING);
     310  assert (currentMessages.size() <= 1);
     311  xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
     312  xClearSEIs(currentMessages, !testWrite);
     313
     314  // Decoding unit info SEI must always be following picture timing
     315  if (!duInfoSeiMessages.empty())
     316  {
     317    currentMessages.push_back(duInfoSeiMessages.front());
     318    if (!testWrite)
     319    {
     320      duInfoSeiMessages.pop_front();
     321    }
     322    xWriteSEI(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
     323    xClearSEIs(currentMessages, !testWrite);
     324  }
     325
     326  // Scalable nesting SEI must always be the following DU info
     327  currentMessages = extractSeisByType(localMessages, SEI::SCALABLE_NESTING);
     328  xWriteSEISeparately(NAL_UNIT_PREFIX_SEI, currentMessages, accessUnit, itNalu, temporalId, sps);
     329  xClearSEIs(currentMessages, !testWrite);
     330
     331  // And finally everything else one by one
     332  xWriteSEISeparately(NAL_UNIT_PREFIX_SEI, localMessages, accessUnit, itNalu, temporalId, sps);
     333  xClearSEIs(localMessages, !testWrite);
     334
     335  if (!testWrite)
     336  {
     337    seiMessages.clear();
     338  }
     339}
     340
     341
     342Void TEncGOP::xWriteLeadingSEIMessages (SEIMessages& seiMessages, SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, Int temporalId, const TComSPS *sps, std::deque<DUData> &duData)
     343{
     344  AccessUnit testAU;
     345  SEIMessages picTimingSEIs = getSeisByType(seiMessages, SEI::PICTURE_TIMING);
     346  assert (picTimingSEIs.size() < 2);
     347  SEIPictureTiming * picTiming = picTimingSEIs.empty() ? NULL : (SEIPictureTiming*) picTimingSEIs.front();
     348
     349  // test writing
     350  xWriteLeadingSEIOrdered(seiMessages, duInfoSeiMessages, testAU, temporalId, sps, true);
     351  // update Timing and DU info SEI
     352  xUpdateDuData(testAU, duData);
     353  xUpdateTimingSEI(picTiming, duData, sps);
     354  xUpdateDuInfoSEI(duInfoSeiMessages, picTiming);
     355  // actual writing
     356  xWriteLeadingSEIOrdered(seiMessages, duInfoSeiMessages, accessUnit, temporalId, sps, false);
     357
     358  // testAU will automatically be cleaned up when losing scope
     359}
     360
     361Void TEncGOP::xWriteTrailingSEIMessages (SEIMessages& seiMessages, AccessUnit &accessUnit, Int temporalId, const TComSPS *sps)
     362{
     363  // Note: using accessUnit.end() works only as long as this function is called after slice coding and before EOS/EOB NAL units
     364  AccessUnit::iterator pos = accessUnit.end();
     365  xWriteSEISeparately(NAL_UNIT_SUFFIX_SEI, seiMessages, accessUnit, pos, temporalId, sps);
     366  deleteSEIs(seiMessages);
     367}
     368
     369Void TEncGOP::xWriteDuSEIMessages (SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, Int temporalId, const TComSPS *sps, std::deque<DUData> &duData)
     370{
     371  const TComHRD *hrd = sps->getVuiParameters()->getHrdParameters();
     372
     373  if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
     374  {
     375    Int naluIdx = 0;
     376    AccessUnit::iterator nalu = accessUnit.begin();
     377
     378    // skip over first DU, we have a DU info SEI there already
     379    while (naluIdx < duData[0].accumNalsDU && nalu!=accessUnit.end())
     380    {
     381      naluIdx++;
     382      nalu++;
     383    }
     384
     385    SEIMessages::iterator duSEI = duInfoSeiMessages.begin();
     386    // loop over remaining DUs
     387    for (Int duIdx = 1; duIdx < duData.size(); duIdx++)
     388    {
     389      if (duSEI == duInfoSeiMessages.end())
     390      {
     391        // if the number of generated SEIs matches the number of DUs, this should not happen
     392        assert (false);
     393        return;
     394      }
     395      // write the next SEI
     396      SEIMessages tmpSEI;
     397      tmpSEI.push_back(*duSEI);
     398      xWriteSEI(NAL_UNIT_PREFIX_SEI, tmpSEI, accessUnit, nalu, temporalId, sps);
     399      // nalu points to the position after the SEI, so we have to increase the index as well
     400      naluIdx++;
     401      while ((naluIdx < duData[duIdx].accumNalsDU) && nalu!=accessUnit.end())
     402      {
     403        naluIdx++;
     404        nalu++;
     405      }
     406      duSEI++;
     407    }
     408  }
     409  deleteSEIs(duInfoSeiMessages);
     410}
     411
     412Void TEncGOP::xCreateIRAPLeadingSEIMessages (SEIMessages& seiMessages, const TComSPS *sps, const TComPPS *pps)
     413{
     414#if NH_MV
     415  OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, 0, getLayerId());
     416#else
    328417  OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
    329 
     418#endif
    330419  if(m_pcCfg->getActiveParameterSetsSEIEnabled())
    331420  {
    332     SEIActiveParameterSets *sei = xCreateSEIActiveParameterSets (sps);
    333 
    334     //nalu = NALUnit(NAL_UNIT_SEI);
    335     m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    336     m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
    337     writeRBSPTrailingBits(nalu.m_Bitstream);
    338     accessUnit.push_back(new NALUnitEBSP(nalu));
    339     delete sei;
    340     m_activeParameterSetSEIPresentInAU = true;
     421    SEIActiveParameterSets *sei = new SEIActiveParameterSets;
     422    m_seiEncoder.initSEIActiveParameterSets (sei, m_pcCfg->getVPS(), sps);
     423    seiMessages.push_back(sei);
    341424  }
    342425
    343426  if(m_pcCfg->getFramePackingArrangementSEIEnabled())
    344427  {
    345     SEIFramePacking *sei = xCreateSEIFramePacking ();
    346 
    347     nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
    348     m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    349     m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
    350     writeRBSPTrailingBits(nalu.m_Bitstream);
    351     accessUnit.push_back(new NALUnitEBSP(nalu));
    352     delete sei;
    353   }
     428    SEIFramePacking *sei = new SEIFramePacking;
     429    m_seiEncoder.initSEIFramePacking (sei, m_iNumPicCoded);
     430    seiMessages.push_back(sei);
     431  }
     432
     433  if(m_pcCfg->getSegmentedRectFramePackingArrangementSEIEnabled())
     434  {
     435    SEISegmentedRectFramePacking *sei = new SEISegmentedRectFramePacking;
     436    m_seiEncoder.initSEISegmentedRectFramePacking(sei);
     437    seiMessages.push_back(sei);
     438  }
     439
    354440  if (m_pcCfg->getDisplayOrientationSEIAngle())
    355441  {
    356     SEIDisplayOrientation *sei = xCreateSEIDisplayOrientation();
    357 
    358     nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
    359     m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    360     m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
    361     writeRBSPTrailingBits(nalu.m_Bitstream);
    362     accessUnit.push_back(new NALUnitEBSP(nalu));
    363     delete sei;
    364   }
     442    SEIDisplayOrientation *sei = new SEIDisplayOrientation;
     443    m_seiEncoder.initSEIDisplayOrientation(sei);
     444    seiMessages.push_back(sei);
     445  }
     446
    365447  if(m_pcCfg->getToneMappingInfoSEIEnabled())
    366448  {
    367     SEIToneMappingInfo *sei = xCreateSEIToneMappingInfo ();
    368      
    369     nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
    370     m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    371     m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
    372     writeRBSPTrailingBits(nalu.m_Bitstream);
    373     accessUnit.push_back(new NALUnitEBSP(nalu));
    374     delete sei;
    375   }
    376 #if H_MV
    377   if( m_pcCfg->getSubBitstreamPropSEIEnabled() )
    378   {
    379     SEISubBitstreamProperty *sei = xCreateSEISubBitstreamProperty ( sps );
    380 
    381     nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
    382     m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    383     m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
    384     writeRBSPTrailingBits(nalu.m_Bitstream);
    385     accessUnit.push_back(new NALUnitEBSP(nalu));
    386     delete sei;
    387   }
    388 #endif
     449    SEIToneMappingInfo *sei = new SEIToneMappingInfo;
     450    m_seiEncoder.initSEIToneMappingInfo (sei);
     451    seiMessages.push_back(sei);
     452  }
     453
     454  if(m_pcCfg->getTMCTSSEIEnabled())
     455  {
     456    SEITempMotionConstrainedTileSets *sei = new SEITempMotionConstrainedTileSets;
     457    m_seiEncoder.initSEITempMotionConstrainedTileSets(sei, pps);
     458    seiMessages.push_back(sei);
     459  }
     460
     461  if(m_pcCfg->getTimeCodeSEIEnabled())
     462  {
     463    SEITimeCode *seiTimeCode = new SEITimeCode;
     464    m_seiEncoder.initSEITimeCode(seiTimeCode);
     465    seiMessages.push_back(seiTimeCode);
     466  }
     467
     468  if(m_pcCfg->getKneeSEIEnabled())
     469  {
     470    SEIKneeFunctionInfo *sei = new SEIKneeFunctionInfo;
     471    m_seiEncoder.initSEIKneeFunctionInfo(sei);
     472    seiMessages.push_back(sei);
     473  }
     474   
     475  if(m_pcCfg->getMasteringDisplaySEI().colourVolumeSEIEnabled)
     476  {
     477    const TComSEIMasteringDisplay &seiCfg=m_pcCfg->getMasteringDisplaySEI();
     478    SEIMasteringDisplayColourVolume *sei = new SEIMasteringDisplayColourVolume;
     479    sei->values = seiCfg;
     480    seiMessages.push_back(sei);
     481  }
     482
     483#if NH_MV
     484  if( m_pcCfg->getSubBitstreamPropSEIEnabled() && ( getLayerId() == 0 ) )
     485  {
     486    SEISubBitstreamProperty *sei = new SEISubBitstreamProperty;
     487    m_seiEncoder.initSEISubBitstreamProperty( sei, sps );   
     488    seiMessages.push_back(sei);
     489  }
     490#endif
     491}
     492
     493Void TEncGOP::xCreatePerPictureSEIMessages (Int picInGOP, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, TComSlice *slice)
     494{
     495  if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( slice->getSliceType() == I_SLICE ) &&
     496    ( slice->getSPS()->getVuiParametersPresentFlag() ) &&
     497    ( ( slice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
     498    || ( slice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
     499  {
     500    SEIBufferingPeriod *bufferingPeriodSEI = new SEIBufferingPeriod();
     501    m_seiEncoder.initSEIBufferingPeriod(bufferingPeriodSEI, slice);
     502    seiMessages.push_back(bufferingPeriodSEI);
     503    m_bufferingPeriodSEIPresentInAU = true;
     504
     505    if (m_pcCfg->getScalableNestingSEIEnabled())
     506    {
     507      SEIBufferingPeriod *bufferingPeriodSEIcopy = new SEIBufferingPeriod();
     508      bufferingPeriodSEI->copyTo(*bufferingPeriodSEIcopy);
     509      nestedSeiMessages.push_back(bufferingPeriodSEIcopy);
     510    }
     511  }
     512
     513  if (picInGOP ==0 && m_pcCfg->getSOPDescriptionSEIEnabled() ) // write SOP description SEI (if enabled) at the beginning of GOP
     514  {
     515    SEISOPDescription* sopDescriptionSEI = new SEISOPDescription();
     516    m_seiEncoder.initSEISOPDescription(sopDescriptionSEI, slice, picInGOP, m_iLastIDR, m_iGopSize);
     517    seiMessages.push_back(sopDescriptionSEI);
     518  }
     519
     520  if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( slice->getSliceType() == I_SLICE ) )
     521  {
     522    if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !slice->getRapPicFlag() )
     523    {
     524      // Gradual decoding refresh SEI
     525      SEIGradualDecodingRefreshInfo *gradualDecodingRefreshInfoSEI = new SEIGradualDecodingRefreshInfo();
     526      gradualDecodingRefreshInfoSEI->m_gdrForegroundFlag = true; // Indicating all "foreground"
     527      seiMessages.push_back(gradualDecodingRefreshInfoSEI);
     528    }
     529    // Recovery point SEI
     530    SEIRecoveryPoint *recoveryPointSEI = new SEIRecoveryPoint();
     531    m_seiEncoder.initSEIRecoveryPoint(recoveryPointSEI, slice);
     532    seiMessages.push_back(recoveryPointSEI);
     533  }
     534  if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
     535  {
     536    SEITemporalLevel0Index *temporalLevel0IndexSEI = new SEITemporalLevel0Index();
     537    m_seiEncoder.initTemporalLevel0IndexSEI(temporalLevel0IndexSEI, slice);
     538    seiMessages.push_back(temporalLevel0IndexSEI);
     539  }
     540
     541  if(slice->getSPS()->getVuiParametersPresentFlag() && m_pcCfg->getChromaSamplingFilterHintEnabled() && ( slice->getSliceType() == I_SLICE ))
     542  {
     543    SEIChromaSamplingFilterHint *seiChromaSamplingFilterHint = new SEIChromaSamplingFilterHint;
     544    m_seiEncoder.initSEIChromaSamplingFilterHint(seiChromaSamplingFilterHint, m_pcCfg->getChromaSamplingHorFilterIdc(), m_pcCfg->getChromaSamplingVerFilterIdc());
     545    seiMessages.push_back(seiChromaSamplingFilterHint);
     546  }
     547
     548  if( m_pcEncTop->getNoDisplaySEITLayer() && ( slice->getTLayer() >= m_pcEncTop->getNoDisplaySEITLayer() ) )
     549  {
     550    SEINoDisplay *seiNoDisplay = new SEINoDisplay;
     551    seiNoDisplay->m_noDisplay = true;
     552    seiMessages.push_back(seiNoDisplay);
     553  }
     554}
     555
     556Void TEncGOP::xCreateScalableNestingSEI (SEIMessages& seiMessages, SEIMessages& nestedSeiMessages)
     557{
     558  SEIMessages tmpMessages;
     559  while (!nestedSeiMessages.empty())
     560  {
     561    SEI* sei=nestedSeiMessages.front();
     562    nestedSeiMessages.pop_front();
     563    tmpMessages.push_back(sei);
     564    SEIScalableNesting *nestingSEI = new SEIScalableNesting();
     565    m_seiEncoder.initSEIScalableNesting(nestingSEI, tmpMessages);
     566    seiMessages.push_back(nestingSEI);
     567    tmpMessages.clear();
     568  }
     569}
     570
     571Void TEncGOP::xCreatePictureTimingSEI  (Int IRAPGOPid, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, SEIMessages& duInfoSeiMessages, TComSlice *slice, Bool isField, std::deque<DUData> &duData)
     572{
     573  Int picSptDpbOutputDuDelay = 0;
     574#if !NH_MV
     575  SEIPictureTiming *pictureTimingSEI = new SEIPictureTiming();
     576#endif
     577
     578  const TComVUI *vui = slice->getSPS()->getVuiParameters();
     579  const TComHRD *hrd = vui->getHrdParameters();
     580
     581  // update decoding unit parameters
     582  if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
     583    ( slice->getSPS()->getVuiParametersPresentFlag() ) &&
     584    (  hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() ) )
     585  {
     586#if NH_MV
     587    // Preliminary fix to avoid memory leak.
     588    SEIPictureTiming *pictureTimingSEI = new SEIPictureTiming();
     589#endif
     590
     591    // DU parameters
     592    if( hrd->getSubPicCpbParamsPresentFlag() )
     593    {
     594      UInt numDU = (UInt) duData.size();
     595      pictureTimingSEI->m_numDecodingUnitsMinus1     = ( numDU - 1 );
     596      pictureTimingSEI->m_duCommonCpbRemovalDelayFlag = false;
     597      pictureTimingSEI->m_numNalusInDuMinus1.resize( numDU );
     598      pictureTimingSEI->m_duCpbRemovalDelayMinus1.resize( numDU );
     599    }
     600    pictureTimingSEI->m_auCpbRemovalDelay = std::min<Int>(std::max<Int>(1, m_totalCoded - m_lastBPSEI), static_cast<Int>(pow(2, static_cast<Double>(hrd->getCpbRemovalDelayLengthMinus1()+1)))); // Syntax element signalled as minus, hence the .
     601    pictureTimingSEI->m_picDpbOutputDelay = slice->getSPS()->getNumReorderPics(slice->getSPS()->getMaxTLayers()-1) + slice->getPOC() - m_totalCoded;
     602    if(m_pcCfg->getEfficientFieldIRAPEnabled() && IRAPGOPid > 0 && IRAPGOPid < m_iGopSize)
     603    {
     604      // if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation
     605      pictureTimingSEI->m_picDpbOutputDelay ++;
     606    }
     607    Int factor = hrd->getTickDivisorMinus2() + 2;
     608    pictureTimingSEI->m_picDpbOutputDuDelay = factor * pictureTimingSEI->m_picDpbOutputDelay;
     609    if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
     610    {
     611      picSptDpbOutputDuDelay = factor * pictureTimingSEI->m_picDpbOutputDelay;
     612    }
     613    if (m_bufferingPeriodSEIPresentInAU)
     614    {
     615      m_lastBPSEI = m_totalCoded;
     616    }
     617
     618    if( hrd->getSubPicCpbParamsPresentFlag() )
     619    {
     620      Int i;
     621      UInt64 ui64Tmp;
     622      UInt uiPrev = 0;
     623      UInt numDU = ( pictureTimingSEI->m_numDecodingUnitsMinus1 + 1 );
     624      std::vector<UInt> &rDuCpbRemovalDelayMinus1 = pictureTimingSEI->m_duCpbRemovalDelayMinus1;
     625      UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
     626
     627      for( i = 0; i < numDU; i ++ )
     628      {
     629        pictureTimingSEI->m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( duData[i].accumNalsDU - 1 ) : ( duData[i].accumNalsDU- duData[i-1].accumNalsDU - 1 );
     630      }
     631
     632      if( numDU == 1 )
     633      {
     634        rDuCpbRemovalDelayMinus1[ 0 ] = 0; /* don't care */
     635      }
     636      else
     637      {
     638        rDuCpbRemovalDelayMinus1[ numDU - 1 ] = 0;/* by definition */
     639        UInt tmp = 0;
     640        UInt accum = 0;
     641
     642        for( i = ( numDU - 2 ); i >= 0; i -- )
     643        {
     644          ui64Tmp = ( ( ( duData[numDU - 1].accumBitsDU  - duData[i].accumBitsDU ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
     645          if( (UInt)ui64Tmp > maxDiff )
     646          {
     647            tmp ++;
     648          }
     649        }
     650        uiPrev = 0;
     651
     652        UInt flag = 0;
     653        for( i = ( numDU - 2 ); i >= 0; i -- )
     654        {
     655          flag = 0;
     656          ui64Tmp = ( ( ( duData[numDU - 1].accumBitsDU  - duData[i].accumBitsDU ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
     657
     658          if( (UInt)ui64Tmp > maxDiff )
     659          {
     660            if(uiPrev >= maxDiff - tmp)
     661            {
     662              ui64Tmp = uiPrev + 1;
     663              flag = 1;
     664            }
     665            else                            ui64Tmp = maxDiff - tmp + 1;
     666          }
     667          rDuCpbRemovalDelayMinus1[ i ] = (UInt)ui64Tmp - uiPrev - 1;
     668          if( (Int)rDuCpbRemovalDelayMinus1[ i ] < 0 )
     669          {
     670            rDuCpbRemovalDelayMinus1[ i ] = 0;
     671          }
     672          else if (tmp > 0 && flag == 1)
     673          {
     674            tmp --;
     675          }
     676          accum += rDuCpbRemovalDelayMinus1[ i ] + 1;
     677          uiPrev = accum;
     678        }
     679      }
     680    }
     681   
     682    if( m_pcCfg->getPictureTimingSEIEnabled() )
     683    {
     684      pictureTimingSEI->m_picStruct = (isField && slice->getPic()->isTopField())? 1 : isField? 2 : 0;
     685      seiMessages.push_back(pictureTimingSEI);
     686
     687      if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI
     688      {
     689          SEIPictureTiming *pictureTimingSEIcopy = new SEIPictureTiming();
     690          pictureTimingSEI->copyTo(*pictureTimingSEIcopy);
     691          nestedSeiMessages.push_back(pictureTimingSEIcopy);
     692        }
     693    }
     694
     695    if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
     696    {
     697      for( Int i = 0; i < ( pictureTimingSEI->m_numDecodingUnitsMinus1 + 1 ); i ++ )
     698      {
     699        SEIDecodingUnitInfo *duInfoSEI = new SEIDecodingUnitInfo();
     700        duInfoSEI->m_decodingUnitIdx = i;
     701        duInfoSEI->m_duSptCpbRemovalDelay = pictureTimingSEI->m_duCpbRemovalDelayMinus1[i] + 1;
     702        duInfoSEI->m_dpbOutputDuDelayPresentFlag = false;
     703        duInfoSEI->m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
     704
     705        duInfoSeiMessages.push_back(duInfoSEI);
     706      }
     707    }
     708  }
     709}
     710
     711Void TEncGOP::xUpdateDuData(AccessUnit &testAU, std::deque<DUData> &duData)
     712{
     713  if (duData.empty())
     714  {
     715    return;
     716  }
     717  // fix first
     718  UInt numNalUnits = (UInt)testAU.size();
     719  UInt numRBSPBytes = 0;
     720  for (AccessUnit::const_iterator it = testAU.begin(); it != testAU.end(); it++)
     721  {
     722    numRBSPBytes += UInt((*it)->m_nalUnitData.str().size());
     723  }
     724  duData[0].accumBitsDU += ( numRBSPBytes << 3 );
     725  duData[0].accumNalsDU += numNalUnits;
     726
     727  // adapt cumulative sums for all following DUs
     728  // and add one DU info SEI, if enabled
     729  for (Int i=1; i<duData.size(); i++)
     730  {
     731    if (m_pcCfg->getDecodingUnitInfoSEIEnabled())
     732    {
     733      numNalUnits  += 1;
     734      numRBSPBytes += ( 5 << 3 );
     735    }
     736    duData[i].accumBitsDU += numRBSPBytes; // probably around 5 bytes
     737    duData[i].accumNalsDU += numNalUnits;
     738  }
     739
     740  // The last DU may have a trailing SEI
     741  if (m_pcCfg->getDecodedPictureHashSEIEnabled())
     742  {
     743    duData.back().accumBitsDU += ( 20 << 3 ); // probably around 20 bytes - should be further adjusted, e.g. by type
     744    duData.back().accumNalsDU += 1;
     745  }
     746
     747}
     748Void TEncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUData> &duData, const TComSPS *sps)
     749{
     750  if (!pictureTimingSEI)
     751  {
     752    return;
     753  }
     754  const TComVUI *vui = sps->getVuiParameters();
     755  const TComHRD *hrd = vui->getHrdParameters();
     756  if( hrd->getSubPicCpbParamsPresentFlag() )
     757  {
     758    Int i;
     759    UInt64 ui64Tmp;
     760    UInt uiPrev = 0;
     761    UInt numDU = ( pictureTimingSEI->m_numDecodingUnitsMinus1 + 1 );
     762    std::vector<UInt> &rDuCpbRemovalDelayMinus1 = pictureTimingSEI->m_duCpbRemovalDelayMinus1;
     763    UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
     764
     765    for( i = 0; i < numDU; i ++ )
     766    {
     767      pictureTimingSEI->m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( duData[i].accumNalsDU - 1 ) : ( duData[i].accumNalsDU- duData[i-1].accumNalsDU - 1 );
     768    }
     769
     770    if( numDU == 1 )
     771    {
     772      rDuCpbRemovalDelayMinus1[ 0 ] = 0; /* don't care */
     773    }
     774    else
     775    {
     776      rDuCpbRemovalDelayMinus1[ numDU - 1 ] = 0;/* by definition */
     777      UInt tmp = 0;
     778      UInt accum = 0;
     779
     780      for( i = ( numDU - 2 ); i >= 0; i -- )
     781      {
     782        ui64Tmp = ( ( ( duData[numDU - 1].accumBitsDU  - duData[i].accumBitsDU ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
     783        if( (UInt)ui64Tmp > maxDiff )
     784        {
     785          tmp ++;
     786        }
     787      }
     788      uiPrev = 0;
     789
     790      UInt flag = 0;
     791      for( i = ( numDU - 2 ); i >= 0; i -- )
     792      {
     793        flag = 0;
     794        ui64Tmp = ( ( ( duData[numDU - 1].accumBitsDU  - duData[i].accumBitsDU ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
     795
     796        if( (UInt)ui64Tmp > maxDiff )
     797        {
     798          if(uiPrev >= maxDiff - tmp)
     799          {
     800            ui64Tmp = uiPrev + 1;
     801            flag = 1;
     802          }
     803          else                            ui64Tmp = maxDiff - tmp + 1;
     804        }
     805        rDuCpbRemovalDelayMinus1[ i ] = (UInt)ui64Tmp - uiPrev - 1;
     806        if( (Int)rDuCpbRemovalDelayMinus1[ i ] < 0 )
     807        {
     808          rDuCpbRemovalDelayMinus1[ i ] = 0;
     809        }
     810        else if (tmp > 0 && flag == 1)
     811        {
     812          tmp --;
     813        }
     814        accum += rDuCpbRemovalDelayMinus1[ i ] + 1;
     815        uiPrev = accum;
     816      }
     817    }
     818  }
     819}
     820Void TEncGOP::xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI)
     821{
     822  if (duInfoSeiMessages.empty() || (pictureTimingSEI == NULL))
     823  {
     824    return;
     825  }
     826
     827  Int i=0;
     828
     829  for (SEIMessages::iterator du = duInfoSeiMessages.begin(); du!= duInfoSeiMessages.end(); du++)
     830  {
     831    SEIDecodingUnitInfo *duInfoSEI = (SEIDecodingUnitInfo*) (*du);
     832    duInfoSEI->m_decodingUnitIdx = i;
     833    duInfoSEI->m_duSptCpbRemovalDelay = pictureTimingSEI->m_duCpbRemovalDelayMinus1[i] + 1;
     834    duInfoSEI->m_dpbOutputDuDelayPresentFlag = false;
     835    i++;
     836  }
     837}
     838
     839static Void
     840cabac_zero_word_padding(TComSlice *const pcSlice, TComPic *const pcPic, const std::size_t binCountsInNalUnits, const std::size_t numBytesInVclNalUnits, std::ostringstream &nalUnitData, const Bool cabacZeroWordPaddingEnabled)
     841{
     842  const TComSPS &sps=*(pcSlice->getSPS());
     843  const Int log2subWidthCxsubHeightC = (pcPic->getComponentScaleX(COMPONENT_Cb)+pcPic->getComponentScaleY(COMPONENT_Cb));
     844  const Int minCuWidth  = pcPic->getMinCUWidth();
     845  const Int minCuHeight = pcPic->getMinCUHeight();
     846  const Int paddedWidth = ((sps.getPicWidthInLumaSamples()  + minCuWidth  - 1) / minCuWidth) * minCuWidth;
     847  const Int paddedHeight= ((sps.getPicHeightInLumaSamples() + minCuHeight - 1) / minCuHeight) * minCuHeight;
     848  const Int rawBits = paddedWidth * paddedHeight *
     849                         (sps.getBitDepth(CHANNEL_TYPE_LUMA) + 2*(sps.getBitDepth(CHANNEL_TYPE_CHROMA)>>log2subWidthCxsubHeightC));
     850  const std::size_t threshold = (32/3)*numBytesInVclNalUnits + (rawBits/32);
     851  if (binCountsInNalUnits >= threshold)
     852  {
     853    // need to add additional cabac zero words (each one accounts for 3 bytes (=00 00 03)) to increase numBytesInVclNalUnits
     854    const std::size_t targetNumBytesInVclNalUnits = ((binCountsInNalUnits - (rawBits/32))*3+31)/32;
     855
     856    if (targetNumBytesInVclNalUnits>numBytesInVclNalUnits) // It should be!
     857    {
     858      const std::size_t numberOfAdditionalBytesNeeded=targetNumBytesInVclNalUnits - numBytesInVclNalUnits;
     859      const std::size_t numberOfAdditionalCabacZeroWords=(numberOfAdditionalBytesNeeded+2)/3;
     860      const std::size_t numberOfAdditionalCabacZeroBytes=numberOfAdditionalCabacZeroWords*3;
     861      if (cabacZeroWordPaddingEnabled)
     862      {
     863        std::vector<Char> zeroBytesPadding(numberOfAdditionalCabacZeroBytes, Char(0));
     864        for(std::size_t i=0; i<numberOfAdditionalCabacZeroWords; i++)
     865        {
     866          zeroBytesPadding[i*3+2]=3;  // 00 00 03
     867        }
     868        nalUnitData.write(&(zeroBytesPadding[0]), numberOfAdditionalCabacZeroBytes);
     869        printf("Adding %d bytes of padding\n", UInt(numberOfAdditionalCabacZeroWords*3));
     870      }
     871      else
     872      {
     873        printf("Standard would normally require adding %d bytes of padding\n", UInt(numberOfAdditionalCabacZeroWords*3));
     874      }
     875    }
     876  }
     877}
     878
     879class EfficientFieldIRAPMapping
     880{
     881  private:
     882    Int  IRAPGOPid;
     883    Bool IRAPtoReorder;
     884    Bool swapIRAPForward;
     885
     886  public:
     887    EfficientFieldIRAPMapping() :
     888      IRAPGOPid(-1),
     889      IRAPtoReorder(false),
     890      swapIRAPForward(false)
     891    { }
     892
     893    Void initialize(const Bool isField, const Int gopSize, const Int POCLast, const Int numPicRcvd, const Int lastIDR, TEncGOP *pEncGop, TEncCfg *pCfg);
     894
     895    Int adjustGOPid(const Int gopID);
     896    Int restoreGOPid(const Int gopID);
     897    Int GetIRAPGOPid() const { return IRAPGOPid; }
     898};
     899
     900Void EfficientFieldIRAPMapping::initialize(const Bool isField, const Int gopSize, const Int POCLast, const Int numPicRcvd, const Int lastIDR, TEncGOP *pEncGop, TEncCfg *pCfg )
     901{
     902  if(isField)
     903  {
     904    Int pocCurr;
     905    for ( Int iGOPid=0; iGOPid < gopSize; iGOPid++ )
     906    {
     907      // determine actual POC
     908      if(POCLast == 0) //case first frame or first top field
     909      {
     910        pocCurr=0;
     911      }
     912      else if(POCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
     913      {
     914        pocCurr = 1;
     915      }
     916      else
     917      {
     918        pocCurr = POCLast - numPicRcvd + pCfg->getGOPEntry(iGOPid).m_POC - isField;
     919      }
     920
     921      // check if POC corresponds to IRAP
     922      NalUnitType tmpUnitType = pEncGop->getNalUnitType(pocCurr, lastIDR, isField);
     923      if(tmpUnitType >= NAL_UNIT_CODED_SLICE_BLA_W_LP && tmpUnitType <= NAL_UNIT_CODED_SLICE_CRA) // if picture is an IRAP
     924      {
     925        if(pocCurr%2 == 0 && iGOPid < gopSize-1 && pCfg->getGOPEntry(iGOPid).m_POC == pCfg->getGOPEntry(iGOPid+1).m_POC-1)
     926        { // if top field and following picture in enc order is associated bottom field
     927          IRAPGOPid = iGOPid;
     928          IRAPtoReorder = true;
     929          swapIRAPForward = true;
     930          break;
     931        }
     932        if(pocCurr%2 != 0 && iGOPid > 0 && pCfg->getGOPEntry(iGOPid).m_POC == pCfg->getGOPEntry(iGOPid-1).m_POC+1)
     933        {
     934          // if picture is an IRAP remember to process it first
     935          IRAPGOPid = iGOPid;
     936          IRAPtoReorder = true;
     937          swapIRAPForward = false;
     938          break;
     939        }
     940      }
     941    }
     942  }
     943}
     944
     945Int EfficientFieldIRAPMapping::adjustGOPid(const Int GOPid)
     946{
     947  if(IRAPtoReorder)
     948  {
     949    if(swapIRAPForward)
     950    {
     951      if(GOPid == IRAPGOPid)
     952      {
     953        return IRAPGOPid +1;
     954      }
     955      else if(GOPid == IRAPGOPid +1)
     956      {
     957        return IRAPGOPid;
     958      }
     959    }
     960    else
     961    {
     962      if(GOPid == IRAPGOPid -1)
     963      {
     964        return IRAPGOPid;
     965      }
     966      else if(GOPid == IRAPGOPid)
     967      {
     968        return IRAPGOPid -1;
     969      }
     970    }
     971  }
     972  return GOPid;
     973}
     974
     975Int EfficientFieldIRAPMapping::restoreGOPid(const Int GOPid)
     976{
     977  if(IRAPtoReorder)
     978  {
     979    if(swapIRAPForward)
     980    {
     981      if(GOPid == IRAPGOPid)
     982      {
     983        IRAPtoReorder = false;
     984        return IRAPGOPid +1;
     985      }
     986      else if(GOPid == IRAPGOPid +1)
     987      {
     988        return GOPid -1;
     989      }
     990    }
     991    else
     992    {
     993      if(GOPid == IRAPGOPid)
     994      {
     995        return IRAPGOPid -1;
     996      }
     997      else if(GOPid == IRAPGOPid -1)
     998      {
     999        IRAPtoReorder = false;
     1000        return IRAPGOPid;
     1001      }
     1002    }
     1003  }
     1004  return GOPid;
     1005}
     1006
     1007
     1008static UInt calculateCollocatedFromL1Flag(TEncCfg *pCfg, const Int GOPid, const Int gopSize)
     1009{
     1010  Int iCloseLeft=1, iCloseRight=-1;
     1011  for(Int i = 0; i<pCfg->getGOPEntry(GOPid).m_numRefPics; i++)
     1012  {
     1013    Int iRef = pCfg->getGOPEntry(GOPid).m_referencePics[i];
     1014    if(iRef>0&&(iRef<iCloseRight||iCloseRight==-1))
     1015    {
     1016      iCloseRight=iRef;
     1017    }
     1018    else if(iRef<0&&(iRef>iCloseLeft||iCloseLeft==1))
     1019    {
     1020      iCloseLeft=iRef;
     1021    }
     1022  }
     1023  if(iCloseRight>-1)
     1024  {
     1025    iCloseRight=iCloseRight+pCfg->getGOPEntry(GOPid).m_POC-1;
     1026  }
     1027  if(iCloseLeft<1)
     1028  {
     1029    iCloseLeft=iCloseLeft+pCfg->getGOPEntry(GOPid).m_POC-1;
     1030    while(iCloseLeft<0)
     1031    {
     1032      iCloseLeft+=gopSize;
     1033    }
     1034  }
     1035  Int iLeftQP=0, iRightQP=0;
     1036  for(Int i=0; i<gopSize; i++)
     1037  {
     1038    if(pCfg->getGOPEntry(i).m_POC==(iCloseLeft%gopSize)+1)
     1039    {
     1040      iLeftQP= pCfg->getGOPEntry(i).m_QPOffset;
     1041    }
     1042    if (pCfg->getGOPEntry(i).m_POC==(iCloseRight%gopSize)+1)
     1043    {
     1044      iRightQP=pCfg->getGOPEntry(i).m_QPOffset;
     1045    }
     1046  }
     1047  if(iCloseRight>-1&&iRightQP<iLeftQP)
     1048  {
     1049    return 0;
     1050  }
     1051  else
     1052  {
     1053    return 1;
     1054  }
    3891055}
    3901056
     
    3921058// Public member functions
    3931059// ====================================================================================================================
    394 #if H_MV
     1060#if NH_MV
    3951061Void TEncGOP::initGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP)
    3961062{
    397   xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut, false );
     1063  xInitGOP( iPOCLast, iNumPicRcvd, false );
    3981064  m_iNumPicCoded = 0;
    3991065}
    4001066#endif
    401 #if H_MV
    402 Void TEncGOP::compressPicInGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP, Int iGOPid, bool isField, bool isTff)
     1067#if NH_MV
     1068Void TEncGOP::compressPicInGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic,
     1069                                TComList<TComPicYuv*>& rcListPicYuvRecOut,  std::list<AccessUnit>& accessUnitsInGOP,
     1070                                Bool isField, Bool isTff, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE, Int iGOPid )
    4031071#else
    404 Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP, bool isField, bool isTff)
    405 #endif
    406 {
    407   TComPic*        pcPic;
     1072Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic,
     1073                           TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP,
     1074                           Bool isField, Bool isTff, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE )
     1075#endif
     1076{
     1077  // TODO: Split this function up.
     1078
     1079  TComPic*        pcPic = NULL;
    4081080  TComPicYuv*     pcPicYuvRecOut;
    4091081  TComSlice*      pcSlice;
     
    4111083  pcBitstreamRedirect = new TComOutputBitstream;
    4121084  AccessUnit::iterator  itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted
    413   UInt                  uiOneBitstreamPerSliceLength = 0;
    414   TEncSbac* pcSbacCoders = NULL;
    415   TComOutputBitstream* pcSubstreamsOut = NULL;
    416 
    417 #if !H_MV
    418   xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut, isField );
    419 
    420  
     1085#if !NH_MV
     1086  xInitGOP( iPOCLast, iNumPicRcvd, isField );
     1087#endif
     1088
    4211089  m_iNumPicCoded = 0;
    422 #endif
    423   SEIPictureTiming pictureTimingSEI;
    424   Bool writeSOP = m_pcCfg->getSOPDescriptionSEIEnabled();
    425   // Initialize Scalable Nesting SEI with single layer values
    426   SEIScalableNesting scalableNestingSEI;
    427   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
    428   scalableNestingSEI.m_nestingOpFlag                 = 0;
    429   scalableNestingSEI.m_nestingNumOpsMinus1           = 0;      //nesting_num_ops_minus1
    430   scalableNestingSEI.m_allLayersFlag                 = 0;
    431   scalableNestingSEI.m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1;  //nesting_no_op_max_temporal_id_plus1
    432   scalableNestingSEI.m_nestingNumLayersMinus1        = 1 - 1;  //nesting_num_layers_minus1
    433   scalableNestingSEI.m_nestingLayerId[0]             = 0;
    434   scalableNestingSEI.m_callerOwnsSEIs                = true;
    435   Int picSptDpbOutputDuDelay = 0;
    436   UInt *accumBitsDU = NULL;
    437   UInt *accumNalsDU = NULL;
     1090  SEIMessages leadingSeiMessages;
     1091  SEIMessages nestedSeiMessages;
     1092  SEIMessages duInfoSeiMessages;
     1093  SEIMessages trailingSeiMessages;
     1094  std::deque<DUData> duData;
    4381095  SEIDecodingUnitInfo decodingUnitInfoSEI;
    439 #if EFFICIENT_FIELD_IRAP
    440   Int IRAPGOPid = -1;
    441   Bool IRAPtoReorder = false;
    442   Bool swapIRAPForward = false;
    443   if(isField)
    444   {
    445     Int pocCurr;
    446 #if !H_MV
    447     for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
    448 #endif
    449     {
    450       // determine actual POC
    451       if(iPOCLast == 0) //case first frame or first top field
    452       {
    453         pocCurr=0;
    454       }
    455       else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
    456       {
    457         pocCurr = 1;
    458       }
    459       else
    460       {
    461         pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField;
    462       }
    463 
    464       // check if POC corresponds to IRAP
    465       NalUnitType tmpUnitType = getNalUnitType(pocCurr, m_iLastIDR, isField);
    466       if(tmpUnitType >= NAL_UNIT_CODED_SLICE_BLA_W_LP && tmpUnitType <= NAL_UNIT_CODED_SLICE_CRA) // if picture is an IRAP
    467       {
    468         if(pocCurr%2 == 0 && iGOPid < m_iGopSize-1 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid+1).m_POC-1)
    469         { // if top field and following picture in enc order is associated bottom field
    470           IRAPGOPid = iGOPid;
    471           IRAPtoReorder = true;
    472           swapIRAPForward = true;
    473           break;
    474         }
    475         if(pocCurr%2 != 0 && iGOPid > 0 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid-1).m_POC+1)
    476         {
    477           // if picture is an IRAP remember to process it first
    478           IRAPGOPid = iGOPid;
    479           IRAPtoReorder = true;
    480           swapIRAPForward = false;
    481           break;
    482         }
    483       }
    484     }
    485   }
    486 #endif
    487 #if !H_MV
     1096
     1097  EfficientFieldIRAPMapping effFieldIRAPMap;
     1098  if (m_pcCfg->getEfficientFieldIRAPEnabled())
     1099  {
     1100   effFieldIRAPMap.initialize(isField, m_iGopSize, iPOCLast, iNumPicRcvd, m_iLastIDR, this, m_pcCfg);
     1101  }
     1102
     1103  // reset flag indicating whether pictures have been encoded
     1104#if !NH_MV
    4881105  for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
    4891106#endif
    4901107  {
    491 #if EFFICIENT_FIELD_IRAP
    492     if(IRAPtoReorder)
    493     {
    494       if(swapIRAPForward)
    495       {
    496         if(iGOPid == IRAPGOPid)
    497         {
    498           iGOPid = IRAPGOPid +1;
    499         }
    500         else if(iGOPid == IRAPGOPid +1)
    501         {
    502           iGOPid = IRAPGOPid;
    503         }
    504       }
    505       else
    506       {
    507         if(iGOPid == IRAPGOPid -1)
    508         {
    509           iGOPid = IRAPGOPid;
    510         }
    511         else if(iGOPid == IRAPGOPid)
    512         {
    513           iGOPid = IRAPGOPid -1;
    514         }
    515       }
    516     }
    517 #endif
    518     UInt uiColDir = 1;
     1108    m_pcCfg->setEncodedFlag(iGOPid, false);
     1109  }
     1110#if !NH_MV
     1111  for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
     1112#endif
     1113  {
     1114    if (m_pcCfg->getEfficientFieldIRAPEnabled())
     1115    {
     1116      iGOPid=effFieldIRAPMap.adjustGOPid(iGOPid);
     1117    }
     1118
    5191119    //-- For time output for each slice
    520     long iBeforeTime = clock();
    521 
    522     //select uiColDir
    523     Int iCloseLeft=1, iCloseRight=-1;
    524     for(Int i = 0; i<m_pcCfg->getGOPEntry(iGOPid).m_numRefPics; i++)
    525     {
    526       Int iRef = m_pcCfg->getGOPEntry(iGOPid).m_referencePics[i];
    527       if(iRef>0&&(iRef<iCloseRight||iCloseRight==-1))
    528       {
    529         iCloseRight=iRef;
    530       }
    531       else if(iRef<0&&(iRef>iCloseLeft||iCloseLeft==1))
    532       {
    533         iCloseLeft=iRef;
    534       }
    535     }
    536     if(iCloseRight>-1)
    537     {
    538       iCloseRight=iCloseRight+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
    539     }
    540     if(iCloseLeft<1)
    541     {
    542       iCloseLeft=iCloseLeft+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
    543       while(iCloseLeft<0)
    544       {
    545         iCloseLeft+=m_iGopSize;
    546       }
    547     }
    548     Int iLeftQP=0, iRightQP=0;
    549     for(Int i=0; i<m_iGopSize; i++)
    550     {
    551       if(m_pcCfg->getGOPEntry(i).m_POC==(iCloseLeft%m_iGopSize)+1)
    552       {
    553         iLeftQP= m_pcCfg->getGOPEntry(i).m_QPOffset;
    554       }
    555       if (m_pcCfg->getGOPEntry(i).m_POC==(iCloseRight%m_iGopSize)+1)
    556       {
    557         iRightQP=m_pcCfg->getGOPEntry(i).m_QPOffset;
    558       }
    559     }
    560     if(iCloseRight>-1&&iRightQP<iLeftQP)
    561     {
    562       uiColDir=0;
    563     }
     1120    clock_t iBeforeTime = clock();
     1121
     1122    UInt uiColDir = calculateCollocatedFromL1Flag(m_pcCfg, iGOPid, m_iGopSize);
    5641123
    5651124    /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
    5661125    Int iTimeOffset;
    5671126    Int pocCurr;
    568    
    5691127    if(iPOCLast == 0) //case first frame or first top field
    5701128    {
     
    5791137    else
    5801138    {
    581       pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField;
     1139      pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - ((isField && m_iGopSize>1) ? 1:0);
    5821140      iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;
    5831141    }
     1142
    5841143    if(pocCurr>=m_pcCfg->getFramesToBeEncoded())
    5851144    {
    586 #if EFFICIENT_FIELD_IRAP
    587       if(IRAPtoReorder)
    588       {
    589         if(swapIRAPForward)
    590         {
    591           if(iGOPid == IRAPGOPid)
    592           {
    593             iGOPid = IRAPGOPid +1;
    594             IRAPtoReorder = false;
    595           }
    596           else if(iGOPid == IRAPGOPid +1)
    597           {
    598             iGOPid --;
    599           }
    600         }
    601         else
    602         {
    603           if(iGOPid == IRAPGOPid)
    604           {
    605             iGOPid = IRAPGOPid -1;
    606           }
    607           else if(iGOPid == IRAPGOPid -1)
    608           {
    609             iGOPid = IRAPGOPid;
    610             IRAPtoReorder = false;
    611           }
    612         }
    613       }
    614 #endif
    615 #if H_MV
     1145      if (m_pcCfg->getEfficientFieldIRAPEnabled())
     1146      {
     1147        iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);
     1148      }
     1149#if NH_MV
    6161150      delete pcBitstreamRedirect;
    6171151      return;
     
    6241158    {
    6251159      m_iLastIDR = pocCurr;
    626     }       
     1160    }
    6271161    // start a new access unit: create an entry in the list of output access units
    6281162    accessUnitsInGOP.push_back(AccessUnit());
    6291163    AccessUnit& accessUnit = accessUnitsInGOP.back();
    630     xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField);
     1164    xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField );
    6311165
    6321166    //  Slice data initialization
    6331167    pcPic->clearSliceBuffer();
    634     assert(pcPic->getNumAllocatedSlice() == 1);
     1168    pcPic->allocateNewSlice();
    6351169    m_pcSliceEncoder->setSliceIdx(0);
    6361170    pcPic->setCurrSliceIdx(0);
    637 
    638 
    639 #if H_MV
    640     m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getVPS(), m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), getLayerId(), isField  );     
     1171#if NH_MV
     1172    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, m_pcEncTop->getVPS(), getLayerId(), isField  );     
    6411173#else
    642     m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), isField );
    643 #endif
    644    
     1174    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iGOPid, pcSlice, isField );
     1175#endif
     1176
    6451177    //Set Frame/Field coding
    6461178    pcSlice->getPic()->setField(isField);
     
    6481180    pcSlice->setLastIDR(m_iLastIDR);
    6491181    pcSlice->setSliceIdx(0);
    650 #if H_MV
     1182#if NH_MV
    6511183    pcSlice->setRefPicSetInterLayer ( &m_refPicSetInterLayer0, &m_refPicSetInterLayer1 );
    6521184    pcPic  ->setLayerId     ( getLayerId()   );
    6531185    pcPic  ->setViewId      ( getViewId()    );   
    654 #if !H_3D
     1186#if !NH_3D
    6551187    pcSlice->setLayerId     ( getLayerId() );
    6561188    pcSlice->setViewId      ( getViewId()  );   
     
    6641196    //set default slice level flag to the same as SPS level flag
    6651197    pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag()  );
    666     pcSlice->setScalingList ( m_pcEncTop->getScalingList()  );
    667     if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_OFF)
    668     {
    669       m_pcEncTop->getTrQuant()->setFlatScalingList();
    670       m_pcEncTop->getTrQuant()->setUseScalingList(false);
    671       m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
    672       m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
    673     }
    674     else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_DEFAULT)
    675     {
    676       pcSlice->setDefaultScalingList ();
    677       m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
    678       m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
    679       m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
    680       m_pcEncTop->getTrQuant()->setUseScalingList(true);
    681     }
    682     else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_FILE_READ)
    683     {
    684       if(pcSlice->getScalingList()->xParseScalingList(m_pcCfg->getScalingListFile()))
    685       {
    686         pcSlice->setDefaultScalingList ();
    687       }
    688       pcSlice->getScalingList()->checkDcOfMatrix();
    689       m_pcEncTop->getSPS()->setScalingListPresentFlag(pcSlice->checkDefaultScalingList());
    690       m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
    691       m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
    692       m_pcEncTop->getTrQuant()->setUseScalingList(true);
    693     }
    694     else
    695     {
    696       printf("error : ScalingList == %d no support\n",m_pcEncTop->getUseScalingListId());
    697       assert(0);
    698     }
    699 
    700 #if H_MV
     1198#if NH_MV
    7011199    // Set the nal unit type
    7021200    pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
     
    7181216    }
    7191217#else
     1218
    7201219    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P')
    7211220    {
     
    7471246      }
    7481247    }
    749 
    750 #if EFFICIENT_FIELD_IRAP
    751 #if FIX1172
     1248    if (m_pcCfg->getEfficientFieldIRAPEnabled())
     1249    {
    7521250    if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
    7531251      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
     
    7621260    pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
    7631261    pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
    764 #endif
    765 #endif
    766     // Do decoding refresh marking if any
    767     pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic);
     1262    }
     1263    // Do decoding refresh marking if any
     1264    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcCfg->getEfficientFieldIRAPEnabled());
    7681265    m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid);
    769     pcSlice->getRPS()->setNumberOfLongtermPictures(0);
    770 #if EFFICIENT_FIELD_IRAP
    771 #else
    772 #if FIX1172
     1266    if (!m_pcCfg->getEfficientFieldIRAPEnabled())
     1267    {
    7731268    if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
    7741269      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
     
    7831278    pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
    7841279    pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
    785 #endif
    786 #endif
    787 
    788 #if ALLOW_RECOVERY_POINT_AS_RAP
     1280    }
    7891281    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP())
    790 #if EFFICIENT_FIELD_IRAP
    791       || (isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1)
    792 #endif
     1282      || (m_pcCfg->getEfficientFieldIRAPEnabled() && isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1)
    7931283      )
    7941284    {
    795       pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3);
    796     }
    797 #else
    798     if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false) != 0) || (pcSlice->isIRAP()))
    799     {
    800       pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP());
    801     }
    802 #endif
     1285      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3, m_pcCfg->getEfficientFieldIRAPEnabled());
     1286    }
     1287
    8031288    pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS());
    8041289
     
    8271312        {
    8281313          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
    829           if(lTid==pcSlice->getTLayer()) 
     1314          if(lTid==pcSlice->getTLayer())
    8301315          {
    831             TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
     1316            const TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
    8321317            for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++)
    8331318            {
    834               if(nRPS->getUsed(jj)) 
     1319              if(nRPS->getUsed(jj))
    8351320              {
    8361321                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
     
    8391324                {
    8401325                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
     1326                  {
    8411327                    break;
     1328                  }
    8421329                }
    8431330                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
     
    8521339        }
    8531340        if(isSTSA==true)
    854         {   
     1341        {
    8551342          if(pcSlice->getTemporalLayerNonReferenceFlag())
    8561343          {
     
    8681355    refPicListModification->setRefPicListModificationFlagL0(0);
    8691356    refPicListModification->setRefPicListModificationFlagL1(0);
    870 #if H_MV
     1357#if NH_MV
    8711358    if ( pcSlice->getPPS()->getNumExtraSliceHeaderBits() > 0 )
    8721359    {
     
    8751362    }   
    8761363
    877     TComVPS*           vps = pcSlice->getVPS();     
    878 #if H_3D
     1364    const TComVPS*           vps = pcSlice->getVPS();     
     1365#if NH_3D
    8791366    Int numDirectRefLayers = vps    ->getNumRefListLayers( getLayerId() );
    8801367#else
    8811368    Int numDirectRefLayers = vps    ->getNumDirectRefLayers( getLayerId() );
    8821369#endif
    883 #if H_3D
     1370#if NH_3D
    8841371    pcSlice->setIvPicLists( m_ivPicLists );         
    8851372
     
    9021389          pcSlice->setNumInterLayerRefPicsMinus1( gopEntry.m_numActiveRefLayerPics - 1 );
    9031390        }
    904 #if H_3D
     1391#if NH_3D
    9051392        if ( gopEntry.m_numActiveRefLayerPics != vps->getNumRefListLayers( getLayerId() ) )
    9061393#else
     
    9271414    assert( pcSlice->getNumActiveRefLayerPics() == gopEntry.m_numActiveRefLayerPics );
    9281415   
    929 #if H_3D
     1416#if NH_3D
    9301417    if ( m_pcEncTop->decProcAnnexI() )
    9311418    {   
    932       pcSlice->deriveInCmpPredAndCpAvailFlag();
     1419      pcSlice->deriveInCmpPredAndCpAvailFlag( );
    9331420      if ( pcSlice->getInCmpPredAvailFlag() )
    9341421      {     
     
    9531440      pcSlice->init3dToolParameters();
    9541441      pcSlice->checkInCompPredRefLayers();
    955     }
    956    
    957 
    958     // This needs to be done after initilizaiton of 3D tool parameters.
     1442    }   
     1443
     1444#if NH_3D_IV_MERGE
     1445    // This needs to be done after initialization of 3D tool parameters.
    9591446    pcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()   + ( ( pcSlice->getMpiFlag( ) || pcSlice->getIvMvPredFlag( ) || pcSlice->getViewSynthesisPredFlag( )   ) ? 1 : 0 ));
     1447#endif
    9601448#endif
    9611449
     
    9761464    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
    9771465#endif
    978 
    979 #if ADAPTIVE_QP_SELECTION
    980     pcSlice->setTrQuant( m_pcEncTop->getTrQuant() );
    981 #endif     
    982 
    9831466    //  Set reference list
    984 #if H_MV   
     1467#if NH_MV   
    9851468    pcSlice->setRefPicList( tempRefPicLists, usedAsLongTerm, numPocTotalCurr );
    9861469#else
    9871470    pcSlice->setRefPicList ( rcListPic );
    9881471#endif
    989 #if H_3D
     1472#if NH_3D_NBDV
    9901473    pcSlice->setDefaultRefView();
    9911474#endif
    992 #if H_3D_ARP
     1475#if NH_3D_ARP
    9931476    //GT: This seems to be broken when layerId in vps is not equal to layerId in nuh
    9941477    pcSlice->setARPStepNum(m_ivPicLists);
    995     if(pcSlice->getARPStepNum() > 1)
    996     {
    997       for(Int iLayerId = 0; iLayerId < getLayerId(); iLayerId ++ )
    998       {
    999         Int  iViewIdx =   pcSlice->getVPS()->getViewIndex(iLayerId);
    1000         Bool bIsDepth = ( pcSlice->getVPS()->getDepthId  ( iLayerId ) == 1 );
    1001         if( iViewIdx<getViewIndex() && !bIsDepth )
    1002         {
    1003           pcSlice->setBaseViewRefPicList( m_ivPicLists->getPicList( iLayerId ), iViewIdx );
    1004         }
    1005       }
    1006     }
    1007 #endif
    1008 #if H_3D_IC
     1478#endif
     1479#if NH_3D_IC
    10091480    pcSlice->setICEnableCandidate( m_aICEnableCandidate );         
    10101481    pcSlice->setICEnableNum( m_aICEnableNum );         
    10111482#endif
     1483
    10121484    //  Slice info. refinement
    1013 #if H_MV
     1485#if NH_MV
    10141486    if ( pcSlice->getSliceType() == B_SLICE )
    10151487    {
     
    10251497    }
    10261498#endif
     1499    pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());
     1500
    10271501    if (pcSlice->getSliceType() == B_SLICE)
    10281502    {
     
    10471521      }
    10481522
    1049       pcSlice->setCheckLDC(bLowDelay); 
     1523      pcSlice->setCheckLDC(bLowDelay);
    10501524    }
    10511525    else
    10521526    {
    1053       pcSlice->setCheckLDC(true); 
     1527      pcSlice->setCheckLDC(true);
    10541528    }
    10551529
     
    10601534
    10611535    pcSlice->setList1IdxToList0Idx();
    1062 #if H_3D_TMVP
     1536#if NH_3D_TMVP
    10631537    if(pcSlice->getLayerId())
    10641538      pcSlice->generateAlterRefforTMVP();
    10651539#endif
     1540
    10661541    if (m_pcEncTop->getTMVPModeId() == 2)
    10671542    {
     
    10751550        pcSlice->setEnableTMVPFlag(1);
    10761551      }
    1077       pcSlice->getSPS()->setTMVPFlagsPresent(1);
    10781552    }
    10791553    else if (m_pcEncTop->getTMVPModeId() == 1)
    10801554    {
    1081       pcSlice->getSPS()->setTMVPFlagsPresent(1);
    10821555      pcSlice->setEnableTMVPFlag(1);
    10831556    }
    10841557    else
    10851558    {
    1086       pcSlice->getSPS()->setTMVPFlagsPresent(0);
    10871559      pcSlice->setEnableTMVPFlag(0);
    10881560    }
    1089 #if H_MV
     1561#if NH_MV
    10901562    if( pcSlice->getIdrPicFlag() )
    10911563    {
     
    10941566#endif
    10951567
    1096 #if H_3D_VSO
     1568#if NH_3D_VSO
    10971569  // Should be moved to TEncTop !!!
    10981570  Bool bUseVSO = m_pcEncTop->getUseVSO();
     
    11281600  }
    11291601#endif
     1602
    11301603    /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
    11311604    //  Slice compression
     
    11441617        for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
    11451618        {
    1146           if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 
     1619          if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) )
    11471620          {
    11481621            bGPBcheck=false;
     
    11611634    }
    11621635    pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
     1636
    11631637
    11641638    Double lambda            = 0.0;
     
    11671641    Int estimatedBits        = 0;
    11681642    Int tmpBitsBeforeWriting = 0;
    1169     if ( m_pcCfg->getUseRateCtrl() )
     1643    if ( m_pcCfg->getUseRateCtrl() ) // TODO: does this work with multiple slices and slice-segments?
    11701644    {
    11711645      Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
     
    11981672      else if ( frameLevel == 0 )   // intra case, but use the model
    11991673      {
    1200         m_pcSliceEncoder->calCostSliceI(pcPic);
     1674        m_pcSliceEncoder->calCostSliceI(pcPic); // TODO: This only analyses the first slice segment - what about the others?
     1675
    12011676        if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case
    12021677        {
     
    12351710      }
    12361711
    1237       sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, sliceQP );
     1712      sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, sliceQP );
    12381713      m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );
    12391714
     
    12411716    }
    12421717
    1243     UInt uiNumSlices = 1;
    1244 
    1245     UInt uiInternalAddress = pcPic->getNumPartInCU()-4;
    1246     UInt uiExternalAddress = pcPic->getPicSym()->getNumberOfCUsInFrame()-1;
    1247     UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
    1248     UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
    1249     UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
    1250     UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
    1251     while(uiPosX>=uiWidth||uiPosY>=uiHeight)
    1252     {
    1253       uiInternalAddress--;
    1254       uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
    1255       uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
    1256     }
    1257     uiInternalAddress++;
    1258     if(uiInternalAddress==pcPic->getNumPartInCU())
    1259     {
    1260       uiInternalAddress = 0;
    1261       uiExternalAddress++;
    1262     }
    1263     UInt uiRealEndAddress = uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress;
    1264 
    1265     Int  p, j;
    1266     UInt uiEncCUAddr;
    1267 
    1268     pcPic->getPicSym()->initTiles(pcSlice->getPPS());
    1269 
    1270     // Allocate some coders, now we know how many tiles there are.
    1271     Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
    1272 
    1273     //generate the Coding Order Map and Inverse Coding Order Map
    1274     for(p=0, uiEncCUAddr=0; p<pcPic->getPicSym()->getNumberOfCUsInFrame(); p++, uiEncCUAddr = pcPic->getPicSym()->xCalculateNxtCUAddr(uiEncCUAddr))
    1275     {
    1276       pcPic->getPicSym()->setCUOrderMap(p, uiEncCUAddr);
    1277       pcPic->getPicSym()->setInverseCUOrderMap(uiEncCUAddr, p);
    1278     }
    1279     pcPic->getPicSym()->setCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());   
    1280     pcPic->getPicSym()->setInverseCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());
    1281 
    1282     // Allocate some coders, now we know how many tiles there are.
    1283     m_pcEncTop->createWPPCoders(iNumSubstreams);
    1284     pcSbacCoders = m_pcEncTop->getSbacCoders();
    1285     pcSubstreamsOut = new TComOutputBitstream[iNumSubstreams];
    1286 
    1287     UInt startCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
    1288     UInt startCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
    1289     pcSlice->setSliceCurStartCUAddr( startCUAddrSlice ); // Setting "start CU addr" for current slice
    1290     m_storedStartCUAddrForEncodingSlice.clear();
    1291 
    1292     UInt startCUAddrSliceSegmentIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
    1293     UInt startCUAddrSliceSegment    = 0; // used to keep track of current Dependent slice's starting CU addr.
    1294     pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment ); // Setting "start CU addr" for current Dependent slice
    1295 
    1296     m_storedStartCUAddrForEncodingSliceSegment.clear();
    1297     UInt nextCUAddr = 0;
    1298     m_storedStartCUAddrForEncodingSlice.push_back (nextCUAddr);
    1299     startCUAddrSliceIdx++;
    1300     m_storedStartCUAddrForEncodingSliceSegment.push_back(nextCUAddr);
    1301     startCUAddrSliceSegmentIdx++;
    1302 #if H_3D_NBDV
     1718    UInt uiNumSliceSegments = 1;
     1719
     1720#if NH_3D_NBDV
    13031721      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.
    13041722      {
    1305         Int iColPoc = pcSlice->getRefPOC(RefPicList(1-pcSlice->getColFromL0Flag()), pcSlice->getColRefIdx());
     1723        Int iColPoc = pcSlice->getRefPOC(RefPicList(1 - pcSlice->getColFromL0Flag()), pcSlice->getColRefIdx());
    13061724        pcPic->setNumDdvCandPics(pcPic->getDisCandRefPictures(iColPoc));
    13071725      }
    13081726#endif
    1309 #if H_3D
     1727#if NH_3D
    13101728      pcSlice->setDepthToDisparityLUTs();
    13111729
    13121730#endif
    13131731
    1314 #if H_3D_NBDV
     1732#if NH_3D_NBDV
    13151733      if(pcSlice->getViewIndex() && !pcSlice->getIsDepth() && !pcSlice->isIntra()) //Notes from QC: this condition shall be changed once the configuration is completed, e.g. in pcSlice->getSPS()->getMultiviewMvPredMode() || ARP in prev. HTM. Remove this comment once it is done.
    13161734      {
     
    13231741      }
    13241742#endif
    1325     while(nextCUAddr<uiRealEndAddress) // determine slice boundaries
    1326     {
    1327       pcSlice->setNextSlice       ( false );
    1328       pcSlice->setNextSliceSegment( false );
    1329       assert(pcPic->getNumAllocatedSlice() == startCUAddrSliceIdx);
    1330       m_pcSliceEncoder->precompressSlice( pcPic );
    1331       m_pcSliceEncoder->compressSlice   ( pcPic );
    1332 
    1333       Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextSliceSegment());
    1334       if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU))
    1335       {
    1336         startCUAddrSlice = pcSlice->getSliceCurEndCUAddr();
    1337         // Reconstruction slice
    1338         m_storedStartCUAddrForEncodingSlice.push_back(startCUAddrSlice);
    1339         startCUAddrSliceIdx++;
    1340         // Dependent slice
    1341         if (startCUAddrSliceSegmentIdx>0 && m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx-1] != startCUAddrSlice)
    1342         {
    1343           m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSlice);
    1344           startCUAddrSliceSegmentIdx++;
    1345         }
    1346 
    1347         if (startCUAddrSlice < uiRealEndAddress)
    1348         {
    1349           pcPic->allocateNewSlice();         
    1350           pcPic->setCurrSliceIdx                  ( startCUAddrSliceIdx-1 );
    1351           m_pcSliceEncoder->setSliceIdx           ( startCUAddrSliceIdx-1 );
    1352           pcSlice = pcPic->getSlice               ( startCUAddrSliceIdx-1 );
    1353           pcSlice->copySliceInfo                  ( pcPic->getSlice(0)      );
    1354           pcSlice->setSliceIdx                    ( startCUAddrSliceIdx-1 );
    1355           pcSlice->setSliceCurStartCUAddr         ( startCUAddrSlice      );
    1356           pcSlice->setSliceSegmentCurStartCUAddr  ( startCUAddrSlice      );
    1357           pcSlice->setSliceBits(0);
    1358           uiNumSlices ++;
    1359         }
    1360       }
    1361       else if (pcSlice->isNextSliceSegment() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU))
    1362       {
    1363         startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
    1364         m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSliceSegment);
    1365         startCUAddrSliceSegmentIdx++;
    1366         pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment );
    1367       }
    1368       else
    1369       {
    1370         startCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
    1371         startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
    1372       }       
    1373 
    1374       nextCUAddr = (startCUAddrSlice > startCUAddrSliceSegment) ? startCUAddrSlice : startCUAddrSliceSegment;
    1375     }
    1376     m_storedStartCUAddrForEncodingSlice.push_back( pcSlice->getSliceCurEndCUAddr());
    1377     startCUAddrSliceIdx++;
    1378     m_storedStartCUAddrForEncodingSliceSegment.push_back(pcSlice->getSliceCurEndCUAddr());
    1379     startCUAddrSliceSegmentIdx++;
    1380 
     1743    // Allocate some coders, now the number of tiles are known.
     1744    const Int numSubstreamsColumns = (pcSlice->getPPS()->getNumTileColumnsMinus1() + 1);
     1745    const Int numSubstreamRows     = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->getFrameHeightInCtus() : (pcSlice->getPPS()->getNumTileRowsMinus1() + 1);
     1746    const Int numSubstreams        = numSubstreamRows * numSubstreamsColumns;
     1747    std::vector<TComOutputBitstream> substreamsOut(numSubstreams);
     1748
     1749    // now compress (trial encode) the various slice segments (slices, and dependent slices)
     1750    {
     1751      const UInt numberOfCtusInFrame=pcPic->getPicSym()->getNumberOfCtusInFrame();
     1752      pcSlice->setSliceCurStartCtuTsAddr( 0 );
     1753      pcSlice->setSliceSegmentCurStartCtuTsAddr( 0 );
     1754
     1755      for(UInt nextCtuTsAddr = 0; nextCtuTsAddr < numberOfCtusInFrame; )
     1756      {
     1757        m_pcSliceEncoder->precompressSlice( pcPic );
     1758        m_pcSliceEncoder->compressSlice   ( pcPic, false, false );
     1759
     1760        const UInt curSliceSegmentEnd = pcSlice->getSliceSegmentCurEndCtuTsAddr();
     1761        if (curSliceSegmentEnd < numberOfCtusInFrame)
     1762        {
     1763          const Bool bNextSegmentIsDependentSlice=curSliceSegmentEnd<pcSlice->getSliceCurEndCtuTsAddr();
     1764          const UInt sliceBits=pcSlice->getSliceBits();
     1765          pcPic->allocateNewSlice();
     1766          // prepare for next slice
     1767          pcPic->setCurrSliceIdx                    ( uiNumSliceSegments );
     1768          m_pcSliceEncoder->setSliceIdx             ( uiNumSliceSegments   );
     1769          pcSlice = pcPic->getSlice                 ( uiNumSliceSegments   );
     1770          assert(pcSlice->getPPS()!=0);
     1771          pcSlice->copySliceInfo                    ( pcPic->getSlice(uiNumSliceSegments-1)  );
     1772          pcSlice->setSliceIdx                      ( uiNumSliceSegments   );
     1773          if (bNextSegmentIsDependentSlice)
     1774          {
     1775            pcSlice->setSliceBits(sliceBits);
     1776          }
     1777          else
     1778          {
     1779            pcSlice->setSliceCurStartCtuTsAddr      ( curSliceSegmentEnd );
     1780            pcSlice->setSliceBits(0);
     1781          }
     1782          pcSlice->setDependentSliceSegmentFlag(bNextSegmentIsDependentSlice);
     1783          pcSlice->setSliceSegmentCurStartCtuTsAddr ( curSliceSegmentEnd );
     1784          // TODO: optimise cabac_init during compress slice to improve multi-slice operation
     1785          // pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());
     1786          uiNumSliceSegments ++;
     1787        }
     1788        nextCtuTsAddr = curSliceSegmentEnd;
     1789      }
     1790    }
     1791
     1792    duData.clear();
    13811793    pcSlice = pcPic->getSlice(0);
    13821794
    1383     // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
    1384     if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoLcuBoundary() )
     1795    // SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
     1796    if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoCtuBoundary() )
    13851797    {
    13861798      m_pcSAO->getPreDBFStatistics(pcPic);
     
    13921804    if ( m_pcCfg->getDeblockingFilterMetric() )
    13931805    {
    1394       dblMetric(pcPic, uiNumSlices);
     1806      applyDeblockingFilterMetric(pcPic, uiNumSliceSegments);
    13951807    }
    13961808    m_pcLoopFilter->loopFilterPic( pcPic );
     
    13981810    /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
    13991811    // Set entropy coder
    1400     m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
    1401 
    1402     /* write various header sets. */
     1812    m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );
    14031813    if ( m_bSeqFirst )
    14041814    {
    1405       OutputNALUnit nalu(NAL_UNIT_VPS);
    1406 #if H_MV
    1407       if( getLayerId() == 0 )
    1408       {
     1815      // write various parameter sets
     1816      actualTotalBits += xWriteParameterSets(accessUnit, pcSlice);
     1817#if PPS_FIX_DEPTH
     1818      if(!pcSlice->getIsDepth() || !pcSlice->getViewIndex() )
     1819      {
     1820#endif
     1821#if PPS_FIX_DEPTH
     1822      }
     1823#endif
     1824
     1825
     1826      // create prefix SEI messages at the beginning of the sequence
     1827      assert(leadingSeiMessages.empty());
     1828      xCreateIRAPLeadingSEIMessages(leadingSeiMessages, pcSlice->getSPS(), pcSlice->getPPS());
     1829
     1830      m_bSeqFirst = false;
     1831    }
     1832
     1833    // reset presence of BP SEI indication
     1834    m_bufferingPeriodSEIPresentInAU = false;
     1835    // create prefix SEI associated with a picture
     1836    xCreatePerPictureSEIMessages(iGOPid, leadingSeiMessages, nestedSeiMessages, pcSlice);
     1837
     1838    /* use the main bitstream buffer for storing the marshalled picture */
     1839    m_pcEntropyCoder->setBitstream(NULL);
     1840
     1841    pcSlice = pcPic->getSlice(0);
     1842
     1843    if (pcSlice->getSPS()->getUseSAO())
     1844    {
     1845      Bool sliceEnabled[MAX_NUM_COMPONENT];
     1846      TComBitCounter tempBitCounter;
     1847      tempBitCounter.resetBits();
     1848      m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(&tempBitCounter);
     1849      m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);
     1850      m_pcSAO->SAOProcess(pcPic, sliceEnabled, pcPic->getSlice(0)->getLambdas(), m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary());
     1851      m_pcSAO->PCMLFDisableProcess(pcPic);
     1852      m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(NULL);
     1853
     1854      //assign SAO slice header
     1855      for(Int s=0; s< uiNumSliceSegments; s++)
     1856      {
     1857        pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, sliceEnabled[COMPONENT_Y]);
     1858        assert(sliceEnabled[COMPONENT_Cb] == sliceEnabled[COMPONENT_Cr]);
     1859        pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, sliceEnabled[COMPONENT_Cb]);
     1860      }
     1861    }
     1862
     1863    // pcSlice is currently slice 0.
     1864    std::size_t binCountsInNalUnits   = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
     1865    std::size_t numBytesInVclNalUnits = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
     1866
     1867    for( UInt sliceSegmentStartCtuTsAddr = 0, sliceIdxCount=0; sliceSegmentStartCtuTsAddr < pcPic->getPicSym()->getNumberOfCtusInFrame(); sliceIdxCount++, sliceSegmentStartCtuTsAddr=pcSlice->getSliceSegmentCurEndCtuTsAddr() )
     1868    {
     1869      pcSlice = pcPic->getSlice(sliceIdxCount);
     1870      if(sliceIdxCount > 0 && pcSlice->getSliceType()!= I_SLICE)
     1871      {
     1872        pcSlice->checkColRefIdx(sliceIdxCount, pcPic);
     1873      }
     1874      pcPic->setCurrSliceIdx(sliceIdxCount);
     1875      m_pcSliceEncoder->setSliceIdx(sliceIdxCount);
     1876
     1877      pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
     1878      pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
     1879
     1880      for ( UInt ui = 0 ; ui < numSubstreams; ui++ )
     1881      {
     1882        substreamsOut[ui].clear();
     1883      }
     1884
     1885      m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );
     1886      m_pcEntropyCoder->resetEntropy      ( pcSlice );
     1887      /* start slice NALunit */
     1888#if NH_MV
     1889      OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), getLayerId() );
     1890#else
     1891      OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
    14091892#endif
    14101893      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1411       m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());
    1412       writeRBSPTrailingBits(nalu.m_Bitstream);
     1894
     1895      pcSlice->setNoRaslOutputFlag(false);
     1896      if (pcSlice->isIRAP())
     1897      {
     1898        if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
     1899        {
     1900          pcSlice->setNoRaslOutputFlag(true);
     1901        }
     1902        //the inference for NoOutputPriorPicsFlag
     1903        // KJS: This cannot happen at the encoder
     1904        if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag())
     1905        {
     1906          if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
     1907          {
     1908            pcSlice->setNoOutputPriorPicsFlag(true);
     1909          }
     1910        }
     1911      }
     1912
     1913      pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());
     1914
     1915      tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
     1916      m_pcEntropyCoder->encodeSliceHeader(pcSlice);
     1917      actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
     1918
     1919      pcSlice->setFinalized(true);
     1920
     1921      pcSlice->clearSubstreamSizes(  );
     1922      {
     1923        UInt numBinsCoded = 0;
     1924        m_pcSliceEncoder->encodeSlice(pcPic, &(substreamsOut[0]), numBinsCoded);
     1925        binCountsInNalUnits+=numBinsCoded;
     1926      }
     1927
     1928      {
     1929        // Construct the final bitstream by concatenating substreams.
     1930        // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
     1931        // Complete the slice header info.
     1932        m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );
     1933        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
     1934        m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
     1935
     1936        // Append substreams...
     1937        TComOutputBitstream *pcOut = pcBitstreamRedirect;
     1938        const Int numZeroSubstreamsAtStartOfSlice  = pcPic->getSubstreamForCtuAddr(pcSlice->getSliceSegmentCurStartCtuTsAddr(), false, pcSlice);
     1939        const Int numSubstreamsToCode  = pcSlice->getNumberOfSubstreamSizes()+1;
     1940        for ( UInt ui = 0 ; ui < numSubstreamsToCode; ui++ )
     1941        {
     1942          pcOut->addSubstream(&(substreamsOut[ui+numZeroSubstreamsAtStartOfSlice]));
     1943        }
     1944      }
     1945
     1946      // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
     1947      // 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.
     1948      Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
     1949      xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
    14131950      accessUnit.push_back(new NALUnitEBSP(nalu));
    14141951      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
    1415 
    1416 #if H_MV
    1417       }
    1418       nalu = NALUnit(NAL_UNIT_SPS, 0, getLayerId());
    1419 #else
    1420       nalu = NALUnit(NAL_UNIT_SPS);
    1421 #endif
    1422       m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1423       if (m_bSeqFirst)
    1424       {
    1425         pcSlice->getSPS()->setNumLongTermRefPicSPS(m_numLongTermRefPicSPS);
    1426         for (Int k = 0; k < m_numLongTermRefPicSPS; k++)
    1427         {
    1428           pcSlice->getSPS()->setLtRefPicPocLsbSps(k, m_ltRefPicPocLsbSps[k]);
    1429           pcSlice->getSPS()->setUsedByCurrPicLtSPSFlag(k, m_ltRefPicUsedByCurrPicFlag[k]);
    1430         }
    1431       }
    1432       if( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
    1433       {
    1434         UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1);
    1435         UInt numDU = ( m_pcCfg->getSliceMode() == 1 ) ? ( pcPic->getNumCUsInFrame() / maxCU ) : ( 0 );
    1436         if( pcPic->getNumCUsInFrame() % maxCU != 0 || numDU == 0 )
    1437         {
    1438           numDU ++;
    1439         }
    1440         pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->setNumDU( numDU );
    1441         pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) );
    1442       }
    1443       if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
    1444       {
    1445         pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true );
    1446       }
    1447       m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
    1448       writeRBSPTrailingBits(nalu.m_Bitstream);
    1449       accessUnit.push_back(new NALUnitEBSP(nalu));
    1450       actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
    1451 
    1452 #if H_MV
    1453       nalu = NALUnit(NAL_UNIT_PPS, 0, getLayerId());
    1454 #else
    1455       nalu = NALUnit(NAL_UNIT_PPS);
    1456 #endif
    1457 #if PPS_FIX_DEPTH
    1458       if(!pcSlice->getIsDepth() || !pcSlice->getViewIndex() )
    1459       {
    1460 #endif
    1461       m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1462       m_pcEntropyCoder->encodePPS(pcSlice->getPPS());
    1463       writeRBSPTrailingBits(nalu.m_Bitstream);
    1464       accessUnit.push_back(new NALUnitEBSP(nalu));
    1465       actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
    1466      
    1467 #if PPS_FIX_DEPTH
    1468       }
    1469 #endif
    1470       xCreateLeadingSEIMessages(accessUnit, pcSlice->getSPS());
    1471 
    1472       m_bSeqFirst = false;
    1473     }
    1474 
    1475     if (writeSOP) // write SOP description SEI (if enabled) at the beginning of GOP
    1476     {
    1477       Int SOPcurrPOC = pocCurr;
    1478 
    1479       OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
    1480       m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    1481       m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1482 
    1483       SEISOPDescription SOPDescriptionSEI;
    1484       SOPDescriptionSEI.m_sopSeqParameterSetId = pcSlice->getSPS()->getSPSId();
    1485 
    1486       UInt i = 0;
    1487       UInt prevEntryId = iGOPid;
    1488       for (j = iGOPid; j < m_iGopSize; j++)
    1489       {
    1490         Int deltaPOC = m_pcCfg->getGOPEntry(j).m_POC - m_pcCfg->getGOPEntry(prevEntryId).m_POC;
    1491         if ((SOPcurrPOC + deltaPOC) < m_pcCfg->getFramesToBeEncoded())
    1492         {
    1493           SOPcurrPOC += deltaPOC;
    1494           SOPDescriptionSEI.m_sopDescVclNaluType[i] = getNalUnitType(SOPcurrPOC, m_iLastIDR, isField);
    1495           SOPDescriptionSEI.m_sopDescTemporalId[i] = m_pcCfg->getGOPEntry(j).m_temporalId;
    1496           SOPDescriptionSEI.m_sopDescStRpsIdx[i] = m_pcEncTop->getReferencePictureSetIdxForSOP(pcSlice, SOPcurrPOC, j);
    1497           SOPDescriptionSEI.m_sopDescPocDelta[i] = deltaPOC;
    1498 
    1499           prevEntryId = j;
    1500           i++;
    1501         }
    1502       }
    1503 
    1504       SOPDescriptionSEI.m_numPicsInSopMinus1 = i - 1;
    1505 
    1506       m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, pcSlice->getSPS());
    1507       writeRBSPTrailingBits(nalu.m_Bitstream);
    1508       accessUnit.push_back(new NALUnitEBSP(nalu));
    1509 
    1510       writeSOP = false;
    1511     }
    1512 
    1513     if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
    1514         ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
    1515         ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
    1516        || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
    1517     {
    1518       if( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() )
    1519       {
    1520         UInt numDU = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumDU();
    1521         pictureTimingSEI.m_numDecodingUnitsMinus1     = ( numDU - 1 );
    1522         pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = false;
    1523 
    1524         if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL )
    1525         {
    1526           pictureTimingSEI.m_numNalusInDuMinus1       = new UInt[ numDU ];
    1527         }
    1528         if( pictureTimingSEI.m_duCpbRemovalDelayMinus1  == NULL )
    1529         {
    1530           pictureTimingSEI.m_duCpbRemovalDelayMinus1  = new UInt[ numDU ];
    1531         }
    1532         if( accumBitsDU == NULL )
    1533         {
    1534           accumBitsDU                                  = new UInt[ numDU ];
    1535         }
    1536         if( accumNalsDU == NULL )
    1537         {
    1538           accumNalsDU                                  = new UInt[ numDU ];
    1539         }
    1540       }
    1541       pictureTimingSEI.m_auCpbRemovalDelay = std::min<Int>(std::max<Int>(1, m_totalCoded - m_lastBPSEI), static_cast<Int>(pow(2, static_cast<double>(pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getCpbRemovalDelayLengthMinus1()+1)))); // Syntax element signalled as minus, hence the .
    1542       pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pcSlice->getPOC() - m_totalCoded;
    1543 #if EFFICIENT_FIELD_IRAP
    1544       if(IRAPGOPid > 0 && IRAPGOPid < m_iGopSize)
    1545       {
    1546         // if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation
    1547         pictureTimingSEI.m_picDpbOutputDelay ++;
    1548       }
    1549 #endif
    1550       Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2;
    1551       pictureTimingSEI.m_picDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
    1552       if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
    1553       {
    1554         picSptDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
    1555       }
    1556     }
    1557 
    1558     if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) &&
    1559         ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
    1560         ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
    1561        || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
    1562     {
    1563       OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
    1564       m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    1565       m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1566 
    1567       SEIBufferingPeriod sei_buffering_period;
    1568      
    1569       UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
    1570       sei_buffering_period.m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
    1571       sei_buffering_period.m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
    1572       sei_buffering_period.m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
    1573       sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
    1574 
    1575       Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
    1576 
    1577       UInt uiTmp = (UInt)( dTmp * 90000.0 );
    1578       uiInitialCpbRemovalDelay -= uiTmp;
    1579       uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
    1580       sei_buffering_period.m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
    1581       sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
    1582       sei_buffering_period.m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
    1583       sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
    1584 
    1585       sei_buffering_period.m_rapCpbParamsPresentFlag              = 0;
    1586       //for the concatenation, it can be set to one during splicing.
    1587       sei_buffering_period.m_concatenationFlag = 0;
    1588       //since the temporal layer HRD is not ready, we assumed it is fixed
    1589       sei_buffering_period.m_auCpbRemovalDelayDelta = 1;
    1590       sei_buffering_period.m_cpbDelayOffset = 0;
    1591       sei_buffering_period.m_dpbDelayOffset = 0;
    1592 
    1593       m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, pcSlice->getSPS());
    1594       writeRBSPTrailingBits(nalu.m_Bitstream);
    1595       {
    1596       UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
    1597       UInt offsetPosition = m_activeParameterSetSEIPresentInAU;   // Insert BP SEI after APS SEI
    1598       AccessUnit::iterator it;
    1599       for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
    1600       {
    1601         it++;
    1602       }
    1603       accessUnit.insert(it, new NALUnitEBSP(nalu));
    1604       m_bufferingPeriodSEIPresentInAU = true;
    1605       }
    1606 
    1607       if (m_pcCfg->getScalableNestingSEIEnabled())
    1608       {
    1609         OutputNALUnit naluTmp(NAL_UNIT_PREFIX_SEI);
    1610         m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    1611         m_pcEntropyCoder->setBitstream(&naluTmp.m_Bitstream);
    1612         scalableNestingSEI.m_nestedSEIs.clear();
    1613         scalableNestingSEI.m_nestedSEIs.push_back(&sei_buffering_period);
    1614         m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
    1615         writeRBSPTrailingBits(naluTmp.m_Bitstream);
    1616         UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
    1617         UInt offsetPosition = m_activeParameterSetSEIPresentInAU + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU;   // Insert BP SEI after non-nested APS, BP and PT SEIs
    1618         AccessUnit::iterator it;
    1619         for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
    1620         {
    1621           it++;
    1622         }
    1623         accessUnit.insert(it, new NALUnitEBSP(naluTmp));
    1624         m_nestedBufferingPeriodSEIPresentInAU = true;
    1625       }
    1626 
    1627       m_lastBPSEI = m_totalCoded;
    1628       m_cpbRemovalDelay = 0;
    1629     }
    1630     m_cpbRemovalDelay ++;
    1631     if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) )
    1632     {
    1633       if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !pcSlice->getRapPicFlag() )
    1634       {
    1635         // Gradual decoding refresh SEI
    1636         OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
    1637         m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    1638         m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1639 
    1640         SEIGradualDecodingRefreshInfo seiGradualDecodingRefreshInfo;
    1641         seiGradualDecodingRefreshInfo.m_gdrForegroundFlag = true; // Indicating all "foreground"
    1642 
    1643         m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, pcSlice->getSPS() );
    1644         writeRBSPTrailingBits(nalu.m_Bitstream);
     1952      numBytesInVclNalUnits += (std::size_t)(accessUnit.back()->m_nalUnitData.str().size());
     1953      bNALUAlignedWrittenToList = true;
     1954
     1955      if (!bNALUAlignedWrittenToList)
     1956      {
     1957        nalu.m_Bitstream.writeAlignZero();
    16451958        accessUnit.push_back(new NALUnitEBSP(nalu));
    1646       }
    1647     // Recovery point SEI
    1648       OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
    1649       m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    1650       m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1651 
    1652       SEIRecoveryPoint sei_recovery_point;
    1653       sei_recovery_point.m_recoveryPocCnt    = 0;
    1654       sei_recovery_point.m_exactMatchingFlag = ( pcSlice->getPOC() == 0 ) ? (true) : (false);
    1655       sei_recovery_point.m_brokenLinkFlag    = false;
    1656 #if ALLOW_RECOVERY_POINT_AS_RAP
    1657       if(m_pcCfg->getDecodingRefreshType() == 3)
    1658       {
    1659         m_iLastRecoveryPicPOC = pocCurr;
    1660       }
    1661 #endif
    1662 
    1663       m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, pcSlice->getSPS() );
    1664       writeRBSPTrailingBits(nalu.m_Bitstream);
    1665       accessUnit.push_back(new NALUnitEBSP(nalu));
    1666     }
    1667 
    1668     /* use the main bitstream buffer for storing the marshalled picture */
    1669     m_pcEntropyCoder->setBitstream(NULL);
    1670 
    1671     startCUAddrSliceIdx = 0;
    1672     startCUAddrSlice    = 0;
    1673 
    1674     startCUAddrSliceSegmentIdx = 0;
    1675     startCUAddrSliceSegment    = 0;
    1676     nextCUAddr                 = 0;
    1677     pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
    1678 
    1679     Int processingState = (pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
    1680     Bool skippedSlice=false;
    1681     while (nextCUAddr < uiRealEndAddress) // Iterate over all slices
    1682     {
    1683       switch(processingState)
    1684       {
    1685       case ENCODE_SLICE:
    1686         {
    1687           pcSlice->setNextSlice       ( false );
    1688           pcSlice->setNextSliceSegment( false );
    1689           if (nextCUAddr == m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx])
    1690           {
    1691             pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
    1692             if(startCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE)
    1693             {
    1694               pcSlice->checkColRefIdx(startCUAddrSliceIdx, pcPic);
    1695             }
    1696             pcPic->setCurrSliceIdx(startCUAddrSliceIdx);
    1697             m_pcSliceEncoder->setSliceIdx(startCUAddrSliceIdx);
    1698             assert(startCUAddrSliceIdx == pcSlice->getSliceIdx());
    1699             // Reconstruction slice
    1700             pcSlice->setSliceCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
    1701             pcSlice->setSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx+1 ] );
    1702             // Dependent slice
    1703             pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
    1704             pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
    1705 
    1706             pcSlice->setNextSlice       ( true );
    1707 
    1708             startCUAddrSliceIdx++;
    1709             startCUAddrSliceSegmentIdx++;
    1710           }
    1711           else if (nextCUAddr == m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx])
    1712           {
    1713             // Dependent slice
    1714             pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
    1715             pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
    1716 
    1717             pcSlice->setNextSliceSegment( true );
    1718 
    1719             startCUAddrSliceSegmentIdx++;
    1720           }
    1721 
    1722           pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
    1723           pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
    1724           UInt uiDummyStartCUAddr;
    1725           UInt uiDummyBoundingCUAddr;
    1726           m_pcSliceEncoder->xDetermineStartAndBoundingCUAddr(uiDummyStartCUAddr,uiDummyBoundingCUAddr,pcPic,true);
    1727 
    1728           uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) % pcPic->getNumPartInCU();
    1729           uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) / pcPic->getNumPartInCU();
    1730           uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
    1731           uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
    1732           uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
    1733           uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
    1734           while(uiPosX>=uiWidth||uiPosY>=uiHeight)
    1735           {
    1736             uiInternalAddress--;
    1737             uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
    1738             uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
    1739           }
    1740           uiInternalAddress++;
    1741           if(uiInternalAddress==pcPic->getNumPartInCU())
    1742           {
    1743             uiInternalAddress = 0;
    1744             uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
    1745           }
    1746           UInt endAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
    1747           if(endAddress<=pcSlice->getSliceSegmentCurStartCUAddr())
    1748           {
    1749             UInt boundingAddrSlice, boundingAddrSliceSegment;
    1750             boundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
    1751             boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
    1752             nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
    1753             if(pcSlice->isNextSlice())
    1754             {
    1755               skippedSlice=true;
    1756             }
    1757             continue;
    1758           }
    1759           if(skippedSlice)
    1760           {
    1761             pcSlice->setNextSlice       ( true );
    1762             pcSlice->setNextSliceSegment( false );
    1763           }
    1764           skippedSlice=false;
    1765           pcSlice->allocSubstreamSizes( iNumSubstreams );
    1766           for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
    1767           {
    1768             pcSubstreamsOut[ui].clear();
    1769           }
    1770 
    1771           m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
    1772           m_pcEntropyCoder->resetEntropy      ();
    1773           /* start slice NALunit */
    1774 #if H_MV
    1775           OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), getLayerId() );
    1776 #else
    1777           OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
    1778 #endif
    1779           Bool sliceSegment = (!pcSlice->isNextSlice());
    1780           if (!sliceSegment)
    1781           {
    1782             uiOneBitstreamPerSliceLength = 0; // start of a new slice
    1783           }
    1784           m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1785 
    1786 #if SETTING_NO_OUT_PIC_PRIOR
    1787           pcSlice->setNoRaslOutputFlag(false);
    1788           if (pcSlice->isIRAP())
    1789           {
    1790             if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
    1791             {
    1792               pcSlice->setNoRaslOutputFlag(true);
    1793             }
    1794             //the inference for NoOutputPriorPicsFlag
    1795             // KJS: This cannot happen at the encoder
    1796             if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag())
    1797             {
    1798               if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
    1799               {
    1800                 pcSlice->setNoOutputPriorPicsFlag(true);
    1801               }
    1802             }
    1803           }
    1804 #endif
    1805 
    1806           tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
    1807           m_pcEntropyCoder->encodeSliceHeader(pcSlice);
    1808           actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
    1809 
    1810           // is it needed?
    1811           {
    1812             if (!sliceSegment)
    1813             {
    1814               pcBitstreamRedirect->writeAlignOne();
    1815             }
    1816             else
    1817             {
    1818               // We've not completed our slice header info yet, do the alignment later.
    1819             }
    1820             m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
    1821             m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
    1822             m_pcEntropyCoder->resetEntropy    ();
    1823             for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
    1824             {
    1825               m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
    1826               m_pcEntropyCoder->resetEntropy    ();
    1827             }
    1828           }
    1829 
    1830           if(pcSlice->isNextSlice())
    1831           {
    1832             // set entropy coder for writing
    1833             m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
    1834             {
    1835               for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
    1836               {
    1837                 m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
    1838                 m_pcEntropyCoder->resetEntropy    ();
    1839               }
    1840               pcSbacCoders[0].load(m_pcSbacCoder);
    1841               m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[0], pcSlice );  //ALF is written in substream #0 with CABAC coder #0 (see ALF param encoding below)
    1842             }
    1843             m_pcEntropyCoder->resetEntropy    ();
    1844             // File writing
    1845             if (!sliceSegment)
    1846             {
    1847               m_pcEntropyCoder->setBitstream(pcBitstreamRedirect);
    1848             }
    1849             else
    1850             {
    1851               m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1852             }
    1853             // for now, override the TILES_DECODER setting in order to write substreams.
    1854             m_pcEntropyCoder->setBitstream    ( &pcSubstreamsOut[0] );
    1855 
    1856           }
    1857           pcSlice->setFinalized(true);
    1858 
    1859           m_pcSbacCoder->load( &pcSbacCoders[0] );
    1860 
    1861           pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength );
    1862             pcSlice->setTileLocationCount ( 0 );
    1863           m_pcSliceEncoder->encodeSlice(pcPic, pcSubstreamsOut);
    1864 
    1865           {
    1866             // Construct the final bitstream by flushing and concatenating substreams.
    1867             // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
    1868             UInt* puiSubstreamSizes = pcSlice->getSubstreamSizes();
    1869             UInt uiTotalCodedSize = 0; // for padding calcs.
    1870             UInt uiNumSubstreamsPerTile = iNumSubstreams;
    1871             if (iNumSubstreams > 1)
    1872             {
    1873               uiNumSubstreamsPerTile /= pcPic->getPicSym()->getNumTiles();
    1874             }
    1875             for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
    1876             {
    1877               // Flush all substreams -- this includes empty ones.
    1878               // Terminating bit and flush.
    1879               m_pcEntropyCoder->setEntropyCoder   ( &pcSbacCoders[ui], pcSlice );
    1880               m_pcEntropyCoder->setBitstream      (  &pcSubstreamsOut[ui] );
    1881               m_pcEntropyCoder->encodeTerminatingBit( 1 );
    1882               m_pcEntropyCoder->encodeSliceFinish();
    1883 
    1884               pcSubstreamsOut[ui].writeByteAlignment();   // Byte-alignment in slice_data() at end of sub-stream
    1885               // Byte alignment is necessary between tiles when tiles are independent.
    1886               uiTotalCodedSize += pcSubstreamsOut[ui].getNumberOfWrittenBits();
    1887 
    1888               Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)&& ((ui+1)%uiNumSubstreamsPerTile == 0);
    1889               if (bNextSubstreamInNewTile)
    1890               {
    1891                 pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
    1892               }
    1893               if (ui+1 < pcSlice->getPPS()->getNumSubstreams())
    1894               {
    1895                 puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits() + (pcSubstreamsOut[ui].countStartCodeEmulations()<<3);
    1896               }
    1897             }
    1898 
    1899             // Complete the slice header info.
    1900             m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
    1901             m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
    1902             m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
    1903 
    1904             // Substreams...
    1905             TComOutputBitstream *pcOut = pcBitstreamRedirect;
    1906           Int offs = 0;
    1907           Int nss = pcSlice->getPPS()->getNumSubstreams();
    1908           if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
    1909           {
    1910             // 1st line present for WPP.
    1911             offs = pcSlice->getSliceSegmentCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
    1912             nss  = pcSlice->getNumEntryPointOffsets()+1;
    1913           }
    1914           for ( UInt ui = 0 ; ui < nss; ui++ )
    1915           {
    1916             pcOut->addSubstream(&pcSubstreamsOut[ui+offs]);
    1917             }
    1918           }
    1919 
    1920           UInt boundingAddrSlice, boundingAddrSliceSegment;
    1921           boundingAddrSlice        = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
    1922           boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
    1923           nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
    1924           // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
    1925           // 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.
    1926           Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
    1927           xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
    1928           accessUnit.push_back(new NALUnitEBSP(nalu));
    1929           actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
    1930           bNALUAlignedWrittenToList = true;
    1931           uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment
    1932 
    1933           if (!bNALUAlignedWrittenToList)
    1934           {
    1935             {
    1936               nalu.m_Bitstream.writeAlignZero();
    1937             }
    1938             accessUnit.push_back(new NALUnitEBSP(nalu));
    1939             uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits() + 24; // length of bitstream after byte-alignment + 3 byte startcode 0x000001
    1940           }
    1941 
    1942           if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
    1943               ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
    1944               ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
    1945              || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
    1946               ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
    1947           {
    1948               UInt numNalus = 0;
    1949             UInt numRBSPBytes = 0;
    1950             for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
    1951             {
    1952               UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
    1953               if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
    1954               {
    1955                 numRBSPBytes += numRBSPBytes_nal;
    1956                 numNalus ++;
    1957               }
    1958             }
    1959             accumBitsDU[ pcSlice->getSliceIdx() ] = ( numRBSPBytes << 3 );
    1960             accumNalsDU[ pcSlice->getSliceIdx() ] = numNalus;   // SEI not counted for bit count; hence shouldn't be counted for # of NALUs - only for consistency
    1961           }
    1962           processingState = ENCODE_SLICE;
    1963           }
    1964           break;
    1965         case EXECUTE_INLOOPFILTER:
    1966           {
    1967             // set entropy coder for RD
    1968             m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
    1969             if ( pcSlice->getSPS()->getUseSAO() )
    1970             {
    1971               m_pcEntropyCoder->resetEntropy();
    1972               m_pcEntropyCoder->setBitstream( m_pcBitCounter );
    1973             Bool sliceEnabled[NUM_SAO_COMPONENTS];
    1974             m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);
    1975             m_pcSAO->SAOProcess(pcPic
    1976               , sliceEnabled
    1977               , pcPic->getSlice(0)->getLambdas()
    1978 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    1979               , m_pcCfg->getSaoLcuBoundary()
    1980 #endif
    1981               );
    1982               m_pcSAO->PCMLFDisableProcess(pcPic);
    1983 
    1984 #if H_3D_DISABLE_CHROMA
    1985             if (pcSlice->getIsDepth())
    1986             {
    1987               sliceEnabled[SAO_Cb] = false;
    1988               sliceEnabled[SAO_Cr] = false;
    1989             }
    1990 #endif
    1991             //assign SAO slice header
    1992             for(Int s=0; s< uiNumSlices; s++)
    1993             {
    1994               pcPic->getSlice(s)->setSaoEnabledFlag(sliceEnabled[SAO_Y]);
    1995               assert(sliceEnabled[SAO_Cb] == sliceEnabled[SAO_Cr]);
    1996               pcPic->getSlice(s)->setSaoEnabledFlagChroma(sliceEnabled[SAO_Cb]);
    1997               }
    1998             }
    1999           processingState = ENCODE_SLICE;
    2000           }
    2001           break;
    2002         default:
    2003           {
    2004             printf("Not a supported encoding state\n");
    2005             assert(0);
    2006             exit(-1);
    2007           }
    2008         }
    2009       } // end iteration over slices
    2010 #if H_3D
    2011       pcPic->compressMotion(2);
    2012 #endif
    2013 #if !H_3D
    2014       pcPic->compressMotion();
    2015 #endif
    2016 #if H_MV
    2017       m_pocLastCoded = pcPic->getPOC();
    2018 #endif
    2019 
    2020       //-- For time output for each slice
    2021       Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
    2022 
    2023       const Char* digestStr = NULL;
    2024       if (m_pcCfg->getDecodedPictureHashSEIEnabled())
    2025       {
    2026         /* calculate MD5sum for entire reconstructed picture */
    2027         SEIDecodedPictureHash sei_recon_picture_digest;
    2028         if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
    2029         {
    2030           sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5;
    2031           calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
    2032           digestStr = digestToString(sei_recon_picture_digest.digest, 16);
    2033         }
    2034         else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
    2035         {
    2036           sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC;
    2037           calcCRC(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
    2038           digestStr = digestToString(sei_recon_picture_digest.digest, 2);
    2039         }
    2040         else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
    2041         {
    2042           sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM;
    2043           calcChecksum(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
    2044           digestStr = digestToString(sei_recon_picture_digest.digest, 4);
    2045         }
    2046 #if H_MV
    2047         OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer(), getLayerId() );
    2048 #else
    2049         OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer());
    2050 #endif
    2051 
    2052         /* write the SEI messages */
    2053         m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    2054         m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, pcSlice->getSPS());
    2055         writeRBSPTrailingBits(nalu.m_Bitstream);
    2056 
    2057         accessUnit.insert(accessUnit.end(), new NALUnitEBSP(nalu));
    2058       }
    2059       if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
    2060       {
    2061         SEITemporalLevel0Index sei_temporal_level0_index;
    2062         if (pcSlice->getRapPicFlag())
    2063         {
    2064           m_tl0Idx = 0;
    2065           m_rapIdx = (m_rapIdx + 1) & 0xFF;
    2066         }
    2067         else
    2068         {
    2069           m_tl0Idx = (m_tl0Idx + (pcSlice->getTLayer() ? 0 : 1)) & 0xFF;
    2070         }
    2071         sei_temporal_level0_index.tl0Idx = m_tl0Idx;
    2072         sei_temporal_level0_index.rapIdx = m_rapIdx;
    2073 
    2074         OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
    2075 
    2076         /* write the SEI messages */
    2077         m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    2078         m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, pcSlice->getSPS());
    2079         writeRBSPTrailingBits(nalu.m_Bitstream);
    2080 
    2081         /* insert the SEI message NALUnit before any Slice NALUnits */
    2082         AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
    2083         accessUnit.insert(it, new NALUnitEBSP(nalu));
    2084       }
    2085 
    2086       xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime );
    2087 
    2088     //In case of field coding, compute the interlaced PSNR for both fields
    2089     if (isField && ((!pcPic->isTopField() && isTff) || (pcPic->isTopField() && !isTff)) && (pcPic->getPOC()%m_iGopSize != 1))
    2090     {
    2091       //get complementary top field
    2092       TComPic* pcPicTop;
    2093       TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
    2094       while ((*iterPic)->getPOC() != pcPic->getPOC()-1)
    2095       {
    2096         iterPic ++;
    2097       }
    2098       pcPicTop = *(iterPic);
    2099       xCalculateInterlacedAddPSNR(pcPicTop, pcPic, pcPicTop->getPicYuvRec(), pcPic->getPicYuvRec(), accessUnit, dEncTime );
    2100     }
    2101     else if (isField && pcPic->getPOC()!= 0 && (pcPic->getPOC()%m_iGopSize == 0))
    2102     {
    2103       //get complementary bottom field
    2104       TComPic* pcPicBottom;
    2105       TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
    2106       while ((*iterPic)->getPOC() != pcPic->getPOC()+1)
    2107       {
    2108         iterPic ++;
    2109       }
    2110       pcPicBottom = *(iterPic);
    2111       xCalculateInterlacedAddPSNR(pcPic, pcPicBottom, pcPic->getPicYuvRec(), pcPicBottom->getPicYuvRec(), accessUnit, dEncTime );
    2112     }
    2113    
    2114       if (digestStr)
    2115       {
    2116         if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
    2117         {
    2118           printf(" [MD5:%s]", digestStr);
    2119         }
    2120         else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
    2121         {
    2122           printf(" [CRC:%s]", digestStr);
    2123         }
    2124         else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
    2125         {
    2126           printf(" [Checksum:%s]", digestStr);
    2127         }
    2128       }
    2129       if ( m_pcCfg->getUseRateCtrl() )
    2130       {
    2131         Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
    2132         Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
    2133         if ( avgLambda < 0.0 )
    2134         {
    2135           avgLambda = lambda;
    2136         }
    2137         m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
    2138         m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
    2139 
    2140         m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
    2141         if ( pcSlice->getSliceType() != I_SLICE )
    2142         {
    2143           m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
    2144         }
    2145         else    // for intra picture, the estimated bits are used to update the current status in the GOP
    2146         {
    2147           m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
    2148         }
    21491959      }
    21501960
    21511961      if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
    21521962          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
    2153           ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
    2154          || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
    2155       {
    2156         TComVUI *vui = pcSlice->getSPS()->getVuiParameters();
    2157         TComHRD *hrd = vui->getHrdParameters();
    2158 
    2159         if( hrd->getSubPicCpbParamsPresentFlag() )
    2160         {
    2161           Int i;
    2162           UInt64 ui64Tmp;
    2163           UInt uiPrev = 0;
    2164           UInt numDU = ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 );
    2165           UInt *pCRD = &pictureTimingSEI.m_duCpbRemovalDelayMinus1[0];
    2166           UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
    2167 
    2168           for( i = 0; i < numDU; i ++ )
    2169           {
    2170             pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] - 1 ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
    2171           }
    2172 
    2173           if( numDU == 1 )
    2174           {
    2175             pCRD[ 0 ] = 0; /* don't care */
    2176           }
    2177           else
    2178           {
    2179             pCRD[ numDU - 1 ] = 0;/* by definition */
    2180             UInt tmp = 0;
    2181             UInt accum = 0;
    2182 
    2183             for( i = ( numDU - 2 ); i >= 0; i -- )
    2184             {
    2185               ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
    2186               if( (UInt)ui64Tmp > maxDiff )
    2187               {
    2188                 tmp ++;
    2189               }
    2190             }
    2191             uiPrev = 0;
    2192 
    2193             UInt flag = 0;
    2194             for( i = ( numDU - 2 ); i >= 0; i -- )
    2195             {
    2196               flag = 0;
    2197               ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
    2198 
    2199               if( (UInt)ui64Tmp > maxDiff )
    2200               {
    2201                 if(uiPrev >= maxDiff - tmp)
    2202                 {
    2203                   ui64Tmp = uiPrev + 1;
    2204                   flag = 1;
    2205                 }
    2206                 else                            ui64Tmp = maxDiff - tmp + 1;
    2207               }
    2208               pCRD[ i ] = (UInt)ui64Tmp - uiPrev - 1;
    2209               if( (Int)pCRD[ i ] < 0 )
    2210               {
    2211                 pCRD[ i ] = 0;
    2212               }
    2213               else if (tmp > 0 && flag == 1)
    2214               {
    2215                 tmp --;
    2216               }
    2217               accum += pCRD[ i ] + 1;
    2218               uiPrev = accum;
    2219             }
    2220           }
    2221         }
    2222         if( m_pcCfg->getPictureTimingSEIEnabled() )
    2223         {
    2224           {
    2225             OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
    2226           m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    2227           pictureTimingSEI.m_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0;
    2228           m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, pcSlice->getSPS());
    2229           writeRBSPTrailingBits(nalu.m_Bitstream);
    2230           UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
    2231           UInt offsetPosition = m_activeParameterSetSEIPresentInAU
    2232                                     + m_bufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
    2233           AccessUnit::iterator it;
    2234           for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
    2235           {
    2236             it++;
    2237           }
    2238           accessUnit.insert(it, new NALUnitEBSP(nalu));
    2239           m_pictureTimingSEIPresentInAU = true;
    2240         }
    2241           if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI
    2242           {
    2243             OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
    2244             m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    2245             scalableNestingSEI.m_nestedSEIs.clear();
    2246             scalableNestingSEI.m_nestedSEIs.push_back(&pictureTimingSEI);
    2247             m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
    2248             writeRBSPTrailingBits(nalu.m_Bitstream);
    2249             UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
    2250             UInt offsetPosition = m_activeParameterSetSEIPresentInAU
    2251               + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU + m_nestedBufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
    2252             AccessUnit::iterator it;
    2253             for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
    2254             {
    2255               it++;
    2256             }
    2257             accessUnit.insert(it, new NALUnitEBSP(nalu));
    2258             m_nestedPictureTimingSEIPresentInAU = true;
    2259           }
    2260         }
    2261         if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
    2262         {             
    2263           m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
    2264           for( Int i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
    2265           {
    2266             OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
    2267 
    2268             SEIDecodingUnitInfo tempSEI;
    2269             tempSEI.m_decodingUnitIdx = i;
    2270             tempSEI.m_duSptCpbRemovalDelay = pictureTimingSEI.m_duCpbRemovalDelayMinus1[i] + 1;
    2271             tempSEI.m_dpbOutputDuDelayPresentFlag = false;
    2272             tempSEI.m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
    2273 
    2274             AccessUnit::iterator it;
    2275             // Insert the first one in the right location, before the first slice
    2276             if(i == 0)
    2277             {
    2278               // Insert before the first slice.
    2279               m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
    2280               writeRBSPTrailingBits(nalu.m_Bitstream);
    2281 
    2282               UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
    2283               UInt offsetPosition = m_activeParameterSetSEIPresentInAU
    2284                                     + m_bufferingPeriodSEIPresentInAU
    2285                                     + m_pictureTimingSEIPresentInAU;  // Insert DU info SEI after APS, BP and PT SEI
    2286               for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
    2287               {
    2288                 it++;
    2289               }
    2290               accessUnit.insert(it, new NALUnitEBSP(nalu));
    2291             }
    2292             else
    2293             {
    2294               Int ctr;
    2295               // For the second decoding unit onwards we know how many NALUs are present
    2296               for (ctr = 0, it = accessUnit.begin(); it != accessUnit.end(); it++)
    2297               {           
    2298                 if(ctr == accumNalsDU[ i - 1 ])
    2299                 {
    2300                   // Insert before the first slice.
    2301                   m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
    2302                   writeRBSPTrailingBits(nalu.m_Bitstream);
    2303 
    2304                   accessUnit.insert(it, new NALUnitEBSP(nalu));
    2305                   break;
    2306                 }
    2307                 if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
    2308                 {
    2309                   ctr++;
    2310                 }
    2311               }
    2312             }           
    2313           }
    2314         }
    2315       }
    2316       xResetNonNestedSEIPresentFlags();
    2317       xResetNestedSEIPresentFlags();
    2318       pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
    2319 
    2320       pcPic->setReconMark   ( true );
    2321 #if H_MV
     1963          ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
     1964         || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
     1965          ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
     1966      {
     1967          UInt numNalus = 0;
     1968        UInt numRBSPBytes = 0;
     1969        for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
     1970        {
     1971          numRBSPBytes += UInt((*it)->m_nalUnitData.str().size());
     1972          numNalus ++;
     1973        }
     1974        duData.push_back(DUData());
     1975        duData.back().accumBitsDU = ( numRBSPBytes << 3 );
     1976        duData.back().accumNalsDU = numNalus;
     1977      }
     1978    } // end iteration over slices
     1979
     1980    // cabac_zero_words processing
     1981    cabac_zero_word_padding(pcSlice, pcPic, binCountsInNalUnits, numBytesInVclNalUnits, accessUnit.back()->m_nalUnitData, m_pcCfg->getCabacZeroWordPaddingEnabled());
     1982#if NH_3D
     1983      pcPic->compressMotion(2);
     1984#else
     1985    pcPic->compressMotion();
     1986#endif
     1987#if NH_MV
     1988      m_pocLastCoded = pcPic->getPOC();
     1989#endif
     1990
     1991    //-- For time output for each slice
     1992    Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
     1993
     1994    std::string digestStr;
     1995    if (m_pcCfg->getDecodedPictureHashSEIEnabled())
     1996    {
     1997      SEIDecodedPictureHash *decodedPictureHashSei = new SEIDecodedPictureHash();
     1998      m_seiEncoder.initDecodedPictureHashSEI(decodedPictureHashSei, pcPic, digestStr, pcSlice->getSPS()->getBitDepths());
     1999      trailingSeiMessages.push_back(decodedPictureHashSei);
     2000    }
     2001    xWriteTrailingSEIMessages(trailingSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS());
     2002
     2003    m_pcCfg->setEncodedFlag(iGOPid, true);
     2004
     2005    xCalculateAddPSNRs( isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, dEncTime, snr_conversion, printFrameMSE );
     2006
     2007    if (!digestStr.empty())
     2008    {
     2009      if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
     2010      {
     2011        printf(" [MD5:%s]", digestStr.c_str());
     2012      }
     2013      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
     2014      {
     2015        printf(" [CRC:%s]", digestStr.c_str());
     2016      }
     2017      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
     2018      {
     2019        printf(" [Checksum:%s]", digestStr.c_str());
     2020      }
     2021    }
     2022
     2023    if ( m_pcCfg->getUseRateCtrl() )
     2024    {
     2025      Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
     2026      Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
     2027      if ( avgLambda < 0.0 )
     2028      {
     2029        avgLambda = lambda;
     2030      }
     2031
     2032      m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
     2033      m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
     2034
     2035      m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
     2036      if ( pcSlice->getSliceType() != I_SLICE )
     2037      {
     2038        m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
     2039      }
     2040      else    // for intra picture, the estimated bits are used to update the current status in the GOP
     2041      {
     2042        m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
     2043      }
     2044    }
     2045
     2046    xCreatePictureTimingSEI(m_pcCfg->getEfficientFieldIRAPEnabled()?effFieldIRAPMap.GetIRAPGOPid():0, leadingSeiMessages, nestedSeiMessages, duInfoSeiMessages, pcSlice, isField, duData);
     2047    if (m_pcCfg->getScalableNestingSEIEnabled())
     2048    {
     2049      xCreateScalableNestingSEI (leadingSeiMessages, nestedSeiMessages);
     2050    }
     2051    xWriteLeadingSEIMessages(leadingSeiMessages, duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData);
     2052    xWriteDuSEIMessages(duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData);
     2053
     2054    pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
     2055
     2056    pcPic->setReconMark   ( true );
     2057#if NH_MV
    23222058      TComSlice::markIvRefPicsAsShortTerm( m_refPicSetInterLayer0, m_refPicSetInterLayer1 ); 
    23232059      std::vector<Int> temp;
    23242060      TComSlice::markCurrPic( pcPic );
    23252061#endif
    2326       m_bFirst = false;
    2327       m_iNumPicCoded++;
    2328       m_totalCoded ++;
    2329       /* logging: insert a newline at end of picture period */
    2330       printf("\n");
    2331       fflush(stdout);
    2332 
    2333       delete[] pcSubstreamsOut;
    2334 
    2335 #if EFFICIENT_FIELD_IRAP
    2336     if(IRAPtoReorder)
    2337     {
    2338       if(swapIRAPForward)
    2339       {
    2340         if(iGOPid == IRAPGOPid)
    2341         {
    2342           iGOPid = IRAPGOPid +1;
    2343           IRAPtoReorder = false;
    2344         }
    2345         else if(iGOPid == IRAPGOPid +1)
    2346         {
    2347           iGOPid --;
    2348         }
    2349       }
    2350       else
    2351       {
    2352         if(iGOPid == IRAPGOPid)
    2353         {
    2354           iGOPid = IRAPGOPid -1;
    2355         }
    2356         else if(iGOPid == IRAPGOPid -1)
    2357         {
    2358           iGOPid = IRAPGOPid;
    2359           IRAPtoReorder = false;
    2360         }
    2361       }
    2362     }
    2363 #endif
    2364   }
     2062    m_bFirst = false;
     2063    m_iNumPicCoded++;
     2064    m_totalCoded ++;
     2065    /* logging: insert a newline at end of picture period */
     2066    printf("\n");
     2067    fflush(stdout);
     2068
     2069    if (m_pcCfg->getEfficientFieldIRAPEnabled())
     2070    {
     2071    iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);
     2072    }
     2073  } // iGOPid-loop
     2074
    23652075  delete pcBitstreamRedirect;
    23662076
    2367   if( accumBitsDU != NULL) delete accumBitsDU;
    2368   if( accumNalsDU != NULL) delete accumNalsDU;
    2369 
    2370 #if !H_MV
    2371   assert ( (m_iNumPicCoded == iNumPicRcvd) || (isField && iPOCLast == 1) );
    2372 #endif
    2373 }
    2374 
    2375 #if !H_MV
    2376 Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, bool isField)
     2077#if !NH_MV
     2078  assert ( (m_iNumPicCoded == iNumPicRcvd) );
     2079#endif
     2080}
     2081
     2082Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths)
    23772083{
    23782084  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
    2379  
    2380    
     2085
     2086
    23812087  //--CFG_KDY
    2382   if(isField)
    2383   {
    2384     m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() * 2);
    2385     m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() * 2);
    2386     m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() * 2);
    2387     m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() * 2);
    2388   }
    2389   else
    2390   {
    2391   m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() );
    2392   m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() );
    2393   m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() );
    2394   m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() );
    2395   }
    2396  
     2088  const Int rateMultiplier=(isField?2:1);
     2089  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
     2090  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
     2091  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
     2092  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
     2093  const ChromaFormat chFmt = m_pcCfg->getChromaFormatIdc();
     2094
    23972095  //-- all
     2096#if NH_MV
     2097  printf( "\n\nSUMMARY -------------------------------------------- LayerId %2d\n", getLayerId() );   
     2098#else
    23982099  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
    2399   m_gcAnalyzeAll.printOut('a');
    2400  
     2100#endif
     2101  m_gcAnalyzeAll.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
     2102
    24012103  printf( "\n\nI Slices--------------------------------------------------------\n" );
    2402   m_gcAnalyzeI.printOut('i');
    2403  
     2104  m_gcAnalyzeI.printOut('i', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
     2105
    24042106  printf( "\n\nP Slices--------------------------------------------------------\n" );
    2405   m_gcAnalyzeP.printOut('p');
    2406  
     2107  m_gcAnalyzeP.printOut('p', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
     2108
    24072109  printf( "\n\nB Slices--------------------------------------------------------\n" );
    2408   m_gcAnalyzeB.printOut('b');
    2409  
    2410 #if _SUMMARY_OUT_
    2411   m_gcAnalyzeAll.printSummaryOut();
    2412 #endif
    2413 #if _SUMMARY_PIC_
    2414   m_gcAnalyzeI.printSummary('I');
    2415   m_gcAnalyzeP.printSummary('P');
    2416   m_gcAnalyzeB.printSummary('B');
    2417 #endif
     2110  m_gcAnalyzeB.printOut('b', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
     2111
     2112  if (!m_pcCfg->getSummaryOutFilename().empty())
     2113  {
     2114    m_gcAnalyzeAll.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryOutFilename());
     2115  }
     2116
     2117  if (!m_pcCfg->getSummaryPicFilenameBase().empty())
     2118  {
     2119    m_gcAnalyzeI.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"I.txt");
     2120    m_gcAnalyzeP.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"P.txt");
     2121    m_gcAnalyzeB.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"B.txt");
     2122  }
    24182123
    24192124  if(isField)
     
    24212126    //-- interlaced summary
    24222127    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
     2128    m_gcAnalyzeAll_in.setBits(m_gcAnalyzeAll.getBits());
     2129    // prior to the above statement, the interlace analyser does not contain the correct total number of bits.
     2130
    24232131    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
    2424     m_gcAnalyzeAll_in.printOutInterlaced('a',  m_gcAnalyzeAll.getBits());
    2425    
    2426 #if _SUMMARY_OUT_
    2427     m_gcAnalyzeAll_in.printSummaryOutInterlaced();
    2428 #endif
     2132    m_gcAnalyzeAll_in.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
     2133
     2134    if (!m_pcCfg->getSummaryOutFilename().empty())
     2135    {
     2136      m_gcAnalyzeAll_in.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryOutFilename());
     2137    }
    24292138  }
    24302139
    24312140  printf("\nRVM: %.3lf\n" , xCalculateRVM());
    24322141}
    2433 #endif
    2434 #if H_3D_VSO
    2435 Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, Dist64& ruiDist, UInt64& ruiBits )
     2142
     2143#if NH_3D_VSO
     2144Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, Dist64& ruiDist )
    24362145#else
    2437 Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
    2438 #endif
    2439 {
    2440   TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
     2146Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist )
     2147#endif
     2148{
    24412149  Bool bCalcDist = false;
    24422150  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
    24432151  m_pcLoopFilter->loopFilterPic( pcPic );
    2444  
    2445   m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
    2446   m_pcEntropyCoder->resetEntropy    ();
    2447   m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
    2448   m_pcEntropyCoder->resetEntropy    ();
    2449   ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
    2450  
     2152
    24512153  if (!bCalcDist)
    2452     ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
     2154  {
     2155    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec(), pcPic->getPicSym()->getSPS().getBitDepths());
     2156  }
    24532157}
    24542158
     
    24582162
    24592163
    2460 Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, bool isField )
     2164Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, Bool isField )
    24612165{
    24622166  assert( iNumPicRcvd > 0 );
     
    24712175  }
    24722176  assert (m_iGopSize > 0);
    2473  
     2177
    24742178  return;
    24752179}
     2180
    24762181
    24772182Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
     
    24822187                         TComPicYuv*&              rpcPicYuvRecOut,
    24832188                         Int                       pocCurr,
    2484                          bool                      isField)
     2189                         Bool                      isField)
    24852190{
    24862191  Int i;
    24872192  //  Rec. output
    24882193  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
    2489  
    2490   if (isField)
    2491   {
    2492     for ( i = 0; i < ( (pocCurr == 0 ) || (pocCurr == 1 ) ? (iNumPicRcvd - iTimeOffset + 1) : (iNumPicRcvd - iTimeOffset + 2) ); i++ )
    2493     {
    2494       iterPicYuvRec--;
    2495     }
    2496   }
    2497   else
    2498   {
    2499     for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
     2194
     2195  if (isField && pocCurr > 1 && m_iGopSize!=1)
     2196  {
     2197    iTimeOffset--;
     2198  }
     2199
     2200  for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
    25002201  {
    25012202    iterPicYuvRec--;
    25022203  }
    2503  
    2504   }
    2505  
    2506   if (isField)
    2507   {
    2508     if(pocCurr == 1)
    2509     {
    2510       iterPicYuvRec++;
    2511     }
    2512   }
     2204
    25132205  rpcPicYuvRecOut = *(iterPicYuvRec);
    2514  
     2206
    25152207  //  Current pic.
    25162208  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
     
    25262218  }
    25272219
    2528 #if !H_MV
    2529   assert( rpcPic != NULL );
     2220#if !NH_MV
     2221  assert (rpcPic != NULL);
    25302222#endif
    25312223  assert (rpcPic->getPOC() == pocCurr);
    2532  
     2224
    25332225  return;
    25342226}
    25352227
    2536 #if H_3D_VSO
    2537 Dist64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
     2228#if NH_3D_VSO
     2229Dist64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1, const BitDepths &bitDepths)
    25382230#else
    2539 UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
    2540 #endif
    2541 {
    2542   Int     x, y;
    2543   Pel*  pSrc0   = pcPic0 ->getLumaAddr();
    2544   Pel*  pSrc1   = pcPic1 ->getLumaAddr();
    2545   UInt  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthY-8);
    2546   Int   iTemp;
    2547  
    2548   Int   iStride = pcPic0->getStride();
    2549   Int   iWidth  = pcPic0->getWidth();
    2550   Int   iHeight = pcPic0->getHeight();
    2551  
    2552 #if H_3D_VSO
     2231UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1, const BitDepths &bitDepths)
     2232#endif
     2233{
     2234#if NH_3D_VSO
    25532235  Dist64  uiTotalDiff = 0;
    25542236#else
    25552237  UInt64  uiTotalDiff = 0;
    25562238#endif
    2557  
    2558   for( y = 0; y < iHeight; y++ )
    2559   {
    2560     for( x = 0; x < iWidth; x++ )
    2561     {
    2562       iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
    2563     }
    2564     pSrc0 += iStride;
    2565     pSrc1 += iStride;
    2566   }
    2567  
    2568   uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthC-8);
    2569   iHeight >>= 1;
    2570   iWidth  >>= 1;
    2571   iStride >>= 1;
    2572  
    2573   pSrc0  = pcPic0->getCbAddr();
    2574   pSrc1  = pcPic1->getCbAddr();
    2575  
    2576   for( y = 0; y < iHeight; y++ )
    2577   {
    2578     for( x = 0; x < iWidth; x++ )
    2579     {
    2580       iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
    2581     }
    2582     pSrc0 += iStride;
    2583     pSrc1 += iStride;
    2584   }
    2585  
    2586   pSrc0  = pcPic0->getCrAddr();
    2587   pSrc1  = pcPic1->getCrAddr();
    2588  
    2589   for( y = 0; y < iHeight; y++ )
    2590   {
    2591     for( x = 0; x < iWidth; x++ )
    2592     {
    2593       iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
    2594     }
    2595     pSrc0 += iStride;
    2596     pSrc1 += iStride;
    2597   }
    2598  
     2239
     2240  for(Int chan=0; chan<pcPic0 ->getNumberValidComponents(); chan++)
     2241  {
     2242    const ComponentID ch=ComponentID(chan);
     2243    Pel*  pSrc0   = pcPic0 ->getAddr(ch);
     2244    Pel*  pSrc1   = pcPic1 ->getAddr(ch);
     2245    UInt  uiShift     = 2 * DISTORTION_PRECISION_ADJUSTMENT(bitDepths.recon[toChannelType(ch)]-8);
     2246
     2247    const Int   iStride = pcPic0->getStride(ch);
     2248    const Int   iWidth  = pcPic0->getWidth(ch);
     2249    const Int   iHeight = pcPic0->getHeight(ch);
     2250
     2251    for(Int y = 0; y < iHeight; y++ )
     2252    {
     2253      for(Int x = 0; x < iWidth; x++ )
     2254      {
     2255        Intermediate_Int iTemp = pSrc0[x] - pSrc1[x];
     2256        uiTotalDiff += UInt64((iTemp*iTemp) >> uiShift);
     2257      }
     2258      pSrc0 += iStride;
     2259      pSrc1 += iStride;
     2260    }
     2261  }
     2262
    25992263  return uiTotalDiff;
    26002264}
    26012265
    2602 #if VERBOSE_RATE
    2603 static const Char* nalUnitTypeToString(NalUnitType type)
    2604 {
    2605   switch (type)
    2606   {
    2607     case NAL_UNIT_CODED_SLICE_TRAIL_R: return "TRAIL_R";
    2608     case NAL_UNIT_CODED_SLICE_TRAIL_N: return "TRAIL_N";
    2609     case NAL_UNIT_CODED_SLICE_TSA_R:      return "TSA_R";
    2610     case NAL_UNIT_CODED_SLICE_TSA_N: return "TSA_N";
    2611     case NAL_UNIT_CODED_SLICE_STSA_R: return "STSA_R";
    2612     case NAL_UNIT_CODED_SLICE_STSA_N: return "STSA_N";
    2613     case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
    2614     case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
    2615     case NAL_UNIT_CODED_SLICE_BLA_N_LP: return "BLA_N_LP";
    2616     case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
    2617     case NAL_UNIT_CODED_SLICE_IDR_N_LP: return "IDR_N_LP";
    2618     case NAL_UNIT_CODED_SLICE_CRA: return "CRA";
    2619     case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
    2620     case NAL_UNIT_CODED_SLICE_RADL_N:     return "RADL_N";
    2621     case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
    2622     case NAL_UNIT_CODED_SLICE_RASL_N:     return "RASL_N";
    2623     case NAL_UNIT_VPS: return "VPS";
    2624     case NAL_UNIT_SPS: return "SPS";
    2625     case NAL_UNIT_PPS: return "PPS";
    2626     case NAL_UNIT_ACCESS_UNIT_DELIMITER: return "AUD";
    2627     case NAL_UNIT_EOS: return "EOS";
    2628     case NAL_UNIT_EOB: return "EOB";
    2629     case NAL_UNIT_FILLER_DATA: return "FILLER";
    2630     case NAL_UNIT_PREFIX_SEI:             return "SEI";
    2631     case NAL_UNIT_SUFFIX_SEI:             return "SEI";
    2632     default: return "UNK";
    2633   }
    2634 }
    2635 #endif
    2636 
    2637 Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime )
    2638 {
    2639   Int     x, y;
    2640   UInt64 uiSSDY  = 0;
    2641   UInt64 uiSSDU  = 0;
    2642   UInt64 uiSSDV  = 0;
    2643  
    2644   Double  dYPSNR  = 0.0;
    2645   Double  dUPSNR  = 0.0;
    2646   Double  dVPSNR  = 0.0;
    2647  
     2266Void TEncGOP::xCalculateAddPSNRs( const Bool isField, const Bool isFieldTopFieldFirst, const Int iGOPid, TComPic* pcPic, const AccessUnit&accessUnit, TComList<TComPic*> &rcListPic, const Double dEncTime, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE )
     2267{
     2268  xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
     2269
     2270  //In case of field coding, compute the interlaced PSNR for both fields
     2271  if(isField)
     2272  {
     2273    Bool bothFieldsAreEncoded = false;
     2274    Int correspondingFieldPOC = pcPic->getPOC();
     2275    Int currentPicGOPPoc = m_pcCfg->getGOPEntry(iGOPid).m_POC;
     2276    if(pcPic->getPOC() == 0)
     2277    {
     2278      // particular case for POC 0 and 1.
     2279      // If they are not encoded first and separately from other pictures, we need to change this
     2280      // POC 0 is always encoded first then POC 1 is encoded
     2281      bothFieldsAreEncoded = false;
     2282    }
     2283    else if(pcPic->getPOC() == 1)
     2284    {
     2285      // if we are at POC 1, POC 0 has been encoded for sure
     2286      correspondingFieldPOC = 0;
     2287      bothFieldsAreEncoded = true;
     2288    }
     2289    else
     2290    {
     2291      if(pcPic->getPOC()%2 == 1)
     2292      {
     2293        correspondingFieldPOC -= 1; // all odd POC are associated with the preceding even POC (e.g poc 1 is associated to poc 0)
     2294        currentPicGOPPoc      -= 1;
     2295      }
     2296      else
     2297      {
     2298        correspondingFieldPOC += 1; // all even POC are associated with the following odd POC (e.g poc 0 is associated to poc 1)
     2299        currentPicGOPPoc      += 1;
     2300      }
     2301      for(Int i = 0; i < m_iGopSize; i ++)
     2302      {
     2303        if(m_pcCfg->getGOPEntry(i).m_POC == currentPicGOPPoc)
     2304        {
     2305          bothFieldsAreEncoded = m_pcCfg->getGOPEntry(i).m_isEncoded;
     2306          break;
     2307        }
     2308      }
     2309    }
     2310
     2311    if(bothFieldsAreEncoded)
     2312    {
     2313      //get complementary top field
     2314      TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
     2315      while ((*iterPic)->getPOC() != correspondingFieldPOC)
     2316      {
     2317        iterPic ++;
     2318      }
     2319      TComPic* correspondingFieldPic = *(iterPic);
     2320
     2321      if( (pcPic->isTopField() && isFieldTopFieldFirst) || (!pcPic->isTopField() && !isFieldTopFieldFirst))
     2322      {
     2323        xCalculateInterlacedAddPSNR(pcPic, correspondingFieldPic, pcPic->getPicYuvRec(), correspondingFieldPic->getPicYuvRec(), snr_conversion, printFrameMSE );
     2324      }
     2325      else
     2326      {
     2327        xCalculateInterlacedAddPSNR(correspondingFieldPic, pcPic, correspondingFieldPic->getPicYuvRec(), pcPic->getPicYuvRec(), snr_conversion, printFrameMSE );
     2328      }
     2329    }
     2330  }
     2331}
     2332
     2333Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime, const InputColourSpaceConversion conversion, const Bool printFrameMSE )
     2334{
     2335  Double  dPSNR[MAX_NUM_COMPONENT];
     2336
     2337  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
     2338  {
     2339    dPSNR[i]=0.0;
     2340  }
     2341
     2342  TComPicYuv cscd;
     2343  if (conversion!=IPCOLOURSPACE_UNCHANGED)
     2344  {
     2345    cscd.create(pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), pcPicD->getChromaFormat(), pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), 0, false);
     2346    TVideoIOYuv::ColourSpaceConvert(*pcPicD, cscd, conversion, false);
     2347  }
     2348  TComPicYuv &picd=(conversion==IPCOLOURSPACE_UNCHANGED)?*pcPicD : cscd;
     2349
    26482350  //===== calculate PSNR =====
    2649   Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
    2650   Pel*  pRec    = pcPicD->getLumaAddr();
    2651   Int   iStride = pcPicD->getStride();
    2652  
    2653   Int   iWidth;
    2654   Int   iHeight;
    2655  
    2656   iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
    2657   iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
    2658  
    2659   Int   iSize   = iWidth*iHeight;
    2660  
    2661   for( y = 0; y < iHeight; y++ )
    2662   {
    2663     for( x = 0; x < iWidth; x++ )
    2664     {
    2665       Int iDiff = (Int)( pOrg[x] - pRec[x] );
    2666       uiSSDY   += iDiff * iDiff;
    2667     }
    2668     pOrg += iStride;
    2669     pRec += iStride;
    2670   }
    2671  
    2672 #if H_3D_VSO
     2351  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
     2352
     2353  for(Int chan=0; chan<pcPicD->getNumberValidComponents(); chan++)
     2354  {
     2355    const ComponentID ch=ComponentID(chan);
     2356    const TComPicYuv *pOrgPicYuv =(conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg() : pcPic ->getPicYuvOrg();
     2357    const Pel*  pOrg       = pOrgPicYuv->getAddr(ch);
     2358    const Int   iOrgStride = pOrgPicYuv->getStride(ch);
     2359    Pel*  pRec    = picd.getAddr(ch);
     2360    const Int   iRecStride = picd.getStride(ch);
     2361
     2362    const Int   iWidth  = pcPicD->getWidth (ch) - (m_pcEncTop->getPad(0) >> pcPic->getComponentScaleX(ch));
     2363    const Int   iHeight = pcPicD->getHeight(ch) - ((m_pcEncTop->getPad(1) >> (pcPic->isField()?1:0)) >> pcPic->getComponentScaleY(ch));
     2364
     2365    Int   iSize   = iWidth*iHeight;
     2366
     2367    UInt64 uiSSDtemp=0;
     2368    for(Int y = 0; y < iHeight; y++ )
     2369    {
     2370      for(Int x = 0; x < iWidth; x++ )
     2371      {
     2372        Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
     2373        uiSSDtemp   += iDiff * iDiff;
     2374      }
     2375      pOrg += iOrgStride;
     2376      pRec += iRecStride;
     2377    }
     2378#if NH_3D_VSO
    26732379#if H_3D_VSO_SYNTH_DIST_OUT
    26742380  if ( m_pcRdCost->getUseRenModel() )
     
    26882394#endif
    26892395#endif
    2690     iHeight >>= 1;
    2691   iWidth  >>= 1;
    2692   iStride >>= 1;
    2693   pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
    2694   pRec  = pcPicD->getCbAddr();
    2695  
    2696   for( y = 0; y < iHeight; y++ )
    2697   {
    2698     for( x = 0; x < iWidth; x++ )
    2699     {
    2700       Int iDiff = (Int)( pOrg[x] - pRec[x] );
    2701       uiSSDU   += iDiff * iDiff;
    2702     }
    2703     pOrg += iStride;
    2704     pRec += iStride;
    2705   }
    2706  
    2707   pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
    2708   pRec  = pcPicD->getCrAddr();
    2709  
    2710   for( y = 0; y < iHeight; y++ )
    2711   {
    2712     for( x = 0; x < iWidth; x++ )
    2713     {
    2714       Int iDiff = (Int)( pOrg[x] - pRec[x] );
    2715       uiSSDV   += iDiff * iDiff;
    2716     }
    2717     pOrg += iStride;
    2718     pRec += iStride;
    2719   }
    2720  
    2721   Int maxvalY = 255 << (g_bitDepthY-8);
    2722   Int maxvalC = 255 << (g_bitDepthC-8);
    2723   Double fRefValueY = (Double) maxvalY * maxvalY * iSize;
    2724   Double fRefValueC = (Double) maxvalC * maxvalC * iSize / 4.0;
    2725   dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
    2726   dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
    2727   dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
    2728 #if H_3D_VSO
     2396    const Int maxval = 255 << (pcPic->getPicSym()->getSPS().getBitDepth(toChannelType(ch)) - 8);
     2397    const Double fRefValue = (Double) maxval * maxval * iSize;
     2398    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
     2399    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize);
     2400  }
     2401
     2402#if NH_3D_VSO
    27292403#if H_3D_VSO_SYNTH_DIST_OUT
    27302404}
    27312405#endif
    2732 #endif
     2406#endif 
    27332407  /* calculate the size of the access unit, excluding:
    27342408   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
     
    27392413  {
    27402414    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
    2741 #if VERBOSE_RATE
     2415    if (m_pcCfg->getSummaryVerboseness() > 0)
     2416    {
    27422417    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
    2743 #endif
     2418    }
    27442419    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
    27452420    {
     
    27522427
    27532428  //===== add PSNR =====
    2754 #if H_MV
    2755   m_pcEncTop->getAnalyzeAll()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
    2756 #else
    2757   m_gcAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
    2758 #endif
     2429  m_gcAnalyzeAll.addResult (dPSNR, (Double)uibits, MSEyuvframe);
     2430
    27592431  TComSlice*  pcSlice = pcPic->getSlice(0);
    27602432  if (pcSlice->isIntra())
    27612433  {
    2762 #if H_MV
    2763     m_pcEncTop->getAnalyzeI()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
    2764 #else
    2765     m_gcAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
    2766 #endif
     2434    m_gcAnalyzeI.addResult (dPSNR, (Double)uibits, MSEyuvframe);
    27672435  }
    27682436  if (pcSlice->isInterP())
    27692437  {
    2770 #if H_MV
    2771     m_pcEncTop->getAnalyzeP()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
    2772 #else
    2773     m_gcAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
    2774 #endif
     2438    m_gcAnalyzeP.addResult (dPSNR, (Double)uibits, MSEyuvframe);
    27752439  }
    27762440  if (pcSlice->isInterB())
    27772441  {
    2778 #if H_MV
    2779     m_pcEncTop->getAnalyzeB()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
    2780 #else
    2781     m_gcAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
    2782 #endif
     2442    m_gcAnalyzeB.addResult (dPSNR, (Double)uibits, MSEyuvframe);
    27832443  }
    27842444
    27852445  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
    2786   if (!pcSlice->isReferenced()) c += 32;
     2446  if (!pcSlice->isReferenced())
     2447  {
     2448    c += 32;
     2449  }
    27872450
    27882451#if ADAPTIVE_QP_SELECTION
    2789 #if H_MV
     2452#if NH_MV
    27902453  printf("Layer %3d   POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d  bits",
    27912454    pcSlice->getLayerId(),
     
    28062469#endif
    28072470#else
    2808 #if H_MV
     2471#if NH_MV
    28092472  printf("Layer %3d   POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
    28102473    pcSlice->getLayerId(),
     
    28232486#endif
    28242487#endif
    2825 
    2826   printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dYPSNR, dUPSNR, dVPSNR );
     2488#if NH_MV
     2489  printf(" [Y %8.4lf dB    U %8.4lf dB    V %8.4lf dB]", dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
     2490#else
     2491  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
     2492#endif
     2493  if (printFrameMSE)
     2494  {
     2495    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
     2496  }
    28272497  printf(" [ET %5.0f ]", dEncTime );
    2828  
     2498
    28292499  for (Int iRefList = 0; iRefList < 2; iRefList++)
    28302500  {
     
    28322502    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
    28332503    {
    2834 #if H_MV
     2504#if NH_MV
    28352505      if( pcSlice->getLayerId() != pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) )
    28362506      {
     
    28412511#endif
    28422512      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
    2843 #if H_MV
     2513#if NH_MV
    28442514      }
    28452515#endif
     
    28472517    printf("]");
    28482518  }
    2849 }
    2850 
    2851 
    2852 Void reinterlace(Pel* top, Pel* bottom, Pel* dst, UInt stride, UInt width, UInt height, bool isTff)
    2853 {
    2854  
    2855   for (Int y = 0; y < height; y++)
    2856   {
    2857     for (Int x = 0; x < width; x++)
    2858     {
    2859       dst[x] = isTff ? top[x] : bottom[x];
    2860       dst[stride+x] = isTff ? bottom[x] : top[x];
    2861     }
    2862     top += stride;
    2863     bottom += stride;
    2864     dst += stride*2;
    2865   }
    2866 }
    2867 
    2868 
    2869 Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgTop, TComPic* pcPicOrgBottom, TComPicYuv* pcPicRecTop, TComPicYuv* pcPicRecBottom, const AccessUnit& accessUnit, Double dEncTime )
    2870 {
    2871 #if  H_MV
     2519
     2520  cscd.destroy();
     2521}
     2522
     2523Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgFirstField, TComPic* pcPicOrgSecondField,
     2524                                           TComPicYuv* pcPicRecFirstField, TComPicYuv* pcPicRecSecondField,
     2525                                           const InputColourSpaceConversion conversion, const Bool printFrameMSE )
     2526{
     2527
     2528#if  NH_MV
    28722529  assert( 0 ); // Field coding and MV need to be aligned.
    28732530#else
    2874   Int     x, y;
    2875  
    2876   UInt64 uiSSDY_in  = 0;
    2877   UInt64 uiSSDU_in  = 0;
    2878   UInt64 uiSSDV_in  = 0;
    2879  
    2880   Double  dYPSNR_in  = 0.0;
    2881   Double  dUPSNR_in  = 0.0;
    2882   Double  dVPSNR_in  = 0.0;
    2883  
    2884   /*------ INTERLACED PSNR -----------*/
    2885  
    2886   /* Luma */
    2887  
    2888   Pel*  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getLumaAddr();
    2889   Pel*  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getLumaAddr();
    2890   Pel*  pRecTop = pcPicRecTop->getLumaAddr();
    2891   Pel*  pRecBottom = pcPicRecBottom->getLumaAddr();
    2892  
    2893   Int   iWidth;
    2894   Int   iHeight;
    2895   Int iStride;
    2896  
    2897   iWidth  = pcPicOrgTop->getPicYuvOrg()->getWidth () - m_pcEncTop->getPad(0);
    2898   iHeight = pcPicOrgTop->getPicYuvOrg()->getHeight() - m_pcEncTop->getPad(1);
    2899   iStride = pcPicOrgTop->getPicYuvOrg()->getStride();
    2900   Int   iSize   = iWidth*iHeight;
    2901   bool isTff = pcPicOrgTop->isTopField();
    2902  
    2903   TComPicYuv* pcOrgInterlaced = new TComPicYuv;
    2904   pcOrgInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
    2905  
    2906   TComPicYuv* pcRecInterlaced = new TComPicYuv;
    2907   pcRecInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
    2908  
    2909   Pel* pOrgInterlaced = pcOrgInterlaced->getLumaAddr();
    2910   Pel* pRecInterlaced = pcRecInterlaced->getLumaAddr();
    2911  
    2912   //=== Interlace fields ====
    2913   reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
    2914   reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
    2915  
     2531
     2532  const TComSPS &sps=pcPicOrgFirstField->getPicSym()->getSPS();
     2533  Double  dPSNR[MAX_NUM_COMPONENT];
     2534  TComPic    *apcPicOrgFields[2]={pcPicOrgFirstField, pcPicOrgSecondField};
     2535  TComPicYuv *apcPicRecFields[2]={pcPicRecFirstField, pcPicRecSecondField};
     2536
     2537  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
     2538  {
     2539    dPSNR[i]=0.0;
     2540  }
     2541
     2542  TComPicYuv cscd[2 /* first/second field */];
     2543  if (conversion!=IPCOLOURSPACE_UNCHANGED)
     2544  {
     2545    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
     2546    {
     2547      TComPicYuv &reconField=*(apcPicRecFields[fieldNum]);
     2548      cscd[fieldNum].create(reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), reconField.getChromaFormat(), reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), 0, false);
     2549      TVideoIOYuv::ColourSpaceConvert(reconField, cscd[fieldNum], conversion, false);
     2550      apcPicRecFields[fieldNum]=cscd+fieldNum;
     2551    }
     2552  }
     2553
    29162554  //===== calculate PSNR =====
    2917   for( y = 0; y < iHeight << 1; y++ )
    2918   {
    2919     for( x = 0; x < iWidth; x++ )
    2920     {
    2921       Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
    2922       uiSSDY_in   += iDiff * iDiff;
    2923     }
    2924     pOrgInterlaced += iStride;
    2925     pRecInterlaced += iStride;
    2926   }
    2927  
    2928   /*Chroma*/
    2929  
    2930   iHeight >>= 1;
    2931   iWidth  >>= 1;
    2932   iStride >>= 1;
    2933  
    2934   pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCbAddr();
    2935   pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCbAddr();
    2936   pRecTop = pcPicRecTop->getCbAddr();
    2937   pRecBottom = pcPicRecBottom->getCbAddr();
    2938   pOrgInterlaced = pcOrgInterlaced->getCbAddr();
    2939   pRecInterlaced = pcRecInterlaced->getCbAddr();
    2940  
    2941   //=== Interlace fields ====
    2942   reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
    2943   reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
    2944  
    2945   //===== calculate PSNR =====
    2946   for( y = 0; y < iHeight << 1; y++ )
    2947   {
    2948     for( x = 0; x < iWidth; x++ )
    2949     {
    2950       Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
    2951       uiSSDU_in   += iDiff * iDiff;
    2952     }
    2953     pOrgInterlaced += iStride;
    2954     pRecInterlaced += iStride;
    2955   }
    2956  
    2957   pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCrAddr();
    2958   pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCrAddr();
    2959   pRecTop = pcPicRecTop->getCrAddr();
    2960   pRecBottom = pcPicRecBottom->getCrAddr();
    2961   pOrgInterlaced = pcOrgInterlaced->getCrAddr();
    2962   pRecInterlaced = pcRecInterlaced->getCrAddr();
    2963  
    2964   //=== Interlace fields ====
    2965   reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
    2966   reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
    2967  
    2968   //===== calculate PSNR =====
    2969   for( y = 0; y < iHeight << 1; y++ )
    2970   {
    2971     for( x = 0; x < iWidth; x++ )
    2972     {
    2973       Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
    2974       uiSSDV_in   += iDiff * iDiff;
    2975     }
    2976     pOrgInterlaced += iStride;
    2977     pRecInterlaced += iStride;
    2978   }
    2979  
    2980   Int maxvalY = 255 << (g_bitDepthY-8);
    2981   Int maxvalC = 255 << (g_bitDepthC-8);
    2982   Double fRefValueY = (Double) maxvalY * maxvalY * iSize*2;
    2983   Double fRefValueC = (Double) maxvalC * maxvalC * iSize*2 / 4.0;
    2984   dYPSNR_in            = ( uiSSDY_in ? 10.0 * log10( fRefValueY / (Double)uiSSDY_in ) : 99.99 );
    2985   dUPSNR_in            = ( uiSSDU_in ? 10.0 * log10( fRefValueC / (Double)uiSSDU_in ) : 99.99 );
    2986   dVPSNR_in            = ( uiSSDV_in ? 10.0 * log10( fRefValueC / (Double)uiSSDV_in ) : 99.99 );
    2987  
    2988   /* calculate the size of the access unit, excluding:
    2989    *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
    2990    *  - SEI NAL units
    2991    */
    2992   UInt numRBSPBytes = 0;
    2993   for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
    2994   {
    2995     UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
    2996    
    2997     if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
    2998       numRBSPBytes += numRBSPBytes_nal;
    2999   }
    3000  
    3001   UInt uibits = numRBSPBytes * 8 ;
    3002  
     2555  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
     2556
     2557  assert(apcPicRecFields[0]->getChromaFormat()==apcPicRecFields[1]->getChromaFormat());
     2558  const UInt numValidComponents=apcPicRecFields[0]->getNumberValidComponents();
     2559
     2560  for(Int chan=0; chan<numValidComponents; chan++)
     2561  {
     2562    const ComponentID ch=ComponentID(chan);
     2563    assert(apcPicRecFields[0]->getWidth(ch)==apcPicRecFields[1]->getWidth(ch));
     2564    assert(apcPicRecFields[0]->getHeight(ch)==apcPicRecFields[1]->getHeight(ch));
     2565
     2566    UInt64 uiSSDtemp=0;
     2567    const Int   iWidth  = apcPicRecFields[0]->getWidth (ch) - (m_pcEncTop->getPad(0) >> apcPicRecFields[0]->getComponentScaleX(ch));
     2568    const Int   iHeight = apcPicRecFields[0]->getHeight(ch) - ((m_pcEncTop->getPad(1) >> 1) >> apcPicRecFields[0]->getComponentScaleY(ch));
     2569
     2570    Int   iSize   = iWidth*iHeight;
     2571
     2572    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
     2573    {
     2574      TComPic *pcPic=apcPicOrgFields[fieldNum];
     2575      TComPicYuv *pcPicD=apcPicRecFields[fieldNum];
     2576
     2577      const Pel*  pOrg    = (conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg()->getAddr(ch) : pcPic ->getPicYuvOrg()->getAddr(ch);
     2578      Pel*  pRec    = pcPicD->getAddr(ch);
     2579      const Int   iStride = pcPicD->getStride(ch);
     2580
     2581
     2582      for(Int y = 0; y < iHeight; y++ )
     2583      {
     2584        for(Int x = 0; x < iWidth; x++ )
     2585        {
     2586          Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
     2587          uiSSDtemp   += iDiff * iDiff;
     2588        }
     2589        pOrg += iStride;
     2590        pRec += iStride;
     2591      }
     2592    }
     2593    const Int maxval = 255 << (sps.getBitDepth(toChannelType(ch)) - 8);
     2594    const Double fRefValue = (Double) maxval * maxval * iSize*2;
     2595    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
     2596    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize*2);
     2597  }
     2598
     2599  UInt uibits = 0; // the number of bits for the pair is not calculated here - instead the overall total is used elsewhere.
     2600
    30032601  //===== add PSNR =====
    3004   m_gcAnalyzeAll_in.addResult (dYPSNR_in, dUPSNR_in, dVPSNR_in, (Double)uibits);
    3005  
    3006   printf("\n                                      Interlaced frame %d: [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", pcPicOrgBottom->getPOC()/2 , dYPSNR_in, dUPSNR_in, dVPSNR_in );
    3007  
    3008   pcOrgInterlaced->destroy();
    3009   delete pcOrgInterlaced;
    3010   pcRecInterlaced->destroy();
    3011   delete pcRecInterlaced;
    3012 #endif
    3013 }
     2602  m_gcAnalyzeAll_in.addResult (dPSNR, (Double)uibits, MSEyuvframe);
     2603
     2604  printf("\n                                      Interlaced frame %d: [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", pcPicOrgSecondField->getPOC()/2 , dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
     2605  if (printFrameMSE)
     2606  {
     2607    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
     2608  }
     2609
     2610  for(UInt fieldNum=0; fieldNum<2; fieldNum++)
     2611  {
     2612    cscd[fieldNum].destroy();
     2613  }
     2614#endif
     2615}
     2616
    30142617/** Function for deciding the nal_unit_type.
    30152618 * \param pocCurr POC of the current picture
    3016  * \returns the nal unit type of the picture
     2619 * \param lastIDR  POC of the last IDR picture
     2620 * \param isField  true to indicate field coding
     2621 * \returns the NAL unit type of the picture
    30172622 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
    30182623 */
     
    30232628    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
    30242629  }
    3025 #if EFFICIENT_FIELD_IRAP
    3026   if(isField && pocCurr == 1)
     2630
     2631  if(m_pcCfg->getEfficientFieldIRAPEnabled() && isField && pocCurr == 1)
    30272632  {
    30282633    // to avoid the picture becoming an IRAP
    30292634    return NAL_UNIT_CODED_SLICE_TRAIL_R;
    30302635  }
    3031 #endif
    3032 
    3033 #if ALLOW_RECOVERY_POINT_AS_RAP
     2636
    30342637  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
    3035 #else
    3036   if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
    3037 #endif
    30382638  {
    30392639    if (m_pcCfg->getDecodingRefreshType() == 1)
     
    30502650    if(pocCurr<m_pocCRA)
    30512651    {
    3052       // All leading pictures are being marked as TFD pictures here since current encoder uses all 
    3053       // reference pictures while encoding leading pictures. An encoder can ensure that a leading 
    3054       // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by 
    3055       // controlling the reference pictures used for encoding that leading picture. Such a leading 
     2652      // All leading pictures are being marked as TFD pictures here since current encoder uses all
     2653      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
     2654      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
     2655      // controlling the reference pictures used for encoding that leading picture. Such a leading
    30562656      // picture need not be marked as a TFD picture.
    30572657      return NAL_UNIT_CODED_SLICE_RASL_R;
     
    30682668}
    30692669
     2670
    30702671Double TEncGOP::xCalculateRVM()
    30712672{
    30722673  Double dRVM = 0;
    3073  
     2674
    30742675  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
    30752676  {
     
    30792680    vRL.resize( N );
    30802681    vB.resize( N );
    3081    
     2682
    30822683    Int i;
    30832684    Double dRavg = 0 , dBavg = 0;
     
    30872688      vRL[i] = 0;
    30882689      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
     2690      {
    30892691        vRL[i] += m_vRVM_RP[j];
     2692      }
    30902693      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
    30912694      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
     
    30932696      dBavg += vB[i];
    30942697    }
    3095    
     2698
    30962699    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
    30972700    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
    3098    
     2701
    30992702    Double dSigamB = 0;
    31002703    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
     
    31042707    }
    31052708    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
    3106    
     2709
    31072710    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
    3108    
     2711
    31092712    dRVM = dSigamB / dRavg * f;
    31102713  }
    3111  
     2714
    31122715  return( dRVM );
    31132716}
    3114 
    31152717/** Attaches the input bitstream to the stream in the output NAL unit
    31162718    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
     
    31182720 *  \param rNalu          target NAL unit
    31192721 */
    3120 Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream*& codedSliceData)
     2722Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream* codedSliceData)
    31212723{
    31222724  // Byte-align
     
    31252727  // Perform bitstream concatenation
    31262728  if (codedSliceData->getNumberOfWrittenBits() > 0)
    3127     {
     2729  {
    31282730    rNalu.m_Bitstream.addSubstream(codedSliceData);
    31292731  }
     
    31342736}
    31352737
    3136 // Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt, 
     2738// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
    31372739// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
    31382740Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
    31392741{
    3140   TComReferencePictureSet *rps = pcSlice->getRPS();
    3141   if(!rps->getNumberOfLongtermPictures())
     2742  if(pcSlice->getRPS()->getNumberOfLongtermPictures() == 0)
    31422743  {
    31432744    return;
    31442745  }
     2746  // we can only modify the local RPS!
     2747  assert (pcSlice->getRPSidx()==-1);
     2748  TComReferencePictureSet *rps = pcSlice->getLocalRPS();
    31452749
    31462750  // Arrange long-term reference pictures in the correct order of LSB and MSB,
     
    31552759  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
    31562760
    3157   // Get the long-term reference pictures 
     2761  // Get the long-term reference pictures
    31582762  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
    31592763  Int i, ctr = 0;
     
    31632767    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
    31642768    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
    3165     indices[ctr]      = i; 
     2769    indices[ctr]      = i;
    31662770    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
    31672771  }
     
    31692773  assert(ctr == numLongPics);
    31702774
    3171   // Arrange pictures in decreasing order of MSB; 
     2775  // Arrange pictures in decreasing order of MSB;
    31722776  for(i = 0; i < numLongPics; i++)
    31732777  {
     
    31882792    // Check if MSB present flag should be enabled.
    31892793    // Check if the buffer contains any pictures that have the same LSB.
    3190     TComList<TComPic*>::iterator  iterPic = rcListPic.begin(); 
     2794    TComList<TComPic*>::iterator  iterPic = rcListPic.begin();
    31912795    TComPic*                      pcPic;
    31922796    while ( iterPic != rcListPic.end() )
     
    32002804        break;
    32012805      }
    3202       iterPic++;     
     2806      iterPic++;
    32032807    }
    32042808  }
     
    32142818  Int currMSB = 0, currLSB = 0;
    32152819  // currPicPoc = currMSB + currLSB
    3216   currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB); 
     2820  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB);
    32172821  currMSB = pcSlice->getPOC() - currLSB;
    32182822
     
    32242828    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
    32252829    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
    3226     rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);     
     2830    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);
    32272831
    32282832    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
     
    32322836    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
    32332837    {
    3234       // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we 
     2838      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
    32352839      // don't have to check the MSB present flag values for this constraint.
    32362840      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
     
    32392843}
    32402844
    3241 /** Function for finding the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
    3242  * \param accessUnit Access Unit of the current picture
    3243  * This function finds the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
    3244  */
    3245 Int TEncGOP::xGetFirstSeiLocation(AccessUnit &accessUnit)
    3246 {
    3247   // Find the location of the first SEI message
    3248   AccessUnit::iterator it;
    3249   Int seiStartPos = 0;
    3250   for(it = accessUnit.begin(); it != accessUnit.end(); it++, seiStartPos++)
    3251   {
    3252      if ((*it)->isSei() || (*it)->isVcl())
    3253      {
    3254        break;
    3255      }               
    3256   }
    3257 //  assert(it != accessUnit.end());  // Triggers with some legit configurations
    3258   return seiStartPos;
    3259 }
    3260 
    3261 Void TEncGOP::dblMetric( TComPic* pcPic, UInt uiNumSlices )
     2845Void TEncGOP::applyDeblockingFilterMetric( TComPic* pcPic, UInt uiNumSlices )
    32622846{
    32632847  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
    3264   Pel* Rec    = pcPicYuvRec->getLumaAddr( 0 );
     2848  Pel* Rec    = pcPicYuvRec->getAddr(COMPONENT_Y);
    32652849  Pel* tempRec = Rec;
    3266   Int  stride = pcPicYuvRec->getStride();
     2850  Int  stride = pcPicYuvRec->getStride(COMPONENT_Y);
    32672851  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
    32682852  UInt maxTBsize = (1<<log2maxTB);
    32692853  const UInt minBlockArtSize = 8;
    3270   const UInt picWidth = pcPicYuvRec->getWidth();
    3271   const UInt picHeight = pcPicYuvRec->getHeight();
     2854  const UInt picWidth = pcPicYuvRec->getWidth(COMPONENT_Y);
     2855  const UInt picHeight = pcPicYuvRec->getHeight(COMPONENT_Y);
    32722856  const UInt noCol = (picWidth>>log2maxTB);
    32732857  const UInt noRows = (picHeight>>log2maxTB);
     
    32792863  UInt rowIdx = 0;
    32802864  Pel p0, p1, p2, q0, q1, q2;
    3281  
     2865
    32822866  Int qp = pcPic->getSlice(0)->getSliceQp();
    3283   Int bitdepthScale = 1 << (g_bitDepthY-8);
     2867  const Int bitDepthLuma=pcPic->getSlice(0)->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
     2868  Int bitdepthScale = 1 << (bitDepthLuma-8);
    32842869  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
    32852870  const Int thr2 = (beta>>2);
    32862871  const Int thr1 = 2*bitdepthScale;
    32872872  UInt a = 0;
    3288  
     2873
    32892874  memset(colSAD, 0, noCol*sizeof(UInt64));
    32902875  memset(rowSAD, 0, noRows*sizeof(UInt64));
    3291  
     2876
    32922877  if (maxTBsize > minBlockArtSize)
    32932878  {
     
    33132898      Rec = tempRec;
    33142899    }
    3315    
     2900
    33162901    // Analyze horizontal artifact edges
    33172902    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
     
    33342919    }
    33352920  }
    3336  
     2921
    33372922  UInt64 colSADsum = 0;
    33382923  UInt64 rowSADsum = 0;
     
    33452930    rowSADsum += rowSAD[r];
    33462931  }
    3347  
     2932
    33482933  colSADsum <<= 10;
    33492934  rowSADsum <<= 10;
     
    33522937  rowSADsum /= (noRows-1);
    33532938  rowSADsum /= picWidth;
    3354  
     2939
    33552940  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
    3356   avgSAD >>= (g_bitDepthY-8);
    3357  
     2941  avgSAD >>= (bitDepthLuma-8);
     2942
    33582943  if ( avgSAD > 2048 )
    33592944  {
     
    33782963    }
    33792964  }
    3380  
     2965
    33812966  free(colSAD);
    33822967  free(rowSAD);
    33832968}
    33842969
    3385 #if H_MV
     2970#if NH_MV
    33862971Void TEncGOP::xSetRefPicListModificationsMv( std::vector<TComPic*> tempPicLists[2], TComSlice* pcSlice, UInt iGOPid )
    33872972{
Note: See TracChangeset for help on using the changeset viewer.