From a97ef4d6d1fc21964b68c6655ed24aa92563a444 Mon Sep 17 00:00:00 2001 From: Karsten Suehring <karsten.suehring@hhi.fraunhofer.de> Date: Wed, 18 Nov 2020 22:20:45 +0100 Subject: [PATCH] Fix potential race condition when frame field information SEI arrives before picture timing SEI Picture Timing SEI is intentionally not used in parsing of frame field information SEI. In the existing code retrieving the picture timing SEI from HRD could return a nullptr, when the SEI has not arrived yet. The pointer is dereferenced without checking and passed into frame field info SEI parsing function and used for a consistency check. This refactoring moves the check after parsing of all SEI messages. --- source/Lib/DecoderLib/DecLib.cpp | 17 +++++++++++++++++ source/Lib/DecoderLib/DecLib.h | 1 + source/Lib/DecoderLib/SEIread.cpp | 10 ++-------- source/Lib/DecoderLib/SEIread.h | 2 +- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index fa5b2144d..c221aecc9 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -1976,6 +1976,23 @@ void DecLib::xParsePrefixSEImessages() delete m_prefixSEINALUs.front(); m_prefixSEINALUs.pop_front(); } + xCheckPrefixSEIMessages(m_SEIs); +} + +void DecLib::xCheckPrefixSEIMessages( SEIMessages& prefixSEIs ) +{ + SEIMessages picTimingSEIs = getSeisByType(prefixSEIs, SEI::PICTURE_TIMING); + SEIMessages frameFieldSEIs = getSeisByType(prefixSEIs, SEI::FRAME_FIELD_INFO); + + if (!picTimingSEIs.empty() && !frameFieldSEIs.empty()) + { + SEIPictureTiming *pt = (SEIPictureTiming*) picTimingSEIs.front(); + SEIFrameFieldInfo *ff = (SEIFrameFieldInfo*) frameFieldSEIs.front(); + if( pt->m_ptDisplayElementalPeriodsMinus1 != ff->m_displayElementalPeriodsMinus1 ) + { + msg( WARNING, "Warning: ffi_display_elemental_periods_minus1 is different in picture timing and frame field information SEI messages!"); + } + } } void DecLib::xDecodePicHeader( InputNALUnit& nalu ) diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h index b1ad6bb88..bb15b81eb 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -320,6 +320,7 @@ protected: } void xParsePrefixSEImessages(); void xParsePrefixSEIsForUnknownVCLNal(); + void xCheckPrefixSEIMessages( SEIMessages& prefixSEIs ); void xCheckNalUnitConstraintFlags( const ConstraintInfo *cInfo, uint32_t naluType ); void xCheckMixedNalUnit(Slice* pcSlice, SPS *sps, InputNALUnit &nalu); diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index 31c07db50..d5c993102 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -177,7 +177,6 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType SEI *sei = NULL; const SEIBufferingPeriod *bp = NULL; - const SEIPictureTiming *pt = NULL; if(nalUnitType == NAL_UNIT_PREFIX_SEI) { @@ -225,8 +224,7 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType break; case SEI::FRAME_FIELD_INFO: sei = new SEIFrameFieldInfo; - pt = hrd.getPictureTimingSEI(); - xParseSEIFrameFieldinfo((SEIFrameFieldInfo&) *sei, *pt, payloadSize, pDecodedMessageOutputStream); + xParseSEIFrameFieldinfo((SEIFrameFieldInfo&) *sei, payloadSize, pDecodedMessageOutputStream); break; case SEI::DEPENDENT_RAP_INDICATION: sei = new SEIDependentRAPIndication; @@ -990,7 +988,7 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi sei.m_ptDisplayElementalPeriodsMinus1 = symbol; } -void SEIReader::xParseSEIFrameFieldinfo(SEIFrameFieldInfo& sei, const SEIPictureTiming& pt, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream) +void SEIReader::xParseSEIFrameFieldinfo(SEIFrameFieldInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream) { output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize); @@ -1024,10 +1022,6 @@ void SEIReader::xParseSEIFrameFieldinfo(SEIFrameFieldInfo& sei, const SEIPicture sei_read_uvlc( pDecodedMessageOutputStream, symbol, "ffi_display_elemental_periods_minus1" ); #endif sei.m_displayElementalPeriodsMinus1 = symbol; - if( pt.m_ptDisplayElementalPeriodsMinus1 != sei.m_displayElementalPeriodsMinus1 ) - { - msg( WARNING, "Warning: ffi_display_elemental_periods_minus1 is different in picture timing and frame field information SEI messages!"); - } } sei_read_code( pDecodedMessageOutputStream, 2, symbol, "ffi_source_scan_type" ); sei.m_sourceScanType = symbol; diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h index 8627a85de..996f6e1f3 100644 --- a/source/Lib/DecoderLib/SEIread.h +++ b/source/Lib/DecoderLib/SEIread.h @@ -66,7 +66,7 @@ protected: void xParseSEIPictureTiming (SEIPictureTiming& sei, uint32_t payloadSize, const uint32_t temporalId, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream); void xParseSEIScalableNesting (SEIScalableNesting& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS* vps, const SPS* sps, HRD &hrd, std::ostream* decodedMessageOutputStream); void xCheckScalableNestingConstraints (const SEIScalableNesting& sei, const NalUnitType nalUnitType, const VPS* vps); - void xParseSEIFrameFieldinfo (SEIFrameFieldInfo& sei, const SEIPictureTiming& pt, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); + void xParseSEIFrameFieldinfo (SEIFrameFieldInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIDependentRAPIndication (SEIDependentRAPIndication& sei, uint32_t payLoadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIFramePacking (SEIFramePacking& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIParameterSetsInclusionIndication(SEIParameterSetsInclusionIndication& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream); -- GitLab