diff --git a/source/Lib/CommonLib/HRD.h b/source/Lib/CommonLib/HRD.h index 52cc7cbf25078c7b98a817447558503796d630cf..03b1cb81e66067852fa45273a09cfdbbe6e680ba 100644 --- a/source/Lib/CommonLib/HRD.h +++ b/source/Lib/CommonLib/HRD.h @@ -91,14 +91,29 @@ private: bool m_nalHrdParametersPresentFlag; bool m_vclHrdParametersPresentFlag; uint32_t m_tickDivisorMinus2; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + bool m_generalDecodingUnitHrdParamsPresentFlag; +#else bool m_decodingUnitCpbParamsInPicTimingSeiFlag; bool m_decodingUnitHrdParamsPresentFlag; +#endif uint32_t m_bitRateScale; uint32_t m_cpbSizeScale; uint32_t m_cpbSizeDuScale; HrdSubLayerInfo m_HRD[MAX_TLAYER]; public: +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + HRDParameters() + :m_nalHrdParametersPresentFlag (false) + ,m_vclHrdParametersPresentFlag (false) + ,m_tickDivisorMinus2 (0) + ,m_generalDecodingUnitHrdParamsPresentFlag (false) + ,m_bitRateScale (0) + ,m_cpbSizeScale (0) + ,m_cpbSizeDuScale (0) + {} +#else HRDParameters() :m_nalHrdParametersPresentFlag (false) ,m_vclHrdParametersPresentFlag (false) @@ -109,6 +124,7 @@ public: ,m_cpbSizeScale (0) ,m_cpbSizeDuScale (0) {} +#endif virtual ~HRDParameters() {} @@ -123,11 +139,16 @@ public: uint32_t getTickDivisorMinus2( ) const { return m_tickDivisorMinus2; } +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + void setGeneralDecodingUnitHrdParamsPresentFlag( bool flag) { m_generalDecodingUnitHrdParamsPresentFlag = flag; } + bool getGeneralDecodingUnitHrdParamsPresentFlag( ) const { return m_generalDecodingUnitHrdParamsPresentFlag; } +#else void setDecodingUnitHrdParamsPresentFlag( bool flag) { m_decodingUnitHrdParamsPresentFlag = flag; } bool getDecodingUnitHrdParamsPresentFlag( ) const { return m_decodingUnitHrdParamsPresentFlag; } void setDecodingUnitCpbParamsInPicTimingSeiFlag( uint32_t value ) { m_decodingUnitCpbParamsInPicTimingSeiFlag = value; } uint32_t getDecodingUnitCpbParamsInPicTimingSeiFlag( ) const { return m_decodingUnitCpbParamsInPicTimingSeiFlag; } +#endif void setBitRateScale( uint32_t value ) { m_bitRateScale = value; } uint32_t getBitRateScale( ) const { return m_bitRateScale; } @@ -196,4 +217,4 @@ protected: SEIBufferingPeriod m_bufferingPeriodSEI; }; -#endif //__HRD__ \ No newline at end of file +#endif //__HRD__ diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp index 4438e50a11c34b9358d635144b945f688b8a8647..b4e2ae744a8883c2cfbe4caa8a1aee987017535c 100644 --- a/source/Lib/CommonLib/SEI.cpp +++ b/source/Lib/CommonLib/SEI.cpp @@ -114,20 +114,33 @@ void SEIBufferingPeriod::copyTo (SEIBufferingPeriod& target) const ::memcpy(target.m_initialCpbRemovalOffset, m_initialCpbRemovalOffset, sizeof(m_initialCpbRemovalOffset)); ::memcpy(target.m_cpbRemovalDelayDelta, m_cpbRemovalDelayDelta, sizeof(m_cpbRemovalDelayDelta)); ::memcpy(target.m_bpCpbCnt, m_bpCpbCnt, sizeof(m_bpCpbCnt)); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + target.m_bpDecodingUnitHrdParamsPresentFlag = m_bpDecodingUnitHrdParamsPresentFlag; + target.m_decodingUnitCpbParamsInPicTimingSeiFlag = m_decodingUnitCpbParamsInPicTimingSeiFlag; +#endif } void SEIPictureTiming::copyTo (SEIPictureTiming& target) const { ::memcpy(target.m_auCpbRemovalDelay, m_auCpbRemovalDelay, sizeof(m_auCpbRemovalDelay)); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + ::memcpy(target.m_ptSubLayerDelaysPresentFlag, m_ptSubLayerDelaysPresentFlag, sizeof(m_ptSubLayerDelaysPresentFlag)); + ::memcpy(target.m_duCommonCpbRemovalDelayMinus1, m_duCommonCpbRemovalDelayMinus1, sizeof(m_duCommonCpbRemovalDelayMinus1)); +#else ::memcpy(target.m_subLayerDelaysPresentFlag, m_subLayerDelaysPresentFlag, sizeof(m_subLayerDelaysPresentFlag)); +#endif ::memcpy(target.m_cpbRemovalDelayDeltaEnabledFlag, m_cpbRemovalDelayDeltaEnabledFlag, sizeof(m_cpbRemovalDelayDeltaEnabledFlag)); ::memcpy(target.m_cpbRemovalDelayDeltaIdx, m_cpbRemovalDelayDeltaIdx, sizeof(m_cpbRemovalDelayDeltaIdx)); +#if !JVET_P0202_P0203_FIX_HRD_RELATED_SEI target.m_ptMaxSubLayers = m_ptMaxSubLayers; +#endif target.m_picDpbOutputDelay = m_picDpbOutputDelay; target.m_picDpbOutputDuDelay = m_picDpbOutputDuDelay; target.m_numDecodingUnitsMinus1 = m_numDecodingUnitsMinus1; target.m_duCommonCpbRemovalDelayFlag = m_duCommonCpbRemovalDelayFlag; +#if !JVET_P0202_P0203_FIX_HRD_RELATED_SEI target.m_duCommonCpbRemovalDelayMinus1 = m_duCommonCpbRemovalDelayMinus1; +#endif target.m_numNalusInDuMinus1 = m_numNalusInDuMinus1; target.m_duCpbRemovalDelayMinus1 = m_duCpbRemovalDelayMinus1; diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h index 4f5cf92a922a007f431a3773b675c7529d9bee31..0f19ff32d722ef8f1b6d81a50c02100c9f744d63 100644 --- a/source/Lib/CommonLib/SEI.h +++ b/source/Lib/CommonLib/SEI.h @@ -193,6 +193,10 @@ public: , m_cpbRemovalDelayDeltasPresentFlag (false) , m_numCpbRemovalDelayDeltas (0) , m_bpMaxSubLayers (0) +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + , m_bpDecodingUnitHrdParamsPresentFlag (false) + , m_decodingUnitCpbParamsInPicTimingSeiFlag (false) +#endif { ::memset(m_initialCpbRemovalDelay, 0, sizeof(m_initialCpbRemovalDelay)); ::memset(m_initialCpbRemovalOffset, 0, sizeof(m_initialCpbRemovalOffset)); @@ -221,6 +225,10 @@ public: int m_numCpbRemovalDelayDeltas; int m_bpMaxSubLayers; uint32_t m_cpbRemovalDelayDelta [15]; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + bool m_bpDecodingUnitHrdParamsPresentFlag; + bool m_decodingUnitCpbParamsInPicTimingSeiFlag; +#endif }; class SEIPictureTiming : public SEI @@ -229,6 +237,20 @@ public: PayloadType payloadType() const { return PICTURE_TIMING; } void copyTo (SEIPictureTiming& target) const; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + SEIPictureTiming() + : m_picDpbOutputDelay (0) + , m_picDpbOutputDuDelay (0) + , m_numDecodingUnitsMinus1 (0) + , m_duCommonCpbRemovalDelayFlag (false) + { + ::memset(m_ptSubLayerDelaysPresentFlag, 0, sizeof(m_ptSubLayerDelaysPresentFlag)); + ::memset(m_duCommonCpbRemovalDelayMinus1, 0, sizeof(m_duCommonCpbRemovalDelayMinus1)); + ::memset(m_cpbRemovalDelayDeltaEnabledFlag, 0, sizeof(m_cpbRemovalDelayDeltaEnabledFlag)); + ::memset(m_cpbRemovalDelayDeltaIdx, 0, sizeof(m_cpbRemovalDelayDeltaIdx)); + ::memset(m_auCpbRemovalDelay, 0, sizeof(m_auCpbRemovalDelay)); + } +#else SEIPictureTiming() : m_ptMaxSubLayers (0) , m_picDpbOutputDelay (0) @@ -242,11 +264,25 @@ public: ::memset(m_cpbRemovalDelayDeltaIdx, 0, sizeof(m_cpbRemovalDelayDeltaIdx)); ::memset(m_auCpbRemovalDelay, 0, sizeof(m_auCpbRemovalDelay)); } +#endif virtual ~SEIPictureTiming() { } +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + bool m_ptSubLayerDelaysPresentFlag[MAX_TLAYER]; + bool m_cpbRemovalDelayDeltaEnabledFlag[MAX_TLAYER]; + uint32_t m_cpbRemovalDelayDeltaIdx[MAX_TLAYER]; + uint32_t m_auCpbRemovalDelay[MAX_TLAYER]; + uint32_t m_picDpbOutputDelay; + uint32_t m_picDpbOutputDuDelay; + uint32_t m_numDecodingUnitsMinus1; + bool m_duCommonCpbRemovalDelayFlag; + uint32_t m_duCommonCpbRemovalDelayMinus1[MAX_TLAYER]; + std::vector<uint32_t> m_numNalusInDuMinus1; + std::vector<uint32_t> m_duCpbRemovalDelayMinus1; +#else int m_ptMaxSubLayers; bool m_subLayerDelaysPresentFlag[MAX_TLAYER]; bool m_cpbRemovalDelayDeltaEnabledFlag[MAX_TLAYER]; @@ -259,6 +295,7 @@ public: uint32_t m_duCommonCpbRemovalDelayMinus1; std::vector<uint32_t> m_numNalusInDuMinus1; std::vector<uint32_t> m_duCpbRemovalDelayMinus1; +#endif }; class SEIDecodingUnitInfo : public SEI @@ -266,15 +303,31 @@ class SEIDecodingUnitInfo : public SEI public: PayloadType payloadType() const { return DECODING_UNIT_INFO; } +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + SEIDecodingUnitInfo() + : m_decodingUnitIdx(0) + , m_dpbOutputDuDelayPresentFlag(false) + , m_picSptDpbOutputDuDelay(0) + { + ::memset(m_duiSubLayerDelaysPresentFlag, 0, sizeof(m_duiSubLayerDelaysPresentFlag)); + ::memset(m_duSptCpbRemovalDelayIncrement, 0, sizeof(m_duSptCpbRemovalDelayIncrement)); + } +#else SEIDecodingUnitInfo() : m_decodingUnitIdx(0) , m_duSptCpbRemovalDelay(0) , m_dpbOutputDuDelayPresentFlag(false) , m_picSptDpbOutputDuDelay(0) {} +#endif virtual ~SEIDecodingUnitInfo() {} int m_decodingUnitIdx; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + bool m_duiSubLayerDelaysPresentFlag[MAX_TLAYER]; + int m_duSptCpbRemovalDelayIncrement[MAX_TLAYER]; +#else int m_duSptCpbRemovalDelay; +#endif bool m_dpbOutputDuDelayPresentFlag; int m_picSptDpbOutputDuDelay; }; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 11a3a8b3c7cc66e8ea9bb0db11f7cf3425ebbf61..0282535ce3eb6b1a34239719fa14ee78a0ac82a6 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_P0202_P0203_FIX_HRD_RELATED_SEI 1 // JVET-P0202 and JVET-P0203: CPB timing for sub-layers with DU and parsing independency to SPS + #define JVET_P1006_PICTURE_HEADER 1 // JVET-P1006: Add picture header and related syntax changes #define JVET_P0365_SCALING_MATRIX_LFNST 1 // JVET-P0365: Signal flag to indicate whether scaling matrices are used for LFNST-coded blocks diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index a36860e38fbe0db534d8c1c88e519d5437c00d4a..085546b463c64feda039402a1a15c85559a052fb 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -158,6 +158,9 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType setBitstream(bs->extractSubstream(payloadSize * 8)); SEI *sei = NULL; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + const SEIBufferingPeriod *bp = NULL; +#endif if(nalUnitType == NAL_UNIT_PREFIX_SEI) { @@ -173,7 +176,19 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType xParseSEIActiveParameterSets((SEIActiveParameterSets&) *sei, payloadSize, pDecodedMessageOutputStream); break; #endif - case SEI::DECODING_UNIT_INFO: + case SEI::DECODING_UNIT_INFO: +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + 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); + } +#else if (!sps) { msg( WARNING, "Warning: Found Decoding unit SEI message, but no active SPS is available. Ignoring."); @@ -183,15 +198,24 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType sei = new SEIDecodingUnitInfo; xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo&) *sei, payloadSize, sps, hrd, pDecodedMessageOutputStream); } +#endif break; case SEI::BUFFERING_PERIOD: sei = new SEIBufferingPeriod; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + xParseSEIBufferingPeriod((SEIBufferingPeriod&) *sei, payloadSize, pDecodedMessageOutputStream); +#else xParseSEIBufferingPeriod((SEIBufferingPeriod&) *sei, payloadSize, sps, pDecodedMessageOutputStream); +#endif hrd.setBufferingPeriodSEI((SEIBufferingPeriod*) sei); break; case SEI::PICTURE_TIMING: { +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + bp = hrd.getBufferingPeriodSEI(); +#else const SEIBufferingPeriod *bp= hrd.getBufferingPeriodSEI(); +#endif if (!bp) { msg( WARNING, "Warning: Found Picture timing SEI message, but no active buffering period is available. Ignoring."); @@ -199,7 +223,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType else { sei = new SEIPictureTiming; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + xParseSEIPictureTiming((SEIPictureTiming&)*sei, payloadSize, temporalId, *bp, pDecodedMessageOutputStream); +#else xParseSEIPictureTiming((SEIPictureTiming&)*sei, payloadSize, sps, temporalId, *bp, pDecodedMessageOutputStream); +#endif } } break; @@ -486,6 +514,46 @@ void SEIReader::xParseSEIActiveParameterSets(SEIActiveParameterSets& sei, uint32 } #endif +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI +void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t payloadSize, const SEIBufferingPeriod& bp, const uint32_t temporalId, std::ostream *pDecodedMessageOutputStream) +{ + uint32_t val; + output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize); + sei_read_uvlc( pDecodedMessageOutputStream, val, "decoding_unit_idx"); + sei.m_decodingUnitIdx = val; + + if(!bp.m_decodingUnitCpbParamsInPicTimingSeiFlag) + { + for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ ) + { + sei_read_flag( pDecodedMessageOutputStream, val, "dui_sub_layer_delays_present_flag[i]" ); + sei.m_duiSubLayerDelaysPresentFlag[i] = val; + if( sei.m_duiSubLayerDelaysPresentFlag[i] ) + { + sei_read_code( pDecodedMessageOutputStream, bp.getDuCpbRemovalDelayIncrementLength(), val, "du_spt_cpb_removal_delay_increment[i]"); + sei.m_duSptCpbRemovalDelayIncrement[i] = val; + } + else + { + sei.m_duSptCpbRemovalDelayIncrement[i] = 0; + } + } + } + else + { + for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ ) + { + sei.m_duSptCpbRemovalDelayIncrement[i] = 0; + } + } + sei_read_flag( pDecodedMessageOutputStream, val, "dpb_output_du_delay_present_flag"); sei.m_dpbOutputDuDelayPresentFlag = (val != 0); + if(sei.m_dpbOutputDuDelayPresentFlag) + { + sei_read_code( pDecodedMessageOutputStream, bp.getDpbOutputDelayDuLength(), val, "pic_spt_dpb_output_du_delay"); + sei.m_picSptDpbOutputDuDelay = val; + } +} +#else void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t payloadSize, const SPS *sps, HRD &hrd, std::ostream *pDecodedMessageOutputStream) { uint32_t val; @@ -509,8 +577,13 @@ void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t pay sei.m_picSptDpbOutputDuDelay = val; } } +#endif +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI +void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream) +#else void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream) +#endif { int i, nalOrVcl; uint32_t code; @@ -521,6 +594,18 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo 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; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + 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; + } +#else if (sei.m_bpNalCpbParamsPresentFlag || sei.m_bpVclCpbParamsPresentFlag) { sei_read_code( pDecodedMessageOutputStream, 5, code, "initial_cpb_removal_delay_length_minus1" ); sei.m_initialCpbRemovalDelayLength = code + 1; @@ -532,6 +617,7 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo sei_read_code( pDecodedMessageOutputStream, 5, code, "dpb_output_delay_du_length_minus1" ); sei.m_dpbOutputDelayDuLength = code + 1; } } +#endif sei_read_flag( pDecodedMessageOutputStream, code, "concatenation_flag"); sei.m_concatenationFlag = code; @@ -568,13 +654,42 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo } } +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI +void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSize, const uint32_t temporalId, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream) +#else void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSize, const SPS *sps, const uint32_t temporalId, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream) +#endif { +#if !JVET_P0202_P0203_FIX_HRD_RELATED_SEI const HRDParameters *hrd = sps->getHrdParameters(); +#endif output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize); uint32_t symbol; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + sei_read_code( pDecodedMessageOutputStream, bp.m_cpbRemovalDelayLength, symbol, "cpb_removal_delay_minus1[bp_max_sub_layers_minus1]" ); + sei.m_auCpbRemovalDelay[bp.m_bpMaxSubLayers - 1] = symbol + 1; + for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ ) + { + sei_read_flag( pDecodedMessageOutputStream, symbol, "pt_sub_layer_delays_present_flag[i]" ); sei.m_ptSubLayerDelaysPresentFlag[i] = (symbol == 1); + if( sei.m_ptSubLayerDelaysPresentFlag[ i ] ) + { + sei_read_flag( pDecodedMessageOutputStream, symbol, "cpb_removal_delay_delta_enabled_flag[i]" ); + sei.m_cpbRemovalDelayDeltaEnabledFlag[i] = (symbol == 1); + if( sei.m_cpbRemovalDelayDeltaEnabledFlag[ i ] ) + { + sei_read_code( pDecodedMessageOutputStream, ceilLog2(bp.m_numCpbRemovalDelayDeltas), symbol, "cpb_removal_delay_delta_idx[i]" ); + sei.m_cpbRemovalDelayDeltaIdx[ i ] = symbol; + } + else + { + sei_read_code( pDecodedMessageOutputStream, bp.m_cpbRemovalDelayLength, symbol, "cpb_removal_delay_minus1[i]" ); + sei.m_auCpbRemovalDelay[ i ] = symbol + 1; + } + } + } +#else sei_read_code( pDecodedMessageOutputStream, 3, symbol, "pt_max_sub_layers_minus1" ); sei.m_ptMaxSubLayers = symbol + 1; sei_read_code( pDecodedMessageOutputStream, bp.m_cpbRemovalDelayLength, symbol, "cpb_removal_delay_minus1[pt_max_sub_layers_minus1]" ); @@ -597,8 +712,53 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi } } } +#endif sei_read_code( pDecodedMessageOutputStream, bp.m_dpbOutputDelayLength, symbol, "dpb_output_delay" ); sei.m_picDpbOutputDelay = symbol; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + if( bp.m_bpDecodingUnitHrdParamsPresentFlag ) + { + sei_read_code( pDecodedMessageOutputStream, bp.getDpbOutputDelayDuLength(), symbol, "pic_dpb_output_du_delay" ); + sei.m_picDpbOutputDuDelay = symbol; + } + if( bp.m_bpDecodingUnitHrdParamsPresentFlag && bp.m_decodingUnitCpbParamsInPicTimingSeiFlag ) + { + 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_read_flag( pDecodedMessageOutputStream, symbol, "du_common_cpb_removal_delay_flag" ); + sei.m_duCommonCpbRemovalDelayFlag = symbol; + if( sei.m_duCommonCpbRemovalDelayFlag ) + { + for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ ) + { + if( sei.m_ptSubLayerDelaysPresentFlag[i] ) + { + sei_read_code( pDecodedMessageOutputStream, bp.getDuCpbRemovalDelayIncrementLength(), symbol, "du_common_cpb_removal_delay_increment_minus1[i]" ); + sei.m_duCommonCpbRemovalDelayMinus1[i] = symbol; + } + } + } + for( int i = 0; i <= sei.m_numDecodingUnitsMinus1; i ++ ) + { + sei_read_uvlc( pDecodedMessageOutputStream, symbol, "num_nalus_in_du_minus1[i]" ); + sei.m_numNalusInDuMinus1[i] = symbol; + if( !sei.m_duCommonCpbRemovalDelayFlag && i < sei.m_numDecodingUnitsMinus1 ) + { + for( int j = temporalId; j < bp.m_bpMaxSubLayers - 1; 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; + } + } + } + } + } +#else if( hrd->getDecodingUnitHrdParamsPresentFlag() ) { sei_read_code( pDecodedMessageOutputStream, bp.getDpbOutputDelayDuLength(), symbol, "pic_dpb_output_du_delay" ); @@ -629,6 +789,7 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi } } } +#endif } void SEIReader::xParseSEIFrameFieldinfo(SEIFrameFieldInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream) diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h index c61649c823440fac3c7155099eac484829bb258b..6b7df6152cce4a725087f4c1222f1d04d1580666 100644 --- a/source/Lib/DecoderLib/SEIread.h +++ b/source/Lib/DecoderLib/SEIread.h @@ -63,10 +63,19 @@ protected: void xParseSEIuserDataUnregistered (SEIuserDataUnregistered &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIActiveParameterSets (SEIActiveParameterSets &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); #endif +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + void xParseSEIDecodingUnitInfo (SEIDecodingUnitInfo& sei, uint32_t payloadSize, const SEIBufferingPeriod& bp, const uint32_t temporalId, std::ostream *pDecodedMessageOutputStream); +#else void xParseSEIDecodingUnitInfo (SEIDecodingUnitInfo& sei, uint32_t payloadSize, const SPS *sps, HRD &hrd, std::ostream *pDecodedMessageOutputStream); +#endif void xParseSEIDecodedPictureHash (SEIDecodedPictureHash& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + 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); +#else void xParseSEIBufferingPeriod (SEIBufferingPeriod& sei, uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream); void xParseSEIPictureTiming (SEIPictureTiming& sei, uint32_t payloadSize, const SPS *sps, const uint32_t temporalId, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream); +#endif void xParseSEIFrameFieldinfo (SEIFrameFieldInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIDependentRAPIndication (SEIDependentRAPIndication& sei, uint32_t payLoadSize, std::ostream *pDecodedMessageOutputStream); #if HEVC_SEI diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index cb58d4d29b7d319544ff1fa39505caee1a062004..ea6a57de29043582968df81c71dd89a6fdb47e2f 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1125,6 +1125,20 @@ void HLSyntaxReader::parseHrdParameters(HRDParameters *hrd, uint32_t firstSubLay uint32_t symbol; READ_FLAG( symbol, "general_nal_hrd_parameters_present_flag" ); hrd->setNalHrdParametersPresentFlag( symbol == 1 ? true : false ); READ_FLAG( symbol, "general_vcl_hrd_parameters_present_flag" ); hrd->setVclHrdParametersPresentFlag( symbol == 1 ? true : false ); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + READ_FLAG( symbol, "general_decoding_unit_hrd_params_present_flag" ); hrd->setGeneralDecodingUnitHrdParamsPresentFlag( symbol == 1 ? true : false ); + + if( hrd->getGeneralDecodingUnitHrdParamsPresentFlag() ) + { + READ_CODE( 8, symbol, "tick_divisor_minus2" ); hrd->setTickDivisorMinus2( symbol ); + } + READ_CODE( 4, symbol, "bit_rate_scale" ); hrd->setBitRateScale( symbol ); + READ_CODE( 4, symbol, "cpb_size_scale" ); hrd->setCpbSizeScale( symbol ); + if( hrd->getGeneralDecodingUnitHrdParamsPresentFlag() ) + { + READ_CODE( 4, symbol, "cpb_size_du_scale" ); hrd->setCpbSizeDuScale( symbol ); + } +#else if( hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() ) { READ_FLAG( symbol, "decoding_unit_hrd_params_present_flag" ); hrd->setDecodingUnitHrdParamsPresentFlag( symbol == 1 ? true : false ); @@ -1141,6 +1155,7 @@ void HLSyntaxReader::parseHrdParameters(HRDParameters *hrd, uint32_t firstSubLay READ_CODE( 4, symbol, "cpb_size_du_scale" ); hrd->setCpbSizeDuScale( symbol ); } } +#endif for( int i = firstSubLayer; i <= maxNumSubLayersMinus1; i ++ ) { diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index c3c4526fc6d996d8217a3fd8e252a1c3669899cc..0005c7750288d8d2a952538d5722117a6ca99fcf 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -583,7 +583,11 @@ void EncGOP::xWriteLeadingSEIMessages (SEIMessages& seiMessages, SEIMessages& du // update Timing and DU info SEI xUpdateDuData(testAU, duData); xUpdateTimingSEI(picTiming, duData, sps); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + xUpdateDuInfoSEI(duInfoSeiMessages, picTiming, sps->getMaxTLayers()); +#else xUpdateDuInfoSEI(duInfoSeiMessages, picTiming); +#endif // actual writing xWriteLeadingSEIOrdered(seiMessages, duInfoSeiMessages, accessUnit, temporalId, sps, false); @@ -600,9 +604,12 @@ void EncGOP::xWriteTrailingSEIMessages (SEIMessages& seiMessages, AccessUnit &ac void EncGOP::xWriteDuSEIMessages (SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, int temporalId, const SPS *sps, std::deque<DUData> &duData) { +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && m_HRD->getBufferingPeriodSEI()->m_decodingUnitCpbParamsInPicTimingSeiFlag ) +#else const HRDParameters *hrd = sps->getHrdParameters(); - if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getDecodingUnitCpbParamsInPicTimingSeiFlag() ) +#endif { int naluIdx = 0; AccessUnit::iterator nalu = accessUnit.begin(); @@ -862,24 +869,39 @@ void EncGOP::xCreatePictureTimingSEI (int IRAPGOPid, SEIMessages& seiMessages, SEIPictureTiming *pictureTimingSEI = new SEIPictureTiming(); // DU parameters +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + if( hrd->getGeneralDecodingUnitHrdParamsPresentFlag() ) +#else if( hrd->getDecodingUnitHrdParamsPresentFlag() ) +#endif { uint32_t numDU = (uint32_t) duData.size(); pictureTimingSEI->m_numDecodingUnitsMinus1 = ( numDU - 1 ); pictureTimingSEI->m_duCommonCpbRemovalDelayFlag = false; pictureTimingSEI->m_numNalusInDuMinus1.resize( numDU ); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + const uint32_t maxNumSubLayers = slice->getSPS()->getMaxTLayers(); + pictureTimingSEI->m_duCpbRemovalDelayMinus1.resize( numDU * maxNumSubLayers ); +#else pictureTimingSEI->m_duCpbRemovalDelayMinus1.resize( numDU ); +#endif } const uint32_t cpbRemovalDelayLegth = m_HRD->getBufferingPeriodSEI()->m_cpbRemovalDelayLength; const uint32_t maxNumSubLayers = slice->getSPS()->getMaxTLayers(); +#if !JVET_P0202_P0203_FIX_HRD_RELATED_SEI pictureTimingSEI->m_ptMaxSubLayers = maxNumSubLayers; +#endif 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 " ); const uint32_t temporalId = slice->getTLayer(); for( int i = temporalId ; i < maxNumSubLayers - 1 ; i ++ ) { int indexWithinGOP = (m_totalCoded[maxNumSubLayers - 1] - m_lastBPSEI[maxNumSubLayers - 1]) % m_pcCfg->getGOPSize(); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + pictureTimingSEI->m_ptSubLayerDelaysPresentFlag[i] = true; +#else pictureTimingSEI->m_subLayerDelaysPresentFlag[i] = true; +#endif if( ((m_rapWithLeading == true) && (indexWithinGOP == 0)) || (m_totalCoded[maxNumSubLayers - 1] == 0) || m_bufferingPeriodSEIPresentInAU) { pictureTimingSEI->m_cpbRemovalDelayDeltaEnabledFlag[i] = false; @@ -1079,13 +1101,22 @@ void EncGOP::xCreatePictureTimingSEI (int IRAPGOPid, SEIMessages& seiMessages, #endif } +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getGeneralDecodingUnitHrdParamsPresentFlag() ) +#else if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getDecodingUnitHrdParamsPresentFlag() ) +#endif { for( int i = 0; i < ( pictureTimingSEI->m_numDecodingUnitsMinus1 + 1 ); i ++ ) { SEIDecodingUnitInfo *duInfoSEI = new SEIDecodingUnitInfo(); duInfoSEI->m_decodingUnitIdx = i; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + for( int j = temporalId; j <= maxNumSubLayers; j++ ) + duInfoSEI->m_duSptCpbRemovalDelayIncrement[j] = pictureTimingSEI->m_duCpbRemovalDelayMinus1[i*maxNumSubLayers+j] + 1; +#else duInfoSEI->m_duSptCpbRemovalDelay = pictureTimingSEI->m_duCpbRemovalDelayMinus1[i] + 1; +#endif duInfoSEI->m_dpbOutputDuDelayPresentFlag = false; duInfoSEI->m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay; @@ -1144,7 +1175,11 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD return; } const HRDParameters *hrd = sps->getHrdParameters(); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + if( hrd->getGeneralDecodingUnitHrdParamsPresentFlag() ) +#else if( hrd->getDecodingUnitHrdParamsPresentFlag() ) +#endif { int i; uint64_t ui64Tmp; @@ -1153,6 +1188,12 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD std::vector<uint32_t> &rDuCpbRemovalDelayMinus1 = pictureTimingSEI->m_duCpbRemovalDelayMinus1; uint32_t maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + int maxNumSubLayers = sps->getMaxTLayers(); + for( int j = 0; j < maxNumSubLayers - 1; j++ ) + pictureTimingSEI->m_ptSubLayerDelaysPresentFlag[j] = false; +#endif + for( i = 0; i < numDU; i ++ ) { pictureTimingSEI->m_numNalusInDuMinus1[ i ] = ( i == 0 ) ? ( duData[i].accumNalsDU - 1 ) : ( duData[i].accumNalsDU- duData[i-1].accumNalsDU - 1 ); @@ -1160,11 +1201,19 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD if( numDU == 1 ) { +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + rDuCpbRemovalDelayMinus1[ 0 + maxNumSubLayers - 1 ] = 0; /* don't care */ +#else rDuCpbRemovalDelayMinus1[ 0 ] = 0; /* don't care */ +#endif } else { +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + rDuCpbRemovalDelayMinus1[ (numDU - 1) * maxNumSubLayers + maxNumSubLayers - 1 ] = 0;/* by definition */ +#else rDuCpbRemovalDelayMinus1[ numDU - 1 ] = 0;/* by definition */ +#endif uint32_t tmp = 0; uint32_t accum = 0; @@ -1193,6 +1242,18 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD } else ui64Tmp = maxDiff - tmp + 1; } +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + rDuCpbRemovalDelayMinus1[ i * maxNumSubLayers + maxNumSubLayers - 1 ] = (uint32_t)ui64Tmp - uiPrev - 1; + if( (int)rDuCpbRemovalDelayMinus1[ i * maxNumSubLayers + maxNumSubLayers - 1 ] < 0 ) + { + rDuCpbRemovalDelayMinus1[ i * maxNumSubLayers + maxNumSubLayers - 1 ] = 0; + } + else if (tmp > 0 && flag == 1) + { + tmp --; + } + accum += rDuCpbRemovalDelayMinus1[ i * maxNumSubLayers + maxNumSubLayers - 1 ] + 1; +#else rDuCpbRemovalDelayMinus1[ i ] = (uint32_t)ui64Tmp - uiPrev - 1; if( (int)rDuCpbRemovalDelayMinus1[ i ] < 0 ) { @@ -1203,12 +1264,17 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD tmp --; } accum += rDuCpbRemovalDelayMinus1[ i ] + 1; +#endif uiPrev = accum; } } } } +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI +void EncGOP::xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI, int maxSubLayers) +#else void EncGOP::xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI) +#endif { if (duInfoSeiMessages.empty() || (pictureTimingSEI == NULL)) { @@ -1221,7 +1287,15 @@ void EncGOP::xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming * { SEIDecodingUnitInfo *duInfoSEI = (SEIDecodingUnitInfo*) (*du); duInfoSEI->m_decodingUnitIdx = i; +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + 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; + } +#else duInfoSEI->m_duSptCpbRemovalDelay = pictureTimingSEI->m_duCpbRemovalDelayMinus1[i] + 1; +#endif duInfoSEI->m_dpbOutputDuDelayPresentFlag = false; i++; } @@ -3419,7 +3493,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) && ( ( pcSlice->getSPS()->getHrdParameters()->getNalHrdParametersPresentFlag() ) || ( pcSlice->getSPS()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) && +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + ( pcSlice->getSPS()->getHrdParameters()->getGeneralDecodingUnitHrdParamsPresentFlag() ) ) +#else ( pcSlice->getSPS()->getHrdParameters()->getDecodingUnitHrdParamsPresentFlag() ) ) +#endif { uint32_t numNalus = 0; uint32_t numRBSPBytes = 0; diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h index bec59665a60d4043f4b8d9b8ff1e80c27e8a50a6..018e8273a1efa821ea4f8c009c9053c23a71b6ee 100644 --- a/source/Lib/EncoderLib/EncGOP.h +++ b/source/Lib/EncoderLib/EncGOP.h @@ -311,7 +311,11 @@ protected: void xCreatePictureTimingSEI (int IRAPGOPid, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, 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); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + void xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI, int maxSubLayers); +#else void xUpdateDuInfoSEI(SEIMessages &duInfoSeiMessages, SEIPictureTiming *pictureTimingSEI); +#endif #if HEVC_SEI void xCreateScalableNestingSEI (SEIMessages& seiMessages, SEIMessages& nestedSeiMessages); diff --git a/source/Lib/EncoderLib/EncHRD.cpp b/source/Lib/EncoderLib/EncHRD.cpp index 82bae20c6bbe0f063d396352bc1ee619ecba0190..5ed238f8f7e7cbf43bb6d0a0f73190efa6120e3e 100644 --- a/source/Lib/EncoderLib/EncHRD.cpp +++ b/source/Lib/EncoderLib/EncHRD.cpp @@ -109,6 +109,14 @@ void EncHRD::initHRDParameters (EncCfg* encCfg) m_hrdParams.setNalHrdParametersPresentFlag( rateCnt ); m_hrdParams.setVclHrdParametersPresentFlag( rateCnt ); useSubCpbParams &= ( m_hrdParams.getNalHrdParametersPresentFlag() || m_hrdParams.getVclHrdParametersPresentFlag() ); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + m_hrdParams.setGeneralDecodingUnitHrdParamsPresentFlag( useSubCpbParams ); + + if( m_hrdParams.getGeneralDecodingUnitHrdParamsPresentFlag() ) + { + m_hrdParams.setTickDivisorMinus2( 100 - 2 ); + } +#else m_hrdParams.setDecodingUnitHrdParamsPresentFlag( useSubCpbParams ); if( m_hrdParams.getDecodingUnitHrdParamsPresentFlag() ) @@ -120,6 +128,7 @@ void EncHRD::initHRDParameters (EncCfg* encCfg) { m_hrdParams.setDecodingUnitCpbParamsInPicTimingSeiFlag( false ); } +#endif #if U0132_TARGET_BITS_SATURATION if (xCalcScale(bitRate) <= 6) diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index 789be24478f5d5798cedde2fe8a7669d8f239778..fa64ac94e09a1f8cd7055034e50fa8431949c66c 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -220,6 +220,11 @@ void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI, } } +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + bufferingPeriodSEI->m_bpDecodingUnitHrdParamsPresentFlag = (m_pcCfg->getSliceMode() > 0) || (m_pcCfg->getSliceSegmentMode() > 0); + bufferingPeriodSEI->m_decodingUnitCpbParamsInPicTimingSeiFlag = !m_pcCfg->getDecodingUnitInfoSEIEnabled(); +#endif + bufferingPeriodSEI->m_initialCpbRemovalDelayLength = 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 diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp index 6118017cb5ecc88c057d4781761b7ab25ab8a67d..8b57a40dfd0f7d7327e0104ad84ff93b88b53ca4 100644 --- a/source/Lib/EncoderLib/SEIwrite.cpp +++ b/source/Lib/EncoderLib/SEIwrite.cpp @@ -43,6 +43,9 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream& bs, const SEI& sei, const SPS *sps, HRD &hrd, const uint32_t temporalId) { +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + const SEIBufferingPeriod *bp = NULL; +#endif switch (sei.payloadType()) { #if HEVC_SEI @@ -54,20 +57,38 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream& bs, const SEI& sei, const break; #endif case SEI::DECODING_UNIT_INFO: +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + bp = hrd.getBufferingPeriodSEI(); + CHECK (bp == nullptr, "Buffering Period need to be initialized in HRD to allow writing of Decoding Unit Information SEI"); + xWriteSEIDecodingUnitInfo(*static_cast<const SEIDecodingUnitInfo*>(& sei), *bp, temporalId); +#else xWriteSEIDecodingUnitInfo(*static_cast<const SEIDecodingUnitInfo*>(& sei), sps, hrd); +#endif break; case SEI::DECODED_PICTURE_HASH: xWriteSEIDecodedPictureHash(*static_cast<const SEIDecodedPictureHash*>(&sei)); break; case SEI::BUFFERING_PERIOD: +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + xWriteSEIBufferingPeriod(*static_cast<const SEIBufferingPeriod*>(&sei)); +#else xWriteSEIBufferingPeriod(*static_cast<const SEIBufferingPeriod*>(&sei), sps); +#endif hrd.setBufferingPeriodSEI(static_cast<const SEIBufferingPeriod*>(&sei)); break; case SEI::PICTURE_TIMING: { +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + bp = hrd.getBufferingPeriodSEI(); +#else const SEIBufferingPeriod *bp = hrd.getBufferingPeriodSEI(); +#endif CHECK (bp == nullptr, "Buffering Period need to be initialized in HRD to allow writing of Picture Timing SEI"); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + xWriteSEIPictureTiming(*static_cast<const SEIPictureTiming*>(&sei), *bp, temporalId); +#else xWriteSEIPictureTiming(*static_cast<const SEIPictureTiming*>(&sei), sps, *bp, temporalId); +#endif } break; case SEI::FRAME_FIELD_INFO: @@ -264,6 +285,26 @@ void SEIWriter::xWriteSEIActiveParameterSets(const SEIActiveParameterSets& sei) } #endif +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI +void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const SEIBufferingPeriod& bp, const uint32_t temporalId) +{ + WRITE_UVLC(sei.m_decodingUnitIdx, "decoding_unit_idx"); + if( !bp.m_decodingUnitCpbParamsInPicTimingSeiFlag ) + { + for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ ) + { + WRITE_FLAG( sei.m_duiSubLayerDelaysPresentFlag[i], "dui_sub_layer_delays_present_flag[i]" ); + if( sei.m_duiSubLayerDelaysPresentFlag[i] ) + WRITE_CODE( sei.m_duSptCpbRemovalDelayIncrement[i], bp.getDuCpbRemovalDelayIncrementLength(), "du_spt_cpb_removal_delay_increment[i]"); + } + } + WRITE_FLAG( sei.m_dpbOutputDuDelayPresentFlag, "dpb_output_du_delay_present_flag"); + if(sei.m_dpbOutputDuDelayPresentFlag) + { + WRITE_CODE(sei.m_picSptDpbOutputDuDelay, bp.getDpbOutputDelayDuLength(), "pic_spt_dpb_output_du_delay"); + } +} +#else void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const SPS *sps, HRD &hrd) { WRITE_UVLC(sei.m_decodingUnitIdx, "decoding_unit_idx"); @@ -277,12 +318,34 @@ void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const WRITE_CODE(sei.m_picSptDpbOutputDuDelay, hrd.getBufferingPeriodSEI()->getDpbOutputDelayDuLength(), "pic_spt_dpb_output_du_delay"); } } +#endif +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI +void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei) +#else void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SPS *sps) +#endif { WRITE_FLAG( sei.m_bpNalCpbParamsPresentFlag, "bp_nal_hrd_parameters_present_flag"); WRITE_FLAG( sei.m_bpVclCpbParamsPresentFlag, "bp_vcl_hrd_parameters_present_flag"); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + CHECK (sei.m_initialCpbRemovalDelayLength < 1, "sei.m_initialCpbRemovalDelayLength must be > 0"); + WRITE_CODE( sei.m_initialCpbRemovalDelayLength - 1, 5, "initial_cpb_removal_delay_length_minus1" ); + CHECK (sei.m_cpbRemovalDelayLength < 1, "sei.m_cpbRemovalDelayLength must be > 0"); + WRITE_CODE( sei.m_cpbRemovalDelayLength - 1, 5, "cpb_removal_delay_length_minus1" ); + CHECK (sei.m_dpbOutputDelayLength < 1, "sei.m_dpbOutputDelayLength must be > 0"); + WRITE_CODE( sei.m_dpbOutputDelayLength - 1, 5, "dpb_output_delay_length_minus1" ); + WRITE_FLAG( sei.m_bpDecodingUnitHrdParamsPresentFlag, "bp_decoding_unit_hrd_params_present_flag" ); + if( sei.m_bpDecodingUnitHrdParamsPresentFlag ) + { + CHECK (sei.m_duCpbRemovalDelayIncrementLength < 1, "sei.m_duCpbRemovalDelayIncrementLength must be > 0"); + WRITE_CODE( sei.m_duCpbRemovalDelayIncrementLength - 1, 5, "du_cpb_removal_delay_increment_length_minus1" ); + CHECK (sei.m_dpbOutputDelayDuLength < 1, "sei.m_dpbOutputDelayDuLength must be > 0"); + WRITE_CODE( sei.m_dpbOutputDelayDuLength - 1, 5, "dpb_output_delay_du_length_minus1" ); + WRITE_FLAG( sei.m_decodingUnitCpbParamsInPicTimingSeiFlag, "decoding_unit_cpb_params_in_pic_timing_sei_flag" ); + } +#else if (sei.m_bpNalCpbParamsPresentFlag || sei.m_bpVclCpbParamsPresentFlag) { CHECK (sei.m_initialCpbRemovalDelayLength < 1, "sei.m_initialCpbRemovalDelayLength must be > 0"); @@ -299,6 +362,7 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP WRITE_CODE( sei.m_dpbOutputDelayDuLength - 1, 5, "dpb_output_delay_du_length_minus1" ); } } +#endif WRITE_FLAG( sei.m_concatenationFlag, "concatenation_flag"); @@ -335,9 +399,33 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP } } } + +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI +void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBufferingPeriod &bp, const uint32_t temporalId) +#else void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SPS *sps, const SEIBufferingPeriod &bp, const uint32_t temporalId) +#endif { - + +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + WRITE_CODE( sei.m_auCpbRemovalDelay[bp.m_bpMaxSubLayers - 1] - 1, bp.m_cpbRemovalDelayLength, "cpb_removal_delay_minus1[bp_max_sub_layers_minus1]" ); + for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ ) + { + WRITE_FLAG( sei.m_ptSubLayerDelaysPresentFlag[i], "pt_sub_layer_delays_present_flag[i]" ); + if( sei.m_ptSubLayerDelaysPresentFlag[i] ) + { + WRITE_FLAG( sei.m_cpbRemovalDelayDeltaEnabledFlag[i], "cpb_removal_delay_delta_enabled_flag[i]" ); + if( sei.m_cpbRemovalDelayDeltaEnabledFlag[i] ) + { + WRITE_CODE( sei.m_cpbRemovalDelayDeltaIdx[i], ceilLog2(bp.m_numCpbRemovalDelayDeltas), "cpb_removal_delay_delta_idx[i]" ); + } + else + { + WRITE_CODE( sei.m_auCpbRemovalDelay[i] - 1, bp.m_cpbRemovalDelayLength, "cpb_removal_delay_minus1[i]" ); + } + } + } +#else CHECK (sei.m_ptMaxSubLayers < 1, "pt_max_sub_layers_minus1 must be > 0"); WRITE_CODE( sei.m_ptMaxSubLayers - 1, 3, "pt_max_sub_layers_minus1" ); WRITE_CODE( sei.m_auCpbRemovalDelay[sei.m_ptMaxSubLayers - 1] - 1, bp.m_cpbRemovalDelayLength, "cpb_removal_delay_minus1[pt_max_sub_layers_minus1]" ); @@ -357,7 +445,39 @@ void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SPS *s } } } +#endif WRITE_CODE( sei.m_picDpbOutputDelay, bp.m_dpbOutputDelayLength, "dpb_output_delay" ); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + if( bp.m_bpDecodingUnitHrdParamsPresentFlag ) + { + WRITE_CODE( sei.m_picDpbOutputDuDelay, bp.m_dpbOutputDelayDuLength, "pic_dpb_output_du_delay" ); + } + if( bp.m_bpDecodingUnitHrdParamsPresentFlag && bp.m_decodingUnitCpbParamsInPicTimingSeiFlag ) + { + WRITE_UVLC( sei.m_numDecodingUnitsMinus1, "num_decoding_units_minus1" ); + WRITE_FLAG( sei.m_duCommonCpbRemovalDelayFlag, "du_commmon_cpb_removal_delay_flag" ); + if( sei.m_duCommonCpbRemovalDelayFlag ) + { + for( int i = temporalId; i < bp.m_bpMaxSubLayers - 1; i ++ ) + { + if( sei.m_ptSubLayerDelaysPresentFlag[i] ) + WRITE_CODE( sei.m_duCommonCpbRemovalDelayMinus1[i], bp.m_duCpbRemovalDelayIncrementLength, "du_common_cpb_removal_delay_increment_minus1[i]" ); + } + } + for( int i = 0; i <= sei.m_numDecodingUnitsMinus1; i ++ ) + { + WRITE_UVLC( 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 ++ ) + { + if( sei.m_ptSubLayerDelaysPresentFlag[j] ) + WRITE_CODE( sei.m_duCpbRemovalDelayMinus1[i * bp.m_bpMaxSubLayers + j], bp.m_duCpbRemovalDelayIncrementLength, "du_cpb_removal_delay_increment_minus1[i][j]" ); + } + } + } + } +#else if( sps->getHrdParameters()->getDecodingUnitHrdParamsPresentFlag() ) { WRITE_CODE( sei.m_picDpbOutputDuDelay, bp.m_dpbOutputDelayDuLength, "pic_dpb_output_du_delay" ); @@ -379,6 +499,7 @@ void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SPS *s } } } +#endif } void SEIWriter::xWriteSEIFrameFieldInfo(const SEIFrameFieldInfo& sei) diff --git a/source/Lib/EncoderLib/SEIwrite.h b/source/Lib/EncoderLib/SEIwrite.h index 8c481f5c334e6c568753ce67c34c0602922ee76c..71c5940bcff38e200343f071854120bd306634f9 100644 --- a/source/Lib/EncoderLib/SEIwrite.h +++ b/source/Lib/EncoderLib/SEIwrite.h @@ -56,10 +56,19 @@ protected: void xWriteSEIuserDataUnregistered(const SEIuserDataUnregistered &sei); void xWriteSEIActiveParameterSets(const SEIActiveParameterSets& sei); #endif +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + void xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const SEIBufferingPeriod& bp, const uint32_t temporalId); +#else void xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const SPS *sps, HRD &hrd); +#endif void xWriteSEIDecodedPictureHash(const SEIDecodedPictureHash& sei); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + void xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei); + void xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBufferingPeriod& bp, const uint32_t temporalId); +#else void xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SPS *sps); void xWriteSEIPictureTiming(const SEIPictureTiming& sei,const SPS *sps, const SEIBufferingPeriod& bp, const uint32_t temporalId); +#endif void xWriteSEIFrameFieldInfo(const SEIFrameFieldInfo& sei); void xWriteSEIDependentRAPIndication(const SEIDependentRAPIndication& sei); #if HEVC_SEI diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index f129117940551341150f9342216afcc5f1fa46ae..059b8634d01db8c93b08b038a4b28dcdd9dd3134 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -679,6 +679,19 @@ void HLSWriter::codeHrdParameters( const HRDParameters *hrd, const uint32_t firs { WRITE_FLAG( hrd->getNalHrdParametersPresentFlag() ? 1 : 0 , "general_nal_hrd_parameters_present_flag" ); WRITE_FLAG( hrd->getVclHrdParametersPresentFlag() ? 1 : 0 , "general_vcl_hrd_parameters_present_flag" ); +#if JVET_P0202_P0203_FIX_HRD_RELATED_SEI + WRITE_FLAG( hrd->getGeneralDecodingUnitHrdParamsPresentFlag() ? 1 : 0, "general_decoding_unit_hrd_params_present_flag" ); + if( hrd->getGeneralDecodingUnitHrdParamsPresentFlag() ) + { + WRITE_CODE( hrd->getTickDivisorMinus2(), 8, "tick_divisor_minus2" ); + } + WRITE_CODE( hrd->getBitRateScale(), 4, "bit_rate_scale" ); + WRITE_CODE( hrd->getCpbSizeScale(), 4, "cpb_size_scale" ); + if( hrd->getGeneralDecodingUnitHrdParamsPresentFlag() ) + { + WRITE_CODE( hrd->getCpbSizeDuScale(), 4, "cpb_size_du_scale" ); + } +#else if( hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() ) { WRITE_FLAG( hrd->getDecodingUnitHrdParamsPresentFlag() ? 1 : 0, "decoding_unit_hrd_params_present_flag" ); @@ -692,8 +705,9 @@ void HLSWriter::codeHrdParameters( const HRDParameters *hrd, const uint32_t firs if( hrd->getDecodingUnitHrdParamsPresentFlag() ) { WRITE_CODE( hrd->getCpbSizeDuScale(), 4, "cpb_size_du_scale" ); + } } - } +#endif for( int i = firstSubLayer; i <= maxNumSubLayersMinus1; i ++ ) {