Changeset 1313 in 3DVCSoftware for trunk/source/Lib/TLibEncoder/TEncGOP.cpp
- Timestamp:
- 13 Aug 2015, 17:38:13 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/Lib/TLibEncoder/TEncGOP.cpp
r1196 r1313 2 2 * License, included below. This software may be subject to other third party 3 3 * and contributor rights, including patent rights, and no such rights are 4 * granted under this license. 4 * granted under this license. 5 5 * 6 * Copyright (c) 2010-2015, ITU/ISO/IEC6 * Copyright (c) 2010-2015, ITU/ISO/IEC 7 7 * All rights reserved. 8 8 * … … 50 50 #include <math.h> 51 51 52 #include <deque> 52 53 using namespace std; 54 53 55 //! \ingroup TLibEncoder 54 56 //! \{ … … 75 77 m_iNumPicCoded = 0; //Niko 76 78 m_bFirst = true; 77 #if ALLOW_RECOVERY_POINT_AS_RAP78 79 m_iLastRecoveryPicPOC = 0; 79 #endif 80 80 81 81 m_pcCfg = NULL; 82 82 m_pcSliceEncoder = NULL; 83 83 m_pcListPic = NULL; 84 84 85 85 m_pcEntropyCoder = NULL; 86 86 m_pcCavlcCoder = NULL; 87 87 m_pcSbacCoder = NULL; 88 88 m_pcBinCABAC = NULL; 89 89 90 90 m_bSeqFirst = true; 91 91 92 92 m_bRefreshPending = 0; 93 93 m_pocCRA = 0; … … 95 95 ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps)); 96 96 ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag)); 97 m_cpbRemovalDelay = 0;98 97 m_lastBPSEI = 0; 99 xResetNonNestedSEIPresentFlags(); 100 xResetNestedSEIPresentFlags(); 101 #if H_MV 98 m_bufferingPeriodSEIPresentInAU = false; 99 #if NH_MV 102 100 m_layerId = 0; 103 101 m_viewId = 0; 104 102 m_pocLastCoded = -1; 105 #if H_3D103 #if NH_3D 106 104 m_viewIndex = 0; 107 105 m_isDepth = false; 108 106 #endif 109 107 #endif 110 #if FIX1172111 108 m_associatedIRAPType = NAL_UNIT_CODED_SLICE_IDR_N_LP; 112 109 m_associatedIRAPPOC = 0; 113 #endif114 110 return; 115 111 } … … 119 115 } 120 116 121 /** Create list to contain pointers to LCU start addresses of slice.117 /** Create list to contain pointers to CTU start addresses of slice. 122 118 */ 123 119 Void TEncGOP::create() … … 135 131 m_pcEncTop = pcTEncTop; 136 132 m_pcCfg = pcTEncTop; 133 m_seiEncoder.init(m_pcCfg, pcTEncTop, this); 137 134 m_pcSliceEncoder = pcTEncTop->getSliceEncoder(); 138 135 m_pcListPic = pcTEncTop->getListPic(); 139 136 140 137 m_pcEntropyCoder = pcTEncTop->getEntropyCoder(); 141 138 m_pcCavlcCoder = pcTEncTop->getCavlcCoder(); … … 143 140 m_pcBinCABAC = pcTEncTop->getBinCABAC(); 144 141 m_pcLoopFilter = pcTEncTop->getLoopFilter(); 145 m_pcBitCounter = pcTEncTop->getBitCounter(); 146 147 //--Adaptive Loop filter 142 148 143 m_pcSAO = pcTEncTop->getSAO(); 149 144 m_pcRateCtrl = pcTEncTop->getRateCtrl(); … … 151 146 m_totalCoded = 0; 152 147 153 #if H_MV148 #if NH_MV 154 149 m_ivPicLists = pcTEncTop->getIvPicLists(); 155 150 m_layerId = pcTEncTop->getLayerId(); 156 151 m_viewId = pcTEncTop->getViewId(); 157 #if H_3D152 #if NH_3D 158 153 m_viewIndex = pcTEncTop->getViewIndex(); 159 154 m_isDepth = pcTEncTop->getIsDepth(); 160 155 #endif 161 156 #endif 162 #if H_3D_IC157 #if NH_3D_IC 163 158 m_aICEnableCandidate = pcTEncTop->getICEnableCandidate(); 164 159 m_aICEnableNum = pcTEncTop->getICEnableNum(); … … 169 164 } 170 165 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 { 166 Int 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 175 Int 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 189 Int 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 203 Int 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 222 Void 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 239 Void 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 261 Void 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 274 Void 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 342 Void 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 361 Void 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 369 Void 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 412 Void 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 328 417 OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); 329 418 #endif 330 419 if(m_pcCfg->getActiveParameterSetsSEIEnabled()) 331 420 { 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); 341 424 } 342 425 343 426 if(m_pcCfg->getFramePackingArrangementSEIEnabled()) 344 427 { 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 354 440 if (m_pcCfg->getDisplayOrientationSEIAngle()) 355 441 { 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 365 447 if(m_pcCfg->getToneMappingInfoSEIEnabled()) 366 448 { 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 493 Void 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 556 Void 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 571 Void 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 711 Void 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 } 748 Void 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 } 820 Void 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 839 static Void 840 cabac_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 879 class 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 900 Void 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 945 Int 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 975 Int 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 1008 static 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 } 389 1055 } 390 1056 … … 392 1058 // Public member functions 393 1059 // ==================================================================================================================== 394 #if H_MV1060 #if NH_MV 395 1061 Void TEncGOP::initGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP) 396 1062 { 397 xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut,false );1063 xInitGOP( iPOCLast, iNumPicRcvd, false ); 398 1064 m_iNumPicCoded = 0; 399 1065 } 400 1066 #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 1068 Void 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 ) 403 1071 #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; 1072 Void 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; 408 1080 TComPicYuv* pcPicYuvRecOut; 409 1081 TComSlice* pcSlice; … … 411 1083 pcBitstreamRedirect = new TComOutputBitstream; 412 1084 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 421 1089 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; 438 1095 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 488 1105 for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ ) 489 1106 #endif 490 1107 { 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 519 1119 //-- 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); 564 1123 565 1124 /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding 566 1125 Int iTimeOffset; 567 1126 Int pocCurr; 568 569 1127 if(iPOCLast == 0) //case first frame or first top field 570 1128 { … … 579 1137 else 580 1138 { 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); 582 1140 iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC; 583 1141 } 1142 584 1143 if(pocCurr>=m_pcCfg->getFramesToBeEncoded()) 585 1144 { 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 616 1150 delete pcBitstreamRedirect; 617 1151 return; … … 624 1158 { 625 1159 m_iLastIDR = pocCurr; 626 } 1160 } 627 1161 // start a new access unit: create an entry in the list of output access units 628 1162 accessUnitsInGOP.push_back(AccessUnit()); 629 1163 AccessUnit& accessUnit = accessUnitsInGOP.back(); 630 xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField );1164 xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField ); 631 1165 632 1166 // Slice data initialization 633 1167 pcPic->clearSliceBuffer(); 634 assert(pcPic->getNumAllocatedSlice() == 1);1168 pcPic->allocateNewSlice(); 635 1169 m_pcSliceEncoder->setSliceIdx(0); 636 1170 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 ); 641 1173 #else 642 m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, i NumPicRcvd, 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 645 1177 //Set Frame/Field coding 646 1178 pcSlice->getPic()->setField(isField); … … 648 1180 pcSlice->setLastIDR(m_iLastIDR); 649 1181 pcSlice->setSliceIdx(0); 650 #if H_MV1182 #if NH_MV 651 1183 pcSlice->setRefPicSetInterLayer ( &m_refPicSetInterLayer0, &m_refPicSetInterLayer1 ); 652 1184 pcPic ->setLayerId ( getLayerId() ); 653 1185 pcPic ->setViewId ( getViewId() ); 654 #if ! H_3D1186 #if !NH_3D 655 1187 pcSlice->setLayerId ( getLayerId() ); 656 1188 pcSlice->setViewId ( getViewId() ); … … 664 1196 //set default slice level flag to the same as SPS level flag 665 1197 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 701 1199 // Set the nal unit type 702 1200 pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField)); … … 718 1216 } 719 1217 #else 1218 720 1219 if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P') 721 1220 { … … 747 1246 } 748 1247 } 749 750 #if EFFICIENT_FIELD_IRAP 751 #if FIX1172 1248 if (m_pcCfg->getEfficientFieldIRAPEnabled()) 1249 { 752 1250 if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP 753 1251 || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL … … 762 1260 pcSlice->setAssociatedIRAPType(m_associatedIRAPType); 763 1261 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()); 768 1265 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 { 773 1268 if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP 774 1269 || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL … … 783 1278 pcSlice->setAssociatedIRAPType(m_associatedIRAPType); 784 1279 pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC); 785 #endif 786 #endif 787 788 #if ALLOW_RECOVERY_POINT_AS_RAP 1280 } 789 1281 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) 793 1283 ) 794 1284 { 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 803 1288 pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS()); 804 1289 … … 827 1312 { 828 1313 Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId; 829 if(lTid==pcSlice->getTLayer()) 1314 if(lTid==pcSlice->getTLayer()) 830 1315 { 831 TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);1316 const TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii); 832 1317 for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++) 833 1318 { 834 if(nRPS->getUsed(jj)) 1319 if(nRPS->getUsed(jj)) 835 1320 { 836 1321 Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj); … … 839 1324 { 840 1325 if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc) 1326 { 841 1327 break; 1328 } 842 1329 } 843 1330 Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId; … … 852 1339 } 853 1340 if(isSTSA==true) 854 { 1341 { 855 1342 if(pcSlice->getTemporalLayerNonReferenceFlag()) 856 1343 { … … 868 1355 refPicListModification->setRefPicListModificationFlagL0(0); 869 1356 refPicListModification->setRefPicListModificationFlagL1(0); 870 #if H_MV1357 #if NH_MV 871 1358 if ( pcSlice->getPPS()->getNumExtraSliceHeaderBits() > 0 ) 872 1359 { … … 875 1362 } 876 1363 877 TComVPS* vps = pcSlice->getVPS();878 #if H_3D1364 const TComVPS* vps = pcSlice->getVPS(); 1365 #if NH_3D 879 1366 Int numDirectRefLayers = vps ->getNumRefListLayers( getLayerId() ); 880 1367 #else 881 1368 Int numDirectRefLayers = vps ->getNumDirectRefLayers( getLayerId() ); 882 1369 #endif 883 #if H_3D1370 #if NH_3D 884 1371 pcSlice->setIvPicLists( m_ivPicLists ); 885 1372 … … 902 1389 pcSlice->setNumInterLayerRefPicsMinus1( gopEntry.m_numActiveRefLayerPics - 1 ); 903 1390 } 904 #if H_3D1391 #if NH_3D 905 1392 if ( gopEntry.m_numActiveRefLayerPics != vps->getNumRefListLayers( getLayerId() ) ) 906 1393 #else … … 927 1414 assert( pcSlice->getNumActiveRefLayerPics() == gopEntry.m_numActiveRefLayerPics ); 928 1415 929 #if H_3D1416 #if NH_3D 930 1417 if ( m_pcEncTop->decProcAnnexI() ) 931 1418 { 932 pcSlice->deriveInCmpPredAndCpAvailFlag( );1419 pcSlice->deriveInCmpPredAndCpAvailFlag( ); 933 1420 if ( pcSlice->getInCmpPredAvailFlag() ) 934 1421 { … … 953 1440 pcSlice->init3dToolParameters(); 954 1441 pcSlice->checkInCompPredRefLayers(); 955 } 956 957 958 // This needs to be done after initi lizaiton of 3D tool parameters.1442 } 1443 1444 #if NH_3D_IV_MERGE 1445 // This needs to be done after initialization of 3D tool parameters. 959 1446 pcSlice->setMaxNumMergeCand ( m_pcCfg->getMaxNumMergeCand() + ( ( pcSlice->getMpiFlag( ) || pcSlice->getIvMvPredFlag( ) || pcSlice->getViewSynthesisPredFlag( ) ) ? 1 : 0 )); 1447 #endif 960 1448 #endif 961 1449 … … 976 1464 pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures())); 977 1465 #endif 978 979 #if ADAPTIVE_QP_SELECTION980 pcSlice->setTrQuant( m_pcEncTop->getTrQuant() );981 #endif982 983 1466 // Set reference list 984 #if H_MV1467 #if NH_MV 985 1468 pcSlice->setRefPicList( tempRefPicLists, usedAsLongTerm, numPocTotalCurr ); 986 1469 #else 987 1470 pcSlice->setRefPicList ( rcListPic ); 988 1471 #endif 989 #if H_3D1472 #if NH_3D_NBDV 990 1473 pcSlice->setDefaultRefView(); 991 1474 #endif 992 #if H_3D_ARP1475 #if NH_3D_ARP 993 1476 //GT: This seems to be broken when layerId in vps is not equal to layerId in nuh 994 1477 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 1009 1480 pcSlice->setICEnableCandidate( m_aICEnableCandidate ); 1010 1481 pcSlice->setICEnableNum( m_aICEnableNum ); 1011 1482 #endif 1483 1012 1484 // Slice info. refinement 1013 #if H_MV1485 #if NH_MV 1014 1486 if ( pcSlice->getSliceType() == B_SLICE ) 1015 1487 { … … 1025 1497 } 1026 1498 #endif 1499 pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx()); 1500 1027 1501 if (pcSlice->getSliceType() == B_SLICE) 1028 1502 { … … 1047 1521 } 1048 1522 1049 pcSlice->setCheckLDC(bLowDelay); 1523 pcSlice->setCheckLDC(bLowDelay); 1050 1524 } 1051 1525 else 1052 1526 { 1053 pcSlice->setCheckLDC(true); 1527 pcSlice->setCheckLDC(true); 1054 1528 } 1055 1529 … … 1060 1534 1061 1535 pcSlice->setList1IdxToList0Idx(); 1062 #if H_3D_TMVP1536 #if NH_3D_TMVP 1063 1537 if(pcSlice->getLayerId()) 1064 1538 pcSlice->generateAlterRefforTMVP(); 1065 1539 #endif 1540 1066 1541 if (m_pcEncTop->getTMVPModeId() == 2) 1067 1542 { … … 1075 1550 pcSlice->setEnableTMVPFlag(1); 1076 1551 } 1077 pcSlice->getSPS()->setTMVPFlagsPresent(1);1078 1552 } 1079 1553 else if (m_pcEncTop->getTMVPModeId() == 1) 1080 1554 { 1081 pcSlice->getSPS()->setTMVPFlagsPresent(1);1082 1555 pcSlice->setEnableTMVPFlag(1); 1083 1556 } 1084 1557 else 1085 1558 { 1086 pcSlice->getSPS()->setTMVPFlagsPresent(0);1087 1559 pcSlice->setEnableTMVPFlag(0); 1088 1560 } 1089 #if H_MV1561 #if NH_MV 1090 1562 if( pcSlice->getIdrPicFlag() ) 1091 1563 { … … 1094 1566 #endif 1095 1567 1096 #if H_3D_VSO1568 #if NH_3D_VSO 1097 1569 // Should be moved to TEncTop !!! 1098 1570 Bool bUseVSO = m_pcEncTop->getUseVSO(); … … 1128 1600 } 1129 1601 #endif 1602 1130 1603 /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice 1131 1604 // Slice compression … … 1144 1617 for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ ) 1145 1618 { 1146 if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 1619 if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 1147 1620 { 1148 1621 bGPBcheck=false; … … 1161 1634 } 1162 1635 pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag()); 1636 1163 1637 1164 1638 Double lambda = 0.0; … … 1167 1641 Int estimatedBits = 0; 1168 1642 Int tmpBitsBeforeWriting = 0; 1169 if ( m_pcCfg->getUseRateCtrl() ) 1643 if ( m_pcCfg->getUseRateCtrl() ) // TODO: does this work with multiple slices and slice-segments? 1170 1644 { 1171 1645 Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid ); … … 1198 1672 else if ( frameLevel == 0 ) // intra case, but use the model 1199 1673 { 1200 m_pcSliceEncoder->calCostSliceI(pcPic); 1674 m_pcSliceEncoder->calCostSliceI(pcPic); // TODO: This only analyses the first slice segment - what about the others? 1675 1201 1676 if ( m_pcCfg->getIntraPeriod() != 1 ) // do not refine allocated bits for all intra case 1202 1677 { … … 1235 1710 } 1236 1711 1237 sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffset Y(), MAX_QP, sliceQP );1712 sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, sliceQP ); 1238 1713 m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP ); 1239 1714 … … 1241 1716 } 1242 1717 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 1303 1721 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. 1304 1722 { 1305 Int iColPoc = pcSlice->getRefPOC(RefPicList(1 -pcSlice->getColFromL0Flag()), pcSlice->getColRefIdx());1723 Int iColPoc = pcSlice->getRefPOC(RefPicList(1 - pcSlice->getColFromL0Flag()), pcSlice->getColRefIdx()); 1306 1724 pcPic->setNumDdvCandPics(pcPic->getDisCandRefPictures(iColPoc)); 1307 1725 } 1308 1726 #endif 1309 #if H_3D1727 #if NH_3D 1310 1728 pcSlice->setDepthToDisparityLUTs(); 1311 1729 1312 1730 #endif 1313 1731 1314 #if H_3D_NBDV1732 #if NH_3D_NBDV 1315 1733 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. 1316 1734 { … … 1323 1741 } 1324 1742 #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(); 1381 1793 pcSlice = pcPic->getSlice(0); 1382 1794 1383 // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas1384 if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSao LcuBoundary() )1795 // SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas 1796 if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoCtuBoundary() ) 1385 1797 { 1386 1798 m_pcSAO->getPreDBFStatistics(pcPic); … … 1392 1804 if ( m_pcCfg->getDeblockingFilterMetric() ) 1393 1805 { 1394 dblMetric(pcPic, uiNumSlices);1806 applyDeblockingFilterMetric(pcPic, uiNumSliceSegments); 1395 1807 } 1396 1808 m_pcLoopFilter->loopFilterPic( pcPic ); … … 1398 1810 /////////////////////////////////////////////////////////////////////////////////////////////////// File writing 1399 1811 // Set entropy coder 1400 m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice ); 1401 1402 /* write various header sets. */ 1812 m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder ); 1403 1813 if ( m_bSeqFirst ) 1404 1814 { 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() ); 1409 1892 #endif 1410 1893 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); 1413 1950 accessUnit.push_back(new NALUnitEBSP(nalu)); 1414 1951 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(); 1645 1958 accessUnit.push_back(new NALUnitEBSP(nalu)); 1646 }1647 // Recovery point SEI1648 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_RAP1657 if(m_pcCfg->getDecodingRefreshType() == 3)1658 {1659 m_iLastRecoveryPicPOC = pocCurr;1660 }1661 #endif1662 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 slices1682 {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 slice1700 pcSlice->setSliceCurStartCUAddr( nextCUAddr ); // to be used in encodeSlice() + context restriction1701 pcSlice->setSliceCurEndCUAddr ( m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx+1 ] );1702 // Dependent slice1703 pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr ); // to be used in encodeSlice() + context restriction1704 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 slice1714 pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr ); // to be used in encodeSlice() + context restriction1715 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_MV1775 OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), getLayerId() );1776 #else1777 OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );1778 #endif1779 Bool sliceSegment = (!pcSlice->isNextSlice());1780 if (!sliceSegment)1781 {1782 uiOneBitstreamPerSliceLength = 0; // start of a new slice1783 }1784 m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);1785 1786 #if SETTING_NO_OUT_PIC_PRIOR1787 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 NoOutputPriorPicsFlag1795 // KJS: This cannot happen at the encoder1796 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 #endif1805 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 else1817 {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 writing1833 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 writing1845 if (!sliceSegment)1846 {1847 m_pcEntropyCoder->setBitstream(pcBitstreamRedirect);1848 }1849 else1850 {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-stream1885 // 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-alignment1932 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 0x0000011940 }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 consistency1961 }1962 processingState = ENCODE_SLICE;1963 }1964 break;1965 case EXECUTE_INLOOPFILTER:1966 {1967 // set entropy coder for RD1968 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(pcPic1976 , sliceEnabled1977 , pcPic->getSlice(0)->getLambdas()1978 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK1979 , m_pcCfg->getSaoLcuBoundary()1980 #endif1981 );1982 m_pcSAO->PCMLFDisableProcess(pcPic);1983 1984 #if H_3D_DISABLE_CHROMA1985 if (pcSlice->getIsDepth())1986 {1987 sliceEnabled[SAO_Cb] = false;1988 sliceEnabled[SAO_Cr] = false;1989 }1990 #endif1991 //assign SAO slice header1992 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 slices2010 #if H_3D2011 pcPic->compressMotion(2);2012 #endif2013 #if !H_3D2014 pcPic->compressMotion();2015 #endif2016 #if H_MV2017 m_pocLastCoded = pcPic->getPOC();2018 #endif2019 2020 //-- For time output for each slice2021 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_MV2047 OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer(), getLayerId() );2048 #else2049 OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer());2050 #endif2051 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 else2068 {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 fields2089 if (isField && ((!pcPic->isTopField() && isTff) || (pcPic->isTopField() && !isTff)) && (pcPic->getPOC()%m_iGopSize != 1))2090 {2091 //get complementary top field2092 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 field2104 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 GOP2146 {2147 m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );2148 }2149 1959 } 2150 1960 2151 1961 if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) && 2152 1962 ( 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 2322 2058 TComSlice::markIvRefPicsAsShortTerm( m_refPicSetInterLayer0, m_refPicSetInterLayer1 ); 2323 2059 std::vector<Int> temp; 2324 2060 TComSlice::markCurrPic( pcPic ); 2325 2061 #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 2365 2075 delete pcBitstreamRedirect; 2366 2076 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 2082 Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths) 2377 2083 { 2378 2084 assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic()); 2379 2380 2085 2086 2381 2087 //--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 2397 2095 //-- all 2096 #if NH_MV 2097 printf( "\n\nSUMMARY -------------------------------------------- LayerId %2d\n", getLayerId() ); 2098 #else 2398 2099 printf( "\n\nSUMMARY --------------------------------------------------------\n" ); 2399 m_gcAnalyzeAll.printOut('a'); 2400 2100 #endif 2101 m_gcAnalyzeAll.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths); 2102 2401 2103 printf( "\n\nI Slices--------------------------------------------------------\n" ); 2402 m_gcAnalyzeI.printOut('i' );2403 2104 m_gcAnalyzeI.printOut('i', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths); 2105 2404 2106 printf( "\n\nP Slices--------------------------------------------------------\n" ); 2405 m_gcAnalyzeP.printOut('p' );2406 2107 m_gcAnalyzeP.printOut('p', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths); 2108 2407 2109 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 } 2418 2123 2419 2124 if(isField) … … 2421 2126 //-- interlaced summary 2422 2127 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 2423 2131 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 } 2429 2138 } 2430 2139 2431 2140 printf("\nRVM: %.3lf\n" , xCalculateRVM()); 2432 2141 } 2433 #endif 2434 #if H_3D_VSO2435 Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, Dist64& ruiDist , UInt64& ruiBits)2142 2143 #if NH_3D_VSO 2144 Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, Dist64& ruiDist ) 2436 2145 #else 2437 Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits ) 2438 #endif 2439 { 2440 TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx()); 2146 Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist ) 2147 #endif 2148 { 2441 2149 Bool bCalcDist = false; 2442 2150 m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag()); 2443 2151 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 2451 2153 if (!bCalcDist) 2452 ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec()); 2154 { 2155 ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec(), pcPic->getPicSym()->getSPS().getBitDepths()); 2156 } 2453 2157 } 2454 2158 … … 2458 2162 2459 2163 2460 Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, bool isField )2164 Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, Bool isField ) 2461 2165 { 2462 2166 assert( iNumPicRcvd > 0 ); … … 2471 2175 } 2472 2176 assert (m_iGopSize > 0); 2473 2177 2474 2178 return; 2475 2179 } 2180 2476 2181 2477 2182 Void TEncGOP::xGetBuffer( TComList<TComPic*>& rcListPic, … … 2482 2187 TComPicYuv*& rpcPicYuvRecOut, 2483 2188 Int pocCurr, 2484 bool isField)2189 Bool isField) 2485 2190 { 2486 2191 Int i; 2487 2192 // Rec. output 2488 2193 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++ ) 2500 2201 { 2501 2202 iterPicYuvRec--; 2502 2203 } 2503 2504 } 2505 2506 if (isField) 2507 { 2508 if(pocCurr == 1) 2509 { 2510 iterPicYuvRec++; 2511 } 2512 } 2204 2513 2205 rpcPicYuvRecOut = *(iterPicYuvRec); 2514 2206 2515 2207 // Current pic. 2516 2208 TComList<TComPic*>::iterator iterPic = rcListPic.begin(); … … 2526 2218 } 2527 2219 2528 #if ! H_MV2529 assert ( rpcPic != NULL);2220 #if !NH_MV 2221 assert (rpcPic != NULL); 2530 2222 #endif 2531 2223 assert (rpcPic->getPOC() == pocCurr); 2532 2224 2533 2225 return; 2534 2226 } 2535 2227 2536 #if H_3D_VSO2537 Dist64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1 )2228 #if NH_3D_VSO 2229 Dist64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1, const BitDepths &bitDepths) 2538 2230 #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 2231 UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1, const BitDepths &bitDepths) 2232 #endif 2233 { 2234 #if NH_3D_VSO 2553 2235 Dist64 uiTotalDiff = 0; 2554 2236 #else 2555 2237 UInt64 uiTotalDiff = 0; 2556 2238 #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 2599 2263 return uiTotalDiff; 2600 2264 } 2601 2265 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 2266 Void 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 2333 Void 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 2648 2350 //===== 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 2673 2379 #if H_3D_VSO_SYNTH_DIST_OUT 2674 2380 if ( m_pcRdCost->getUseRenModel() ) … … 2688 2394 #endif 2689 2395 #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 2729 2403 #if H_3D_VSO_SYNTH_DIST_OUT 2730 2404 } 2731 2405 #endif 2732 #endif 2406 #endif 2733 2407 /* calculate the size of the access unit, excluding: 2734 2408 * - any AnnexB contributions (start_code_prefix, zero_byte, etc.,) … … 2739 2413 { 2740 2414 UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size()); 2741 #if VERBOSE_RATE 2415 if (m_pcCfg->getSummaryVerboseness() > 0) 2416 { 2742 2417 printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal); 2743 #endif 2418 } 2744 2419 if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI) 2745 2420 { … … 2752 2427 2753 2428 //===== 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 2759 2431 TComSlice* pcSlice = pcPic->getSlice(0); 2760 2432 if (pcSlice->isIntra()) 2761 2433 { 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); 2767 2435 } 2768 2436 if (pcSlice->isInterP()) 2769 2437 { 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); 2775 2439 } 2776 2440 if (pcSlice->isInterB()) 2777 2441 { 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); 2783 2443 } 2784 2444 2785 2445 Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B'); 2786 if (!pcSlice->isReferenced()) c += 32; 2446 if (!pcSlice->isReferenced()) 2447 { 2448 c += 32; 2449 } 2787 2450 2788 2451 #if ADAPTIVE_QP_SELECTION 2789 #if H_MV2452 #if NH_MV 2790 2453 printf("Layer %3d POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits", 2791 2454 pcSlice->getLayerId(), … … 2806 2469 #endif 2807 2470 #else 2808 #if H_MV2471 #if NH_MV 2809 2472 printf("Layer %3d POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits", 2810 2473 pcSlice->getLayerId(), … … 2823 2486 #endif 2824 2487 #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 } 2827 2497 printf(" [ET %5.0f ]", dEncTime ); 2828 2498 2829 2499 for (Int iRefList = 0; iRefList < 2; iRefList++) 2830 2500 { … … 2832 2502 for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++) 2833 2503 { 2834 #if H_MV2504 #if NH_MV 2835 2505 if( pcSlice->getLayerId() != pcSlice->getRefLayerId( RefPicList(iRefList), iRefIndex ) ) 2836 2506 { … … 2841 2511 #endif 2842 2512 printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR()); 2843 #if H_MV2513 #if NH_MV 2844 2514 } 2845 2515 #endif … … 2847 2517 printf("]"); 2848 2518 } 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 2523 Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgFirstField, TComPic* pcPicOrgSecondField, 2524 TComPicYuv* pcPicRecFirstField, TComPicYuv* pcPicRecSecondField, 2525 const InputColourSpaceConversion conversion, const Bool printFrameMSE ) 2526 { 2527 2528 #if NH_MV 2872 2529 assert( 0 ); // Field coding and MV need to be aligned. 2873 2530 #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 2916 2554 //===== 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 3003 2601 //===== 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 3014 2617 /** Function for deciding the nal_unit_type. 3015 2618 * \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 3017 2622 * This function checks the configuration and returns the appropriate nal_unit_type for the picture. 3018 2623 */ … … 3023 2628 return NAL_UNIT_CODED_SLICE_IDR_W_RADL; 3024 2629 } 3025 #if EFFICIENT_FIELD_IRAP 3026 if( isField && pocCurr == 1)2630 2631 if(m_pcCfg->getEfficientFieldIRAPEnabled() && isField && pocCurr == 1) 3027 2632 { 3028 2633 // to avoid the picture becoming an IRAP 3029 2634 return NAL_UNIT_CODED_SLICE_TRAIL_R; 3030 2635 } 3031 #endif 3032 3033 #if ALLOW_RECOVERY_POINT_AS_RAP 2636 3034 2637 if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0) 3035 #else3036 if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)3037 #endif3038 2638 { 3039 2639 if (m_pcCfg->getDecodingRefreshType() == 1) … … 3050 2650 if(pocCurr<m_pocCRA) 3051 2651 { 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 3056 2656 // picture need not be marked as a TFD picture. 3057 2657 return NAL_UNIT_CODED_SLICE_RASL_R; … … 3068 2668 } 3069 2669 2670 3070 2671 Double TEncGOP::xCalculateRVM() 3071 2672 { 3072 2673 Double dRVM = 0; 3073 2674 3074 2675 if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 ) 3075 2676 { … … 3079 2680 vRL.resize( N ); 3080 2681 vB.resize( N ); 3081 2682 3082 2683 Int i; 3083 2684 Double dRavg = 0 , dBavg = 0; … … 3087 2688 vRL[i] = 0; 3088 2689 for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ ) 2690 { 3089 2691 vRL[i] += m_vRVM_RP[j]; 2692 } 3090 2693 vRL[i] /= ( 2 * RVM_VCEGAM10_M ); 3091 2694 vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i]; … … 3093 2696 dBavg += vB[i]; 3094 2697 } 3095 2698 3096 2699 dRavg /= ( N - 2 * RVM_VCEGAM10_M ); 3097 2700 dBavg /= ( N - 2 * RVM_VCEGAM10_M ); 3098 2701 3099 2702 Double dSigamB = 0; 3100 2703 for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ ) … … 3104 2707 } 3105 2708 dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) ); 3106 2709 3107 2710 Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) ); 3108 2711 3109 2712 dRVM = dSigamB / dRavg * f; 3110 2713 } 3111 2714 3112 2715 return( dRVM ); 3113 2716 } 3114 3115 2717 /** Attaches the input bitstream to the stream in the output NAL unit 3116 2718 Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call. … … 3118 2720 * \param rNalu target NAL unit 3119 2721 */ 3120 Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream* &codedSliceData)2722 Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream* codedSliceData) 3121 2723 { 3122 2724 // Byte-align … … 3125 2727 // Perform bitstream concatenation 3126 2728 if (codedSliceData->getNumberOfWrittenBits() > 0) 3127 2729 { 3128 2730 rNalu.m_Bitstream.addSubstream(codedSliceData); 3129 2731 } … … 3134 2736 } 3135 2737 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, 3137 2739 // and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value 3138 2740 Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic) 3139 2741 { 3140 TComReferencePictureSet *rps = pcSlice->getRPS(); 3141 if(!rps->getNumberOfLongtermPictures()) 2742 if(pcSlice->getRPS()->getNumberOfLongtermPictures() == 0) 3142 2743 { 3143 2744 return; 3144 2745 } 2746 // we can only modify the local RPS! 2747 assert (pcSlice->getRPSidx()==-1); 2748 TComReferencePictureSet *rps = pcSlice->getLocalRPS(); 3145 2749 3146 2750 // Arrange long-term reference pictures in the correct order of LSB and MSB, … … 3155 2759 ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag)); // Indicate if MSB needs to be present 3156 2760 3157 // Get the long-term reference pictures 2761 // Get the long-term reference pictures 3158 2762 Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures(); 3159 2763 Int i, ctr = 0; … … 3163 2767 longtermPicsPoc[ctr] = rps->getPOC(i); // LTRP POC 3164 2768 longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB 3165 indices[ctr] = i; 2769 indices[ctr] = i; 3166 2770 longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr]; 3167 2771 } … … 3169 2773 assert(ctr == numLongPics); 3170 2774 3171 // Arrange pictures in decreasing order of MSB; 2775 // Arrange pictures in decreasing order of MSB; 3172 2776 for(i = 0; i < numLongPics; i++) 3173 2777 { … … 3188 2792 // Check if MSB present flag should be enabled. 3189 2793 // 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(); 3191 2795 TComPic* pcPic; 3192 2796 while ( iterPic != rcListPic.end() ) … … 3200 2804 break; 3201 2805 } 3202 iterPic++; 2806 iterPic++; 3203 2807 } 3204 2808 } … … 3214 2818 Int currMSB = 0, currLSB = 0; 3215 2819 // currPicPoc = currMSB + currLSB 3216 currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB); 2820 currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB); 3217 2821 currMSB = pcSlice->getPOC() - currLSB; 3218 2822 … … 3224 2828 rps->setPocLSBLT (i, longtermPicsLSB[ctr]); 3225 2829 rps->setDeltaPocMSBCycleLT (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB); 3226 rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]); 2830 rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]); 3227 2831 3228 2832 assert(rps->getDeltaPocMSBCycleLT(i) >= 0); // Non-negative value … … 3232 2836 for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--) 3233 2837 { 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 3235 2839 // don't have to check the MSB present flag values for this constraint. 3236 2840 assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!! … … 3239 2843 } 3240 2844 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 ) 2845 Void TEncGOP::applyDeblockingFilterMetric( TComPic* pcPic, UInt uiNumSlices ) 3262 2846 { 3263 2847 TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec(); 3264 Pel* Rec = pcPicYuvRec->get LumaAddr( 0);2848 Pel* Rec = pcPicYuvRec->getAddr(COMPONENT_Y); 3265 2849 Pel* tempRec = Rec; 3266 Int stride = pcPicYuvRec->getStride( );2850 Int stride = pcPicYuvRec->getStride(COMPONENT_Y); 3267 2851 UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize(); 3268 2852 UInt maxTBsize = (1<<log2maxTB); 3269 2853 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); 3272 2856 const UInt noCol = (picWidth>>log2maxTB); 3273 2857 const UInt noRows = (picHeight>>log2maxTB); … … 3279 2863 UInt rowIdx = 0; 3280 2864 Pel p0, p1, p2, q0, q1, q2; 3281 2865 3282 2866 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); 3284 2869 Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale; 3285 2870 const Int thr2 = (beta>>2); 3286 2871 const Int thr1 = 2*bitdepthScale; 3287 2872 UInt a = 0; 3288 2873 3289 2874 memset(colSAD, 0, noCol*sizeof(UInt64)); 3290 2875 memset(rowSAD, 0, noRows*sizeof(UInt64)); 3291 2876 3292 2877 if (maxTBsize > minBlockArtSize) 3293 2878 { … … 3313 2898 Rec = tempRec; 3314 2899 } 3315 2900 3316 2901 // Analyze horizontal artifact edges 3317 2902 for(Int r = maxTBsize; r < picHeight; r += maxTBsize) … … 3334 2919 } 3335 2920 } 3336 2921 3337 2922 UInt64 colSADsum = 0; 3338 2923 UInt64 rowSADsum = 0; … … 3345 2930 rowSADsum += rowSAD[r]; 3346 2931 } 3347 2932 3348 2933 colSADsum <<= 10; 3349 2934 rowSADsum <<= 10; … … 3352 2937 rowSADsum /= (noRows-1); 3353 2938 rowSADsum /= picWidth; 3354 2939 3355 2940 UInt64 avgSAD = ((colSADsum + rowSADsum)>>1); 3356 avgSAD >>= ( g_bitDepthY-8);3357 2941 avgSAD >>= (bitDepthLuma-8); 2942 3358 2943 if ( avgSAD > 2048 ) 3359 2944 { … … 3378 2963 } 3379 2964 } 3380 2965 3381 2966 free(colSAD); 3382 2967 free(rowSAD); 3383 2968 } 3384 2969 3385 #if H_MV2970 #if NH_MV 3386 2971 Void TEncGOP::xSetRefPicListModificationsMv( std::vector<TComPic*> tempPicLists[2], TComSlice* pcSlice, UInt iGOPid ) 3387 2972 {
Note: See TracChangeset for help on using the changeset viewer.