From 31f6085f321d9d1e83559680a79fb0714fa4e08c Mon Sep 17 00:00:00 2001
From: Wei Jia <wei.jia@bytedance.com>
Date: Fri, 18 Aug 2023 15:39:16 +0000
Subject: [PATCH] JVET-AE0126: NNPF cleanup and editorial changes for VSEI
 include item 2, item 3, item 5, and item 7

---
 .../SEINeuralNetworkPostFiltering.cpp         | 13 ++++++++++
 source/Lib/CommonLib/TypeDef.h                |  2 ++
 source/Lib/DecoderLib/SEIread.cpp             | 26 +++++++++++++++++++
 source/Lib/EncoderLib/SEIEncoder.cpp          |  5 ++++
 source/Lib/EncoderLib/SEIwrite.cpp            | 17 ++++++++++++
 5 files changed, 63 insertions(+)

diff --git a/source/Lib/CommonLib/SEINeuralNetworkPostFiltering.cpp b/source/Lib/CommonLib/SEINeuralNetworkPostFiltering.cpp
index 1af50c12a..def152ba0 100644
--- a/source/Lib/CommonLib/SEINeuralNetworkPostFiltering.cpp
+++ b/source/Lib/CommonLib/SEINeuralNetworkPostFiltering.cpp
@@ -35,6 +35,11 @@
    \brief    SEI NN post filtering (application) class
 */
 
+#include "CommonLib/CommonDef.h"
+#include <cmath>
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+#include "CommonLib/SEI.h"
+#endif
 #include "SEINeuralNetworkPostFiltering.h"
 
 
