diff --git a/source/Lib/CommonLib/HRD.h b/source/Lib/CommonLib/HRD.h index 82d40dabafdea7ed29bac44eb0cbd12e6ca10bf5..89f66cc2abbf6ebdeef9bcac5c789e3724063539 100644 --- a/source/Lib/CommonLib/HRD.h +++ b/source/Lib/CommonLib/HRD.h @@ -176,6 +176,21 @@ public: }; +#if JVET_S0102_ASPECT4 +inline void checkBPSyntaxElementLength(const SEIBufferingPeriod* bp1, const SEIBufferingPeriod* bp2) +{ + CHECK(bp1->m_initialCpbRemovalDelayLength != bp2->m_initialCpbRemovalDelayLength || + bp1->m_cpbRemovalDelayLength != bp2->m_cpbRemovalDelayLength || + bp1->m_dpbOutputDelayLength != bp2->m_dpbOutputDelayLength || + bp1->m_duCpbRemovalDelayIncrementLength != bp2->m_duCpbRemovalDelayIncrementLength || + bp1->m_dpbOutputDelayDuLength != bp2->m_dpbOutputDelayDuLength, + "All scalable-nested and non-scalable nested BP SEI messages in a CVS shall have the same value for " + "each of the syntax elements bp_cpb_initial_removal_delay_length_minus1, bp_cpb_removal_delay_length_minus1, " + "bp_dpb_output_delay_length_minus1, bp_du_cpb_removal_delay_increment_length_minus1, " + "and bp_dpb_output_delay_du_length_minus1"); +} +#endif + class HRD { public: @@ -195,8 +210,20 @@ public: OlsHrdParams* getOlsHrdParametersAddr() { return m_olsHrdParams; } const OlsHrdParams& getOlsHrdParameters(int idx) const { return m_olsHrdParams[idx]; } +#if JVET_S0102_ASPECT4 + void setBufferingPeriodSEI(const SEIBufferingPeriod* bp) + { + if (m_bufferingPeriodInitialized) + { + checkBPSyntaxElementLength(bp, &m_bufferingPeriodSEI); + } + bp->copyTo(m_bufferingPeriodSEI); + m_bufferingPeriodInitialized = true; + } +#else void setBufferingPeriodSEI(const SEIBufferingPeriod* bp) { bp->copyTo(m_bufferingPeriodSEI); m_bufferingPeriodInitialized = true; } +#endif const SEIBufferingPeriod* getBufferingPeriodSEI() const { return m_bufferingPeriodInitialized ? &m_bufferingPeriodSEI : nullptr; } void setPictureTimingSEI(const SEIPictureTiming* pt) { pt->copyTo(m_pictureTimingSEI); m_pictureTimingAvailable = true; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 4f4ebd36cc508af2184bc35896c416cc0e2f6415..df38f2497145bdf6a2e3d8137ed7855a6cb3f980 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -123,6 +123,8 @@ #define JVET_S0048_SCALING_OFFSET 1 // JVET-S0048 Aspect2: change the constraint on the value ranges of scaling window offsets to be more flexible +#define JVET_S0102_ASPECT4 1 // JVET-S0102 Aspect 4: Mandate same value for buffering period syntax elements + #define JVET_S0248_HRD_CLEANUP 1 // JVET-S0248 Aspect7: When bp_alt_cpb_params_present_flag is equal to 1, the value of bp_du_hrd_params_present_flag shall be equal to 0. #define JVET_S0100_ASPECT3 1 // JVET-S0100 Aspect 3: constraints on vps_dpb_max_tid and vps_hrd_max_tid depending on vps_ptl_max_tid diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index b82a556554411566b5031034e4d1c03cc3715e9c..18d51ec9faf1e78375b57b91f05cd6f73c1a8a4b 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -223,7 +223,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType break; case SEI::SCALABLE_NESTING: sei = new SEIScalableNesting; +#if JVET_S0102_ASPECT4 + xParseSEIScalableNesting((SEIScalableNesting&)*sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, hrd, pDecodedMessageOutputStream); +#else xParseSEIScalableNesting((SEIScalableNesting&)*sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, pDecodedMessageOutputStream); +#endif break; case SEI::FRAME_FIELD_INFO: sei = new SEIFrameFieldInfo; @@ -329,7 +333,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType #if JVET_R0294_SUBPIC_HASH case SEI::SCALABLE_NESTING: sei = new SEIScalableNesting; +#if JVET_S0102_ASPECT4 + xParseSEIScalableNesting((SEIScalableNesting&)*sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, hrd, pDecodedMessageOutputStream); +#else xParseSEIScalableNesting((SEIScalableNesting&)*sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, pDecodedMessageOutputStream); +#endif break; #endif default: @@ -476,7 +484,11 @@ void SEIReader::xParseSEIDecodedPictureHash(SEIDecodedPictureHash& sei, uint32_t } } +#if JVET_S0102_ASPECT4 +void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS* vps, const SPS* sps, HRD &hrd, std::ostream* decodedMessageOutputStream) +#else void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS *vps, const SPS *sps, std::ostream *decodedMessageOutputStream) +#endif { uint32_t symbol; SEIMessages seis; @@ -560,6 +572,13 @@ void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitT { SEIBufferingPeriod *bp = (SEIBufferingPeriod*) tmpSEIs.front(); m_nestedHrd.setBufferingPeriodSEI(bp); +#if JVET_S0102_ASPECT4 + const SEIBufferingPeriod *nonNestedBp = hrd.getBufferingPeriodSEI(); + if (nonNestedBp) + { + checkBPSyntaxElementLength(nonNestedBp, bp); + } +#endif } sei.m_nestedSEIs.push_back(tmpSEIs.front()); tmpSEIs.clear(); diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h index 410ec7e21f8840ad63914c312af38779b753219b..28d844b943cc3ef3aa7c54318562014284eea662 100644 --- a/source/Lib/DecoderLib/SEIread.h +++ b/source/Lib/DecoderLib/SEIread.h @@ -64,7 +64,11 @@ protected: void xParseSEIDecodedPictureHash (SEIDecodedPictureHash& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIBufferingPeriod (SEIBufferingPeriod& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIPictureTiming (SEIPictureTiming& sei, uint32_t payloadSize, const uint32_t temporalId, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream); +#if JVET_S0102_ASPECT4 + 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); +#else void xParseSEIScalableNesting (SEIScalableNesting& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS *vps, const SPS *sps, std::ostream *decodedMessageOutputStream); +#endif 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 xParseSEIDependentRAPIndication (SEIDependentRAPIndication& sei, uint32_t payLoadSize, std::ostream *pDecodedMessageOutputStream);