diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 976f5169aede9adc69fda902254c0e30442e4de2..92ff74f3fe9ab148026eebc568758f96ce3977fe 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -4820,7 +4820,11 @@ bool EncAppCfg::xCheckParameter() { xConfirmPara(m_nnPostFilterSEICharacteristicsId[i] > (uint32_t)(((uint64_t)1 << 32) - 2), "SEINNPostFilterCharacteristicsId must be in the range of 0 to 2^32-2"); xConfirmPara(m_nnPostFilterSEICharacteristicsModeIdc[i] > 255, "SEINNPostFilterCharacteristicsModeIdc must be in the range of 0 to 255"); +#if JVET_AB0049 + xConfirmPara(m_nnPostFilterSEICharacteristicsPurpose[i] > 1023, "SEINNPostFilterCharacteristicsPurpose must be in the range of 0 to 1023"); +#else xConfirmPara(m_nnPostFilterSEICharacteristicsPurpose[i] > (uint32_t)(((uint64_t)1 << 32) - 2), "SEINNPostFilterCharacteristicsPurpose must be in the range of 0 to 2^32-2"); +#endif xConfirmPara(m_nnPostFilterSEICharacteristicsInpTensorBitDepthMinus8[i] > 24, "SEINNPostFilterCharacteristicsInpTensorBitDepthMinus8 must be in the range of 0 to 24"); xConfirmPara(m_nnPostFilterSEICharacteristicsOutTensorBitDepthMinus8[i] > 24, "SEINNPostFilterCharacteristicsOutTensorBitDepthMinus8 must be in the range of 0 to 24"); #if M60678_BALLOT_COMMENTS_OF_FI_03 @@ -4855,7 +4859,11 @@ bool EncAppCfg::xCheckParameter() if (m_nnPostFilterSEIActivationEnabled) { + #if JVET_AB0049 + xConfirmPara(m_nnPostFilterSEIActivationId > (uint32_t)(((uint64_t)1 << 32) - 2), "SEINNPostFilterActivationId must be in the range of 0 to 2^32-2"); + #else xConfirmPara(m_nnPostFilterSEIActivationId > (1 << 20) - 1, "SEINNPostFilterActivationId must be in the range of 0 to 2^20-1"); + #endif } if (m_phaseIndicationSEIEnabledFullResolution) diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 91930ec555584f03921f1989d254c2f22bce301b..3315da220d14f8f16063e105ef061db2fe37ecb8 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -55,7 +55,7 @@ // clang-format off //########### place macros to be removed in next cycle below this line ############### - +#define JVET_AB0049 1 // JVET-AB0049: Modification of NNPFC #define JVET_T0056_SEI_MANIFEST 1 // JVET-T0056: SEI manifest SEI message #define JVET_T0056_SEI_PREFIX_INDICATION 1 // JVET-T0056: SEI prefix indication SEI message #define JVET_AB0069_SEI_PROCESSING_ORDER 1 // JVET-AB0069: SEI processing order SEI message update diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp index 92f219be9b86d7266e180655e5d0aa88a91b9232..ac986354b75581177c2a27ea6700ef2958bcdf2f 100644 --- a/source/Lib/DecoderLib/SEIread.cpp +++ b/source/Lib/DecoderLib/SEIread.cpp @@ -446,11 +446,28 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType sei = new SEINeuralNetworkPostFilterCharacteristics; xParseSEINNPostFilterCharacteristics((SEINeuralNetworkPostFilterCharacteristics &) *sei, payloadSize, sps, pDecodedMessageOutputStream); + + +#if JVET_AB0049 + nnpfcValues.push_back(((SEINeuralNetworkPostFilterCharacteristics*)sei)->m_id); +#endif break; case SEI::PayloadType::NEURAL_NETWORK_POST_FILTER_ACTIVATION: sei = new SEINeuralNetworkPostFilterActivation; xParseSEINNPostFilterActivation((SEINeuralNetworkPostFilterActivation &) *sei, payloadSize, pDecodedMessageOutputStream); +#if JVET_AB0049 + assert(nnpfcValues.size() > 0); + for(int i=0; i<nnpfcValues.size(); ++i) + { + if(((SEINeuralNetworkPostFilterCharacteristics*)sei)->m_id == nnpfcValues[i]) + { + nnpfcProcessed = true; + } + } + assert(nnpfcProcessed == true); // No NNPFC, no NNPFA + nnpfcProcessed = false; +#endif break; case SEI::PayloadType::PHASE_INDICATION: sei = new SEIPhaseIndication; @@ -2629,6 +2646,9 @@ void SEIReader::xParseSEINNPostFilterCharacteristics(SEINeuralNetworkPostFilterC sei_read_uvlc( pDecodedMessageOutputStream, val, "nnpfc_id" ); sei.m_id = val; +#if JVET_AB0049 + CHECK((sei.m_id >= 256 && sei.m_id <= 511) || (sei.m_id >= (1<<31) && sei.m_id <= (uint32_t)(((uint64_t)1 << 32) - 2)), "Reserved nnpfc_id value, shall ignore the SEI message"); +#endif sei_read_uvlc( pDecodedMessageOutputStream, val, "nnpfc_mode_idc" ); sei.m_modeIdc = val; @@ -2903,6 +2923,9 @@ void SEIReader::xParseSEINNPostFilterActivation(SEINeuralNetworkPostFilterActiva sei_read_uvlc( pDecodedMessageOutputStream, val, "nnpfa_id" ); sei.m_id =val; +#if JVET_AB0049 + CHECK((sei.m_id >= 256 && sei.m_id <= 511) || (sei.m_id >= (1<<31) && sei.m_id <= (uint32_t)(((uint64_t)1 << 32) - 2)), "Reserved nnpfa_id value, shall ignore the SEI message"); +#endif } void SEIReader::xParseSEIPhaseIndication(SEIPhaseIndication& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream) diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h index 02f8ec5b0e09d7a471c94cfb27f3096178197b4a..45fa5101d0e3d94b836d97c3c7defc7021885850 100644 --- a/source/Lib/DecoderLib/SEIread.h +++ b/source/Lib/DecoderLib/SEIread.h @@ -61,7 +61,11 @@ public: const VPS *vps, const SPS *sps, HRD &hrd, uint32_t payloadSize, std::vector<SeiPayload> *seiList); void getSEIDecodingUnitInfoDuiIdx(InputBitstream* bs, const NalUnitType nalUnitType, const uint32_t nuh_layer_id, HRD &hrd, uint32_t payloadSize, int& duiIdx); - +#if JVET_AB0049 + int nnpfcProcessed; + std::vector<int> nnpfcValues; +#endif + protected: void xReadSEImessage (SEIMessages& seis, const NalUnitType nalUnitType, const uint32_t nuh_layer_id, const uint32_t temporalId, const VPS *vps, const SPS *sps, HRD &hrd, std::ostream *pDecodedMessageOutputStream); void xParseSEIFillerPayload (SEIFillerPayload &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream); diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index 61d9c344759edac44b8f4dd034ff546204b73d2f..1b50e100c48fa1ca98aa6f5933f95487728d71ad 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -1295,6 +1295,37 @@ void SEIEncoder::initSEINeuralNetworkPostFilterCharacteristics(SEINeuralNetworkP { sei->m_picWidthInLumaSamples = m_pcCfg->getNNPostFilterSEICharacteristicsPicWidthInLumaSamples(filterIdx); sei->m_picHeightInLumaSamples = m_pcCfg->getNNPostFilterSEICharacteristicsPicHeightInLumaSamples(filterIdx); +#if JVET_AB0049 + int confWinLeftOffset = m_pcEncLib->getPPS(0)->getConformanceWindow().getWindowLeftOffset(); + int confWinTopOffset = m_pcEncLib->getPPS(0)->getConformanceWindow().getWindowTopOffset(); + int confWinRightOffset = m_pcEncLib->getPPS(0)->getConformanceWindow().getWindowRightOffset(); + int confWinBottomOffset = m_pcEncLib->getPPS(0)->getConformanceWindow().getWindowBottomOffset(); + int ppsPicWidthInLumaSample = m_pcEncLib->getPPS(0)->getPicWidthInLumaSamples(); + int ppsPicHeightInLumaSample = m_pcEncLib->getPPS(0)->getPicHeightInLumaSamples(); + ChromaFormat chromaFormatIDC = m_pcEncLib->getSPS(0)->getChromaFormatIdc(); + uint8_t subWidthC; + uint8_t subHeightC; + if (chromaFormatIDC == ChromaFormat::CHROMA_420) + { + subWidthC = 2; + subHeightC = 2; + } + else if (chromaFormatIDC == ChromaFormat::CHROMA_422) + { + subWidthC = 2; + subHeightC = 1; + } + else + { + subWidthC = 1; + subHeightC = 1; + } + + int croppedWidth = ppsPicWidthInLumaSample - subWidthC * (confWinRightOffset + confWinLeftOffset); + int croppedHeight = ppsPicHeightInLumaSample - subHeightC * (confWinBottomOffset + confWinTopOffset); + assert(sei->m_picWidthInLumaSamples >= croppedWidth && sei->m_picWidthInLumaSamples <= croppedWidth * 16 - 1); + assert(sei->m_picHeightInLumaSamples >= croppedHeight && sei->m_picHeightInLumaSamples <= croppedHeight * 16 - 1); +#endif } #if JVET_AB0058_NN_FRAME_RATE_UPSAMPLING if (sei->m_purpose == NNPC_PurposeType::FRANE_RATE_UPSAMPLING)