diff --git a/cfg/sei_vui/post_filter_hint_info.cfg b/cfg/sei_vui/post_filter_hint_info.cfg new file mode 100644 index 0000000000000000000000000000000000000000..c943e157ac26c39da6eb65f2ad4f430d6fd006f7 --- /dev/null +++ b/cfg/sei_vui/post_filter_hint_info.cfg @@ -0,0 +1,9 @@ +#======== post-filter hint SEI message ===================== +SEIPostFilterHintEnabled : 1 +SEIPostFilterHintCancelFlag : 0 +SEIPostFilterHintPersistenceFlag : 0 +SEIPostFilterHintSizeY : 5 +SEIPostFilterHintSizeX : 5 +SEIPostFilterHintType : 0 +SEIPostFilterHintChromaCoeffPresentFlag : 0 +SEIPostFilterHintValue : 5 9 10 9 5 9 13 14 13 9 10 14 16 14 10 9 13 14 13 9 5 9 10 9 5 diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 652fa97f4eaa7a655a30a8a376a0edce6309428b..c211ef19eed628568be29ee7ae9fdbb842e58b0a 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -1307,6 +1307,17 @@ void EncApp::xInitLibCfg( int layerIdx ) m_cEncLib.setPoSEIProcessingOrder (m_poSEIProcessingOrder); m_cEncLib.setPoSEINumofSeiMessages (m_numofSEIMessages); +#if JVET_AB0070_POST_FILTER_HINT + m_cEncLib.setPostFilterHintSEIEnabled(m_postFilterHintSEIEnabled); + m_cEncLib.setPostFilterHintSEICancelFlag(m_postFilterHintSEICancelFlag); + m_cEncLib.setPostFilterHintSEIPersistenceFlag(m_postFilterHintSEIPersistenceFlag); + m_cEncLib.setPostFilterHintSEISizeY(m_postFilterHintSEISizeY); + m_cEncLib.setPostFilterHintSEISizeX(m_postFilterHintSEISizeX); + m_cEncLib.setPostFilterHintSEIType(m_postFilterHintSEIType); + m_cEncLib.setPostFilterHintSEIChromaCoeffPresentFlag(m_postFilterHintSEIChromaCoeffPresentFlag); + m_cEncLib.setPostFilterHintSEIValues(m_postFilterHintValues); +#endif + m_cEncLib.setVuiParametersPresentFlag ( m_vuiParametersPresentFlag ); m_cEncLib.setSamePicTimingInAllOLS (m_samePicTimingInAllOLS); m_cEncLib.setAspectRatioInfoPresentFlag ( m_aspectRatioInfoPresentFlag); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 1c956b727e8d79b62ba0e062e16f9212fa2c56e1..60d741c5563a16be5858a285c935058edd9c0664 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -738,6 +738,10 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) SMultiValueInput<uint16_t> cfg_poSEIProcessingOrder (0, 255, 0, 256); #endif +#if JVET_AB0070_POST_FILTER_HINT + SMultiValueInput<int32_t> cfg_postFilterHintSEIValues(INT32_MIN + 1, INT32_MAX, 1 * 1 * 1, 15 * 15 * 3); +#endif + #if JVET_AB0058_NN_FRAME_RATE_UPSAMPLING std::vector<SMultiValueInput<uint32_t>> cfg_nnPostFilterSEICharacteristicsInterpolatedPicturesList; for (int i = 0; i < MAX_NUM_NN_POST_FILTERS; i++) @@ -1592,6 +1596,17 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("SEIPOPayLoadType", cfg_poSEIPayloadType, cfg_poSEIPayloadType, "List of payloadType for processing") ("SEIPOProcessingOrder", cfg_poSEIProcessingOrder, cfg_poSEIProcessingOrder, "List of payloadType processing order") +#if JVET_AB0070_POST_FILTER_HINT + ("SEIPostFilterHintEnabled", m_postFilterHintSEIEnabled, false, "Control generation of post-filter Hint SEI message") + ("SEIPostFilterHintCancelFlag", m_postFilterHintSEICancelFlag, false, "Specifies the persistence of any previous post-filter Hint SEI message in output order") + ("SEIPostFilterHintPersistenceFlag", m_postFilterHintSEIPersistenceFlag, false, "Specifies the persistence of the post-filter Hint SEI message for the current layer") + ("SEIPostFilterHintSizeY", m_postFilterHintSEISizeY, 1u, "Specifies the vertical size of the post-filter coefficient or correlation array") + ("SEIPostFilterHintSizeX", m_postFilterHintSEISizeX, 1u, "Specifies the horizontal size of the post-filter coefficient or correlation array") + ("SEIPostFilterHintType", m_postFilterHintSEIType, 0u, "Specifies the type of the post-filter: 2D-FIR filter (0, default), 1D-FIR filters (1) or Cross-correlation matrix (0)") + ("SEIPostFilterHintChromaCoeffPresentFlag", m_postFilterHintSEIChromaCoeffPresentFlag, false, "Specifies the presence of post-filter coefficients for chroma") + ("SEIPostFilterHintValue", cfg_postFilterHintSEIValues, cfg_postFilterHintSEIValues, "Specifies post-filter coefficients or elements of a cross-correlation matrix") +#endif + #if JVET_T0056_SEI_MANIFEST //SEI manifest ("SEISEIManifestEnabled", m_SEIManifestSEIEnabled, false, "Controls if SEI Manifest SEI messages enabled") @@ -3388,6 +3403,22 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) assert(m_poSEIProcessingOrder.size() == m_poSEIPayloadType.size()); } +#if JVET_AB0070_POST_FILTER_HINT + if (m_postFilterHintSEIEnabled) + { + assert(cfg_postFilterHintSEIValues.values.size() > 0); + assert(cfg_postFilterHintSEIValues.values.size() + == (m_postFilterHintSEIChromaCoeffPresentFlag ? 3 : 1) * m_postFilterHintSEISizeY + * m_postFilterHintSEISizeX); + m_postFilterHintValues.resize(cfg_postFilterHintSEIValues.values.size()); + + for (uint32_t i = 0; i < m_postFilterHintValues.size(); i++) + { + m_postFilterHintValues[i] = cfg_postFilterHintSEIValues.values[i]; + } + } +#endif + if( m_costMode == COST_LOSSLESS_CODING ) { bool firstSliceLossless = false; diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index f912b2a20a2b91e1d4436631093bbb0e1436d2d4..c64c3bec0645797457ba3c6508d325ee77c56806 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -785,6 +785,17 @@ protected: #endif uint32_t m_numofSEIMessages; +#if JVET_AB0070_POST_FILTER_HINT + bool m_postFilterHintSEIEnabled; + bool m_postFilterHintSEICancelFlag; + bool m_postFilterHintSEIPersistenceFlag; + uint32_t m_postFilterHintSEISizeY; + uint32_t m_postFilterHintSEISizeX; + uint32_t m_postFilterHintSEIType; + bool m_postFilterHintSEIChromaCoeffPresentFlag; + std::vector<int32_t> m_postFilterHintValues; +#endif + bool m_constrainedRaslEncoding; bool m_sampleAspectRatioInfoSEIEnabled; diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 5e3f731b81755a045e7ed6c4243705bf2cd79812..e59037a1496adca9e1109180064944fe81d0dcb2 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -876,6 +876,17 @@ protected: #endif uint32_t m_numofSEIMessages; +#if JVET_AB0070_POST_FILTER_HINT + bool m_postFilterHintSEIEnabled; + bool m_postFilterHintSEICancelFlag; + bool m_postFilterHintSEIPersistenceFlag; + uint32_t m_postFilterHintSEISizeY; + uint32_t m_postFilterHintSEISizeX; + uint32_t m_postFilterHintSEIType; + bool m_postFilterHintSEIChromaCoeffPresentFlag; + std::vector<int32_t> m_postFilterHintValues; +#endif + bool m_constrainedRaslEncoding; //====== Weighted Prediction ======== @@ -2490,6 +2501,25 @@ public: void setPoSEINumofSeiMessages(uint32_t i) { m_numofSEIMessages = i; } uint32_t getPoSEINumofSeiMessages() const { return m_numofSEIMessages; } +#if JVET_AB0070_POST_FILTER_HINT + void setPostFilterHintSEIEnabled(bool b) { m_postFilterHintSEIEnabled = b; } + bool getPostFilterHintSEIEnabled() { return m_postFilterHintSEIEnabled; } + void setPostFilterHintSEICancelFlag(bool b) { m_postFilterHintSEICancelFlag = b; } + bool getPostFilterHintSEICancelFlag() { return m_postFilterHintSEICancelFlag; } + void setPostFilterHintSEIPersistenceFlag(bool b) { m_postFilterHintSEIPersistenceFlag = b; } + bool getPostFilterHintSEIPersistenceFlag() { return m_postFilterHintSEIPersistenceFlag; } + void setPostFilterHintSEISizeY(uint32_t i) { m_postFilterHintSEISizeY = i; } + uint32_t getPostFilterHintSEISizeY() { return m_postFilterHintSEISizeY; } + void setPostFilterHintSEISizeX(uint32_t i) { m_postFilterHintSEISizeX = i; } + uint32_t getPostFilterHintSEISizeX() { return m_postFilterHintSEISizeX; } + void setPostFilterHintSEIType(uint32_t i) { m_postFilterHintSEIType = i; } + uint32_t getPostFilterHintSEIType() { return m_postFilterHintSEIType; } + void setPostFilterHintSEIChromaCoeffPresentFlag(bool b) { m_postFilterHintSEIChromaCoeffPresentFlag = b; } + bool getPostFilterHintSEIChromaCoeffPresentFlag() { return m_postFilterHintSEIChromaCoeffPresentFlag; } + void setPostFilterHintSEIValues(const std::vector<int32_t> &b) { m_postFilterHintValues = b; } + int32_t getPostFilterHintSEIValues(int32_t idx) const { return m_postFilterHintValues[idx]; } +#endif + void setUseWP ( bool b ) { m_useWeightedPred = b; } void setWPBiPred ( bool b ) { m_useWeightedBiPred = b; } bool getUseWP () { return m_useWeightedPred; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index e7be5d21fa56ffba206220a782dc4395007ed6ec..0d159484737389f1868467a97a02b7ef8a8ae8d3 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1008,6 +1008,16 @@ void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessage m_seiEncoder.initSEINeuralNetworkPostFilterActivation(nnpfActivationSEI); seiMessages.push_back(nnpfActivationSEI); } + +#if JVET_AB0070_POST_FILTER_HINT + if (m_pcCfg->getPostFilterHintSEIEnabled()) + { + SEIPostFilterHint *postFilterHintSEI = new SEIPostFilterHint; + + m_seiEncoder.initSEIPostFilterHint(postFilterHintSEI); + seiMessages.push_back(postFilterHintSEI); + } +#endif } void EncGOP::xCreatePhaseIndicationSEIMessages(SEIMessages& seiMessages, Slice* slice, int ppsId) diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index 9ff1ef6c6511c3b97f755258f64711b8d8c5550f..9b077b20c0520aa7ff16cfbc56a5f4b491567273 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -618,6 +618,29 @@ void SEIEncoder::initSEIProcessingOrderInfo(SEIProcessingOrderInfo *seiProcessin } } +#if JVET_AB0070_POST_FILTER_HINT +void SEIEncoder::initSEIPostFilterHint(SEIPostFilterHint *seiPostFilterHint) +{ + assert(m_isInitialized); + assert(seiPostFilterHint != nullptr); + + seiPostFilterHint->m_filterHintCancelFlag = m_pcCfg->getPostFilterHintSEICancelFlag(); + seiPostFilterHint->m_filterHintPersistenceFlag = m_pcCfg->getPostFilterHintSEIPersistenceFlag(); + seiPostFilterHint->m_filterHintSizeY = m_pcCfg->getPostFilterHintSEISizeY(); + seiPostFilterHint->m_filterHintSizeX = m_pcCfg->getPostFilterHintSEISizeX(); + seiPostFilterHint->m_filterHintType = m_pcCfg->getPostFilterHintSEIType(); + seiPostFilterHint->m_filterHintChromaCoeffPresentFlag = m_pcCfg->getPostFilterHintSEIChromaCoeffPresentFlag(); + + seiPostFilterHint->m_filterHintValues.resize((seiPostFilterHint->m_filterHintChromaCoeffPresentFlag ? 3 : 1) + * seiPostFilterHint->m_filterHintSizeY + * seiPostFilterHint->m_filterHintSizeX); + for (uint32_t i = 0; i < seiPostFilterHint->m_filterHintValues.size(); i++) + { + seiPostFilterHint->m_filterHintValues[i] = m_pcCfg->getPostFilterHintSEIValues(i); + } +} +#endif + template <typename T> static void readTokenValue(T &returnedValue, /// value returned bool &failed, /// used and updated diff --git a/source/Lib/EncoderLib/SEIEncoder.h b/source/Lib/EncoderLib/SEIEncoder.h index ba4c1d896540a937b221f4111690b68f94cf5942..a0b4317ddbb3ea6306251bc9279ccb3f25662382 100644 --- a/source/Lib/EncoderLib/SEIEncoder.h +++ b/source/Lib/EncoderLib/SEIEncoder.h @@ -100,6 +100,9 @@ public: void initSEINeuralNetworkPostFilterCharacteristics(SEINeuralNetworkPostFilterCharacteristics *sei, int filterIdx); void initSEINeuralNetworkPostFilterActivation(SEINeuralNetworkPostFilterActivation *sei); void initSEIProcessingOrderInfo(SEIProcessingOrderInfo *sei); +#if JVET_AB0070_POST_FILTER_HINT + void initSEIPostFilterHint(SEIPostFilterHint *sei); +#endif #if GREEN_METADATA_SEI_ENABLED void initSEIGreenMetadataInfo(SEIGreenMetadataInfo *sei, FeatureCounterStruct featureCounter, SEIQualityMetrics metrics, SEIComplexityMetrics greenMetadata); #endif