diff --git a/cfg/sei_vui/sei_processing_order.cfg b/cfg/sei_vui/sei_processing_order.cfg index 68c567ac7350f13d008075938ad207b2d98401b5..5c4fb4d2f7066024e47aa7c1a5786ff65e3d7a3c 100644 --- a/cfg/sei_vui/sei_processing_order.cfg +++ b/cfg/sei_vui/sei_processing_order.cfg @@ -1,10 +1,40 @@ #======== SEI messages processing order =============== -SEIPOEnabled : 1 #Enabling SEI processing order flag. -SEIPOPrefixFlag : 1 0 0 0 1 #In this example, it supports 5 SEI payload types. -SEIPOPayLoadType : 4 19 142 211 4 #SEI PayloadTypes to be processed -SEIPOProcessingOrder : 3 2 1 0 4 #Processing order of SEI payload types -SEIPONumofPrefixByte : 6 0 0 0 5 +SEIPOEnabled : 1 #Enabling SEI processing order flag. +SEIPONumMinus2 : 2 #Number of SEIs minus2 in SEI PO SEI +SEIPOWrappingFlag : 0 1 1 0 #Wrapping flag +SEIPOImportanceFlag : 1 0 0 0 #importance flag +SEIPOPrefixFlag : 0 0 0 1 +SEIPOPayLoadType : 142 144 149 4 #SEI PayloadTypes to be processed: 142: CTI SEI, 144:CLL SEI, 149:CCV +SEIPOProcessingOrder : 0 1 1 2 #Processing order of SEI payload types +SEIPONumofPrefixByte : 0 0 0 6 SEIPOPrefixByte : 0 60 0 1 4 1 181 0 59 0 9 +SEICLLMaxContentLightLevel : 4000 +SEICLLMaxPicAvgLightLevel : 600 +SEICCVCancelFlag : 0 +SEICCVPersistenceFlag : 1 +SEICCVPrimariesPresent : 1 +m_ccvSEIPrimariesX0 : 0.300 +m_ccvSEIPrimariesY0 : 0.600 +m_ccvSEIPrimariesX1 : 0.150 +m_ccvSEIPrimariesY1 : 0.060 +m_ccvSEIPrimariesX2 : 0.640 +m_ccvSEIPrimariesY2 : 0.330 +SEICCVMinLuminanceValuePresent : 1 +SEICCVMinLuminanceValue : 0.0 +SEICCVMaxLuminanceValuePresent : 1 +SEICCVMaxLuminanceValue : 0.1 +SEICCVAvgLuminanceValuePresent : 1 +SEICCVAvgLuminanceValue : 0.01 +#======== SEI messages processing order =============== +# SEIPOEnabled : 1 #Enabling SEI processing order flag +# SEIPONumMinus2 : 2 #Number of SEIs minus2 in SEI PO SEI +# SEIPOWrappingFlag : 0 0 0 0 #Wrapping flag +# SEIPOImportanceFlag : 1 1 0 0 #importance flag +# SEIPOPrefixFlag : 1 1 0 0 +# SEIPOPayLoadType : 4 4 211 19 #SEI PayloadTypes to be processed +# SEIPOProcessingOrder : 0 0 1 2 #Processing order of SEI payload types +# SEIPONumofPrefixByte : 6 5 0 0 +# SEIPOPrefixByte : 0 60 0 1 4 1 181 0 59 0 9 #add 2 more T35 SEIs to test prefix cases # T35 (HDR10+): 0x00 0x3c 0x00 0x01 0x4 0x1 diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 786aa31503eb6dfc5c97d4e87064ec255a736c42..a7a8be0647c016388a6ed2dc316008254554f856 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -1365,6 +1365,11 @@ void EncApp::xInitLibCfg( int layerIdx ) m_cEncLib.setSiiSEISubLayerNumUnitsInSI(m_siiSEISubLayerNumUnitsInSI); m_cEncLib.setPoSEIEnabled (m_poSEIEnabled); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + m_cEncLib.setPoSEINumMinus2 (m_poSEINumMinus2); + m_cEncLib.setPoSEIWrappingFlag (m_poSEIWrappingFlag); + m_cEncLib.setPoSEIImportanceFlag (m_poSEIImportanceFlag); +#endif m_cEncLib.setPoSEIPrefixFlag (m_poSEIPrefixFlag); m_cEncLib.setPoSEIPayloadType (m_poSEIPayloadType); m_cEncLib.setPoSEIProcessingOrder (m_poSEIProcessingOrder); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index e26b632d3a4e9f8a17d16fa54b011fa55f63744e..654ec34aa9975a78cb7867cef275d9649dd85a6d 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -728,6 +728,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) SMultiValueInput<uint32_t> cfg_FgcSEICompModelValueComp1 (0, 65535, 0, 256 * 6); SMultiValueInput<uint32_t> cfg_FgcSEICompModelValueComp2 (0, 65535, 0, 256 * 6); SMultiValueInput<unsigned> cfg_siiSEIInputNumUnitsInSI(0, std::numeric_limits<uint32_t>::max(), 0, 7); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + SMultiValueInput<bool> cfg_poSEIWrappingFlag(false, true, 0, 256); + SMultiValueInput<bool> cfg_poSEIImportanceFlag(false, true, 0, 256); +#endif SMultiValueInput<bool> cfg_poSEIPrefixFlag(false, true, 0, 256); SMultiValueInput<uint16_t> cfg_poSEIPayloadType(0, 32768, 0, 256 * 2); SMultiValueInput<uint16_t> cfg_poSEIProcessingOrder(0, 65535, 0, 65536); @@ -1619,6 +1623,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) //Processing order of SEI (pos) ("SEIPOEnabled", m_poSEIEnabled, false, "Specifies whether SEI processing order is applied or not") +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + ("SEIPONumMinus2", m_poSEINumMinus2, 0u, "Specifies the number of SEIs minus 2 in the SEI processing order SEI message") + ("SEIPOWrappingFlag", cfg_poSEIWrappingFlag, cfg_poSEIWrappingFlag, "Specifies whether po_num_prefix_bytes is present or not") + ("SEIPOImportanceFlag", cfg_poSEIImportanceFlag, cfg_poSEIImportanceFlag, "Specifies whether po_num_prefix_bytes is present or not") +#endif ("SEIPOPrefixFlag", cfg_poSEIPrefixFlag, cfg_poSEIPrefixFlag, "Specifies whether po_num_prefix_bytes is present or not") ("SEIPOPayLoadType", cfg_poSEIPayloadType, cfg_poSEIPayloadType, "List of payloadType for processing") ("SEIPOProcessingOrder", cfg_poSEIProcessingOrder, cfg_poSEIProcessingOrder, "List of payloadType processing order") @@ -3599,14 +3608,29 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) CHECK(cfg_poSEIPayloadType.values.size() <= 1, "there should be at least 2 SEIPOPayLoadType"); CHECK(cfg_poSEIProcessingOrder.values.size() != cfg_poSEIPayloadType.values.size(), "the number of SEIPOPayLoadType should be equal to the number of SEIPOProcessingOrder"); CHECK(cfg_poSEIPrefixFlag.values.size() <= 1, "there should be at least 2 SEIPOPrefixFlag"); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + CHECK(cfg_poSEIPayloadType.values.size() != m_poSEINumMinus2 + 2, "the number of SEIPOPayLoadType should be equal to the number of SEI messages"); + CHECK(cfg_poSEIWrappingFlag.values.size() != m_poSEINumMinus2 + 2, "the number of SEIPOWrappingFlag should be equal to the number of SEI messages"); + CHECK(cfg_poSEIImportanceFlag.values.size() != m_poSEINumMinus2 + 2, "the number of SEIImportanceFlag should be equal to the number of SEI messages"); + m_poSEIWrappingFlag.resize((uint32_t)cfg_poSEIPayloadType.values.size()); + m_poSEIImportanceFlag.resize((uint32_t)cfg_poSEIPayloadType.values.size()); +#endif m_poSEIPrefixFlag.resize((uint32_t)cfg_poSEIPayloadType.values.size()); m_poSEIPayloadType.resize((uint32_t) cfg_poSEIPayloadType.values.size()); m_poSEIProcessingOrder.resize((uint32_t) cfg_poSEIPayloadType.values.size()); m_poSEIPrefixByte.resize((uint32_t) cfg_poSEIPayloadType.values.size()); uint16_t prefixByteIdx = 0; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + for (uint32_t i = 0; i < (m_poSEINumMinus2 + 2); i++) +#else for (uint32_t i = 0; i < (uint32_t) cfg_poSEIPayloadType.values.size(); i++) +#endif { m_poSEIPrefixFlag[i] = cfg_poSEIPrefixFlag.values[i]; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + m_poSEIWrappingFlag[i] = cfg_poSEIWrappingFlag.values[i]; + m_poSEIImportanceFlag[i] = cfg_poSEIImportanceFlag.values[i]; +#endif m_poSEIPayloadType[i] = cfg_poSEIPayloadType.values[i]; if (m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::MASTERING_DISPLAY_COLOUR_VOLUME || m_poSEIPayloadType[i] == (uint16_t)SEI::PayloadType::CONTENT_LIGHT_LEVEL_INFO || diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 7b5342dbd6f22431923015478ef0bfa0fadd3dae..8589baa8eba3e4cc4c0b6236e6035534e56221af 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -810,6 +810,11 @@ protected: std::vector<bool> m_nnPostFilterSEIActivationOutputFlag; bool m_poSEIEnabled; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + uint32_t m_poSEINumMinus2; + std::vector<bool> m_poSEIWrappingFlag; + std::vector<bool> m_poSEIImportanceFlag; +#endif std::vector<bool> m_poSEIPrefixFlag; std::vector<uint16_t> m_poSEIPayloadType; std::vector<uint16_t> m_poSEIProcessingOrder; diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp index 78dd15c59043a218cb5fe8317ff0ac91942572df..196c7e434bf77241e06a0c0403c0f229496c6cb4 100644 --- a/source/Lib/CommonLib/SEI.cpp +++ b/source/Lib/CommonLib/SEI.cpp @@ -563,6 +563,12 @@ SEIShutterIntervalInfo::SEIShutterIntervalInfo(const SEIShutterIntervalInfo& sei SEIProcessingOrderInfo::SEIProcessingOrderInfo(const SEIProcessingOrderInfo& sei) { m_posEnabled = sei.m_posEnabled; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + m_posNumMinus2 = sei.m_posNumMinus2; + m_posWrappingFlag = sei.m_posWrappingFlag; + m_posImportanceFlag = sei.m_posImportanceFlag; + m_posWrapSeiMessages = sei.m_posWrapSeiMessages; +#endif m_posPrefixFlag = sei.m_posPrefixFlag; m_posPayloadType = sei.m_posPayloadType; m_posProcessingOrder = sei.m_posProcessingOrder; diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h index dd1314090976761dd7a771c3c5b0cb8e52095331..948ef45d2ab4a80a03d7507f90290e157211e314 100644 --- a/source/Lib/CommonLib/SEI.h +++ b/source/Lib/CommonLib/SEI.h @@ -121,6 +121,12 @@ struct SeiPayload int subpicId; }; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC +typedef std::list<SEI*> SEIMessages; +SEIMessages getSeisByType(const SEIMessages& seiList, SEI::PayloadType seiType); +SEIMessages extractSeisByType(SEIMessages& seiList, SEI::PayloadType seiType); +void deleteSEIs(SEIMessages& seiList); +#endif class SEIFillerPayload : public SEI { public: @@ -153,13 +159,40 @@ public: PayloadType payloadType() const { return PayloadType::SEI_PROCESSING_ORDER; } SEIProcessingOrderInfo() {} SEIProcessingOrderInfo(const SEIProcessingOrderInfo& sei); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + virtual ~SEIProcessingOrderInfo() { deleteSEIs(m_posWrapSeiMessages); } +#else virtual ~SEIProcessingOrderInfo() {} +#endif bool m_posEnabled; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + uint32_t m_posNumMinus2; + std::vector<bool> m_posWrappingFlag; + std::vector<bool> m_posImportanceFlag; +#endif std::vector<bool> m_posPrefixFlag; std::vector<uint16_t> m_posPayloadType; std::vector<uint16_t> m_posProcessingOrder; std::vector<std::vector<uint8_t>> m_posPrefixByte; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + SEIMessages m_posWrapSeiMessages; + static bool checkWrappingSEIPayloadType(SEI::PayloadType const payloadType) + { + switch (payloadType) + { + case SEI::PayloadType::FILM_GRAIN_CHARACTERISTICS: + case SEI::PayloadType::POST_FILTER_HINT: + case SEI::PayloadType::CONTENT_LIGHT_LEVEL_INFO: + case SEI::PayloadType::NEURAL_NETWORK_POST_FILTER_CHARACTERISTICS: + case SEI::PayloadType::COLOUR_TRANSFORM_INFO: + case SEI::PayloadType::CONTENT_COLOUR_VOLUME: + return true; + default: + return false; + } + } +#endif }; class SEIEquirectangularProjection : public SEI @@ -832,6 +865,7 @@ public: SEIMasteringDisplay values; }; +#if !JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC typedef std::list<SEI*> SEIMessages; /// output a selection of SEI messages by payload type. Ownership stays in original message list. @@ -842,6 +876,7 @@ SEIMessages extractSeisByType(SEIMessages &seiList, SEI::PayloadType seiType); /// delete list of SEI messages (freeing the referenced objects) void deleteSEIs (SEIMessages &seiList); +#endif class SEIScalableNesting : public SEI { diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 5d40cf3ce205ea26237390f39a8e8c57ba48313e..9bc6ad19c0705cbb50fa87402e10051cf9fa4f6c 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -57,6 +57,7 @@ #define JVET_AD0045 1 // encoder control for DMVR //########### place macros to be removed in next cycle below this line ############### +#define JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC 1 // JVET_AE0156: Wrapping and importance indication for SEI PO SEI message #define JVET_AE0126_NNPF_EDITORIAL_CHANGES 1 // JVET_AE0126: NNPF cleanup and editorial changes for VSEI include item 2, item 3, item 5, and item 7 diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index 26d601e0d860d1c47c62842b30051859d2e05dc7..8ad86c074fabb19eb23f588e911fa4a1ddec1eca 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -532,7 +532,12 @@ bool SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType break; case SEI::PayloadType::SEI_PROCESSING_ORDER: sei = new SEIProcessingOrderInfo; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + xParseSEIProcessingOrder((SEIProcessingOrderInfo&)*sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, hrd, + pDecodedMessageOutputStream); +#else xParseSEIProcessingOrder((SEIProcessingOrderInfo &) *sei, payloadSize, pDecodedMessageOutputStream); +#endif break; case SEI::PayloadType::POST_FILTER_HINT: sei = new SEIPostFilterHint; @@ -738,44 +743,100 @@ void SEIReader::xParseSEIShutterInterval(SEIShutterIntervalInfo& sei, uint32_t p } } +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC +void SEIReader::xParseSEIProcessingOrder(SEIProcessingOrderInfo& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS* vps, const SPS* sps, HRD& hrd, std::ostream* decodedMessageOutputStream) +#else void SEIReader::xParseSEIProcessingOrder(SEIProcessingOrderInfo& sei, uint32_t payloadSize, std::ostream *decodedMessageOutputStream) +#endif { +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + uint32_t i; +#else uint32_t i,b; +#endif uint32_t numMaxSeiMessages, val; output_sei_message_header(sei, decodedMessageOutputStream, payloadSize); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + sei_read_code(decodedMessageOutputStream, 8, val, "po_sei_num_minus2"); + sei.m_posNumMinus2 = val; + numMaxSeiMessages = sei.m_posNumMinus2 + 2; +#else //Since each entry is at least 4 bytes (2 byte "sei_payloadType" + 2 byte "sei_payloadOrder"), //the maximum number of entry is payloadSize/4 numMaxSeiMessages = payloadSize / 4; +#endif sei.m_posPrefixFlag.resize(numMaxSeiMessages); sei.m_posPayloadType.resize(numMaxSeiMessages); sei.m_posProcessingOrder.resize(numMaxSeiMessages); sei.m_posPrefixByte.resize(numMaxSeiMessages); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + sei.m_posWrappingFlag.resize(numMaxSeiMessages); + sei.m_posImportanceFlag.resize(numMaxSeiMessages); + for (i = 0; i < numMaxSeiMessages; i++) +#else for (i = 0, b = 0; b < payloadSize; i++, b += 4) +#endif { +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + sei_read_flag(decodedMessageOutputStream, val, "po_sei_wrapping_flag[i]"); + sei.m_posWrappingFlag[i] = val; + sei_read_flag(decodedMessageOutputStream, val, "po_sei_importance_flag[i]"); + sei.m_posImportanceFlag[i] = val; + if (sei.m_posWrappingFlag[i]) + { + sei_read_code(decodedMessageOutputStream, 6, val, "po_sei_reserved_alignment_6bits"); + SEIMessages tmpSEI; + const bool seiMessageRead = xReadSEImessage(tmpSEI, nalUnitType, nuhLayerId, 0, vps, sps, m_nestedHrd, decodedMessageOutputStream); + if (seiMessageRead) + { + sei.m_posWrapSeiMessages.push_back(tmpSEI.front()); + tmpSEI.clear(); + } + } + else + { +#endif sei_read_flag(decodedMessageOutputStream, val, "po_sei_prefix_flag[i]"); sei.m_posPrefixFlag[i] = val; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + sei_read_code(decodedMessageOutputStream, 13, val, "po_sei_payload_type[i]"); +#else sei_read_code(decodedMessageOutputStream, 15, val, "po_sei_payload_type[i]"); +#endif sei.m_posPayloadType[i] = val; if (sei.m_posPrefixFlag[i]) { sei_read_code(decodedMessageOutputStream, 8, val, "po_num_prefix_byte[i]"); sei.m_posPrefixByte[i].resize(val); +#if !JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC b ++; +#endif for (uint32_t j = 0; j < sei.m_posPrefixByte[i].size(); j++) { sei_read_code(decodedMessageOutputStream, 8, val, "po_prefix_byte[i][j]"); sei.m_posPrefixByte[i][j] = val; } +#if !JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC b += (uint32_t)sei.m_posPrefixByte[i].size(); +#endif + } +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC } +#endif +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + sei_read_code(decodedMessageOutputStream, 8, val, "po_sei_processing_order[i]"); +#else sei_read_code(decodedMessageOutputStream, 16, val, "po_sei_processing_order[i]"); +#endif sei.m_posProcessingOrder[i] = val; } +#if !JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC // resize vectors to match the number of valid entries sei.m_posPayloadType.resize(i); sei.m_posProcessingOrder.resize(i); sei.m_posPrefixByte.resize(i); +#endif CHECK(i<2, "An SEI processing order SEI message shall contain at least two pairs sei_payloadType[i] and sei_processingOrder[i]"); } diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h index a9ffeb1810bbe7882e85e573a3aa81e814801c22..2a57ccf6e100d116e6c10b19b31d5440d46aa586 100644 --- a/source/Lib/DecoderLib/SEIread.h +++ b/source/Lib/DecoderLib/SEIread.h @@ -115,7 +115,11 @@ protected: void xParseSEINNPostFilterCharacteristics(SEINeuralNetworkPostFilterCharacteristics& sei, uint32_t payloadSize, const SPS* sps, std::ostream* pDecodedMessageOutputStream); void xParseSEINNPostFilterActivation(SEINeuralNetworkPostFilterActivation& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void xParseSEIPhaseIndication(SEIPhaseIndication& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + void xParseSEIProcessingOrder(SEIProcessingOrderInfo& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS* vps, const SPS* sps, HRD& hrd, std::ostream* decodedMessageOutputStream); +#else void xParseSEIProcessingOrder (SEIProcessingOrderInfo& sei, uint32_t payloadSize, std::ostream *decodedMessageOutputStream); +#endif void xParseSEIPostFilterHint(SEIPostFilterHint &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); void sei_read_scode(std::ostream *pOS, uint32_t length, int& code, const char *pSymbolName); diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 0d2e54dc6326af8c6252e8d71d00b321cb138e91..29aaf74fb5fee5b63f5f5b2ea8a3d1a21071178c 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -895,6 +895,11 @@ protected: bool m_SEIPrefixIndicationSEIEnabled; //SEI message processing order bool m_poSEIEnabled; +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + uint32_t m_poSEINumMinus2; + std::vector<bool> m_poSEIWrappingFlag; + std::vector<bool> m_poSEIImportanceFlag; +#endif std::vector<bool> m_poSEIPrefixFlag; std::vector<uint16_t> m_poSEIPayloadType; std::vector<uint16_t> m_poSEIProcessingOrder; @@ -2585,6 +2590,14 @@ public: //SEI messages processing order void setPoSEIEnabled(bool b) { m_poSEIEnabled = b; } bool getPoSEIEnabled() { return m_poSEIEnabled; } +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + void setPoSEINumMinus2(uint32_t i) { m_poSEINumMinus2 = i; } + uint32_t getPoSEINumMinus2() { return m_poSEINumMinus2; } + void setPoSEIWrappingFlag(const std::vector<bool>& b) { m_poSEIWrappingFlag = b; } + bool getPoSEIWrappingFlag(uint16_t idx) const { return m_poSEIWrappingFlag[idx]; } + void setPoSEIImportanceFlag(const std::vector<bool>& b) { m_poSEIImportanceFlag = b; } + bool getPoSEIImportanceFlag(uint16_t idx) const { return m_poSEIImportanceFlag[idx]; } +#endif void setPoSEIPrefixFlag(const std::vector<bool>& b) { m_poSEIPrefixFlag = b; } bool getPoSEIPrefixFlag(uint16_t idx) const { return m_poSEIPrefixFlag[idx]; } void setPoSEIPayloadType(const std::vector<uint16_t>& b) { m_poSEIPayloadType = b; } diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index 01255f1d8456292c082aaa9140adca1549911343..5e2d3ca49198dad9f91b37d12976f6869fc4c7c7 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -613,20 +613,97 @@ void SEIEncoder::initSEIProcessingOrderInfo(SEIProcessingOrderInfo *seiProcessin seiProcessingOrderInfo->m_posEnabled = m_pcCfg->getPoSEIEnabled(); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + seiProcessingOrderInfo->m_posNumMinus2 = m_pcCfg->getPoSEINumMinus2(); + seiProcessingOrderInfo->m_posWrappingFlag.resize(m_pcCfg->getPoSEIPayloadTypeSize()); + seiProcessingOrderInfo->m_posImportanceFlag.resize(m_pcCfg->getPoSEIPayloadTypeSize()); + seiProcessingOrderInfo->m_posWrapSeiMessages.clear(); +#endif seiProcessingOrderInfo->m_posPrefixFlag.resize(m_pcCfg->getPoSEIPayloadTypeSize()); seiProcessingOrderInfo->m_posPayloadType.resize(m_pcCfg->getPoSEIPayloadTypeSize()); seiProcessingOrderInfo->m_posProcessingOrder.resize(m_pcCfg->getPoSEIPayloadTypeSize()); seiProcessingOrderInfo->m_posPrefixByte.resize(m_pcCfg->getPoSEIPayloadTypeSize()); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + for (uint32_t i = 0; i < (m_pcCfg->getPoSEINumMinus2() + 2); i++) +#else for (uint32_t i = 0; i < m_pcCfg->getPoSEIPayloadTypeSize(); i++) +#endif { +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + seiProcessingOrderInfo->m_posWrappingFlag[i] = m_pcCfg->getPoSEIWrappingFlag(i); + seiProcessingOrderInfo->m_posImportanceFlag[i] = m_pcCfg->getPoSEIImportanceFlag(i); +#endif seiProcessingOrderInfo->m_posPrefixFlag[i] = m_pcCfg->getPoSEIPrefixFlag(i); seiProcessingOrderInfo->m_posPayloadType[i] = m_pcCfg->getPoSEIPayloadType(i); seiProcessingOrderInfo->m_posProcessingOrder[i] = m_pcCfg->getPoSEIProcessingOrder(i); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + if (seiProcessingOrderInfo->m_posPrefixFlag[i]) +#else if (seiProcessingOrderInfo->m_posPayloadType[i] == (uint16_t) SEI::PayloadType::USER_DATA_REGISTERED_ITU_T_T35) +#endif { seiProcessingOrderInfo->m_posPrefixByte[i] = m_pcCfg->getPoSEIPrefixByte(i); } } +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + for (uint32_t i = 0; i < (m_pcCfg->getPoSEINumMinus2() + 2); i++) + { + if (seiProcessingOrderInfo->m_posWrappingFlag[i]) + { + CHECK(!seiProcessingOrderInfo->checkWrappingSEIPayloadType(SEI::PayloadType(seiProcessingOrderInfo->m_posPayloadType[i])), "not support in sei processing order SEI"); + switch (SEI::PayloadType(seiProcessingOrderInfo->m_posPayloadType[i])) + { + case SEI::PayloadType::FILM_GRAIN_CHARACTERISTICS: + { + SEIFilmGrainCharacteristics* seiFGC = new SEIFilmGrainCharacteristics; + initSEIFilmGrainCharacteristics(seiFGC); + seiProcessingOrderInfo->m_posWrapSeiMessages.push_back(seiFGC); + break; + } + case SEI::PayloadType::CONTENT_LIGHT_LEVEL_INFO: + { + SEIContentLightLevelInfo* seiCCL = new SEIContentLightLevelInfo; + initSEIContentLightLevel(seiCCL); + seiProcessingOrderInfo->m_posWrapSeiMessages.push_back(seiCCL); + break; + } + case SEI::PayloadType::CONTENT_COLOUR_VOLUME: + { + SEIContentColourVolume* seiCCV = new SEIContentColourVolume; + initSEIContentColourVolume(seiCCV); + seiProcessingOrderInfo->m_posWrapSeiMessages.push_back(seiCCV); + break; + } + case SEI::PayloadType::COLOUR_TRANSFORM_INFO: + { + SEIColourTransformInfo* seiCTI = new SEIColourTransformInfo; + initSEIColourTransformInfo(seiCTI); + seiProcessingOrderInfo->m_posWrapSeiMessages.push_back(seiCTI); + break; + } + case SEI::PayloadType::NEURAL_NETWORK_POST_FILTER_CHARACTERISTICS: + { + SEINeuralNetworkPostFilterCharacteristics* seiNNPFC = new SEINeuralNetworkPostFilterCharacteristics; + initSEINeuralNetworkPostFilterCharacteristics(seiNNPFC, 0); + seiProcessingOrderInfo->m_posWrapSeiMessages.push_back(seiNNPFC); + break; + } + case SEI::PayloadType::POST_FILTER_HINT: + { + SEIPostFilterHint* seiPFH = new SEIPostFilterHint; + initSEIPostFilterHint(seiPFH); + seiProcessingOrderInfo->m_posWrapSeiMessages.push_back(seiPFH); + break; + } + default: + { + msg(ERROR, "not support in sei processing order SEI\n"); + exit(1); + } + } + } + } +#endif } void SEIEncoder::initSEIPostFilterHint(SEIPostFilterHint *seiPostFilterHint) diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp index 838eef2176afffcb943f0da293ea802f69738765..37801fd9544549686c31f842c1e493513d6c1548 100644 --- a/source/Lib/EncoderLib/SEIwrite.cpp +++ b/source/Lib/EncoderLib/SEIwrite.cpp @@ -183,7 +183,11 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream &bs, const SEI &sei, HRD &h xWriteSEINeuralNetworkPostFilterActivation(*static_cast<const SEINeuralNetworkPostFilterActivation *>(&sei)); break; case SEI::PayloadType::SEI_PROCESSING_ORDER: +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + xWriteSEIProcessingOrder(bs, *static_cast<const SEIProcessingOrderInfo*>(&sei)); +#else xWriteSEIProcessingOrder(*static_cast<const SEIProcessingOrderInfo *>(&sei)); +#endif break; case SEI::PayloadType::POST_FILTER_HINT: xWriteSEIPostFilterHint(*static_cast<const SEIPostFilterHint *>(&sei)); @@ -1543,15 +1547,45 @@ void SEIWriter::xWriteSEIShutterInterval(const SEIShutterIntervalInfo &sei) } } +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC +void SEIWriter::xWriteSEIProcessingOrder(OutputBitstream& bs, const SEIProcessingOrderInfo& sei) +#else void SEIWriter::xWriteSEIProcessingOrder(const SEIProcessingOrderInfo &sei) +#endif { CHECK(sei.m_posPayloadType.size() < 2, "An SEI processing order SEI message shall contain at least two pairs sei_payloadType[i] and sei_processingOrder[i]"); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + SEIMessages wrapSEI; + xWriteCode(sei.m_posNumMinus2, 8, "po_num_sei_message_minus2"); + for (uint32_t i = 0; i < ( sei.m_posNumMinus2 + 2 ); i++) +#else for (uint32_t i = 0; i < sei.m_posPayloadType.size(); i++) +#endif { - xWriteFlag(sei.m_posPrefixFlag[i], "po_sei_prefix_flag[i]"); - xWriteCode(sei.m_posPayloadType[i], 15, "po_sei_payload_type[i]"); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + xWriteFlag(sei.m_posWrappingFlag[i], "po_sei_wrapping_flag[i]"); + xWriteFlag(sei.m_posImportanceFlag[i], "po_sei_importance_flag[i]"); + if (sei.m_posWrappingFlag[i]) + { + xWriteCode(0, 6, "spo_sei_reserved_zero_6bits"); + wrapSEI = getSeisByType(sei.m_posWrapSeiMessages, SEI::PayloadType(sei.m_posPayloadType[i])); + writeSEImessages(bs, wrapSEI, m_nestingHrd, true, 0); + } + else + { +#endif + xWriteFlag(sei.m_posPrefixFlag[i], "po_sei_prefix_flag[i]"); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + xWriteCode(sei.m_posPayloadType[i], 13, "po_sei_payload_type[i]"); +#else + xWriteCode(sei.m_posPayloadType[i], 15, "po_sei_payload_type[i]"); +#endif +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + if (sei.m_posPrefixFlag[i]) +#else if (sei.m_posPayloadType[i] == (uint16_t) SEI::PayloadType::USER_DATA_REGISTERED_ITU_T_T35) +#endif { xWriteCode((uint32_t)sei.m_posPrefixByte[i].size(), 8, "po_num_t35_byte[i]"); for (uint32_t j = 0; j < sei.m_posPrefixByte[i].size(); j++) @@ -1559,7 +1593,14 @@ void SEIWriter::xWriteSEIProcessingOrder(const SEIProcessingOrderInfo &sei) xWriteCode(sei.m_posPrefixByte[i][j], 8, "po_t35_byte[i][j]"); } } +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + } +#endif +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + xWriteCode(sei.m_posProcessingOrder[i], 8, "po_sei_processing_order[i]"); +#else xWriteCode(sei.m_posProcessingOrder[i], 16, "po_sei_processing_order[i]"); +#endif } } diff --git a/source/Lib/EncoderLib/SEIwrite.h b/source/Lib/EncoderLib/SEIwrite.h index f60a0a0db3a950783fb8db1dc4ce6f9e52bf0eab..56e73fc2ef030239731d182a16b12184df2fba06 100644 --- a/source/Lib/EncoderLib/SEIwrite.h +++ b/source/Lib/EncoderLib/SEIwrite.h @@ -107,7 +107,11 @@ protected: void xWriteByteAlign(); void xWriteSEINeuralNetworkPostFilterCharacteristics(const SEINeuralNetworkPostFilterCharacteristics& sei); void xWriteSEINeuralNetworkPostFilterActivation(const SEINeuralNetworkPostFilterActivation &sei); +#if JVET_AE0156_SEI_PO_WRAP_IMPORTANCE_IDC + void xWriteSEIProcessingOrder(OutputBitstream& bs, const SEIProcessingOrderInfo& sei); +#else void xWriteSEIProcessingOrder(const SEIProcessingOrderInfo &sei); +#endif #if GREEN_METADATA_SEI_ENABLED void xWriteSEIGreenMetadataInfo (const SEIGreenMetadataInfo &sei); #endif