From ac7861d4820c9376520205a84b3123a9b7514278 Mon Sep 17 00:00:00 2001 From: Frank Bossen <fbossen@gmail.com> Date: Fri, 26 Jan 2024 14:01:22 +0100 Subject: [PATCH] Clean up code related to BP SEI Includes: - fix syntax element names for tracing - add validation checks - move validation check to correct place - define `enum HrdType` for indexing by `NAL` or `VCL` - consistently use `bp` variable name for BP SEI objects - use `static_vector` instead of having separate variable for array size --- source/Lib/CommonLib/HRD.h | 17 +- source/Lib/CommonLib/SEI.cpp | 59 +--- source/Lib/CommonLib/SEI.h | 111 ++++---- source/Lib/DecoderLib/DecLib.cpp | 6 +- source/Lib/DecoderLib/SEIread.cpp | 390 +++++++++++++++------------ source/Lib/DecoderLib/SEIread.h | 3 +- source/Lib/EncoderLib/EncGOP.cpp | 18 +- source/Lib/EncoderLib/EncGOP.h | 2 +- source/Lib/EncoderLib/SEIEncoder.cpp | 148 +++++----- source/Lib/EncoderLib/SEIwrite.cpp | 190 +++++++------ 10 files changed, 457 insertions(+), 487 deletions(-) diff --git a/source/Lib/CommonLib/HRD.h b/source/Lib/CommonLib/HRD.h index 4a39b68a1..a0c10126b 100644 --- a/source/Lib/CommonLib/HRD.h +++ b/source/Lib/CommonLib/HRD.h @@ -179,11 +179,11 @@ public: 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, + CHECK(bp1->cpbInitialRemovalDelayLength != bp2->cpbInitialRemovalDelayLength + || bp1->cpbRemovalDelayLength != bp2->cpbRemovalDelayLength + || bp1->dpbOutputDelayLength != bp2->dpbOutputDelayLength + || bp1->duCpbRemovalDelayIncrementLength != bp2->duCpbRemovalDelayIncrementLength + || bp1->dpbOutputDelayDuLength != bp2->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, " @@ -206,7 +206,7 @@ public: OlsHrdParams* getOlsHrdParametersAddr() { return m_olsHrdParams; } const OlsHrdParams& getOlsHrdParameters(int idx) const { return m_olsHrdParams[idx]; } - void setBufferingPeriodSEI(const SEIBufferingPeriod* bp) + void setBufferingPeriodSEI(const SEIBufferingPeriod* bp) { if (m_bufferingPeriodInitialized) { @@ -216,7 +216,10 @@ public: m_bufferingPeriodInitialized = true; } - const SEIBufferingPeriod* getBufferingPeriodSEI() const { return m_bufferingPeriodInitialized ? &m_bufferingPeriodSEI : nullptr; } + const SEIBufferingPeriod* getBufferingPeriodSEI() const + { + return m_bufferingPeriodInitialized ? &m_bufferingPeriodSEI : nullptr; + } void setPictureTimingSEI(const SEIPictureTiming* pt) { pt->copyTo(m_pictureTimingSEI); m_pictureTimingAvailable = true; } const SEIPictureTiming* getPictureTimingSEI() const { return m_pictureTimingAvailable ? &m_pictureTimingSEI : nullptr; } diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp index aea00c887..1c6d3d321 100644 --- a/source/Lib/CommonLib/SEI.cpp +++ b/source/Lib/CommonLib/SEI.cpp @@ -96,34 +96,7 @@ void deleteSEIs (SEIMessages &seiList) seiList.clear(); } -void SEIBufferingPeriod::copyTo (SEIBufferingPeriod& target) const -{ - target.m_bpNalCpbParamsPresentFlag = m_bpNalCpbParamsPresentFlag; - target.m_bpVclCpbParamsPresentFlag = m_bpVclCpbParamsPresentFlag; - target.m_initialCpbRemovalDelayLength = m_initialCpbRemovalDelayLength; - target.m_cpbRemovalDelayLength = m_cpbRemovalDelayLength; - target.m_dpbOutputDelayLength = m_dpbOutputDelayLength; - target.m_duCpbRemovalDelayIncrementLength = m_duCpbRemovalDelayIncrementLength; - target.m_dpbOutputDelayDuLength = m_dpbOutputDelayDuLength; - target.m_concatenationFlag = m_concatenationFlag; - target.m_auCpbRemovalDelayDelta = m_auCpbRemovalDelayDelta; - target.m_cpbRemovalDelayDeltasPresentFlag = m_cpbRemovalDelayDeltasPresentFlag; - target.m_numCpbRemovalDelayDeltas = m_numCpbRemovalDelayDeltas; - target.m_bpMaxSubLayers = m_bpMaxSubLayers; - ::memcpy(target.m_initialCpbRemovalDelay, m_initialCpbRemovalDelay, sizeof(m_initialCpbRemovalDelay)); - ::memcpy(target.m_initialCpbRemovalOffset, m_initialCpbRemovalOffset, sizeof(m_initialCpbRemovalOffset)); - ::memcpy(target.m_cpbRemovalDelayDelta, m_cpbRemovalDelayDelta, sizeof(m_cpbRemovalDelayDelta)); - target.m_bpCpbCnt = m_bpCpbCnt; - target.m_bpDecodingUnitHrdParamsPresentFlag = m_bpDecodingUnitHrdParamsPresentFlag; - target.m_decodingUnitCpbParamsInPicTimingSeiFlag = m_decodingUnitCpbParamsInPicTimingSeiFlag; - target.m_decodingUnitDpbDuParamsInPicTimingSeiFlag = m_decodingUnitDpbDuParamsInPicTimingSeiFlag; - target.m_sublayerInitialCpbRemovalDelayPresentFlag = m_sublayerInitialCpbRemovalDelayPresentFlag; - target.m_concatenationFlag = m_concatenationFlag; - target.m_maxInitialRemovalDelayForConcatenation = m_maxInitialRemovalDelayForConcatenation; - target.m_sublayerDpbOutputOffsetsPresentFlag = m_sublayerDpbOutputOffsetsPresentFlag; - ::memcpy(target.m_dpbOutputTidOffset, m_dpbOutputTidOffset, sizeof(m_dpbOutputTidOffset)); - target.m_altCpbParamsPresentFlag = m_altCpbParamsPresentFlag; -} +void SEIBufferingPeriod::copyTo(SEIBufferingPeriod& target) const { target = *this; } void SEIPictureTiming::copyTo (SEIPictureTiming& target) const { @@ -787,35 +760,7 @@ SEIDecodedPictureHash::SEIDecodedPictureHash(const SEIDecodedPictureHash& sei) m_pictureHash = sei.m_pictureHash; } -SEIBufferingPeriod::SEIBufferingPeriod(const SEIBufferingPeriod& sei) -{ - m_bpNalCpbParamsPresentFlag = sei.m_bpNalCpbParamsPresentFlag; - m_bpVclCpbParamsPresentFlag = sei.m_bpVclCpbParamsPresentFlag; - m_initialCpbRemovalDelayLength = sei.m_initialCpbRemovalDelayLength; - m_cpbRemovalDelayLength = sei.m_cpbRemovalDelayLength; - m_dpbOutputDelayLength = sei.m_dpbOutputDelayLength; - m_bpCpbCnt = sei.m_bpCpbCnt; - m_duCpbRemovalDelayIncrementLength = sei.m_duCpbRemovalDelayIncrementLength; - m_dpbOutputDelayDuLength = sei.m_dpbOutputDelayDuLength; - std::memcpy(m_initialCpbRemovalDelay, sei.m_initialCpbRemovalDelay, sizeof(sei.m_initialCpbRemovalDelay)); - std::memcpy(m_initialCpbRemovalOffset, sei.m_initialCpbRemovalOffset, sizeof(sei.m_initialCpbRemovalOffset)); - m_concatenationFlag = sei.m_concatenationFlag; - m_auCpbRemovalDelayDelta = sei.m_auCpbRemovalDelayDelta; - m_cpbRemovalDelayDeltasPresentFlag = sei.m_cpbRemovalDelayDeltasPresentFlag; - m_numCpbRemovalDelayDeltas = sei.m_numCpbRemovalDelayDeltas; - m_bpMaxSubLayers = sei.m_bpMaxSubLayers; - std::memcpy(m_cpbRemovalDelayDelta, sei.m_cpbRemovalDelayDelta, sizeof(sei.m_cpbRemovalDelayDelta)); - m_bpDecodingUnitHrdParamsPresentFlag = sei.m_bpDecodingUnitHrdParamsPresentFlag; - m_decodingUnitCpbParamsInPicTimingSeiFlag = sei.m_decodingUnitCpbParamsInPicTimingSeiFlag; - m_decodingUnitDpbDuParamsInPicTimingSeiFlag = sei.m_decodingUnitDpbDuParamsInPicTimingSeiFlag; - m_sublayerInitialCpbRemovalDelayPresentFlag = sei.m_sublayerInitialCpbRemovalDelayPresentFlag; - m_additionalConcatenationInfoPresentFlag = sei.m_additionalConcatenationInfoPresentFlag; - m_maxInitialRemovalDelayForConcatenation = sei.m_maxInitialRemovalDelayForConcatenation; - m_sublayerDpbOutputOffsetsPresentFlag = sei.m_sublayerDpbOutputOffsetsPresentFlag; - std::memcpy(m_dpbOutputTidOffset, sei.m_dpbOutputTidOffset, sizeof(sei.m_dpbOutputTidOffset)); - m_altCpbParamsPresentFlag = sei.m_altCpbParamsPresentFlag; - m_useAltCpbParamsFlag = sei.m_useAltCpbParamsFlag; -} +SEIBufferingPeriod::SEIBufferingPeriod(const SEIBufferingPeriod& sei) = default; SEIPictureTiming::SEIPictureTiming(const SEIPictureTiming& sei) { diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h index 5f7e548ef..71f0a9a57 100644 --- a/source/Lib/CommonLib/SEI.h +++ b/source/Lib/CommonLib/SEI.h @@ -605,73 +605,74 @@ public: virtual ~SEIDependentRAPIndication() { } }; +enum class HrdType +{ + NAL, + VCL, + NUM +}; class SEIBufferingPeriod : public SEI { public: + struct CpbEntry + { + uint32_t delay; + uint32_t offset; + }; + PayloadType payloadType() const { return PayloadType::BUFFERING_PERIOD; } - void copyTo (SEIBufferingPeriod& target) const; + void copyTo(SEIBufferingPeriod& target) const; SEIBufferingPeriod() - : m_bpNalCpbParamsPresentFlag (false) - , m_bpVclCpbParamsPresentFlag (false) - , m_initialCpbRemovalDelayLength (0) - , m_cpbRemovalDelayLength (0) - , m_dpbOutputDelayLength (0) - , m_bpCpbCnt(0) - , m_duCpbRemovalDelayIncrementLength (0) - , m_dpbOutputDelayDuLength (0) - , m_cpbRemovalDelayDeltasPresentFlag (false) - , m_numCpbRemovalDelayDeltas (0) - , m_bpMaxSubLayers (0) - , m_bpDecodingUnitHrdParamsPresentFlag (false) - , m_decodingUnitCpbParamsInPicTimingSeiFlag (false) - , m_decodingUnitDpbDuParamsInPicTimingSeiFlag(false) - , m_sublayerInitialCpbRemovalDelayPresentFlag(false) - , m_additionalConcatenationInfoPresentFlag (false) - , m_maxInitialRemovalDelayForConcatenation (0) - , m_sublayerDpbOutputOffsetsPresentFlag (false) - , m_altCpbParamsPresentFlag (false) - , m_useAltCpbParamsFlag (false) { - ::memset(m_initialCpbRemovalDelay, 0, sizeof(m_initialCpbRemovalDelay)); - ::memset(m_initialCpbRemovalOffset, 0, sizeof(m_initialCpbRemovalOffset)); - ::memset(m_cpbRemovalDelayDelta, 0, sizeof(m_cpbRemovalDelayDelta)); - ::memset(m_dpbOutputTidOffset, 0, sizeof(m_dpbOutputTidOffset)); + hasHrdParams.fill(false); + + for (auto hrdType: { HrdType::NAL, HrdType::VCL }) + { + for (int sublayerIdx = 0; sublayerIdx < MAX_TLAYER; sublayerIdx++) + { + initialCpbRemoval[hrdType][sublayerIdx].fill({ 0, 0 }); + } + } + + cpbRemovalDelayDeltaVals.clear(); + dpbOutputTidOffset.fill(0); } + SEIBufferingPeriod(const SEIBufferingPeriod& sei); virtual ~SEIBufferingPeriod() {} - void setDuCpbRemovalDelayIncrementLength( uint32_t value ) { m_duCpbRemovalDelayIncrementLength = value; } - uint32_t getDuCpbRemovalDelayIncrementLength( ) const { return m_duCpbRemovalDelayIncrementLength; } - void setDpbOutputDelayDuLength( uint32_t value ) { m_dpbOutputDelayDuLength = value; } - uint32_t getDpbOutputDelayDuLength( ) const { return m_dpbOutputDelayDuLength; } - bool m_bpNalCpbParamsPresentFlag; - bool m_bpVclCpbParamsPresentFlag; - uint32_t m_initialCpbRemovalDelayLength; - uint32_t m_cpbRemovalDelayLength; - uint32_t m_dpbOutputDelayLength; - int m_bpCpbCnt; - uint32_t m_duCpbRemovalDelayIncrementLength; - uint32_t m_dpbOutputDelayDuLength; - uint32_t m_initialCpbRemovalDelay [MAX_TLAYER][MAX_CPB_CNT][2]; - uint32_t m_initialCpbRemovalOffset [MAX_TLAYER][MAX_CPB_CNT][2]; - bool m_concatenationFlag; - uint32_t m_auCpbRemovalDelayDelta; - bool m_cpbRemovalDelayDeltasPresentFlag; - int m_numCpbRemovalDelayDeltas; - int m_bpMaxSubLayers; - uint32_t m_cpbRemovalDelayDelta [16]; - bool m_bpDecodingUnitHrdParamsPresentFlag; - bool m_decodingUnitCpbParamsInPicTimingSeiFlag; - bool m_decodingUnitDpbDuParamsInPicTimingSeiFlag; - bool m_sublayerInitialCpbRemovalDelayPresentFlag; - bool m_additionalConcatenationInfoPresentFlag; - uint32_t m_maxInitialRemovalDelayForConcatenation; - bool m_sublayerDpbOutputOffsetsPresentFlag; - uint32_t m_dpbOutputTidOffset [MAX_TLAYER]; - bool m_altCpbParamsPresentFlag; - bool m_useAltCpbParamsFlag; + EnumArray<bool, HrdType> hasHrdParams; + + bool concatenation = false; + bool hasDuHrdParams = false; + bool duCpbParamsInPicTimingSei = false; + bool duDpbParamsInPicTimingSei = false; + bool hasSublayerInitialCpbRemovalDelay = false; + bool hasAdditionalConcatenationInfo = false; + bool hasSublayerDpbOutputOffsets = false; + bool hasAltCpbParams = false; + bool useAltCpbParams = false; + + uint32_t cpbInitialRemovalDelayLength = 0; + uint32_t cpbRemovalDelayLength = 0; + uint32_t dpbOutputDelayLength = 0; + uint32_t cpbCount = 0; + uint32_t duCpbRemovalDelayIncrementLength = 0; + uint32_t dpbOutputDelayDuLength = 0; + uint32_t cpbRemovalDelayDelta = 0; + uint32_t maxInitialRemovalDelayForConcatenation = 0; + int maxSublayers = 0; + + EnumArray<std::array<std::array<CpbEntry, MAX_CPB_CNT>, MAX_TLAYER>, HrdType> initialCpbRemoval; + + static_vector<uint32_t, 16> cpbRemovalDelayDeltaVals; + + bool hasCpbRemovalDelayDeltas() const { return !cpbRemovalDelayDeltaVals.empty(); } + uint32_t numCpbRemovalDelayDeltas() const { return static_cast<uint32_t>(cpbRemovalDelayDeltaVals.size()); } + + std::array<uint32_t, MAX_TLAYER> dpbOutputTidOffset; }; class SEIPictureTiming : public SEI diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 82f03b88f..4c2a50c4b 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -2754,10 +2754,10 @@ void DecLib::xCheckDUISEIMessages(SEIMessages &prefixSEIs) { bool duDelayFlag = false; - SEIBufferingPeriod *bp = (SEIBufferingPeriod *) BPSEIs.front(); - if (bp->m_bpDecodingUnitHrdParamsPresentFlag) + auto* bp = reinterpret_cast<SEIBufferingPeriod*>(BPSEIs.front()); + if (bp->hasDuHrdParams) { - if (!bp->m_decodingUnitDpbDuParamsInPicTimingSeiFlag) + if (!bp->duDpbParamsInPicTimingSei) { if (DUISEIs.empty()) { diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index e2b6691e9..635352487 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -203,8 +203,7 @@ void SEIReader::parseAndExtractSEIScalableNesting(InputBitstream *bs, const NalU void SEIReader::getSEIDecodingUnitInfoDuiIdx(InputBitstream* bs, const NalUnitType nalUnitType, const uint32_t nuh_layer_id, HRD &hrd, uint32_t payloadSize, int& duiIdx) { - const SEIBufferingPeriod *bp = nullptr; - bp = hrd.getBufferingPeriodSEI(); + const SEIBufferingPeriod* bp = hrd.getBufferingPeriodSEI(); if (!bp) { // msg( WARNING, "Warning: Found Decoding unit information SEI message, but no active buffering period is available. Ignoring."); @@ -303,8 +302,7 @@ bool SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType InputBitstream *bs = getBitstream(); setBitstream(bs->extractSubstream(payloadSize * 8)); - SEI *sei = nullptr; - const SEIBufferingPeriod *bp = nullptr; + SEI* sei = nullptr; if(nalUnitType == NAL_UNIT_PREFIX_SEI) { @@ -319,36 +317,45 @@ bool SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType xParseSEIuserDataUnregistered((SEIuserDataUnregistered&) *sei, payloadSize, pDecodedMessageOutputStream); break; case SEI::PayloadType::DECODING_UNIT_INFO: - bp = hrd.getBufferingPeriodSEI(); - if (!bp) { - msg( WARNING, "Warning: Found Decoding unit information SEI message, but no active buffering period is available. Ignoring."); - } - else - { - sei = new SEIDecodingUnitInfo; - xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo&) *sei, payloadSize, *bp, temporalId, pDecodedMessageOutputStream); + const SEIBufferingPeriod* bp = hrd.getBufferingPeriodSEI(); + if (bp == nullptr) + { + msg(WARNING, "Warning: Found Decoding unit information SEI message, but no active buffering period is " + "available. Ignoring."); + } + else + { + sei = new SEIDecodingUnitInfo; + xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo&) *sei, payloadSize, *bp, temporalId, + pDecodedMessageOutputStream); + } + break; } - break; case SEI::PayloadType::BUFFERING_PERIOD: - sei = new SEIBufferingPeriod; - xParseSEIBufferingPeriod((SEIBufferingPeriod&) *sei, payloadSize, pDecodedMessageOutputStream); - hrd.setBufferingPeriodSEI((SEIBufferingPeriod*) sei); - break; - case SEI::PayloadType::PICTURE_TIMING: - bp = hrd.getBufferingPeriodSEI(); - if (!bp) { - msg(WARNING, - "Warning: Found Picture timing SEI message, but no active buffering period is available. Ignoring."); + auto bp = new SEIBufferingPeriod; + xParseSEIBufferingPeriod(*bp, payloadSize, pDecodedMessageOutputStream); + hrd.setBufferingPeriodSEI(bp); + sei = bp; + break; } - else + case SEI::PayloadType::PICTURE_TIMING: { - sei = new SEIPictureTiming; - xParseSEIPictureTiming((SEIPictureTiming &) *sei, payloadSize, temporalId, *bp, pDecodedMessageOutputStream); - hrd.setPictureTimingSEI((SEIPictureTiming *) sei); + const SEIBufferingPeriod* bp = hrd.getBufferingPeriodSEI(); + if (bp == nullptr) + { + msg(WARNING, + "Warning: Found Picture timing SEI message, but no active buffering period is available. Ignoring."); + } + else + { + sei = new SEIPictureTiming; + xParseSEIPictureTiming((SEIPictureTiming&) *sei, payloadSize, temporalId, *bp, pDecodedMessageOutputStream); + hrd.setPictureTimingSEI((SEIPictureTiming*) sei); + } + break; } - break; case SEI::PayloadType::SCALABLE_NESTING: sei = new SEIScalableNesting; xParseSEIScalableNesting((SEIScalableNesting &) *sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, hrd, @@ -1031,7 +1038,7 @@ void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitT { if (tmpSEIs.front()->payloadType() == SEI::PayloadType::BUFFERING_PERIOD) { - SEIBufferingPeriod *bp = (SEIBufferingPeriod*)tmpSEIs.front(); + auto bp = reinterpret_cast<SEIBufferingPeriod*>(tmpSEIs.front()); m_nestedHrd.setBufferingPeriodSEI(bp); const SEIBufferingPeriod *nonNestedBp = hrd.getBufferingPeriodSEI(); if (nonNestedBp) @@ -1307,9 +1314,8 @@ void SEIReader::xParseSEIScalableNestingBinary(SEIScalableNesting &sei, const Na int duiIdx = 0; if (SEI::PayloadType(payloadType) == SEI::PayloadType::DECODING_UNIT_INFO) { - const SEIBufferingPeriod *bp = nullptr; - bp = hrd.getBufferingPeriodSEI(); - if (!bp) + const SEIBufferingPeriod* bp = hrd.getBufferingPeriodSEI(); + if (bp == nullptr) { //msg( WARNING, "Warning: Found Decoding unit information SEI message, but no active buffering period is available. Ignoring."); } @@ -1492,11 +1498,11 @@ void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t pay sei_read_uvlc( pDecodedMessageOutputStream, val, "decoding_unit_idx"); sei.m_decodingUnitIdx = val; - if(!bp.m_decodingUnitCpbParamsInPicTimingSeiFlag) + if (!bp.duCpbParamsInPicTimingSei) { - for (int i = temporalId; i <= bp.m_bpMaxSubLayers - 1; i++) + for (int i = temporalId; i < bp.maxSublayers; i++) { - if (i < (bp.m_bpMaxSubLayers - 1)) + if (i < bp.maxSublayers - 1) { sei_read_flag( pDecodedMessageOutputStream, val, "dui_sub_layer_delays_present_flag[i]" ); sei.m_duiSubLayerDelaysPresentFlag[i] = val; @@ -1507,7 +1513,8 @@ void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t pay } if( sei.m_duiSubLayerDelaysPresentFlag[i] ) { - sei_read_code( pDecodedMessageOutputStream, bp.getDuCpbRemovalDelayIncrementLength(), val, "du_spt_cpb_removal_delay_increment[i]"); + sei_read_code(pDecodedMessageOutputStream, bp.duCpbRemovalDelayIncrementLength, val, + "du_spt_cpb_removal_delay_increment[i]"); sei.m_duSptCpbRemovalDelayIncrement[i] = val; } else @@ -1518,13 +1525,13 @@ void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t pay } else { - for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ ) + for (int i = temporalId; i < bp.maxSublayers - 1; i++) { sei.m_duSptCpbRemovalDelayIncrement[i] = 0; } } - if (!bp.m_decodingUnitDpbDuParamsInPicTimingSeiFlag) + if (!bp.duDpbParamsInPicTimingSei) { sei_read_flag(pDecodedMessageOutputStream, val, "dpb_output_du_delay_present_flag"); sei.m_dpbOutputDuDelayPresentFlag = (val != 0); } @@ -1534,130 +1541,155 @@ void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t pay } if(sei.m_dpbOutputDuDelayPresentFlag) { - sei_read_code( pDecodedMessageOutputStream, bp.getDpbOutputDelayDuLength(), val, "pic_spt_dpb_output_du_delay"); - if (sei.m_picSptDpbOutputDuDelay != -1) - CHECK(sei.m_picSptDpbOutputDuDelay!=val,"When signaled m_picSptDpbOutputDuDelay value must be same for DUs"); + sei_read_code(pDecodedMessageOutputStream, bp.dpbOutputDelayDuLength, val, "pic_spt_dpb_output_du_delay"); + CHECK(sei.m_picSptDpbOutputDuDelay != -1 && sei.m_picSptDpbOutputDuDelay != val, + "When signaled m_picSptDpbOutputDuDelay value must be same for DUs"); sei.m_picSptDpbOutputDuDelay = val; } } -void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream) +void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& bp, uint32_t payloadSize, + std::ostream* pDecodedMessageOutputStream) { - int i, nalOrVcl; uint32_t code; - output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize); - - sei_read_flag( pDecodedMessageOutputStream, code, "bp_nal_hrd_parameters_present_flag" ); sei.m_bpNalCpbParamsPresentFlag = code; - sei_read_flag( pDecodedMessageOutputStream, code, "bp_vcl_hrd_parameters_present_flag" ); sei.m_bpVclCpbParamsPresentFlag = code; - - sei_read_code( pDecodedMessageOutputStream, 5, code, "initial_cpb_removal_delay_length_minus1" ); sei.m_initialCpbRemovalDelayLength = code + 1; - sei_read_code( pDecodedMessageOutputStream, 5, code, "cpb_removal_delay_length_minus1" ); sei.m_cpbRemovalDelayLength = code + 1; - sei_read_code( pDecodedMessageOutputStream, 5, code, "dpb_output_delay_length_minus1" ); sei.m_dpbOutputDelayLength = code + 1; - sei_read_flag( pDecodedMessageOutputStream, code, "bp_decoding_unit_hrd_params_present_flag" ); sei.m_bpDecodingUnitHrdParamsPresentFlag = code; - if( sei.m_bpDecodingUnitHrdParamsPresentFlag ) - { - sei_read_code( pDecodedMessageOutputStream, 5, code, "du_cpb_removal_delay_increment_length_minus1" ); sei.m_duCpbRemovalDelayIncrementLength = code + 1; - sei_read_code( pDecodedMessageOutputStream, 5, code, "dpb_output_delay_du_length_minus1" ); sei.m_dpbOutputDelayDuLength = code + 1; - sei_read_flag( pDecodedMessageOutputStream, code, "decoding_unit_cpb_params_in_pic_timing_sei_flag" ); sei.m_decodingUnitCpbParamsInPicTimingSeiFlag = code; - sei_read_flag(pDecodedMessageOutputStream, code, "decoding_unit_dpb_du_params_in_pic_timing_sei_flag"); sei.m_decodingUnitDpbDuParamsInPicTimingSeiFlag = code; + output_sei_message_header(bp, pDecodedMessageOutputStream, payloadSize); + + sei_read_flag(pDecodedMessageOutputStream, code, "bp_nal_hrd_params_present_flag"); + bp.hasHrdParams[HrdType::NAL] = code != 0; + sei_read_flag(pDecodedMessageOutputStream, code, "bp_vcl_hrd_params_present_flag"); + bp.hasHrdParams[HrdType::VCL] = code != 0; + + CHECK(!bp.hasHrdParams[HrdType::NAL] && !bp.hasHrdParams[HrdType::VCL], + "bp_vcl_hrd_params_present_flag and bp_nal_hrd_params_present_flag in a BP SEI message shall not both be equal " + "to 0"); + + sei_read_code(pDecodedMessageOutputStream, 5, code, "bp_cpb_initial_removal_delay_length_minus1"); + bp.cpbInitialRemovalDelayLength = code + 1; + sei_read_code(pDecodedMessageOutputStream, 5, code, "bp_cpb_removal_delay_length_minus1"); + bp.cpbRemovalDelayLength = code + 1; + sei_read_code(pDecodedMessageOutputStream, 5, code, "bp_dpb_output_delay_length_minus1"); + bp.dpbOutputDelayLength = code + 1; + sei_read_flag(pDecodedMessageOutputStream, code, "bp_du_hrd_params_present_flag"); + bp.hasDuHrdParams = code != 0; + if (bp.hasDuHrdParams) + { + sei_read_code(pDecodedMessageOutputStream, 5, code, "bp_du_cpb_removal_delay_increment_length_minus1"); + bp.duCpbRemovalDelayIncrementLength = code + 1; + sei_read_code(pDecodedMessageOutputStream, 5, code, "bp_dpb_output_delay_du_length_minus1"); + bp.dpbOutputDelayDuLength = code + 1; + sei_read_flag(pDecodedMessageOutputStream, code, "bp_du_cpb_params_in_pic_timing_sei_flag"); + bp.duCpbParamsInPicTimingSei = code != 0; + sei_read_flag(pDecodedMessageOutputStream, code, "bp_du_dpb_params_in_pic_timing_sei_flag"); + bp.duDpbParamsInPicTimingSei = code != 0; } else { - sei.m_duCpbRemovalDelayIncrementLength = 24; - sei.m_dpbOutputDelayDuLength = 24; - sei.m_decodingUnitCpbParamsInPicTimingSeiFlag = false; - sei.m_decodingUnitDpbDuParamsInPicTimingSeiFlag = false; + bp.duCpbRemovalDelayIncrementLength = 24; + bp.dpbOutputDelayDuLength = 24; + bp.duCpbParamsInPicTimingSei = false; + bp.duDpbParamsInPicTimingSei = false; } - CHECK(sei.m_altCpbParamsPresentFlag && sei.m_bpDecodingUnitHrdParamsPresentFlag,"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"); - - sei_read_flag( pDecodedMessageOutputStream, code, "concatenation_flag"); - sei.m_concatenationFlag = code; - sei_read_flag ( pDecodedMessageOutputStream, code, "additional_concatenation_info_present_flag"); - sei.m_additionalConcatenationInfoPresentFlag = code; - if (sei.m_additionalConcatenationInfoPresentFlag) + sei_read_flag(pDecodedMessageOutputStream, code, "bp_concatenation_flag"); + bp.concatenation = code != 0; + sei_read_flag(pDecodedMessageOutputStream, code, "bp_additional_concatenation_info_present_flag"); + bp.hasAdditionalConcatenationInfo = code != 0; + if (bp.hasAdditionalConcatenationInfo) { - sei_read_code( pDecodedMessageOutputStream, sei.m_initialCpbRemovalDelayLength, code, "max_initial_removal_delay_for_concatenation" ); - sei.m_maxInitialRemovalDelayForConcatenation = code; + sei_read_code(pDecodedMessageOutputStream, bp.cpbInitialRemovalDelayLength, code, + "bp_max_initial_removal_delay_for_concatenation"); + bp.maxInitialRemovalDelayForConcatenation = code; } - sei_read_code( pDecodedMessageOutputStream, ( sei.m_cpbRemovalDelayLength ), code, "au_cpb_removal_delay_delta_minus1" ); - sei.m_auCpbRemovalDelayDelta = code + 1; - sei_read_code(pDecodedMessageOutputStream, 3, code, "bp_max_sub_layers_minus1"); - sei.m_bpMaxSubLayers = code + 1; - if (sei.m_bpMaxSubLayers - 1 > 0) - { - sei_read_flag(pDecodedMessageOutputStream, code, "cpb_removal_delay_deltas_present_flag"); - sei.m_cpbRemovalDelayDeltasPresentFlag = code; - } - else - { - sei.m_cpbRemovalDelayDeltasPresentFlag = false; - } - if (sei.m_cpbRemovalDelayDeltasPresentFlag) + sei_read_code(pDecodedMessageOutputStream, bp.cpbRemovalDelayLength, code, "bp_cpb_removal_delay_delta_minus1"); + bp.cpbRemovalDelayDelta = code + 1; + sei_read_code(pDecodedMessageOutputStream, 3, code, "bp_max_sublayers_minus1"); + bp.maxSublayers = code + 1; + + bp.cpbRemovalDelayDeltaVals.clear(); + + if (bp.maxSublayers > 1) { - sei_read_uvlc( pDecodedMessageOutputStream, code, "num_cpb_removal_delay_deltas_minus1" ); - CHECK(code>15, "The value of num_cpb_removal_offsets_minus1 shall be in the range of 0 to 15, inclusive.") - sei.m_numCpbRemovalDelayDeltas = code + 1; - for( i = 0; i < sei.m_numCpbRemovalDelayDeltas; i ++ ) + sei_read_flag(pDecodedMessageOutputStream, code, "bp_cpb_removal_delay_deltas_present_flag"); + + if (code != 0) { - sei_read_code( pDecodedMessageOutputStream, ( sei.m_cpbRemovalDelayLength ), code, "cpb_removal_delay_delta[i]" ); - sei.m_cpbRemovalDelayDelta[ i ] = code; + sei_read_uvlc(pDecodedMessageOutputStream, code, "bp_num_cpb_removal_delay_deltas_minus1"); + CHECK(code >= bp.cpbRemovalDelayDeltaVals.capacity(), + "The value of num_cpb_removal_offsets_minus1 shall be in the range of 0 to 15, inclusive.") + bp.cpbRemovalDelayDeltaVals.resize(code + 1); + for (size_t i = 0; i < bp.numCpbRemovalDelayDeltas(); i++) + { + sei_read_code(pDecodedMessageOutputStream, bp.cpbRemovalDelayLength, code, "bp_cpb_removal_delay_delta_val[i]"); + bp.cpbRemovalDelayDeltaVals[i] = code; + } } } + sei_read_uvlc(pDecodedMessageOutputStream, code, "bp_cpb_cnt_minus1"); - sei.m_bpCpbCnt = code + 1; - if (sei.m_bpMaxSubLayers - 1 > 0) + CHECK(code >= MAX_CPB_CNT, "The value of bp_cpb_cnt_minus1 shall be in the range of 0 to 31, inclusive"); + + bp.cpbCount = code + 1; + if (bp.maxSublayers > 1) { sei_read_flag(pDecodedMessageOutputStream, code, "bp_sublayer_initial_cpb_removal_delay_present_flag"); - sei.m_sublayerInitialCpbRemovalDelayPresentFlag = code; + bp.hasSublayerInitialCpbRemovalDelay = code != 0; } else { - sei.m_sublayerInitialCpbRemovalDelayPresentFlag = false; + bp.hasSublayerInitialCpbRemovalDelay = false; } - for (i = (sei.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : sei.m_bpMaxSubLayers - 1); i < sei.m_bpMaxSubLayers; i++) + + for (int sublayerIdx = (bp.hasSublayerInitialCpbRemovalDelay ? 0 : bp.maxSublayers - 1); + sublayerIdx < bp.maxSublayers; sublayerIdx++) { - for( nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ ) + for (auto hrdType: { HrdType::NAL, HrdType::VCL }) { - if( ( ( nalOrVcl == 0 ) && ( sei.m_bpNalCpbParamsPresentFlag ) ) || - ( ( nalOrVcl == 1 ) && ( sei.m_bpVclCpbParamsPresentFlag ) ) ) + if (bp.hasHrdParams[hrdType]) { - for( int j = 0; j < ( sei.m_bpCpbCnt ); j ++ ) + for (int j = 0; j < bp.cpbCount; j++) { - sei_read_code( pDecodedMessageOutputStream, sei.m_initialCpbRemovalDelayLength, code, nalOrVcl ? "vcl_initial_cpb_removal_delay[i][j]" : "nal_initial_cpb_removal_delay[i][j]" ); - sei.m_initialCpbRemovalDelay[i][j][nalOrVcl] = code; - sei_read_code( pDecodedMessageOutputStream, sei.m_initialCpbRemovalDelayLength, code, nalOrVcl ? "vcl_initial_cpb_removal_offset[i][j]" : "nal_initial_cpb_removal_offset[i][j]" ); - sei.m_initialCpbRemovalOffset[i][j][nalOrVcl] = code; + sei_read_code(pDecodedMessageOutputStream, bp.cpbInitialRemovalDelayLength, code, + hrdType == HrdType::NAL ? "bp_nal_initial_cpb_removal_delay[i][j]" + : "bp_vcl_initial_cpb_removal_delay[i][j]"); + bp.initialCpbRemoval[hrdType][sublayerIdx][j].delay = code; + sei_read_code(pDecodedMessageOutputStream, bp.cpbInitialRemovalDelayLength, code, + hrdType == HrdType::NAL ? "bp_nal_initial_cpb_removal_offset[i][j]" + : "bp_vcl_initial_cpb_removal_offset[i][j]"); + bp.initialCpbRemoval[hrdType][sublayerIdx][j].offset = code; } } } } - if (sei.m_bpMaxSubLayers-1 > 0) + if (bp.maxSublayers > 1) { sei_read_flag(pDecodedMessageOutputStream, code, "bp_sublayer_dpb_output_offsets_present_flag"); - sei.m_sublayerDpbOutputOffsetsPresentFlag = code; + bp.hasSublayerDpbOutputOffsets = code; } else { - sei.m_sublayerDpbOutputOffsetsPresentFlag = false; + bp.hasSublayerDpbOutputOffsets = false; } - if(sei.m_sublayerDpbOutputOffsetsPresentFlag) + if (bp.hasSublayerDpbOutputOffsets) { - for(int i = 0; i < sei.m_bpMaxSubLayers - 1; i++) + for (int i = 0; i < bp.maxSublayers - 1; i++) { - sei_read_uvlc( pDecodedMessageOutputStream, code, "dpb_output_tid_offset[i]" ); - sei.m_dpbOutputTidOffset[i] = code; + sei_read_uvlc(pDecodedMessageOutputStream, code, "bp_dpb_output_tid_offset[i]"); + bp.dpbOutputTidOffset[i] = code; } - sei.m_dpbOutputTidOffset[sei.m_bpMaxSubLayers-1] = 0; + bp.dpbOutputTidOffset[bp.maxSublayers - 1] = 0; } sei_read_flag(pDecodedMessageOutputStream, code, "bp_alt_cpb_params_present_flag"); - sei.m_altCpbParamsPresentFlag = code; - if (sei.m_altCpbParamsPresentFlag) + bp.hasAltCpbParams = code; + if (bp.hasAltCpbParams) { - sei_read_flag(pDecodedMessageOutputStream, code, "use_alt_cpb_params_flag"); sei.m_useAltCpbParamsFlag = code; + sei_read_flag(pDecodedMessageOutputStream, code, "bp_use_alt_cpb_params_flag"); + bp.useAltCpbParams = code; } + + CHECK(bp.hasAltCpbParams && bp.hasDuHrdParams, "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"); } void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSize, const uint32_t temporalId, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream) @@ -1665,16 +1697,17 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize); uint32_t symbol; - sei_read_code( pDecodedMessageOutputStream, bp.m_cpbRemovalDelayLength, symbol, "pt_cpb_removal_delay_minus1[bp_max_sub_layers_minus1]" ); - sei.m_auCpbRemovalDelay[bp.m_bpMaxSubLayers - 1] = symbol + 1; - sei.m_ptSubLayerDelaysPresentFlag[bp.m_bpMaxSubLayers - 1] = true; - for (int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i++) + sei_read_code(pDecodedMessageOutputStream, bp.cpbRemovalDelayLength, symbol, + "pt_cpb_removal_delay_minus1[bp_max_sub_layers_minus1]"); + sei.m_auCpbRemovalDelay[bp.maxSublayers - 1] = symbol + 1; + sei.m_ptSubLayerDelaysPresentFlag[bp.maxSublayers - 1] = true; + for (int i = temporalId; i < bp.maxSublayers - 1; i++) { sei_read_flag(pDecodedMessageOutputStream, symbol, "pt_sublayer_delays_present_flag[i]"); sei.m_ptSubLayerDelaysPresentFlag[i] = (symbol == 1); if (sei.m_ptSubLayerDelaysPresentFlag[i]) { - if (bp.m_cpbRemovalDelayDeltasPresentFlag) + if (bp.hasCpbRemovalDelayDeltas()) { sei_read_flag(pDecodedMessageOutputStream, symbol, "pt_cpb_removal_delay_delta_enabled_flag[i]"); sei.m_cpbRemovalDelayDeltaEnabledFlag[i] = (symbol == 1); @@ -1685,9 +1718,10 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi } if (sei.m_cpbRemovalDelayDeltaEnabledFlag[i]) { - if ((bp.m_numCpbRemovalDelayDeltas - 1) > 0) + if (bp.numCpbRemovalDelayDeltas() > 1) { - sei_read_code(pDecodedMessageOutputStream, ceilLog2(bp.m_numCpbRemovalDelayDeltas), symbol, "pt_cpb_removal_delay_delta_idx[i]"); + sei_read_code(pDecodedMessageOutputStream, ceilLog2(bp.numCpbRemovalDelayDeltas()), symbol, + "pt_cpb_removal_delay_delta_idx[i]"); sei.m_cpbRemovalDelayDeltaIdx[i] = symbol; } else @@ -1697,75 +1731,73 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi } else { - sei_read_code(pDecodedMessageOutputStream, bp.m_cpbRemovalDelayLength, symbol, "pt_cpb_removal_delay_minus1[i]"); + sei_read_code(pDecodedMessageOutputStream, bp.cpbRemovalDelayLength, symbol, "pt_cpb_removal_delay_minus1[i]"); sei.m_auCpbRemovalDelay[i] = symbol + 1; } } } - sei_read_code(pDecodedMessageOutputStream, bp.m_dpbOutputDelayLength, symbol, "pt_dpb_output_delay"); + sei_read_code(pDecodedMessageOutputStream, bp.dpbOutputDelayLength, symbol, "pt_dpb_output_delay"); sei.m_picDpbOutputDelay = symbol; - if( bp.m_altCpbParamsPresentFlag ) + if (bp.hasAltCpbParams) { sei_read_flag( pDecodedMessageOutputStream, symbol, "cpb_alt_timing_info_present_flag" ); sei.m_cpbAltTimingInfoPresentFlag = symbol; if( sei.m_cpbAltTimingInfoPresentFlag ) { - if (bp.m_bpNalCpbParamsPresentFlag) + if (bp.hasHrdParams[HrdType::NAL]) { - sei.m_nalCpbAltInitialRemovalDelayDelta.resize(bp.m_bpMaxSubLayers); - sei.m_nalCpbAltInitialRemovalOffsetDelta.resize(bp.m_bpMaxSubLayers); - for (int i = 0; i <= bp.m_bpMaxSubLayers - 1; ++i) + sei.m_nalCpbAltInitialRemovalDelayDelta.resize(bp.maxSublayers); + sei.m_nalCpbAltInitialRemovalOffsetDelta.resize(bp.maxSublayers); + for (int i = 0; i < bp.maxSublayers; ++i) { - sei.m_nalCpbAltInitialRemovalDelayDelta[i].resize(bp.m_bpCpbCnt, 0); - sei.m_nalCpbAltInitialRemovalOffsetDelta[i].resize(bp.m_bpCpbCnt, 0); + sei.m_nalCpbAltInitialRemovalDelayDelta[i].resize(bp.cpbCount, 0); + sei.m_nalCpbAltInitialRemovalOffsetDelta[i].resize(bp.cpbCount, 0); } - sei.m_nalCpbDelayOffset.resize(bp.m_bpMaxSubLayers, 0); - sei.m_nalDpbDelayOffset.resize(bp.m_bpMaxSubLayers, 0); - for (int i = (bp.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : bp.m_bpMaxSubLayers - 1); - i <= bp.m_bpMaxSubLayers - 1; ++i) + sei.m_nalCpbDelayOffset.resize(bp.maxSublayers, 0); + sei.m_nalDpbDelayOffset.resize(bp.maxSublayers, 0); + for (int i = (bp.hasSublayerInitialCpbRemovalDelay ? 0 : bp.maxSublayers - 1); i < bp.maxSublayers; ++i) { - for (int j = 0; j < bp.m_bpCpbCnt; j++) + for (int j = 0; j < bp.cpbCount; j++) { - sei_read_code(pDecodedMessageOutputStream, bp.m_initialCpbRemovalDelayLength, symbol, + sei_read_code(pDecodedMessageOutputStream, bp.cpbInitialRemovalDelayLength, symbol, "nal_cpb_alt_initial_cpb_removal_delay_delta[ i ][ j ]"); sei.m_nalCpbAltInitialRemovalDelayDelta[i][j] = symbol; - sei_read_code(pDecodedMessageOutputStream, bp.m_initialCpbRemovalDelayLength, symbol, + sei_read_code(pDecodedMessageOutputStream, bp.cpbInitialRemovalDelayLength, symbol, "nal_cpb_alt_initial_cpb_removal_offset_delta[ i ][ j ]"); sei.m_nalCpbAltInitialRemovalOffsetDelta[i][j] = symbol; } - sei_read_code(pDecodedMessageOutputStream, bp.m_cpbRemovalDelayLength, sei.m_nalCpbDelayOffset[i], + sei_read_code(pDecodedMessageOutputStream, bp.cpbRemovalDelayLength, sei.m_nalCpbDelayOffset[i], "nal_cpb_delay_offset[ i ]"); - sei_read_code(pDecodedMessageOutputStream, bp.m_dpbOutputDelayLength, sei.m_nalDpbDelayOffset[i], + sei_read_code(pDecodedMessageOutputStream, bp.dpbOutputDelayLength, sei.m_nalDpbDelayOffset[i], "nal_dpb_delay_offset[ i ]"); } } - if (bp.m_bpVclCpbParamsPresentFlag) + if (bp.hasHrdParams[HrdType::VCL]) { - sei.m_vclCpbAltInitialRemovalDelayDelta.resize(bp.m_bpMaxSubLayers); - sei.m_vclCpbAltInitialRemovalOffsetDelta.resize(bp.m_bpMaxSubLayers); - for (int i = 0; i <= bp.m_bpMaxSubLayers - 1; ++i) + sei.m_vclCpbAltInitialRemovalDelayDelta.resize(bp.maxSublayers); + sei.m_vclCpbAltInitialRemovalOffsetDelta.resize(bp.maxSublayers); + for (int i = 0; i < bp.maxSublayers; ++i) { - sei.m_vclCpbAltInitialRemovalDelayDelta[i].resize(bp.m_bpCpbCnt, 0); - sei.m_vclCpbAltInitialRemovalOffsetDelta[i].resize(bp.m_bpCpbCnt, 0); + sei.m_vclCpbAltInitialRemovalDelayDelta[i].resize(bp.cpbCount, 0); + sei.m_vclCpbAltInitialRemovalOffsetDelta[i].resize(bp.cpbCount, 0); } - sei.m_vclCpbDelayOffset.resize(bp.m_bpMaxSubLayers, 0); - sei.m_vclDpbDelayOffset.resize(bp.m_bpMaxSubLayers, 0); - for (int i = (bp.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : bp.m_bpMaxSubLayers - 1); - i <= bp.m_bpMaxSubLayers - 1; ++i) + sei.m_vclCpbDelayOffset.resize(bp.maxSublayers, 0); + sei.m_vclDpbDelayOffset.resize(bp.maxSublayers, 0); + for (int i = (bp.hasSublayerInitialCpbRemovalDelay ? 0 : bp.maxSublayers - 1); i < bp.maxSublayers; ++i) { - for (int j = 0; j < bp.m_bpCpbCnt; j++) + for (int j = 0; j < bp.cpbCount; j++) { - sei_read_code(pDecodedMessageOutputStream, bp.m_initialCpbRemovalDelayLength, symbol, + sei_read_code(pDecodedMessageOutputStream, bp.cpbInitialRemovalDelayLength, symbol, "vcl_cpb_alt_initial_cpb_removal_delay_delta[ i ][ j ]"); sei.m_vclCpbAltInitialRemovalDelayDelta[i][j] = symbol; - sei_read_code(pDecodedMessageOutputStream, bp.m_initialCpbRemovalDelayLength, symbol, + sei_read_code(pDecodedMessageOutputStream, bp.cpbInitialRemovalDelayLength, symbol, "vcl_cpb_alt_initial_cpb_removal_offset_delta[ i ][ j ]"); sei.m_vclCpbAltInitialRemovalOffsetDelta[i][j] = symbol; } - sei_read_code(pDecodedMessageOutputStream, bp.m_cpbRemovalDelayLength, sei.m_vclCpbDelayOffset[i], + sei_read_code(pDecodedMessageOutputStream, bp.cpbRemovalDelayLength, sei.m_vclCpbDelayOffset[i], "vcl_cpb_delay_offset[ i ]"); - sei_read_code(pDecodedMessageOutputStream, bp.m_dpbOutputDelayLength, sei.m_vclDpbDelayOffset[i], + sei_read_code(pDecodedMessageOutputStream, bp.dpbOutputDelayLength, sei.m_vclDpbDelayOffset[i], "vcl_dpb_delay_offset[ i ]"); } } @@ -1774,40 +1806,38 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi else { sei.m_cpbAltTimingInfoPresentFlag = false; - sei.m_nalCpbAltInitialRemovalDelayDelta.resize(bp.m_bpMaxSubLayers); - sei.m_nalCpbAltInitialRemovalOffsetDelta.resize(bp.m_bpMaxSubLayers); - sei.m_nalCpbDelayOffset.resize(bp.m_bpMaxSubLayers, 0); - sei.m_nalDpbDelayOffset.resize(bp.m_bpMaxSubLayers, 0); - for (int i = (bp.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : bp.m_bpMaxSubLayers - 1); - i <= bp.m_bpMaxSubLayers - 1; ++i) + sei.m_nalCpbAltInitialRemovalDelayDelta.resize(bp.maxSublayers); + sei.m_nalCpbAltInitialRemovalOffsetDelta.resize(bp.maxSublayers); + sei.m_nalCpbDelayOffset.resize(bp.maxSublayers, 0); + sei.m_nalDpbDelayOffset.resize(bp.maxSublayers, 0); + for (int i = (bp.hasSublayerInitialCpbRemovalDelay ? 0 : bp.maxSublayers - 1); i < bp.maxSublayers; ++i) { - sei.m_nalCpbAltInitialRemovalDelayDelta[i].resize(bp.m_bpCpbCnt, 0); - sei.m_nalCpbAltInitialRemovalOffsetDelta[i].resize(bp.m_bpCpbCnt, 0); + sei.m_nalCpbAltInitialRemovalDelayDelta[i].resize(bp.cpbCount, 0); + sei.m_nalCpbAltInitialRemovalOffsetDelta[i].resize(bp.cpbCount, 0); } - sei.m_vclCpbAltInitialRemovalDelayDelta.resize(bp.m_bpMaxSubLayers); - sei.m_vclCpbAltInitialRemovalOffsetDelta.resize(bp.m_bpMaxSubLayers); - sei.m_vclCpbDelayOffset.resize(bp.m_bpMaxSubLayers, 0); - sei.m_vclDpbDelayOffset.resize(bp.m_bpMaxSubLayers, 0); - for (int i = (bp.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : bp.m_bpMaxSubLayers - 1); - i <= bp.m_bpMaxSubLayers - 1; ++i) + sei.m_vclCpbAltInitialRemovalDelayDelta.resize(bp.maxSublayers); + sei.m_vclCpbAltInitialRemovalOffsetDelta.resize(bp.maxSublayers); + sei.m_vclCpbDelayOffset.resize(bp.maxSublayers, 0); + sei.m_vclDpbDelayOffset.resize(bp.maxSublayers, 0); + for (int i = (bp.hasSublayerInitialCpbRemovalDelay ? 0 : bp.maxSublayers - 1); i < bp.maxSublayers; ++i) { - sei.m_vclCpbAltInitialRemovalDelayDelta[i].resize(bp.m_bpCpbCnt, 0); - sei.m_vclCpbAltInitialRemovalOffsetDelta[i].resize(bp.m_bpCpbCnt, 0); + sei.m_vclCpbAltInitialRemovalDelayDelta[i].resize(bp.cpbCount, 0); + sei.m_vclCpbAltInitialRemovalOffsetDelta[i].resize(bp.cpbCount, 0); } } - if ( bp.m_bpDecodingUnitHrdParamsPresentFlag && bp.m_decodingUnitDpbDuParamsInPicTimingSeiFlag ) + if (bp.hasDuHrdParams && bp.duDpbParamsInPicTimingSei) { - sei_read_code( pDecodedMessageOutputStream, bp.getDpbOutputDelayDuLength(), symbol, "pic_dpb_output_du_delay" ); + sei_read_code(pDecodedMessageOutputStream, bp.dpbOutputDelayDuLength, symbol, "pic_dpb_output_du_delay"); sei.m_picDpbOutputDuDelay = symbol; } - if( bp.m_bpDecodingUnitHrdParamsPresentFlag && bp.m_decodingUnitCpbParamsInPicTimingSeiFlag ) + if (bp.hasDuHrdParams && bp.duCpbParamsInPicTimingSei) { sei_read_uvlc( pDecodedMessageOutputStream, symbol, "num_decoding_units_minus1" ); sei.m_numDecodingUnitsMinus1 = symbol; sei.m_numNalusInDuMinus1.resize(sei.m_numDecodingUnitsMinus1 + 1 ); - sei.m_duCpbRemovalDelayMinus1.resize( (sei.m_numDecodingUnitsMinus1 + 1) * bp.m_bpMaxSubLayers ); + sei.m_duCpbRemovalDelayMinus1.resize((sei.m_numDecodingUnitsMinus1 + 1) * bp.maxSublayers); if (sei.m_numDecodingUnitsMinus1 > 0) { @@ -1815,11 +1845,12 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi sei.m_duCommonCpbRemovalDelayFlag = symbol; if( sei.m_duCommonCpbRemovalDelayFlag ) { - for( int i = temporalId; i <= bp.m_bpMaxSubLayers - 1; i ++ ) + for (int i = temporalId; i < bp.maxSublayers; i++) { if( sei.m_ptSubLayerDelaysPresentFlag[i] ) { - sei_read_code( pDecodedMessageOutputStream, bp.getDuCpbRemovalDelayIncrementLength(), symbol, "du_common_cpb_removal_delay_increment_minus1[i]" ); + sei_read_code(pDecodedMessageOutputStream, bp.duCpbRemovalDelayIncrementLength, symbol, + "du_common_cpb_removal_delay_increment_minus1[i]"); sei.m_duCommonCpbRemovalDelayMinus1[i] = symbol; } } @@ -1830,12 +1861,13 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi sei.m_numNalusInDuMinus1[i] = symbol; if( !sei.m_duCommonCpbRemovalDelayFlag && i < sei.m_numDecodingUnitsMinus1 ) { - for( int j = temporalId; j <= bp.m_bpMaxSubLayers - 1; j ++ ) + for (int j = temporalId; j < bp.maxSublayers; j++) { if( sei.m_ptSubLayerDelaysPresentFlag[j] ) { - sei_read_code( pDecodedMessageOutputStream, bp.getDuCpbRemovalDelayIncrementLength(), symbol, "du_cpb_removal_delay_increment_minus1[i][j]" ); - sei.m_duCpbRemovalDelayMinus1[i * bp.m_bpMaxSubLayers + j] = symbol; + sei_read_code(pDecodedMessageOutputStream, bp.duCpbRemovalDelayIncrementLength, symbol, + "du_cpb_removal_delay_increment_minus1[i][j]"); + sei.m_duCpbRemovalDelayMinus1[i * bp.maxSublayers + j] = symbol; } } } diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h index 06e47e91d..f76514420 100644 --- a/source/Lib/DecoderLib/SEIread.h +++ b/source/Lib/DecoderLib/SEIread.h @@ -70,7 +70,8 @@ protected: void xParseSEIuserDataUnregistered (SEIuserDataUnregistered &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIDecodingUnitInfo (SEIDecodingUnitInfo& sei, uint32_t payloadSize, const SEIBufferingPeriod& bp, const uint32_t temporalId, std::ostream *pDecodedMessageOutputStream); void xParseSEIDecodedPictureHash (SEIDecodedPictureHash& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); - void xParseSEIBufferingPeriod (SEIBufferingPeriod& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); + void xParseSEIBufferingPeriod(SEIBufferingPeriod& bp, uint32_t payloadSize, + std::ostream* pDecodedMessageOutputStream); 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 xParseSEIScalableNestingBinary(SEIScalableNesting &sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index cca9ce1d1..eae71dc0b 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -679,7 +679,7 @@ void EncGOP::xWriteTrailingSEIMessages (SEIMessages& seiMessages, AccessUnit &ac void EncGOP::xWriteDuSEIMessages (SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, int temporalId, std::deque<DUData> &duData) { - if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && m_HRD->getBufferingPeriodSEI()->m_decodingUnitCpbParamsInPicTimingSeiFlag ) + if (m_pcCfg->getDecodingUnitInfoSEIEnabled() && m_HRD->getBufferingPeriodSEI()->duCpbParamsInPicTimingSei) { int naluIdx = 0; AccessUnit::iterator nalu = accessUnit.begin(); @@ -945,7 +945,7 @@ void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessage slice->getNalUnitLayerId()==slice->getVPS()->getLayerId(0) && (slice->getSPS()->getGeneralHrdParametersPresentFlag())) { - SEIBufferingPeriod *bufferingPeriodSEI = new SEIBufferingPeriod(); + auto bufferingPeriodSEI = new SEIBufferingPeriod; const bool noLeadingPictures = slice->getNalUnitType() != NAL_UNIT_CODED_SLICE_IDR_W_RADL && slice->getNalUnitType() != NAL_UNIT_CODED_SLICE_CRA; m_seiEncoder.initSEIBufferingPeriod(bufferingPeriodSEI,noLeadingPictures); @@ -955,7 +955,7 @@ void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessage if (m_pcCfg->getScalableNestingSEIEnabled()) { - SEIBufferingPeriod *bufferingPeriodSEIcopy = new SEIBufferingPeriod(); + auto bufferingPeriodSEIcopy = new SEIBufferingPeriod; bufferingPeriodSEI->copyTo(*bufferingPeriodSEIcopy); nestedSeiMessages.push_back(bufferingPeriodSEIcopy); } @@ -1126,7 +1126,7 @@ void EncGOP::xCreatePictureTimingSEI(int irapGopId, SEIMessages &seiMessages, SE const uint32_t maxNumSubLayers = slice->getSPS()->getMaxTLayers(); pictureTimingSEI->m_duCpbRemovalDelayMinus1.resize( numDU * maxNumSubLayers ); } - const uint32_t cpbRemovalDelayLegth = m_HRD->getBufferingPeriodSEI()->m_cpbRemovalDelayLength; + const uint32_t cpbRemovalDelayLegth = m_HRD->getBufferingPeriodSEI()->cpbRemovalDelayLength; const uint32_t maxNumSubLayers = slice->getSPS()->getMaxTLayers(); pictureTimingSEI->m_auCpbRemovalDelay[maxNumSubLayers-1] = std::min<int>(std::max<int>(1, m_totalCoded[maxNumSubLayers-1] - m_lastBPSEI[maxNumSubLayers-1]), static_cast<int>(pow(2, static_cast<double>(cpbRemovalDelayLegth)))); // Syntax element signalled as minus, hence the . CHECK( (m_totalCoded[maxNumSubLayers-1] - m_lastBPSEI[maxNumSubLayers-1]) > pow(2, static_cast<double>(cpbRemovalDelayLegth)), " cpbRemovalDelayLegth too small for m_auCpbRemovalDelay[pt_max_sub_layers_minus1] at picture timing SEI " ); @@ -1145,7 +1145,8 @@ void EncGOP::xCreatePictureTimingSEI(int irapGopId, SEIMessages &seiMessages, SE } else { - pictureTimingSEI->m_cpbRemovalDelayDeltaEnabledFlag[i] = m_HRD->getBufferingPeriodSEI()->m_cpbRemovalDelayDeltasPresentFlag; + pictureTimingSEI->m_cpbRemovalDelayDeltaEnabledFlag[i] = + m_HRD->getBufferingPeriodSEI()->hasCpbRemovalDelayDeltas(); } if( pictureTimingSEI->m_cpbRemovalDelayDeltaEnabledFlag[i] ) { @@ -1473,7 +1474,7 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD } } -void EncGOP::xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI, int maxSubLayers) +void EncGOP::xUpdateDuInfoSEI(SEIMessages& duInfoSeiMessages, SEIPictureTiming* pictureTimingSEI, int maxSublayers) { if (duInfoSeiMessages.empty() || (pictureTimingSEI == nullptr)) { @@ -1486,10 +1487,11 @@ void EncGOP::xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming * { SEIDecodingUnitInfo *duInfoSEI = (SEIDecodingUnitInfo*) (*du); duInfoSEI->m_decodingUnitIdx = i; - for ( int j = 0; j < maxSubLayers; j++ ) + for (int j = 0; j < maxSublayers; j++) { duInfoSEI->m_duiSubLayerDelaysPresentFlag[j] = pictureTimingSEI->m_ptSubLayerDelaysPresentFlag[j]; - duInfoSEI->m_duSptCpbRemovalDelayIncrement[j] = pictureTimingSEI->m_duCpbRemovalDelayMinus1[i*maxSubLayers+j] + 1; + duInfoSEI->m_duSptCpbRemovalDelayIncrement[j] = + pictureTimingSEI->m_duCpbRemovalDelayMinus1[i * maxSublayers + j] + 1; } duInfoSEI->m_dpbOutputDuDelayPresentFlag = false; i++; diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h index 5640b63b5..39f4b9975 100644 --- a/source/Lib/EncoderLib/EncGOP.h +++ b/source/Lib/EncoderLib/EncGOP.h @@ -354,7 +354,7 @@ protected: SEIMessages &duInfoSeiMessages, Slice *slice, bool isField, std::deque<DUData> &duData); void xUpdateDuData(AccessUnit &testAU, std::deque<DUData> &duData); void xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUData> &duData, const SPS *sps); - void xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI, int maxSubLayers); + void xUpdateDuInfoSEI(SEIMessages& duInfoSeiMessages, SEIPictureTiming* pictureTimingSEI, int maxSublayers); void xCreateScalableNestingSEI(SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, const std::vector<int> &targetOLSs, const std::vector<int> &targetLayers, const std::vector<uint16_t>& subpicIDs, uint16_t maxSubpicIdInPic); void xWriteSEI (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, int temporalId); void xWriteSEISeparately (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, int temporalId); diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index c24b1ca33..843ef0bae 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -80,36 +80,37 @@ void SEIEncoder::initSEIParameterSetsInclusionIndication(SEIParameterSetsInclusi seiParameterSetsInclusionIndication->m_selfContainedClvsFlag = m_pcCfg->getSelfContainedClvsFlag(); } -void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI, bool noLeadingPictures) +void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod* bp, bool noLeadingPictures) { CHECK(!(m_isInitialized), "bufferingPeriodSEI already initialized"); - CHECK(!(bufferingPeriodSEI != nullptr), "Need a bufferingPeriodSEI for initialization (got nullptr)"); - - uint32_t uiInitialCpbRemovalDelay = (90000/2); // 0.5 sec - bufferingPeriodSEI->m_bpNalCpbParamsPresentFlag = true; - bufferingPeriodSEI->m_bpVclCpbParamsPresentFlag = true; - bufferingPeriodSEI->m_bpMaxSubLayers = m_pcCfg->getMaxTempLayer() ; - bufferingPeriodSEI->m_bpCpbCnt = 1; - for(int i=0; i < bufferingPeriodSEI->m_bpMaxSubLayers; i++) + CHECK(bp == nullptr, "Need a bufferingPeriodSEI for initialization (got nullptr)"); + + const uint32_t initialCpbRemovalDelay = (90000 / 2); // 0.5 sec + bp->maxSublayers = m_pcCfg->getMaxTempLayer(); + bp->cpbCount = 1; + + for (auto hrdType: { HrdType::NAL, HrdType::VCL }) { - for(int j=0; j < bufferingPeriodSEI->m_bpCpbCnt; j++) + bp->hasHrdParams[hrdType] = true; + for (int sublayerIdx = 0; sublayerIdx < bp->maxSublayers; sublayerIdx++) { - bufferingPeriodSEI->m_initialCpbRemovalDelay[i][j][0] = uiInitialCpbRemovalDelay; - bufferingPeriodSEI->m_initialCpbRemovalDelay[i][j][1] = uiInitialCpbRemovalDelay; - bufferingPeriodSEI->m_initialCpbRemovalOffset[i][j][0] = uiInitialCpbRemovalDelay; - bufferingPeriodSEI->m_initialCpbRemovalOffset[i][j][1] = uiInitialCpbRemovalDelay; + for (int j = 0; j < bp->cpbCount; j++) + { + bp->initialCpbRemoval[hrdType][sublayerIdx][j] = { initialCpbRemovalDelay, initialCpbRemovalDelay }; + } } } + // We don't set concatenation_flag here. max_initial_removal_delay_for_concatenation depends on the usage scenario. // The parameters could be added to config file, but as long as the initialisation of generic buffering parameters is // not controllable, it does not seem to make sense to provide settings for these. - bufferingPeriodSEI->m_concatenationFlag = false; - bufferingPeriodSEI->m_maxInitialRemovalDelayForConcatenation = uiInitialCpbRemovalDelay; + bp->concatenation = false; + bp->maxInitialRemovalDelayForConcatenation = initialCpbRemovalDelay; - bufferingPeriodSEI->m_bpDecodingUnitHrdParamsPresentFlag = m_pcCfg->getNoPicPartitionFlag() == false; - bufferingPeriodSEI->m_decodingUnitCpbParamsInPicTimingSeiFlag = !m_pcCfg->getDecodingUnitInfoSEIEnabled(); + bp->hasDuHrdParams = m_pcCfg->getNoPicPartitionFlag() == false; + bp->duCpbParamsInPicTimingSei = !m_pcCfg->getDecodingUnitInfoSEIEnabled(); - bufferingPeriodSEI->m_initialCpbRemovalDelayLength = 16; // assuming 0.5 sec, log2( 90,000 * 0.5 ) = 16-bit + bp->cpbInitialRemovalDelayLength = 16; // assuming 0.5 sec, log2( 90,000 * 0.5 ) = 16-bit // Note: The following parameters require some knowledge about the GOP structure. // Using getIntraPeriod() should be avoided though, because it assumes certain GOP // properties, which are only valid in CTC. @@ -117,98 +118,71 @@ void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI, bool isRandomAccess = m_pcCfg->getIntraPeriod() > 0; if( isRandomAccess ) { - bufferingPeriodSEI->m_cpbRemovalDelayLength = 6; // 32 = 2^5 (plus 1) - bufferingPeriodSEI->m_dpbOutputDelayLength = 6; // 32 + 3 = 2^6 + bp->cpbRemovalDelayLength = 6; // 32 = 2^5 (plus 1) + bp->dpbOutputDelayLength = 6; // 32 + 3 = 2^6 } else { - bufferingPeriodSEI->m_cpbRemovalDelayLength = 9; // max. 2^10 - bufferingPeriodSEI->m_dpbOutputDelayLength = 9; // max. 2^10 + bp->cpbRemovalDelayLength = 9; // max. 2^10 + bp->dpbOutputDelayLength = 9; // max. 2^10 } - bufferingPeriodSEI->m_duCpbRemovalDelayIncrementLength = 7; // ceil( log2( tick_divisor_minus2 + 2 ) ) - bufferingPeriodSEI->m_dpbOutputDelayDuLength = bufferingPeriodSEI->m_dpbOutputDelayLength + bufferingPeriodSEI->m_duCpbRemovalDelayIncrementLength; + bp->duCpbRemovalDelayIncrementLength = 7; // ceil( log2( tick_divisor_minus2 + 2 ) ) + bp->dpbOutputDelayDuLength = bp->dpbOutputDelayLength + bp->duCpbRemovalDelayIncrementLength; //for the concatenation, it can be set to one during splicing. - bufferingPeriodSEI->m_concatenationFlag = 0; + bp->concatenation = 0; //since the temporal layer HRDParameters is not ready, we assumed it is fixed - bufferingPeriodSEI->m_auCpbRemovalDelayDelta = 1; - bufferingPeriodSEI->m_cpbRemovalDelayDeltasPresentFlag = m_pcCfg->getBpDeltasGOPStructure() ; - if (bufferingPeriodSEI->m_cpbRemovalDelayDeltasPresentFlag) + bp->cpbRemovalDelayDelta = 1; + + if (m_pcCfg->getBpDeltasGOPStructure()) { switch (m_pcCfg->getGOPSize()) { - case 8: + case 8: + if (noLeadingPictures) { - if (noLeadingPictures) - { - bufferingPeriodSEI->m_numCpbRemovalDelayDeltas = 5; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[0] = 1; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[1] = 2; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[2] = 3; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[3] = 6; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[4] = 7; - } - else - { - bufferingPeriodSEI->m_numCpbRemovalDelayDeltas = 3; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[0] = 1; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[1] = 2; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[2] = 3; - } + bp->cpbRemovalDelayDeltaVals = { 1, 2, 3, 6, 7 }; } - break; - case 16: + else { - if (noLeadingPictures) - { - bufferingPeriodSEI->m_numCpbRemovalDelayDeltas = 9; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[0] = 1; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[1] = 2; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[2] = 3; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[3] = 4; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[4] = 6; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[5] = 7; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[6] = 9; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[7] = 14; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[8] = 15; - } - else - { - bufferingPeriodSEI->m_numCpbRemovalDelayDeltas = 5; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[0] = 1; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[1] = 2; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[2] = 3; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[3] = 6; - bufferingPeriodSEI->m_cpbRemovalDelayDelta[4] = 7; - } + bp->cpbRemovalDelayDeltaVals = { 1, 2, 3 }; } - break; - default: + break; + case 16: + if (noLeadingPictures) { - THROW("m_cpbRemovalDelayDelta not applicable for the GOP size"); + bp->cpbRemovalDelayDeltaVals = { 1, 2, 3, 4, 6, 7, 9, 14, 15 }; } - break; + else + { + bp->cpbRemovalDelayDeltaVals = { 1, 2, 3, 6, 7 }; + } + break; + default: + THROW("cpbRemovalDelayDelta not applicable for the GOP size"); + break; } } - bufferingPeriodSEI->m_sublayerDpbOutputOffsetsPresentFlag = true; - for(int i = 0; i < bufferingPeriodSEI->m_bpMaxSubLayers; i++) + else { - bufferingPeriodSEI->m_dpbOutputTidOffset[i] = m_pcCfg->getMaxNumReorderPics(i) * static_cast<int>(pow(2, static_cast<double>(bufferingPeriodSEI->m_bpMaxSubLayers-1-i))); - if(bufferingPeriodSEI->m_dpbOutputTidOffset[i] >= m_pcCfg->getMaxNumReorderPics(bufferingPeriodSEI->m_bpMaxSubLayers-1)) - { - bufferingPeriodSEI->m_dpbOutputTidOffset[i] -= m_pcCfg->getMaxNumReorderPics(bufferingPeriodSEI->m_bpMaxSubLayers-1); - } - else - { - bufferingPeriodSEI->m_dpbOutputTidOffset[i] = 0; - } + bp->cpbRemovalDelayDeltaVals.clear(); + } + + bp->hasSublayerDpbOutputOffsets = true; + const uint32_t lastSublayer = bp->maxSublayers - 1; + for (int sublayerIdx = 0; sublayerIdx <= lastSublayer; sublayerIdx++) + { + bp->dpbOutputTidOffset[sublayerIdx] = + std::max<int>(m_pcCfg->getMaxNumReorderPics(sublayerIdx) * (1 << (lastSublayer - sublayerIdx)) + - m_pcCfg->getMaxNumReorderPics(lastSublayer), + 0); } // A commercial encoder should track the buffer state for all layers and sub-layers // to ensure CPB conformance. Such tracking is required for calculating alternative // CPB parameters. // Unfortunately VTM does not have such tracking. Thus we cannot encode alternative // CPB parameters here. - bufferingPeriodSEI->m_altCpbParamsPresentFlag = false; - bufferingPeriodSEI->m_useAltCpbParamsFlag = false; + bp->hasAltCpbParams = false; + bp->useAltCpbParams = false; } void SEIEncoder::initSEIErp(SEIEquirectangularProjection* seiEquirectangularProjection) diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp index fe3900407..5d575a854 100644 --- a/source/Lib/EncoderLib/SEIwrite.cpp +++ b/source/Lib/EncoderLib/SEIwrite.cpp @@ -321,192 +321,202 @@ void SEIWriter::xWriteSEIDecodedPictureHash(const SEIDecodedPictureHash& sei) void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const SEIBufferingPeriod& bp, const uint32_t temporalId) { xWriteUvlc(sei.m_decodingUnitIdx, "decoding_unit_idx"); - if( !bp.m_decodingUnitCpbParamsInPicTimingSeiFlag ) + if (!bp.duCpbParamsInPicTimingSei) { - for (int i = temporalId; i <= bp.m_bpMaxSubLayers - 1; i++) + for (int i = temporalId; i < bp.maxSublayers; i++) { - if (i < bp.m_bpMaxSubLayers - 1) + if (i < bp.maxSublayers - 1) { xWriteFlag(sei.m_duiSubLayerDelaysPresentFlag[i], "dui_sub_layer_delays_present_flag[i]"); } if( sei.m_duiSubLayerDelaysPresentFlag[i] ) { - xWriteCode( sei.m_duSptCpbRemovalDelayIncrement[i], bp.getDuCpbRemovalDelayIncrementLength(), "du_spt_cpb_removal_delay_increment[i]"); + xWriteCode(sei.m_duSptCpbRemovalDelayIncrement[i], bp.duCpbRemovalDelayIncrementLength, + "du_spt_cpb_removal_delay_increment[i]"); } } } - if (!bp.m_decodingUnitDpbDuParamsInPicTimingSeiFlag) + if (!bp.duDpbParamsInPicTimingSei) { xWriteFlag(sei.m_dpbOutputDuDelayPresentFlag, "dpb_output_du_delay_present_flag"); } if(sei.m_dpbOutputDuDelayPresentFlag) { - xWriteCode(sei.m_picSptDpbOutputDuDelay, bp.getDpbOutputDelayDuLength(), "pic_spt_dpb_output_du_delay"); + xWriteCode(sei.m_picSptDpbOutputDuDelay, bp.dpbOutputDelayDuLength, "pic_spt_dpb_output_du_delay"); } } void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei) { - xWriteFlag( sei.m_bpNalCpbParamsPresentFlag, "bp_nal_hrd_parameters_present_flag"); - xWriteFlag( sei.m_bpVclCpbParamsPresentFlag, "bp_vcl_hrd_parameters_present_flag"); - CHECK(!sei.m_bpNalCpbParamsPresentFlag && !sei.m_bpVclCpbParamsPresentFlag, "bp_nal_hrd_parameters_present_flag and/or bp_vcl_hrd_parameters_present_flag must be true"); - CHECK (sei.m_initialCpbRemovalDelayLength < 1, "sei.m_initialCpbRemovalDelayLength must be > 0"); - xWriteCode( sei.m_initialCpbRemovalDelayLength - 1, 5, "initial_cpb_removal_delay_length_minus1" ); - CHECK (sei.m_cpbRemovalDelayLength < 1, "sei.m_cpbRemovalDelayLength must be > 0"); - xWriteCode( sei.m_cpbRemovalDelayLength - 1, 5, "cpb_removal_delay_length_minus1" ); - CHECK (sei.m_dpbOutputDelayLength < 1, "sei.m_dpbOutputDelayLength must be > 0"); - xWriteCode( sei.m_dpbOutputDelayLength - 1, 5, "dpb_output_delay_length_minus1" ); - xWriteFlag( sei.m_bpDecodingUnitHrdParamsPresentFlag, "bp_decoding_unit_hrd_params_present_flag" ); - if( sei.m_bpDecodingUnitHrdParamsPresentFlag ) + CHECK(!sei.hasHrdParams[HrdType::NAL] && !sei.hasHrdParams[HrdType::VCL], + "at least one of bp_nal_hrd_params_present_flag and bp_vcl_hrd_params_present_flag must be true"); + xWriteFlag(sei.hasHrdParams[HrdType::NAL], "bp_nal_hrd_params_present_flag"); + xWriteFlag(sei.hasHrdParams[HrdType::VCL], "bp_vcl_hrd_params_present_flag"); + + CHECK(sei.cpbInitialRemovalDelayLength < 1, "sei.cpbInitialRemovalDelayLength must be > 0"); + xWriteCode(sei.cpbInitialRemovalDelayLength - 1, 5, "bp_cpb_initial_removal_delay_length_minus1"); + + CHECK(sei.cpbRemovalDelayLength < 1, "sei.cpbRemovalDelayLength must be > 0"); + xWriteCode(sei.cpbRemovalDelayLength - 1, 5, "bp_cpb_removal_delay_length_minus1"); + + CHECK(sei.dpbOutputDelayLength < 1, "sei.dpbOutputDelayLength must be > 0"); + xWriteCode(sei.dpbOutputDelayLength - 1, 5, "bp_dpb_output_delay_length_minus1"); + + xWriteFlag(sei.hasDuHrdParams, "bp_du_hrd_params_present_flag"); + if (sei.hasDuHrdParams) { - CHECK (sei.m_duCpbRemovalDelayIncrementLength < 1, "sei.m_duCpbRemovalDelayIncrementLength must be > 0"); - xWriteCode( sei.m_duCpbRemovalDelayIncrementLength - 1, 5, "du_cpb_removal_delay_increment_length_minus1" ); - CHECK (sei.m_dpbOutputDelayDuLength < 1, "sei.m_dpbOutputDelayDuLength must be > 0"); - xWriteCode( sei.m_dpbOutputDelayDuLength - 1, 5, "dpb_output_delay_du_length_minus1" ); - xWriteFlag( sei.m_decodingUnitCpbParamsInPicTimingSeiFlag, "decoding_unit_cpb_params_in_pic_timing_sei_flag" ); - xWriteFlag(sei.m_decodingUnitDpbDuParamsInPicTimingSeiFlag, "decoding_unit_dpb_du_params_in_pic_timing_sei_flag"); + CHECK(sei.duCpbRemovalDelayIncrementLength < 1, "sei.duCpbRemovalDelayIncrementLength must be > 0"); + xWriteCode(sei.duCpbRemovalDelayIncrementLength - 1, 5, "bp_du_cpb_removal_delay_increment_length_minus1"); + + CHECK(sei.dpbOutputDelayDuLength < 1, "sei.dpbOutputDelayDuLength must be > 0"); + xWriteCode(sei.dpbOutputDelayDuLength - 1, 5, "bp_dpb_output_delay_du_length_minus1"); + + xWriteFlag(sei.duCpbParamsInPicTimingSei, "bp_du_cpb_params_in_pic_timing_sei_flag"); + xWriteFlag(sei.duDpbParamsInPicTimingSei, "bp_du_dpb_params_in_pic_timing_sei_flag"); } - xWriteFlag( sei.m_concatenationFlag, "concatenation_flag"); - xWriteFlag( sei.m_additionalConcatenationInfoPresentFlag, "additional_concatenation_info_present_flag"); - if (sei.m_additionalConcatenationInfoPresentFlag) + xWriteFlag(sei.concatenation, "bp_concatenation_flag"); + xWriteFlag(sei.hasAdditionalConcatenationInfo, "bp_additional_concatenation_info_present_flag"); + if (sei.hasAdditionalConcatenationInfo) { - xWriteCode( sei.m_maxInitialRemovalDelayForConcatenation, sei.m_initialCpbRemovalDelayLength, "max_initial_removal_delay_for_concatenation" ); + xWriteCode(sei.maxInitialRemovalDelayForConcatenation, sei.cpbInitialRemovalDelayLength, + "bp_max_initial_removal_delay_for_concatenation"); } - CHECK (sei.m_auCpbRemovalDelayDelta < 1, "sei.m_auCpbRemovalDelayDelta must be > 0"); - xWriteCode( sei.m_auCpbRemovalDelayDelta - 1, sei.m_cpbRemovalDelayLength, "au_cpb_removal_delay_delta_minus1" ); + CHECK(sei.cpbRemovalDelayDelta < 1, "sei.cpbRemovalDelayDelta must be > 0"); + xWriteCode(sei.cpbRemovalDelayDelta - 1, sei.cpbRemovalDelayLength, "bp_cpb_removal_delay_delta_minus1"); - CHECK(sei.m_bpMaxSubLayers < 1, "bp_max_sub_layers_minus1 must be > 0"); - xWriteCode(sei.m_bpMaxSubLayers - 1, 3, "bp_max_sub_layers_minus1"); - if (sei.m_bpMaxSubLayers - 1 > 0) + CHECK(sei.maxSublayers < 1, "bp_max_sublayers must be > 0"); + xWriteCode(sei.maxSublayers - 1, 3, "bp_max_sublayers_minus1"); + if (sei.maxSublayers > 1) { - xWriteFlag(sei.m_cpbRemovalDelayDeltasPresentFlag, "cpb_removal_delay_deltas_present_flag"); + xWriteFlag(sei.hasCpbRemovalDelayDeltas(), "bp_cpb_removal_delay_deltas_present_flag"); } - if (sei.m_cpbRemovalDelayDeltasPresentFlag) + if (sei.hasCpbRemovalDelayDeltas()) { - CHECK (sei.m_numCpbRemovalDelayDeltas < 1, "m_numCpbRemovalDelayDeltas must be > 0"); - xWriteUvlc( sei.m_numCpbRemovalDelayDeltas - 1, "num_cpb_removal_delay_deltas_minus1" ); - for( int i = 0; i < sei.m_numCpbRemovalDelayDeltas; i ++ ) + xWriteUvlc(sei.numCpbRemovalDelayDeltas() - 1, "bp_num_cpb_removal_delay_deltas_minus1"); + for (int i = 0; i < sei.numCpbRemovalDelayDeltas(); i++) { - xWriteCode( sei.m_cpbRemovalDelayDelta[i], sei.m_cpbRemovalDelayLength, "cpb_removal_delay_delta[i]" ); + xWriteCode(sei.cpbRemovalDelayDeltaVals[i], sei.cpbRemovalDelayLength, "bp_cpb_removal_delay_delta_val[i]"); } } - CHECK (sei.m_bpCpbCnt < 1, "sei.m_bpCpbCnt must be > 0"); - xWriteUvlc( sei.m_bpCpbCnt - 1, "bp_cpb_cnt_minus1"); - if (sei.m_bpMaxSubLayers - 1 > 0) + CHECK(sei.cpbCount < 1, "sei.cpbCount must be > 0"); + xWriteUvlc(sei.cpbCount - 1, "bp_cpb_cnt_minus1"); + if (sei.maxSublayers - 1 > 0) { - xWriteFlag(sei.m_sublayerInitialCpbRemovalDelayPresentFlag, "bp_sublayer_initial_cpb_removal_delay_present_flag"); + xWriteFlag(sei.hasSublayerInitialCpbRemovalDelay, "bp_sublayer_initial_cpb_removal_delay_present_flag"); } - for (int i = (sei.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : sei.m_bpMaxSubLayers - 1); i < sei.m_bpMaxSubLayers; i++) + for (int i = (sei.hasSublayerInitialCpbRemovalDelay ? 0 : sei.maxSublayers - 1); i < sei.maxSublayers; i++) { - for( int nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ ) + for (auto hrdType: { HrdType::NAL, HrdType::VCL }) { - if( ( ( nalOrVcl == 0 ) && ( sei.m_bpNalCpbParamsPresentFlag ) ) || - ( ( nalOrVcl == 1 ) && ( sei.m_bpVclCpbParamsPresentFlag ) ) ) + if (sei.hasHrdParams[hrdType]) { - for( int j = 0; j < sei.m_bpCpbCnt; j ++ ) + for (int j = 0; j < sei.cpbCount; j++) { - xWriteCode( sei.m_initialCpbRemovalDelay[i][j][nalOrVcl], sei.m_initialCpbRemovalDelayLength, "initial_cpb_removal_delay[i][j][nalOrVcl]" ); - xWriteCode( sei.m_initialCpbRemovalOffset[i][j][nalOrVcl], sei.m_initialCpbRemovalDelayLength, "initial_cpb_removal_delay_offset[i][j][nalOrVcl]" ); + xWriteCode(sei.initialCpbRemoval[hrdType][i][j].delay, sei.cpbInitialRemovalDelayLength, + hrdType == HrdType::NAL ? "bp_nal_initial_cpb_removal_delay[i][j]" + : "bp_vcl_initial_cpb_removal_delay[i][j]"); + xWriteCode(sei.initialCpbRemoval[hrdType][i][j].offset, sei.cpbInitialRemovalDelayLength, + hrdType == HrdType::NAL ? "bp_nal_initial_cpb_removal_offset[i][j]" + : "bp_vcl_initial_cpb_removal_offset[i][j]"); } } } } - if (sei.m_bpMaxSubLayers-1 > 0) + if (sei.maxSublayers - 1 > 0) { - xWriteFlag(sei.m_sublayerDpbOutputOffsetsPresentFlag, "bp_sublayer_dpb_output_offsets_present_flag"); + xWriteFlag(sei.hasSublayerDpbOutputOffsets, "bp_sublayer_dpb_output_offsets_present_flag"); } - if(sei.m_sublayerDpbOutputOffsetsPresentFlag) + if (sei.hasSublayerDpbOutputOffsets) { - for(int i = 0; i < sei.m_bpMaxSubLayers - 1; i++) + for (int i = 0; i < sei.maxSublayers - 1; i++) { - xWriteUvlc( sei.m_dpbOutputTidOffset[i], "dpb_output_tid_offset[i]" ); + xWriteUvlc(sei.dpbOutputTidOffset[i], "bp_dpb_output_tid_offset[i]"); } } - xWriteFlag(sei.m_altCpbParamsPresentFlag, "bp_alt_cpb_params_present_flag"); - if (sei.m_altCpbParamsPresentFlag) + xWriteFlag(sei.hasAltCpbParams, "bp_alt_cpb_params_present_flag"); + if (sei.hasAltCpbParams) { - xWriteFlag(sei.m_useAltCpbParamsFlag, "use_alt_cpb_params_flag"); + xWriteFlag(sei.useAltCpbParams, "bp_use_alt_cpb_params_flag"); } - } void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBufferingPeriod &bp, const uint32_t temporalId) { - - xWriteCode( sei.m_auCpbRemovalDelay[bp.m_bpMaxSubLayers - 1] - 1, bp.m_cpbRemovalDelayLength, "pt_cpb_removal_delay_minus1[bp_max_sub_layers_minus1]" ); - for (int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i++) + xWriteCode(sei.m_auCpbRemovalDelay[bp.maxSublayers - 1] - 1, bp.cpbRemovalDelayLength, + "pt_cpb_removal_delay_minus1[bp_max_sub_layers_minus1]"); + for (int i = temporalId; i < bp.maxSublayers - 1; i++) { xWriteFlag(sei.m_ptSubLayerDelaysPresentFlag[i], "pt_sublayer_delays_present_flag[i]"); if (sei.m_ptSubLayerDelaysPresentFlag[i]) { - if (bp.m_cpbRemovalDelayDeltasPresentFlag) + if (bp.hasCpbRemovalDelayDeltas()) { xWriteFlag(sei.m_cpbRemovalDelayDeltaEnabledFlag[i], "pt_cpb_removal_delay_delta_enabled_flag[i]"); } if (sei.m_cpbRemovalDelayDeltaEnabledFlag[i]) { - if ((bp.m_numCpbRemovalDelayDeltas - 1) > 0) + if (bp.numCpbRemovalDelayDeltas() > 1) { - xWriteCode(sei.m_cpbRemovalDelayDeltaIdx[i], ceilLog2(bp.m_numCpbRemovalDelayDeltas), "pt_cpb_removal_delay_delta_idx[i]"); + xWriteCode(sei.m_cpbRemovalDelayDeltaIdx[i], ceilLog2(bp.numCpbRemovalDelayDeltas()), + "pt_cpb_removal_delay_delta_idx[i]"); } } else { - xWriteCode(sei.m_auCpbRemovalDelay[i] - 1, bp.m_cpbRemovalDelayLength, "pt_cpb_removal_delay_minus1[i]"); + xWriteCode(sei.m_auCpbRemovalDelay[i] - 1, bp.cpbRemovalDelayLength, "pt_cpb_removal_delay_minus1[i]"); } } } - xWriteCode(sei.m_picDpbOutputDelay, bp.m_dpbOutputDelayLength, "pt_dpb_output_delay"); - if( bp.m_altCpbParamsPresentFlag ) + xWriteCode(sei.m_picDpbOutputDelay, bp.dpbOutputDelayLength, "pt_dpb_output_delay"); + if (bp.hasAltCpbParams) { xWriteFlag( sei.m_cpbAltTimingInfoPresentFlag, "cpb_alt_timing_info_present_flag" ); if( sei.m_cpbAltTimingInfoPresentFlag ) { - if (bp.m_bpNalCpbParamsPresentFlag) + if (bp.hasHrdParams[HrdType::NAL]) { - for (int i = (bp.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : bp.m_bpMaxSubLayers - 1); i <= bp.m_bpMaxSubLayers - 1; ++i) + for (int i = (bp.hasSublayerInitialCpbRemovalDelay ? 0 : bp.maxSublayers - 1); i < bp.maxSublayers; ++i) { - for (int j = 0; j < bp.m_bpCpbCnt; j++) + for (int j = 0; j < bp.cpbCount; j++) { - xWriteCode(sei.m_nalCpbAltInitialRemovalDelayDelta[i][j], bp.m_initialCpbRemovalDelayLength, + xWriteCode(sei.m_nalCpbAltInitialRemovalDelayDelta[i][j], bp.cpbInitialRemovalDelayLength, "nal_cpb_alt_initial_cpb_removal_delay_delta[ i ][ j ]"); - xWriteCode(sei.m_nalCpbAltInitialRemovalOffsetDelta[i][j], bp.m_initialCpbRemovalDelayLength, + xWriteCode(sei.m_nalCpbAltInitialRemovalOffsetDelta[i][j], bp.cpbInitialRemovalDelayLength, "nal_cpb_alt_initial_cpb_removal_offset_delta[ i ][ j ]"); } - xWriteCode(sei.m_nalCpbDelayOffset[i], bp.m_cpbRemovalDelayLength, "nal_cpb_delay_offset[ i ]"); - xWriteCode(sei.m_nalDpbDelayOffset[i], bp.m_dpbOutputDelayLength, "nal_dpb_delay_offset[ i ]"); + xWriteCode(sei.m_nalCpbDelayOffset[i], bp.cpbRemovalDelayLength, "nal_cpb_delay_offset[ i ]"); + xWriteCode(sei.m_nalDpbDelayOffset[i], bp.dpbOutputDelayLength, "nal_dpb_delay_offset[ i ]"); } } - if (bp.m_bpVclCpbParamsPresentFlag) + if (bp.hasHrdParams[HrdType::VCL]) { - for (int i = (bp.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : bp.m_bpMaxSubLayers - 1); - i <= bp.m_bpMaxSubLayers - 1; ++i) + for (int i = (bp.hasSublayerInitialCpbRemovalDelay ? 0 : bp.maxSublayers - 1); i < bp.maxSublayers; ++i) { - for (int j = 0; j < bp.m_bpCpbCnt; j++) + for (int j = 0; j < bp.cpbCount; j++) { - xWriteCode(sei.m_vclCpbAltInitialRemovalDelayDelta[i][j], bp.m_initialCpbRemovalDelayLength, + xWriteCode(sei.m_vclCpbAltInitialRemovalDelayDelta[i][j], bp.cpbInitialRemovalDelayLength, "vcl_cpb_alt_initial_cpb_removal_delay_delta[ i ][ j ]"); - xWriteCode(sei.m_vclCpbAltInitialRemovalOffsetDelta[i][j], bp.m_initialCpbRemovalDelayLength, + xWriteCode(sei.m_vclCpbAltInitialRemovalOffsetDelta[i][j], bp.cpbInitialRemovalDelayLength, "vcl_cpb_alt_initial_cpb_removal_offset_delta[ i ][ j ]"); } - xWriteCode(sei.m_vclCpbDelayOffset[i], bp.m_cpbRemovalDelayLength, "vcl_cpb_delay_offset[ i ]"); - xWriteCode(sei.m_vclDpbDelayOffset[i], bp.m_dpbOutputDelayLength, "vcl_dpb_delay_offset[ i ]"); + xWriteCode(sei.m_vclCpbDelayOffset[i], bp.cpbRemovalDelayLength, "vcl_cpb_delay_offset[ i ]"); + xWriteCode(sei.m_vclDpbDelayOffset[i], bp.dpbOutputDelayLength, "vcl_dpb_delay_offset[ i ]"); } } } } - if (bp.m_bpDecodingUnitHrdParamsPresentFlag && bp.m_decodingUnitDpbDuParamsInPicTimingSeiFlag) + if (bp.hasDuHrdParams && bp.duDpbParamsInPicTimingSei) { - xWriteCode( sei.m_picDpbOutputDuDelay, bp.m_dpbOutputDelayDuLength, "pic_dpb_output_du_delay" ); + xWriteCode(sei.m_picDpbOutputDuDelay, bp.dpbOutputDelayDuLength, "pic_dpb_output_du_delay"); } - if( bp.m_bpDecodingUnitHrdParamsPresentFlag && bp.m_decodingUnitCpbParamsInPicTimingSeiFlag ) + if (bp.hasDuHrdParams && bp.duCpbParamsInPicTimingSei) { xWriteUvlc( sei.m_numDecodingUnitsMinus1, "num_decoding_units_minus1" ); if (sei.m_numDecodingUnitsMinus1 > 0) @@ -514,11 +524,12 @@ void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBuf xWriteFlag( sei.m_duCommonCpbRemovalDelayFlag, "du_commmon_cpb_removal_delay_flag" ); if( sei.m_duCommonCpbRemovalDelayFlag ) { - for( int i = temporalId; i <= bp.m_bpMaxSubLayers - 1; i ++ ) + for (int i = temporalId; i < bp.maxSublayers; i++) { if( sei.m_ptSubLayerDelaysPresentFlag[i] ) { - xWriteCode( sei.m_duCommonCpbRemovalDelayMinus1[i], bp.m_duCpbRemovalDelayIncrementLength, "du_common_cpb_removal_delay_increment_minus1[i]" ); + xWriteCode(sei.m_duCommonCpbRemovalDelayMinus1[i], bp.duCpbRemovalDelayIncrementLength, + "du_common_cpb_removal_delay_increment_minus1[i]"); } } } @@ -527,11 +538,12 @@ void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBuf xWriteUvlc( sei.m_numNalusInDuMinus1[i], "num_nalus_in_du_minus1[i]" ); if( !sei.m_duCommonCpbRemovalDelayFlag && i < sei.m_numDecodingUnitsMinus1 ) { - for( int j = temporalId; j <= bp.m_bpMaxSubLayers - 1; j ++ ) + for (int j = temporalId; j < bp.maxSublayers; j++) { if( sei.m_ptSubLayerDelaysPresentFlag[j] ) { - xWriteCode( sei.m_duCpbRemovalDelayMinus1[i * bp.m_bpMaxSubLayers + j], bp.m_duCpbRemovalDelayIncrementLength, "du_cpb_removal_delay_increment_minus1[i][j]" ); + xWriteCode(sei.m_duCpbRemovalDelayMinus1[i * bp.maxSublayers + j], bp.duCpbRemovalDelayIncrementLength, + "du_cpb_removal_delay_increment_minus1[i][j]"); } } } -- GitLab