@@ -131,6 +136,14 @@ void SEINeuralNetworkPostFiltering::filterPictures(PicList& picList)
     {
       croppedWidth  = superResolutionNnpfc->m_picWidthInLumaSamples;
       croppedHeight = superResolutionNnpfc->m_picHeightInLumaSamples;
+
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+      int outputPicWidth  = (int)ceil(((double) croppedWidth * (superResolutionNnpfc->m_picWidthNumeratorMinus1 + 1)) / (superResolutionNnpfc->m_picWidthDenominatorMinus1 + 1));
+      int outputPicHeight = (int)ceil(((double) croppedHeight * (superResolutionNnpfc->m_picHeightNumeratorMinus1 + 1)) / (superResolutionNnpfc->m_picHeightDenominatorMinus1 + 1));
+
+      CHECK(outputPicWidth == croppedWidth && outputPicHeight == croppedHeight, "When resolutionResamplingFlag is equal to 1, either nnpfcOutputPicWidth is not equal to CroppedWidth or nnpfcOutputPicHeight is not equal to CroppedHeight.");
+#endif
+
     }
     else
     {
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 19fb632d2..3c3d1ce7c 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -58,6 +58,8 @@
 
 //########### place macros to be removed in next cycle below this line ###############
 
+#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
+
 #define JVET_Z0150_MEMORY_USAGE_PRINT                     1 // JVET-Z0150: Print memory usage
 
 #define JVET_AE0060_COND_SIG_INF                          1 // signal nnpfc_chroma_loc_info_present_flag only when nnpfc_out_order_idc is not equal to 0 and infer nnpfc_chroma_loc_info_present_flag to be equal to 0 when not present.
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index a952dd563..8697a2d2b 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -2807,8 +2807,13 @@ void SEIReader::xParseSEINNPostFilterCharacteristics(SEINeuralNetworkPostFilterC
     std::string val2;
     while (!isByteAligned())
     {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+      sei_read_flag(pDecodedMessageOutputStream, val, "nnpfc_alignment_zero_bit");
+      CHECK(val != 0, "nnpfc_alignment_zero_bit not equal to zero");
+#else
       sei_read_flag(pDecodedMessageOutputStream, val, "nnpfc_reserved_zero_bit");
       CHECK(val != 0, "nnpfc_reserved_zero_bit not equal to zero");
+#endif
     }
 
     sei_read_string(pDecodedMessageOutputStream, val2, "nnpfc_uri_tag");
@@ -2853,7 +2858,11 @@ void SEIReader::xParseSEINNPostFilterCharacteristics(SEINeuralNetworkPostFilterC
       bool atLeastOne = false;
       for (int i = 0; i <= sei.m_numberInputDecodedPicturesMinus1; i++)
       {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+        sei_read_flag(pDecodedMessageOutputStream, val, "nnpfc_input_pic_filtering_flag");
+#else
         sei_read_flag(pDecodedMessageOutputStream, val, "nnpfc_input_pic_output_flag");
+#endif
         sei.m_inputPicOutputFlag.push_back((bool)val);
         if (sei.m_inputPicOutputFlag[i])
         {
@@ -2863,7 +2872,11 @@ void SEIReader::xParseSEINNPostFilterCharacteristics(SEINeuralNetworkPostFilterC
       }
       if ((sei.m_purpose & NNPC_PurposeType::FRAME_RATE_UPSAMPLING) == 0)
       {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+        CHECK(!atLeastOne, "When picRateUpsamplingFlag is equal to 0 and nnpfc_num_input_pics_minus1 is greater than 0, at least one value of nnpfc_input_pic_filtering_flag[i] shall be greater than 0");
+#else
         CHECK(!atLeastOne, "When picRateUpsamplingFlag is equal to 0 and nnpfc_num_input_pics_minus1 is greater than 0, at least one value of nnpfc_input_pic_output_flag[i] shall be greater than 0");
+#endif
       }
       sei_read_flag(pDecodedMessageOutputStream, val, "nnpfc_absent_input_pic_zero_flag");
       sei.m_absentInputPicZeroFlag = val;
@@ -3163,8 +3176,13 @@ void SEIReader::xParseSEINNPostFilterCharacteristics(SEINeuralNetworkPostFilterC
   {
     while (!isByteAligned())
     {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+      sei_read_flag( pDecodedMessageOutputStream,   val,    "nnpfc_alignment_zero_bit");
+      CHECK (val != 0, "nnpfc_alignment_zero_bit not equal to zero");
+#else
       sei_read_flag( pDecodedMessageOutputStream,   val,    "nnpfc_reserved_zero_bit");
       CHECK (val != 0, "nnpfc_reserved_zero_bit not equal to zero");
+#endif
     }
 
     int payloadBytesRemaining = getBitstream()->getNumBitsLeft() / 8;
@@ -3199,10 +3217,18 @@ void SEIReader::xParseSEINNPostFilterActivation(SEINeuralNetworkPostFilterActiva
 
   if(!sei.m_cancelFlag)
   {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+    sei_read_flag( pDecodedMessageOutputStream, val, "nnpfa_persistence_flag" );
+    sei.m_persistenceFlag = val;
+    sei_read_flag( pDecodedMessageOutputStream, val, "nnpfa_target_base_flag" );
+    sei.m_targetBaseFlag = val;
+#else
     sei_read_flag( pDecodedMessageOutputStream, val, "nnpfa_target_base_flag" );
     sei.m_targetBaseFlag = val;
     sei_read_flag( pDecodedMessageOutputStream, val, "nnpfa_persistence_flag" );
     sei.m_persistenceFlag = val;
+#endif
+
     sei_read_uvlc( pDecodedMessageOutputStream, val, "nnpfa_num_output_entries" );
     uint32_t numOutputEntries = val;
     sei.m_outputFlag.resize(numOutputEntries);
diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp
index 04f588588..d893d0885 100644
--- a/source/Lib/EncoderLib/SEIEncoder.cpp
+++ b/source/Lib/EncoderLib/SEIEncoder.cpp
@@ -1514,8 +1514,13 @@ void SEIEncoder::initSEINeuralNetworkPostFilterActivation(SEINeuralNetworkPostFi
   sei->m_cancelFlag  = m_pcCfg->getNnPostFilterSEIActivationCancelFlag();
   if(!sei->m_cancelFlag)
   {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+    sei->m_persistenceFlag = m_pcCfg->getNnPostFilterSEIActivationPersistenceFlag();
+    sei->m_targetBaseFlag = m_pcCfg->getNnPostFilterSEIActivationTargetBaseFlag();
+#else
     sei->m_targetBaseFlag = m_pcCfg->getNnPostFilterSEIActivationTargetBaseFlag();
     sei->m_persistenceFlag = m_pcCfg->getNnPostFilterSEIActivationPersistenceFlag();
+#endif
     sei->m_outputFlag = m_pcCfg->getNnPostFilterSEIActivationOutputFlag();
   }
 }
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index 6c50bc3dc..6dfa0c1e0 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -1689,7 +1689,11 @@ void SEIWriter::xWriteSEINeuralNetworkPostFilterCharacteristics(const SEINeuralN
   {
     while (!isByteAligned())
     {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+      xWriteFlag(0, "nnpfc_alignment_zero_bit");
+#else
       xWriteFlag(0, "nnpfc_reserved_zero_bit");
+#endif
     }
     xWriteString(sei.m_uriTag, "nnpfc_uri_tag");
     xWriteString(sei.m_uri, "nnpfc_uri");
@@ -1703,7 +1707,11 @@ void SEIWriter::xWriteSEINeuralNetworkPostFilterCharacteristics(const SEINeuralN
     {
       for (int i = 0; i <= sei.m_numberInputDecodedPicturesMinus1; ++i)
       {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+        xWriteFlag(sei.m_inputPicOutputFlag[i], "nnpfc_input_pic_filtering_flag");
+#else
         xWriteFlag(sei.m_inputPicOutputFlag[i], "nnpfc_input_pic_output_flag");
+#endif
       }
       xWriteFlag(sei.m_absentInputPicZeroFlag, "nnpfc_absent_input_pic_zero_flag");
     }
@@ -1838,7 +1846,11 @@ void SEIWriter::xWriteSEINeuralNetworkPostFilterCharacteristics(const SEINeuralN
   {
     while (!isByteAligned())
     {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+      xWriteFlag(0, "nnpfc_alignment_zero_bit");
+#else
       xWriteFlag(0, "nnpfc_reserved_zero_bit");
+#endif
     }
     for (long i = 0; i < sei.m_payloadLength; i++)
     {
@@ -1854,8 +1866,13 @@ void SEIWriter::xWriteSEINeuralNetworkPostFilterActivation(const SEINeuralNetwor
   xWriteFlag(sei.m_cancelFlag, "nnpfa_cancel_flag");
   if(!sei.m_cancelFlag)
   {
+#if JVET_AE0126_NNPF_EDITORIAL_CHANGES
+    xWriteFlag(sei.m_persistenceFlag, "nnpfa_persistence_flag");
+    xWriteFlag(sei.m_targetBaseFlag, "nnpfa_target_base_flag");
+#else
     xWriteFlag(sei.m_targetBaseFlag, "nnpfa_target_base_flag");
     xWriteFlag(sei.m_persistenceFlag, "nnpfa_persistence_flag");
+#endif
     xWriteUvlc((uint32_t)sei.m_outputFlag.size(), "nnpfa_num_output_entries");
     for (uint32_t i = 0; i < (uint32_t)sei.m_outputFlag.size(); i++)
     {
-- 
GitLab