diff --git a/cfg/sei_vui/modality_information.cfg b/cfg/sei_vui/modality_information.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..a4393e5f4037ec8ed84f154d2d1a4c2a3300a09f
--- /dev/null
+++ b/cfg/sei_vui/modality_information.cfg
@@ -0,0 +1,10 @@
+#======== Modality Information SEI message =====================
+SEIModalityInfoEnabled:                    1        #Enabling Modality Information flag
+SEIMiCancelFlag:                           0        #Indicates that Modality Information SEI message cancels the persistence or follows
+SEIMiPersistenceFlag:                      1        #Specifies the persistence of the Modality Information SEI message
+SEIMiModalityType:                         1        #Specifies the type of modality. 0: unspecified; 1: visible picture; 2: Infrared Picture; 3: Ultraviolet Picture
+SEIMiSpectrumRangePresentFlag:             0        #Specifies the presence of the spectrum band of the optical radiation wavelength    
+SEIMiMinWavelengthMantissa:                0        #Specifies the mantissa part of the minimum wavelength indicating the spectral band of optical radiation
+SEIMiMinWavelengthExponentPlus15:          0        #Specifies the exponent part of the minimum wavelength indicating the spectral band of optical radiation
+SEIMiMaxWavelengthMantissa:                0        #Specifies the mantissa part of the maximum wavelength indicating the spectral band of optical radiation
+SEIMiMaxWavelengthExponentPlus15:          0        #Specifies the exponent part of the maximum wavelength indicating the spectral band of optical radiation
diff --git a/cfg/sei_vui/text_description_information.cfg b/cfg/sei_vui/text_description_information.cfg
index c694f5bd9aa0daf32aa0bc3b57791a6055417a2a..8029609717a4b6fd05aa2480db7d564ce9c9bdc4 100644
--- a/cfg/sei_vui/text_description_information.cfg
+++ b/cfg/sei_vui/text_description_information.cfg
@@ -1,8 +1,9 @@
 #======== Text Description Information SEI message =====================
-SEITextDescriptionID:                                              1 # Indentifier value of this text description information SEI message, must be in the range 1 -16383
-SEITextDescriptionCancelFlag:                                  0 # if 0 cancels the persistence of any previous text description information SEI message with the same txt_descr_id
+SEITextDescriptionID:                                        1 # Indentifier value of this text description information SEI message, must be in the range 1 -16383
+SEITextDescriptionCancelFlag:                                0 # if 1 cancels the persistence of any previous text description information SEI message with the same txt_descr_id
+SEITextDescriptionIDCancelFlag:                              0 # if 1 cancels the persistence of any previous text description information SEI message with the same txt_descr_id and the same txt_descr_purpose
 SEITextDescriptionPersistenceFlag:                           1 # if 1 enables the the persistence of the text information description message for the current layer
-SEITextDescriptionPurpose:                                      1 # Indicates the purpose of the text description, must be in the range 0-5
-SEITextDescriptionsNumStringsMinus1:                     0 # Specifies the number of entries plus 1 for  SEITextDescriptionStringLang[i] and SEITextDescriptionString[i]
-SEITextDescriptionStringLang0:                         en-US # Specifies the language of the txt_descr_string[ i ]
-SEITextDescriptionString0:                                   test # Specifies i-th text description information string
+SEITextDescriptionPurpose:                                   1 # Indicates the purpose of the text description, must be in the range 0-5
+SEITextDescriptionsNumStringsMinus1:                         0 # Specifies the number of entries plus 1 for  SEITextDescriptionStringLang[i] and SEITextDescriptionString[i]
+SEITextDescriptionStringLang0:                           en-US # Specifies the language of the txt_descr_string[ i ]
+SEITextDescriptionString0:                                test # Specifies i-th text description information string
diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index 0d7d31d1f0711bcf268c770de2ae7a3b22fab6c3..cb20c45ca463d9d23561641a331be87aca46f54d 100644
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -4025,6 +4025,7 @@ The table below lists the SEI messages defined for Version 1 and Range-Extension
   212 & Phase indication                         & Table \ref{tab:sei-phase-indication} \\
   213 & Processing order SEI messages            & Table \ref{tab:sei-processing order}\\
   216 & Source Picture Timing Information        & Table \ref{tab:sei-source-picture-timing-info}\\
+  218 & Modality Information SEI messages        & Table \ref{tab:sei-modality-info}\\
 \end{SEIListTable}
 %%
 %% SEI messages
@@ -6188,9 +6189,13 @@ Specifies type of information the of privacy protection optimization that is app
 \Default{1} &
 Specifies the identifier value of this text description SEI message, valid range is 1-16383.
 \\
+\Option{SEITextDescriptionIDCancelFlag} &
+\Default{true} &
+Indicates that the text description information SEI cancels the persistence of previous text description SEI with the same txt_desc_id and the same txt_descr_purpose.
+\\
 \Option{SEITextDescriptionCancelFlag} &
 \Default{true} &
-Indicates that the test description information SEI cancels the persistence of previous text description SEI with the same txt_desc_id.
+Indicates that the text description information SEI cancels the persistence of previous text description SEI with the same txt_descr_purpose.
 \\
 \Option{SEITextDescriptionPersistenceFlag} &
 \Default{true} &
@@ -6246,6 +6251,52 @@ Specifies the number of time units that pass in one second.
 Specifies the number of time units of a clock operating at the frequency spti_time_scale Hz that corresponds to the indicated elemental source picture interval of consecutive pictures in output order in the CLVS.
 \\
 \end{OptionTableNoShorthand}
+
+\begin{OptionTableNoShorthand}{Modality Information SEI messages }{tab:sei-modality-info}
+\Option{SEIModalityInfoEnabled} &
+\Default{true} &
+Enables (true) or disables (false) the insertion of modality information SEI message.
+\\
+\Option{SEIMiCancelFlag} &
+\Default{false} &
+Indicates that modality information SEI message cancels the persistence (true) or follows (false).
+\\
+\Option{SEIMiPersistenceFlag} &
+\Default{true} &
+Specifies the persistence of the Modality Information SEI message.
+\\
+\Option{SEIMiModalityType} &
+\Default{1} &
+Specifies the type of modality
+\par
+\begin{tabular}{cp{0.35\textwidth}}
+0 & Unspecified \\
+1 & Visible picture \\
+2 & Infrared Picture \\
+3 & Ultraviolet Picture \\
+\end{tabular}
+\\
+\Option{SEIMiSpectrumRangePresentFlag} &
+\Default{false} &
+Specifies the presence of the spectrum band of the optical radiation wavelength.
+\\
+\Option{SEIMiMinWavelengthMantissa} &
+\Default{0} &
+Specifies the mantissa part of the minimum wavelength indicating the spectral band of optical radiation.
+\\
+\Option{SEIMiMinWavelengthExponentPlus15} &
+\Default{0} &
+Specifies the exponent part of the minimum wavelength indicating the spectral band of optical radiation.
+\\
+\Option{SEIMiMaxWavelengthMantissa} &
+\Default{0} &
+Specifies the mantissa part of the maximum wavelength indicating the spectral band of optical radiation.
+\\
+\Option{SEIMiMaxWavelengthExponentPlus15} &
+\Default{0} &
+Specifies the exponent part of the maximum wavelength indicating the spectral band of optical radiation.
+\\
+\end{OptionTableNoShorthand}
 %\Option{SEITimeCode} &
 %\Default{false} &
 %When true, generate time code SEI messages.
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 386a68eef8d6a42c887771d9879d8e2a7dcbc138..2c0af94e3b55a80bd89154f7edd239144ecce27b 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -1134,6 +1134,18 @@ void EncApp::xInitLibCfg( int layerIdx )
   m_cEncLib.setEOISEISpatialResamplingTypeFlag(m_eoiSEISpatialResamplingTypeFlag);
   m_cEncLib.setEOISEIPrivacyProtectionTypeIdc(m_eoiSEIPrivacyProtectionTypeIdc);
   m_cEncLib.setEOISEIPrivacyProtectedInfoType(m_eoiSEIPrivacyProtectedInfoType);
+#endif
+#if JVET_AG0322_MODALITY_INFORMATION
+  // Modality Information SEI
+  m_cEncLib.setMiSEIEnabled                                      (m_miSEIEnabled);
+  m_cEncLib.setMiCancelFlag                                      (m_miCancelFlag);
+  m_cEncLib.setMiPersistenceFlag                                 (m_miPersistenceFlag);
+  m_cEncLib.setMiModalityType                                    (m_miModalityType);
+  m_cEncLib.setMiSpectrumRangePresentFlag                        (m_miSpectrumRangePresentFlag);
+  m_cEncLib.setMiMinWavelengthMantissa                           (m_miMinWavelengthMantissa);
+  m_cEncLib.setMiMinWavelengthExponentPlus15                     (m_miMinWavelengthExponentPlus15);
+  m_cEncLib.setMiMaxWavelengthMantissa                           (m_miMaxWavelengthMantissa);
+  m_cEncLib.setMiMaxWavelengthExponentPlus15                     (m_miMaxWavelengthExponentPlus15);
 #endif
   // content colour volume SEI
   m_cEncLib.setCcvSEIEnabled                                     (m_ccvSEIEnabled);
@@ -1453,6 +1465,9 @@ void EncApp::xInitLibCfg( int layerIdx )
  #if JVET_AH2006_TXTDESCRINFO_SEI
   m_cEncLib.setTextDescriptionSEIId(m_SEITextDescriptionID);
   m_cEncLib.setTextSEICancelFlag(m_SEITextCancelFlag);
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+  m_cEncLib.setTextSEIIDCancelFlag(m_SEITextIDCancelFlag);
+#endif
   m_cEncLib.setTextSEIPersistenceFlag(m_SEITextPersistenceFlag);
   m_cEncLib.setTextSEIPurpose(m_SEITextDescriptionPurpose);
   m_cEncLib.setTextSEINumStringsMinus1(m_SEITextNumStringsMinus1);
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 8705f04ae2f3521a6147ebb250d0a9267f436b3e..a5402d7bbac73a5cb4d959c00246547849eca9c9 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1531,6 +1531,20 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 ("SEIEOIPrivacyProtectedInfoType", m_eoiSEIPrivacyProtectedInfoType, 0u, "indicates the types of protected information")
 #endif 
 
+#if JVET_AG0322_MODALITY_INFORMATION
+// Modality Information SEI 
+  ("SEIModalityInfoEnabled",                          m_miSEIEnabled,                                    false, "Control generation of Modality Information SEI messages")
+  ("SEIMiCancelFlag",                                 m_miCancelFlag,                                    false, "Indicates that Modality Information SEI message cancels the persistence or follows")
+  ("SEIMiPersistenceFlag",                            m_miPersistenceFlag,                                true, "Specifies the persistence of the Modality Information SEI message")
+  ("SEIMiModalityType",                               m_miModalityType,                                      1, "Specifies the type of modality. 0: unspecified; 1: visible picture; 2: Infrared Picture; 3: Ultraviolet Picture")
+  ("SEIMiSpectrumRangePresentFlag",                   m_miSpectrumRangePresentFlag,                      false, "Specifies the presence of the spectrum band of the optical radiation wavelength")
+  ("SEIMiMinWavelengthMantissa",                      m_miMinWavelengthMantissa,                             0, "Specifies the mantissa part of the minimum wavelength indicating the spectral band of optical radiation")
+  ("SEIMiMinWavelengthExponentPlus15",                m_miMinWavelengthExponentPlus15,                       0, "Specifies the exponent part of the minimum wavelength indicating the spectral band of optical radiation")
+  ("SEIMiMaxWavelengthMantissa",                      m_miMaxWavelengthMantissa,                             0, "Specifies the mantissa part of the maximum wavelength indicating the spectral band of optical radiation")
+  ("SEIMiMaxWavelengthExponentPlus15",                m_miMaxWavelengthExponentPlus15,                       0, "Specifies the exponent part of the maximum wavelength indicating the spectral band of optical radiation")
+#endif
+
+
 // film grain characteristics SEI
   ("SEIFGCEnabled",                                   m_fgcSEIEnabled,                                   false, "Control generation of the film grain characteristics SEI message")
   ("SEIFGCCancelFlag",                                m_fgcSEICancelFlag,                                 true, "Specifies the persistence of any previous film grain characteristics SEI message in output order.")
@@ -2098,7 +2112,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 
 #if JVET_AH2006_TXTDESCRINFO_SEI
   opts.addOptions()("SEITextDescriptionID", m_SEITextDescriptionID, 1u, "Identifier value of this text description information SEI message, must be in the range 1-16383");
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+  opts.addOptions()("SEITextDescriptionCancelFlag", m_SEITextCancelFlag, true, "Cancels the persistence of any previous text description information SEI message with the same txt_descr_purpose");
+  opts.addOptions()("SEITextDescriptionIDCancelFlag", m_SEITextIDCancelFlag, true, "Cancels the persistence of any previous text description information SEI message with the same txt_descr_id and the same txt_descr_purpose");
+#else
   opts.addOptions()("SEITextDescriptionCancelFlag", m_SEITextCancelFlag, true, "Cancels the persistence of any previous text description information SEI message with the same txt_descr_id");
+#endif
   opts.addOptions()("SEITextDescriptionPersistenceFlag", m_SEITextPersistenceFlag, true, "Specifies the persistence of the text information description message for the current layer");
   opts.addOptions()("SEITextDescriptionPurpose", m_SEITextDescriptionPurpose, 0u, "Indicates the purpose of the text description, must be in the range 0-5");
   opts.addOptions()("SEITextDescriptionsNumStringsMinus1", m_SEITextNumStringsMinus1, 0u, "Indicates the number of entries plus 1 for txt_descr_string_lang[ i ] and txt_descr_string[ i ]");
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 772e92f8d8fcf3678a8a260e5a8fda203e66fd87..2b58fcea3abf2370a635d7d5341790d43b8008a4 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -560,6 +560,18 @@ protected:
   uint32_t m_eoiSEIPrivacyProtectedInfoType;
 #endif 
 
+#if JVET_AG0322_MODALITY_INFORMATION
+  bool      m_miSEIEnabled;
+  bool      m_miCancelFlag;
+  bool      m_miPersistenceFlag;
+  int       m_miModalityType; 
+  bool      m_miSpectrumRangePresentFlag;
+  int       m_miMinWavelengthMantissa; 
+  int       m_miMinWavelengthExponentPlus15; 
+  int       m_miMaxWavelengthMantissa; 
+  int       m_miMaxWavelengthExponentPlus15; 
+#endif
+
   // film grain characterstics sei
   bool      m_fgcSEIEnabled;
   bool      m_fgcSEICancelFlag;
@@ -869,6 +881,9 @@ protected:
 
   bool                 m_postFilterHintSEIEnabled;
   bool                 m_postFilterHintSEICancelFlag;
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+  bool                 m_SEITextIDCancelFlag;
+#endif
   bool                 m_postFilterHintSEIPersistenceFlag;
   uint32_t             m_postFilterHintSEISizeY;
   uint32_t             m_postFilterHintSEISizeX;
diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp
index 7971342802e899b4c19d4e2a88a8cb1fae972afc..4e9de5d13f85992ee27e246238546b5a54d8a2fd 100644
--- a/source/Lib/CommonLib/SEI.cpp
+++ b/source/Lib/CommonLib/SEI.cpp
@@ -486,6 +486,9 @@ static const std::map<SEI::PayloadType, const char *> payloadTypeStrings = {
 #if JVET_AG2034_SPTI_SEI
   { SEI::PayloadType::SOURCE_PICTURE_TIMING_INFO, "Source picture timing info" },
 #endif
+#if JVET_AG0322_MODALITY_INFORMATION
+  { SEI::PayloadType::MODALITY_INFORMATION, "Modality information" }
+#endif
 };
 
 const char *SEI::getSEIMessageString(SEI::PayloadType payloadType)
@@ -731,16 +734,6 @@ SEIPhaseIndication::SEIPhaseIndication(const SEIPhaseIndication& sei)
   m_verPhaseDenMinus1 = sei.m_verPhaseDenMinus1;
 }
 
-SEIuserDataUnregistered::SEIuserDataUnregistered(const SEIuserDataUnregistered& sei)
-{
-  std::memcpy(uuid_iso_iec_11578, sei.uuid_iso_iec_11578, sizeof(sei.uuid_iso_iec_11578));
-  userDataLength = sei.userDataLength;
-  if (nullptr != userData)
-  {
-    userData = new uint8_t(*sei.userData);
-  }
-}
-
 SEIDecodedPictureHash::SEIDecodedPictureHash(const SEIDecodedPictureHash& sei)
 {
   method = sei.method;
@@ -1139,6 +1132,9 @@ SEIPostFilterHint::SEIPostFilterHint(const SEIPostFilterHint& sei)
   {
     m_textDescriptionID = sei.m_textDescriptionID;
     m_textCancelFlag = sei.m_textCancelFlag;
+  #if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+    m_textIDCancelFlag = sei.m_textIDCancelFlag;
+#endif
     m_textPersistenceFlag = sei.m_textPersistenceFlag;
     m_textDescriptionPurpose = sei.m_textDescriptionPurpose;
     m_textNumStringsMinus1 = sei.m_textNumStringsMinus1;
@@ -1202,3 +1198,18 @@ SEIEncoderOptimizationInfo::SEIEncoderOptimizationInfo(
 }
 #endif
 
+#if JVET_AG0322_MODALITY_INFORMATION
+SEIModalityInfo::SEIModalityInfo(const SEIModalityInfo& sei)
+{
+  m_miCancelFlag = sei.m_miCancelFlag;
+  m_miPersistenceFlag = sei.m_miPersistenceFlag;
+  m_miModalityType = sei.m_miModalityType;
+  m_miSpectrumRangePresentFlag = sei.m_miSpectrumRangePresentFlag;
+  m_miMinWavelengthMantissa = sei.m_miMinWavelengthMantissa;
+  m_miMinWavelengthExponentPlus15 = sei.m_miMinWavelengthExponentPlus15;
+  m_miMaxWavelengthMantissa = sei.m_miMaxWavelengthMantissa;
+  m_miMaxWavelengthExponentPlus15 = sei.m_miMaxWavelengthExponentPlus15;
+}
+#endif
+
+
diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h
index 9588ae36a3ee6782edea4a223304b4ae36c854c5..7486df67b20c6375968f28678befaff58cd4e543 100644
--- a/source/Lib/CommonLib/SEI.h
+++ b/source/Lib/CommonLib/SEI.h
@@ -110,6 +110,9 @@ public:
 #if JVET_AI0153_OMI_SEI
     OBJECT_MASK_INFO = 217,
 #endif
+#if JVET_AG0322_MODALITY_INFORMATION
+    MODALITY_INFORMATION = 218,
+#endif
 #if JVET_AH2006_TXTDESCRINFO_SEI
     SEI_TEXT_DESCRIPTION                       = 219,
 #endif
@@ -589,25 +592,20 @@ public:
   int                   m_verPhaseDenMinus1;
 };
 
-static constexpr uint32_t ISO_IEC_11578_LEN=16;
-
-class SEIuserDataUnregistered : public SEI
+class SEIUserDataUnregistered : public SEI
 {
 public:
   PayloadType payloadType() const { return PayloadType::USER_DATA_UNREGISTERED; }
 
-  SEIuserDataUnregistered()
-    {}
-  SEIuserDataUnregistered(const SEIuserDataUnregistered& sei);
+  SEIUserDataUnregistered() {}
+  SEIUserDataUnregistered(const SEIUserDataUnregistered& sei) = default;
 
-  virtual ~SEIuserDataUnregistered()
-  {
-    delete userData;
-  }
+  virtual ~SEIUserDataUnregistered() {}
 
-  uint8_t uuid_iso_iec_11578[ISO_IEC_11578_LEN];
-  uint32_t  userDataLength;
-  uint8_t *userData = nullptr;
+  static constexpr uint32_t ISO_IEC_11578_LEN = 16;
+
+  std::array<uint8_t, ISO_IEC_11578_LEN> uuid;
+  std::vector<uint8_t>                   data;
 };
 
 class SEIDecodedPictureHash : public SEI
@@ -1588,6 +1586,9 @@ public:
 
   uint16_t                 m_textDescriptionID;
   bool                     m_textCancelFlag;
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+  bool                     m_textIDCancelFlag;
+#endif
   bool                     m_textPersistenceFlag;
   uint8_t                  m_textDescriptionPurpose;
   uint8_t                  m_textNumStringsMinus1;
@@ -1646,6 +1647,37 @@ public:
 };
 
 #endif
+
+#if JVET_AG0322_MODALITY_INFORMATION
+class SEIModalityInfo : public SEI
+{
+public:
+  PayloadType payloadType() const { return PayloadType::MODALITY_INFORMATION; }
+  SEIModalityInfo() 
+    : m_miCancelFlag(false)
+    , m_miPersistenceFlag(true)
+    , m_miModalityType(1)
+    , m_miSpectrumRangePresentFlag(false)
+    , m_miMinWavelengthMantissa(0)
+    , m_miMinWavelengthExponentPlus15(0)
+    , m_miMaxWavelengthMantissa(0)
+    , m_miMaxWavelengthExponentPlus15(0)
+  { }
+  SEIModalityInfo(const SEIModalityInfo& sei);
+
+  virtual ~SEIModalityInfo() { }
+
+  bool             m_miCancelFlag;
+  bool             m_miPersistenceFlag;
+  uint8_t          m_miModalityType;  
+  bool             m_miSpectrumRangePresentFlag; 
+  uint16_t         m_miMinWavelengthMantissa; 
+  uint8_t          m_miMinWavelengthExponentPlus15; 
+  uint16_t         m_miMaxWavelengthMantissa;  
+  uint8_t          m_miMaxWavelengthExponentPlus15;  
+};
+#endif
+
 //! \}
 
 
diff --git a/source/Lib/CommonLib/SEINeuralNetworkPostFiltering.cpp b/source/Lib/CommonLib/SEINeuralNetworkPostFiltering.cpp
index 31c08b1367835703c7525641301987a42fccfeac..dd3834f98d72953c138115469d9ee58afabae2be 100644
--- a/source/Lib/CommonLib/SEINeuralNetworkPostFiltering.cpp
+++ b/source/Lib/CommonLib/SEINeuralNetworkPostFiltering.cpp
@@ -186,6 +186,15 @@ void SEINeuralNetworkPostFiltering::filterPictures(PicList& picList)
     for (auto sei : currCodedPic->m_nnpfcActivated)
     {
       auto currNnpfc = (SEINeuralNetworkPostFilterCharacteristics*) sei;
+#if JVET_AI0061_PROPOSAL2_SPATIAL_EXTRAPOLATION
+      if ((currNnpfc->m_purpose & NNPC_PurposeType::SPATIAL_EXTRAPOLATION) != 0)
+      {
+        currNnpfc->m_overlap = 0;
+        currNnpfc->m_constantPatchSizeFlag = 1;
+        currNnpfc->m_patchWidthMinus1 = croppedWidth - 1;
+        currNnpfc->m_patchHeightMinus1 = croppedHeight - 1;
+      }
+#endif
       checkInputPics(currCodedPic, currNnpfc, sourceWidth, sourceHeight, croppedWidth, croppedHeight);
     }
 
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index cf9b9b7459571f051bce1ef644cd645f2d72b952..0de9dfe13daf00b48b66c94ce2693ff5a0c62bb0 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -70,6 +70,8 @@
 
 #define JVET_AI0153_OMI_SEI 1 // JVET-AI0153: OMI-SEI Implementation as JVET-AH0346
 
+#define JVET_AI0061_PROPOSAL2_SPATIAL_EXTRAPOLATION 1 // JVET AI0061-Proposal2: Ensure spatial extrapolation works correctly (Option 1)
+
 //########### place macros to be be kept below this line ###############
 
 #define GDR_ENABLED   1
@@ -92,9 +94,15 @@
 
 #define JVET_AH2006_EOI_SEI                               1 // Implementation of Encoder Optimizaion Information SEI message 
 
+#define JVET_AG0322_MODALITY_INFORMATION                  1 // Implementation of Modality Information SEI message
+
 #define NNPFC_SPATIAL_EXTRAPOLATION                       1 // Implementation of the spatial extrapolation purpose
 
 #define JVET_AH2006_TXTDESCRINFO_SEI                      1 // Text description information message 
+#if JVET_AH2006_TXTDESCRINFO_SEI
+#define JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE          1 // Define persistence scop for text description information SEI to be purpose specific
+#endif
+
 
 #define REUSE_CU_RESULTS                                  1
 #if REUSE_CU_RESULTS
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 63ec52e31432f65c38db5a0b3546d0aad4356f83..505f8a2f4d9873d6e9de9d581f30ec8ce04eb3c0 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -2201,8 +2201,8 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
 
   if (pInfo->numCand < AMVP_MAX_NUM_CANDS)
   {
-    const int currRefPOC = cs.slice->getRefPic(eRefPicList, refIdx)->getPOC();
-    addAMVPHMVPCand(pu, eRefPicList, currRefPOC, *pInfo);
+    Picture* currRefPic = cs.slice->getRefPic(eRefPicList, refIdx);
+    addAMVPHMVPCand(pu, eRefPicList, currRefPic, *pInfo);
   }
 
   if (pInfo->numCand > AMVP_MAX_NUM_CANDS)
@@ -2970,7 +2970,7 @@ bool PU::addMVPCandUnscaled(const PredictionUnit &pu, const RefPicList &eRefPicL
   return false;
 }
 
-void PU::addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList, const int currRefPOC, AMVPInfo &info)
+void PU::addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList, const Picture* currRefPic, AMVPInfo &info)
 {
   const Slice &slice = *(*pu.cs).slice;
 
@@ -3011,7 +3011,7 @@ void PU::addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList,
       const RefPicList eRefPicListIndex = (predictorSource == 0) ? eRefPicList : eRefPicList2nd;
       const int        neibRefIdx = neibMi.refIdx[eRefPicListIndex];
 
-      if (neibRefIdx >= 0 && (CU::isIBC(*pu.cu) || (currRefPOC == slice.getRefPOC(eRefPicListIndex, neibRefIdx))))
+      if (neibRefIdx >= 0 && (CU::isIBC(*pu.cu) || (currRefPic == slice.getRefPic(eRefPicListIndex, neibRefIdx))))
       {
         Mv pmv = neibMi.mv[eRefPicListIndex];
         pmv.roundTransPrecInternal2Amvr(pu.cu->imv);
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index 2bb622bd0cb726758104dcb973bfc1115464e537..1db7377025fd37b7a0712bc89d11cb4f6ef3e160 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -176,7 +176,7 @@ namespace PU
                         const PredictionUnit &pu, bool &allCandSolidInAbove
 #endif
   );
-  void addAMVPHMVPCand                (const PredictionUnit &pu, const RefPicList eRefPicList, const int currRefPOC, AMVPInfo &info);
+  void addAMVPHMVPCand                (const PredictionUnit &pu, const RefPicList eRefPicList, const Picture* currRefPic, AMVPInfo &info);
   bool addAffineMVPCandUnscaled       ( const PredictionUnit &pu, const RefPicList &refPicList, const int &refIdx, const Position &pos, const MvpDir &dir, AffineAMVPInfo &affiAmvpInfo );
   bool isBipredRestriction            (const PredictionUnit &pu);
   void spanMotionInfo                 (      PredictionUnit &pu, const MergeCtx &mrgCtx = MergeCtx() );
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index acdabd1228834a2e271a68cfa4b7b8029160e031..c3d118e200aa20fe3b29cc64ee0ac9e5d09ac417 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -307,9 +307,12 @@ bool SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       xParseSEIFillerPayload((SEIFillerPayload&) *sei, payloadSize, pDecodedMessageOutputStream);
       break;
     case SEI::PayloadType::USER_DATA_UNREGISTERED:
-      sei = new SEIuserDataUnregistered;
-      xParseSEIuserDataUnregistered((SEIuserDataUnregistered&) *sei, payloadSize, pDecodedMessageOutputStream);
-      break;
+      {
+        auto udu = new SEIUserDataUnregistered;
+        xParseSEIuserDataUnregistered(*udu, payloadSize, pDecodedMessageOutputStream);
+        sei = udu;
+        break;
+      }
     case SEI::PayloadType::DECODING_UNIT_INFO:
       {
         const SEIBufferingPeriod* bp = hrd.getBufferingPeriodSEI();
@@ -565,6 +568,12 @@ bool SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       sei = new SEISourcePictureTimingInfo;
       xParseSEISourcePictureTimingInfo((SEISourcePictureTimingInfo&) *sei, payloadSize, pDecodedMessageOutputStream);
       break;
+#endif
+#if JVET_AG0322_MODALITY_INFORMATION    
+    case SEI::PayloadType::MODALITY_INFORMATION:
+      sei = new SEIModalityInfo; 
+      xParseSEIModalityInfo((SEIModalityInfo &) *sei, payloadSize, pDecodedMessageOutputStream);
+      break;
 #endif
     default:
       for (uint32_t i = 0; i < payloadSize; i++)
@@ -586,9 +595,12 @@ bool SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
     switch (SEI::PayloadType(payloadType))
     {
     case SEI::PayloadType::USER_DATA_UNREGISTERED:
-      sei = new SEIuserDataUnregistered;
-      xParseSEIuserDataUnregistered((SEIuserDataUnregistered &) *sei, payloadSize, pDecodedMessageOutputStream);
-      break;
+      {
+        auto udu = new SEIUserDataUnregistered;
+        xParseSEIuserDataUnregistered(*udu, payloadSize, pDecodedMessageOutputStream);
+        sei = udu;
+        break;
+      }
     case SEI::PayloadType::DECODED_PICTURE_HASH:
       sei = new SEIDecodedPictureHash;
       xParseSEIDecodedPictureHash((SEIDecodedPictureHash &) *sei, payloadSize, pDecodedMessageOutputStream);
@@ -720,34 +732,30 @@ void SEIReader::xParseSEIFillerPayload(SEIFillerPayload &sei, uint32_t payloadSi
  * of payloasSize bytes into sei.
  */
 
-void SEIReader::xParseSEIuserDataUnregistered(SEIuserDataUnregistered &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+void SEIReader::xParseSEIuserDataUnregistered(SEIUserDataUnregistered& sei, uint32_t payloadSize,
+                                              std::ostream* pDecodedMessageOutputStream)
 {
-  CHECK(payloadSize < ISO_IEC_11578_LEN, "Payload too small");
+  CHECK(payloadSize < sei.uuid.size(), "Payload too small");
   uint32_t val;
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
 
-  for (uint32_t i = 0; i < ISO_IEC_11578_LEN; i++)
+  for (uint32_t i = 0; i < sei.uuid.size(); i++)
   {
-    sei_read_code( pDecodedMessageOutputStream, 8, val, "uuid_iso_iec_11578");
-    sei.uuid_iso_iec_11578[i] = val;
+    sei_read_code(pDecodedMessageOutputStream, 8, val, "uuid_iso_iec_11578");
+    sei.uuid[i] = val;
   }
 
-  sei.userDataLength = payloadSize - ISO_IEC_11578_LEN;
-  if (!sei.userDataLength)
-  {
-    sei.userData = 0;
-    return;
-  }
+  sei.data.resize(payloadSize - sei.uuid.size());
 
-  sei.userData = new uint8_t[sei.userDataLength];
-  for (uint32_t i = 0; i < sei.userDataLength; i++)
+  for (uint32_t i = 0; i < sei.data.size(); i++)
   {
     sei_read_code(nullptr, 8, val, "user_data_payload_byte");
-    sei.userData[i] = val;
+    sei.data[i] = val;
   }
+
   if (pDecodedMessageOutputStream)
   {
-    (*pDecodedMessageOutputStream) << "  User data payload size: " << sei.userDataLength << "\n";
+    (*pDecodedMessageOutputStream) << "  User data payload size: " << sei.data.size() << "\n";
   }
 }
 
@@ -2075,6 +2083,35 @@ void SEIReader::xParseSEIEncoderOptimizationInfo(SEIEncoderOptimizationInfo& sei
 }
 #endif 
 
+#if JVET_AG0322_MODALITY_INFORMATION
+void SEIReader::xParseSEIModalityInfo(SEIModalityInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  uint32_t code;
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+  sei_read_flag( pDecodedMessageOutputStream,           code,    "mi_modality_info_cancel_flag" );                      sei.m_miCancelFlag = code;
+  if (!sei.m_miCancelFlag)
+   {
+    sei_read_flag( pDecodedMessageOutputStream,         code,    "mi_modality_info_persistence_flag" );                 sei.m_miPersistenceFlag = code;
+    sei_read_code( pDecodedMessageOutputStream,     5,  code,    "mi_modality_type" );                                  sei.m_miModalityType = code;
+    sei_read_flag( pDecodedMessageOutputStream,         code,    "mi_spectrum_range_present_flag" );                    sei.m_miSpectrumRangePresentFlag = code;
+    if (sei.m_miSpectrumRangePresentFlag)
+    {
+      sei_read_code( pDecodedMessageOutputStream,  11,  code,    "mi_min_wavelength_mantissa " );                       sei.m_miMinWavelengthMantissa = code;
+      sei_read_code( pDecodedMessageOutputStream,  5,   code,    "mi_min_wavelength_exponent_plus15" );                 sei.m_miMinWavelengthExponentPlus15 = code;
+      sei_read_code( pDecodedMessageOutputStream,  11,  code,    "mi_max_wavelength_mantissa " );                       sei.m_miMaxWavelengthMantissa = code;
+      sei_read_code( pDecodedMessageOutputStream,  5,   code,    "mi_max_wavelength_exponent_plus15" );                 sei.m_miMaxWavelengthExponentPlus15 = code;
+    }
+    sei_read_uvlc(pDecodedMessageOutputStream,          code,    "mi_modality_type_extension_bits");   // mi_modality_type_extension_bits shall be equal to 0 in the current edition
+    CHECK(code > 2048, "Values of mi_modality_type_extension_bits greater than 2048 shall not be present in bitstreams");
+    for (uint32_t i = 0; i < code; i++)
+    {
+      uint32_t code2;
+      sei_read_code(pDecodedMessageOutputStream, 1, code2, "mi_reserved_modality_type_extension");   // Decoders shall ignore the presence and value of mi_reserved_modality_type_extension                                                   
+    }
+  }
+}
+#endif
+
 void SEIReader::xParseSEIFrameFieldinfo(SEIFrameFieldInfo& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
 {
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
@@ -3306,28 +3343,35 @@ void SEIReader::xParseSEINNPostFilterCharacteristics(SEINeuralNetworkPostFilterC
       CHECK(sei.m_chromaSampleLocTypeFrame > Chroma420LocType::UNSPECIFIED, "The value of nnpfc_chroma_sample_loc_type_frame shall be in the range of 0 to 6, inclusive");
     }
 
-    sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_overlap");
-    sei.m_overlap = val;
+#if JVET_AI0061_PROPOSAL2_SPATIAL_EXTRAPOLATION
+    if((sei.m_purpose & NNPC_PurposeType::SPATIAL_EXTRAPOLATION) == 0)
+    {
+#endif
+      sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_overlap");
+      sei.m_overlap = val;
 
-    sei_read_flag(pDecodedMessageOutputStream, val, "nnpfc_constant_patch_size_flag");
-    sei.m_constantPatchSizeFlag = val;
+      sei_read_flag(pDecodedMessageOutputStream, val, "nnpfc_constant_patch_size_flag");
+      sei.m_constantPatchSizeFlag = val;
 
-    if (sei.m_constantPatchSizeFlag)
-    {
-      sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_patch_width_minus1");
-      sei.m_patchWidthMinus1 = val;
+      if (sei.m_constantPatchSizeFlag)
+      {
+        sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_patch_width_minus1");
+        sei.m_patchWidthMinus1 = val;
 
-      sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_patch_height_minus1");
-      sei.m_patchHeightMinus1 = val;
-    }
-    else
-    {
-      sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_extended_patch_width_cd_delta_minus1");
-      sei.m_extendedPatchWidthCdDeltaMinus1 = val;
+        sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_patch_height_minus1");
+        sei.m_patchHeightMinus1 = val;
+      }
+      else
+      {
+        sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_extended_patch_width_cd_delta_minus1");
+        sei.m_extendedPatchWidthCdDeltaMinus1 = val;
 
-      sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_extended_patch_height_cd_delta_minus1");
-      sei.m_extendedPatchHeightCdDeltaMinus1 = val;
+        sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_extended_patch_height_cd_delta_minus1");
+        sei.m_extendedPatchHeightCdDeltaMinus1 = val;
+      }
+#if JVET_AI0061_PROPOSAL2_SPATIAL_EXTRAPOLATION
     }
+#endif
 
     sei_read_uvlc(pDecodedMessageOutputStream, val, "nnpfc_padding_type");
     sei.m_paddingType = val;
@@ -3594,25 +3638,43 @@ void SEIReader::xParseSEISourcePictureTimingInfo(SEISourcePictureTimingInfo& sei
   void SEIReader::xParseSEITextDescription(SEITextDescription &sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
   {
     uint32_t val;
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+    sei_read_code(pDecodedMessageOutputStream, 8, val, "txt_descr_purpose");
+    sei.m_textDescriptionPurpose = val;
+#else
     sei_read_code(pDecodedMessageOutputStream, 14, val, "txt_descr_id");
     sei.m_textDescriptionID = val;
+#endif
     sei_read_flag(pDecodedMessageOutputStream, val, "txt_cancel_flag");
     sei.m_textCancelFlag = val;
     if (!sei.m_textCancelFlag)
     {
-      sei_read_flag(pDecodedMessageOutputStream, val, "txt_persistence_flag");
-      sei.m_textPersistenceFlag = val;
-      sei_read_code(pDecodedMessageOutputStream, 8, val, "txt_descr_purpose");
-      sei.m_textDescriptionPurpose = val;
-      sei_read_code(pDecodedMessageOutputStream, 8, val, "txt_num_strings_minus1");
-      sei.m_textNumStringsMinus1 = val;
-      sei.m_textDescriptionStringLang.resize(sei.m_textNumStringsMinus1+1);
-      sei.m_textDescriptionString.resize(sei.m_textNumStringsMinus1+1);
-      for (int i=0; i<=sei.m_textNumStringsMinus1; i++)
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+      sei_read_code(pDecodedMessageOutputStream, 13, val, "txt_descr_id");
+      sei.m_textDescriptionID = val;
+      sei_read_flag(pDecodedMessageOutputStream, val, "txt_id_cancel_flag");
+      sei.m_textIDCancelFlag = val;
+      if (!sei.m_textIDCancelFlag)
       {
-        sei_read_string(pDecodedMessageOutputStream, sei.m_textDescriptionStringLang[i], "txt_descr_string_lang[i]");
-        sei_read_string(pDecodedMessageOutputStream, sei.m_textDescriptionString[i], "txt_descr_string[i]");
+#endif
+        sei_read_flag(pDecodedMessageOutputStream, val, "txt_persistence_flag");
+        sei.m_textPersistenceFlag = val;
+#if !JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+        sei_read_code(pDecodedMessageOutputStream, 8, val, "txt_descr_purpose");
+        sei.m_textDescriptionPurpose = val;
+#endif
+        sei_read_code(pDecodedMessageOutputStream, 8, val, "txt_num_strings_minus1");
+        sei.m_textNumStringsMinus1 = val;
+        sei.m_textDescriptionStringLang.resize(sei.m_textNumStringsMinus1+1);
+        sei.m_textDescriptionString.resize(sei.m_textNumStringsMinus1+1);
+        for (int i=0; i<=sei.m_textNumStringsMinus1; i++)
+        {
+          sei_read_string(pDecodedMessageOutputStream, sei.m_textDescriptionStringLang[i], "txt_descr_string_lang[i]");
+          sei_read_string(pDecodedMessageOutputStream, sei.m_textDescriptionString[i], "txt_descr_string[i]");
+        }
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
       }
+#endif
       
     }
   }
diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h
index 7cd24f1b8f825e9386ff9ed305b1e68cd78fe972..076d55d55680c4b114781eea22012ee1bb97a2b0 100644
--- a/source/Lib/DecoderLib/SEIread.h
+++ b/source/Lib/DecoderLib/SEIread.h
@@ -68,7 +68,8 @@ protected:
   bool xCheckNnpfcUpdatePresentSeiMsg         (uint32_t seiId,                        const std::vector<int> nnpfcValueList);
   bool 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);
-  void xParseSEIuserDataUnregistered          (SEIuserDataUnregistered &sei,          uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIuserDataUnregistered(SEIUserDataUnregistered& sei, uint32_t payloadSize,
+                                     std::ostream* pDecodedMessageOutputStream);
   void xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& dui, uint32_t payloadSize, const SEIBufferingPeriod& bp,
                                  const uint32_t temporalId, std::ostream* pDecodedMessageOutputStream);
   void xParseSEIDecodedPictureHash            (SEIDecodedPictureHash& sei,            uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
@@ -95,6 +96,9 @@ protected:
   void xParseSEIAlternativeTransferCharacteristics(SEIAlternativeTransferCharacteristics& sei,              uint32_t payLoadSize,                     std::ostream *pDecodedMessageOutputStream);
 #if JVET_AH2006_EOI_SEI
   void xParseSEIEncoderOptimizationInfo(SEIEncoderOptimizationInfo& sei, uint32_t payloadSize, std::ostream* pDecodedMessageOutputStream);
+#endif 
+#if JVET_AG0322_MODALITY_INFORMATION
+  void xParseSEIModalityInfo                  (SEIModalityInfo& sei,                  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
 #endif 
   void xParseSEIEquirectangularProjection     (SEIEquirectangularProjection &sei,     uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEISphereRotation                (SEISphereRotation &sei,                uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 91235415dcb3aed17a5a715e3d750a8fdca6db61..3356ceacb1991f64820867f808fd7635e8b7c81f 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -185,13 +185,13 @@ void VLCReader::xReadFlag( uint32_t& value, const char* )
 }
 
 #if ENABLE_TRACING || RExt__DECODER_DEBUG_BIT_STATISTICS
-void VLCReader::xReadString( std::string& value, const char *symbolName )
+void VLCReader::xReadString( std::string& valueOut, const char *symbolName )
 #else
-void VLCReader::xReadString( std::string& value, const char*  )
+void VLCReader::xReadString( std::string& valueOut, const char*  )
 #endif
 {
   uint32_t code;
-  value = "";
+  std::string value( "" );;
   do
   {
     m_pcBitstream->read(8, code);
@@ -204,6 +204,7 @@ void VLCReader::xReadString( std::string& value, const char*  )
 #if ENABLE_TRACING
   DTRACE(g_trace_ctx, D_HEADER, "%-50s u(1)  : %s\n", symbolName, value.c_str());
 #endif
+  valueOut = value;
 }
 
 #if RExt__DECODER_DEBUG_BIT_STATISTICS || ENABLE_TRACING
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 4395bc76ab549b601b488f93132d3094e8107545..f0ea7cad9f2d1e3998ba934cf07efbf30bda4cfe 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -813,6 +813,19 @@ protected:
   uint32_t m_eoiSEIPrivacyProtectedInfoType;
 #endif 
 
+#if JVET_AG0322_MODALITY_INFORMATION
+  // Modality Information SEI
+  bool        m_miSEIEnabled;
+  bool        m_miCancelFlag;
+  bool        m_miPersistenceFlag;
+  int         m_miModalityType; 
+  bool        m_miSpectrumRangePresentFlag;
+  int         m_miMinWavelengthMantissa; 
+  int         m_miMinWavelengthExponentPlus15; 
+  int         m_miMaxWavelengthMantissa; 
+  int         m_miMaxWavelengthExponentPlus15; 
+#endif 
+
   // film grain characterstics sei
   bool      m_fgcSEIEnabled;
   bool      m_fgcSEICancelFlag;
@@ -972,6 +985,9 @@ protected:
 #if JVET_AH2006_TXTDESCRINFO_SEI
   uint16_t                 m_textDescriptionSEIId;
   bool                     m_textSEICancelFlag;
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+  bool                     m_textSEIIDCancelFlag;
+#endif
   bool                     m_textSEIPersistenceFlag;
   uint8_t                  m_textSEIDescriptionPurpose;
   uint8_t                  m_textSEINumStringsMinus1;
@@ -2485,6 +2501,29 @@ public:
   void setEOISEIPrivacyProtectedInfoType(uint32_t privacyProtectedInfoType) { m_eoiSEIPrivacyProtectedInfoType = privacyProtectedInfoType; }
   uint32_t getEOISEIPrivacyProtectedInfoType() const { return m_eoiSEIPrivacyProtectedInfoType; }
 #endif 
+
+#if JVET_AG0322_MODALITY_INFORMATION
+  //Modality Information SEI 
+  void     setMiSEIEnabled(bool b) { m_miSEIEnabled = b; }
+  bool     getMiSEIEnabled()                                                                              { return m_miSEIEnabled; }
+  void     setMiCancelFlag(const bool val) { m_miCancelFlag = val; }
+  bool     getMiCancelFlag() const                                                                        { return m_miCancelFlag; }
+  void     setMiPersistenceFlag(const bool val) { m_miPersistenceFlag = val; }
+  bool     getMiPersistenceFlag() const                                                                   { return m_miPersistenceFlag; }
+  void     setMiModalityType(const int val) { m_miModalityType = val; }
+  int      getMiModalityType() const                                                                      { return m_miModalityType; }
+  void     setMiSpectrumRangePresentFlag(const bool val) { m_miSpectrumRangePresentFlag = val; }
+  bool     getMiSpectrumRangePresentFlag() const                                                          { return m_miSpectrumRangePresentFlag; }
+  void     setMiMinWavelengthMantissa(const int val) { m_miMinWavelengthMantissa = val; }
+  int      getMiMinWavelengthMantissa() const                                                             { return m_miMinWavelengthMantissa; }
+  void     setMiMinWavelengthExponentPlus15(const int val) { m_miMinWavelengthExponentPlus15 = val; }
+  int      getMiMinWavelengthExponentPlus15() const                                                       { return m_miMinWavelengthExponentPlus15; }
+  void     setMiMaxWavelengthMantissa(const int val) { m_miMaxWavelengthMantissa = val; }
+  int      getMiMaxWavelengthMantissa() const                                                             { return m_miMaxWavelengthMantissa; }
+  void     setMiMaxWavelengthExponentPlus15(const int val) { m_miMaxWavelengthExponentPlus15 = val; }
+  int      getMiMaxWavelengthExponentPlus15() const                                                       { return m_miMaxWavelengthExponentPlus15; }
+#endif
+
   // film grain SEI
   void  setFilmGrainCharactersticsSEIEnabled (bool b)                { m_fgcSEIEnabled = b; }
   bool  getFilmGrainCharactersticsSEIEnabled()                       { return m_fgcSEIEnabled; }
@@ -2788,6 +2827,10 @@ public:
   uint32_t     getTextDescriptionSEIId() {return m_textDescriptionSEIId;}
   void         setTextSEICancelFlag(bool b) {m_textSEICancelFlag = b;}
   bool         getTextSEICancelFlag() {return m_textSEICancelFlag;}
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+  void         setTextSEIIDCancelFlag(bool b) { m_textSEIIDCancelFlag = b; }
+  bool         getTextSEIIDCancelFlag() { return m_textSEIIDCancelFlag; }
+#endif
   void         setTextSEIPersistenceFlag(bool b) {m_textSEIPersistenceFlag = b;}
   bool         getTextSEIPersistenceFlag() {return m_textSEIPersistenceFlag;}
   void         setTextSEIPurpose(uint8_t i) {m_textSEIDescriptionPurpose = i;}
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 75fea0efb4a24263910d3e34bdc540e9e2f41491..be7b269e577fbcc8b603bf2f96427d8781e24248 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -1047,6 +1047,17 @@ void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessage
   }
 #endif
 
+
+#if JVET_AG0322_MODALITY_INFORMATION
+  // modality information SEI
+  if (m_pcCfg->getMiSEIEnabled())
+  {
+    SEIModalityInfo* seiMI = new SEIModalityInfo;
+    m_seiEncoder.initSEIModalityInfo(seiMI);
+    seiMessages.push_back(seiMI);
+  }
+#endif
+
   if (m_pcCfg->getNnPostFilterSEIActivationEnabled() && !m_pcCfg->getNnPostFilterSEIActivationUseSuffixSEI())
   {
     xCreateNNPostFilterActivationSEIMessage(seiMessages, slice);
diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp
index 83d8275c753bf6a37f5910c0e1b6c75731f9973e..42689af050b955164033bb0e2426463a34022e1f 100644
--- a/source/Lib/EncoderLib/SEIEncoder.cpp
+++ b/source/Lib/EncoderLib/SEIEncoder.cpp
@@ -742,6 +742,9 @@ void SEIEncoder::initSEITextDescription(SEITextDescription *seiTestDescrition)
   CHECK(!(seiTestDescrition != nullptr), "Need a seiTtestDescribtion for initialization (got nullptr)");
   seiTestDescrition->m_textDescriptionID = m_pcCfg->getTextDescriptionSEIId();
   seiTestDescrition->m_textCancelFlag = m_pcCfg->getTextSEICancelFlag();
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+  seiTestDescrition->m_textIDCancelFlag = m_pcCfg->getTextSEIIDCancelFlag();
+#endif
   seiTestDescrition->m_textPersistenceFlag = m_pcCfg->getTextSEIPersistenceFlag();
   seiTestDescrition->m_textDescriptionPurpose = m_pcCfg->getTextSEIPurpose();
   seiTestDescrition->m_textNumStringsMinus1 = m_pcCfg->getTextSEINumStringsMinus1();
@@ -1842,4 +1845,27 @@ void SEIEncoder::initSEIEncoderOptimizationInfo(SEIEncoderOptimizationInfo *sei)
 }
 #endif
 
+#if JVET_AG0322_MODALITY_INFORMATION
+void SEIEncoder::initSEIModalityInfo(SEIModalityInfo *seiMI)
+{
+  CHECK(!(m_isInitialized), "Modality Information SEI is already initialised");
+  CHECK(seiMI == nullptr, "Modality Information SEI: Cannot initialise from nullptr");
+  //  Set SEI message parameters read from command line options
+  seiMI->m_miCancelFlag = m_pcCfg->getMiCancelFlag(); 
+  if (!seiMI->m_miCancelFlag)
+  {
+    seiMI->m_miPersistenceFlag            = m_pcCfg->getMiPersistenceFlag();
+    seiMI->m_miModalityType               = m_pcCfg->getMiModalityType();
+    seiMI->m_miSpectrumRangePresentFlag   = m_pcCfg->getMiSpectrumRangePresentFlag();
+    if (seiMI->m_miSpectrumRangePresentFlag)
+    {
+      seiMI->m_miMinWavelengthMantissa         = m_pcCfg->getMiMinWavelengthMantissa();
+      seiMI->m_miMinWavelengthExponentPlus15   = m_pcCfg->getMiMinWavelengthExponentPlus15();
+      seiMI->m_miMaxWavelengthMantissa         = m_pcCfg->getMiMaxWavelengthMantissa();
+      seiMI->m_miMaxWavelengthExponentPlus15   = m_pcCfg->getMiMaxWavelengthExponentPlus15();
+    }
+  }
+}
+#endif
+
 //! \}
diff --git a/source/Lib/EncoderLib/SEIEncoder.h b/source/Lib/EncoderLib/SEIEncoder.h
index 2f22e81a9e08fd1254d52050c3dab3783787d62d..5288aea578a4669a6e3b361aa052370ec372c0d3 100644
--- a/source/Lib/EncoderLib/SEIEncoder.h
+++ b/source/Lib/EncoderLib/SEIEncoder.h
@@ -110,6 +110,9 @@ public:
 #if JVET_AH2006_EOI_SEI
   void initSEIEncoderOptimizationInfo(SEIEncoderOptimizationInfo *sei);
 #endif 
+#if JVET_AG0322_MODALITY_INFORMATION
+  void initSEIModalityInfo(SEIModalityInfo *sei);
+#endif
 #if JVET_AH2006_TXTDESCRINFO_SEI
   void initSEITextDescription(SEITextDescription *sei);
 #endif
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index 2f0086fa2dd80e4d186e60a53e94c98d1258c06e..5ccaf963d78fecc047461c5b0b7c330355d2fb4e 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -48,7 +48,7 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream &bs, const SEI &sei, HRD &h
   switch (sei.payloadType())
   {
   case SEI::PayloadType::USER_DATA_UNREGISTERED:
-    xWriteSEIuserDataUnregistered(*static_cast<const SEIuserDataUnregistered*>(&sei));
+    xWriteSEIuserDataUnregistered(reinterpret_cast<const SEIUserDataUnregistered&>(sei));
     break;
   case SEI::PayloadType::DECODING_UNIT_INFO:
     bp = hrd.getBufferingPeriodSEI();
@@ -206,6 +206,11 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream &bs, const SEI &sei, HRD &h
     xWriteSEISourcePictureTimingInfo(*static_cast<const SEISourcePictureTimingInfo*>(&sei));
     break;
 #endif
+#if JVET_AG0322_MODALITY_INFORMATION
+  case SEI::PayloadType::MODALITY_INFORMATION:
+    xWriteSEIModalityInfo(*static_cast<const SEIModalityInfo *>(&sei));
+    break;
+#endif 
 #if JVET_AH2006_TXTDESCRINFO_SEI
   case SEI::PayloadType::SEI_TEXT_DESCRIPTION:
     xWriteSEITextDescription(*static_cast<const SEITextDescription*>(&sei));
@@ -287,16 +292,16 @@ void SEIWriter::writeSEImessages(OutputBitstream& bs, const SEIMessages &seiList
  * marshal a user_data_unregistered SEI message sei, storing the marshalled
  * representation in bitstream bs.
  */
-void SEIWriter::xWriteSEIuserDataUnregistered(const SEIuserDataUnregistered &sei)
+void SEIWriter::xWriteSEIuserDataUnregistered(const SEIUserDataUnregistered& sei)
 {
-  for (uint32_t i = 0; i < ISO_IEC_11578_LEN; i++)
+  for (uint32_t i = 0; i < sei.uuid.size(); i++)
   {
-    xWriteCode(sei.uuid_iso_iec_11578[i], 8 , "uuid_iso_iec_11578[i]");
+    xWriteCode(sei.uuid[i], 8, "uuid_iso_iec_11578[i]");
   }
 
-  for (uint32_t i = 0; i < sei.userDataLength; i++)
+  for (uint32_t i = 0; i < sei.data.size(); i++)
   {
-    xWriteCode(sei.userData[i], 8 , "user_data_payload_byte");
+    xWriteCode(sei.data[i], 8, "user_data_payload_byte");
   }
 }
 
@@ -1993,18 +1998,25 @@ void SEIWriter::xWriteSEINeuralNetworkPostFilterCharacteristics(const SEINeuralN
       xWriteUvlc(to_underlying(sei.m_chromaSampleLocTypeFrame), "nnpfc_chroma_sample_loc_type_frame");
     }
     
-    xWriteUvlc(sei.m_overlap, "nnpfc_overlap");
-    xWriteFlag(sei.m_constantPatchSizeFlag, "nnpfc_constant_patch_size_flag");
-    if (sei.m_constantPatchSizeFlag)
+#if JVET_AI0061_PROPOSAL2_SPATIAL_EXTRAPOLATION
+    if((sei.m_purpose & NNPC_PurposeType::SPATIAL_EXTRAPOLATION) == 0)
     {
-    xWriteUvlc(sei.m_patchWidthMinus1, "nnpfc_patch_width_minus1");
-    xWriteUvlc(sei.m_patchHeightMinus1, "nnpfc_patch_height_minus1");
-    }
-    else
-    {
-      xWriteUvlc(sei.m_extendedPatchWidthCdDeltaMinus1, "extended_nnpfc_patch_width_cd_delta_minus1");
-      xWriteUvlc(sei.m_extendedPatchHeightCdDeltaMinus1, "extended_nnpfc_patch_height_cd_delta_minus1");
+#endif
+      xWriteUvlc(sei.m_overlap, "nnpfc_overlap");
+      xWriteFlag(sei.m_constantPatchSizeFlag, "nnpfc_constant_patch_size_flag");
+      if (sei.m_constantPatchSizeFlag)
+      {
+        xWriteUvlc(sei.m_patchWidthMinus1, "nnpfc_patch_width_minus1");
+        xWriteUvlc(sei.m_patchHeightMinus1, "nnpfc_patch_height_minus1");
+      }
+      else
+      {
+        xWriteUvlc(sei.m_extendedPatchWidthCdDeltaMinus1, "extended_nnpfc_patch_width_cd_delta_minus1");
+        xWriteUvlc(sei.m_extendedPatchHeightCdDeltaMinus1, "extended_nnpfc_patch_height_cd_delta_minus1");
+      }
+#if JVET_AI0061_PROPOSAL2_SPATIAL_EXTRAPOLATION
     }
+#endif
     xWriteUvlc(sei.m_paddingType, "nnpfc_padding_type");
     if (sei.m_paddingType == NNPC_PaddingType::FIXED_PADDING)
     {
@@ -2119,21 +2131,38 @@ void SEIWriter::xWriteSEINeuralNetworkPostFilterActivation(const SEINeuralNetwor
 #if JVET_AH2006_TXTDESCRINFO_SEI
 void SEIWriter::xWriteSEITextDescription(const SEITextDescription &sei)
 {
-  CHECK((sei.m_textDescriptionID < 1 || sei.m_textDescriptionID > 16383) , "text description id must be in the range 1-16383");
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+  CHECK(sei.m_textDescriptionPurpose > 5, "txt_descr_purpose shall be in the range 0-5");
+  xWriteCode(sei.m_textDescriptionPurpose, 8, "txt_descr_purpose");
+#else
+  CHECK((sei.m_textDescriptionID < 1 || sei.m_textDescriptionID > 16383), "text description id must be in the range 1-16383");
   xWriteCode(sei.m_textDescriptionID, 14, "txt_descr_id");
+#endif
   xWriteFlag(sei.m_textCancelFlag, "txt_cancel_flag");
   if (!sei.m_textCancelFlag) 
   {
-    xWriteFlag(sei.m_textPersistenceFlag, "txt_persistence_flag");
-    CHECK(sei.m_textDescriptionPurpose>5, "txt_descr_purpose shall be in the range 0-5");
-    xWriteCode(sei.m_textDescriptionPurpose, 8, "txt_descr_purpose");
-    xWriteCode(sei.m_textNumStringsMinus1, 8, "txt_num_strings_minus1");
-    for (int i=0; i<=sei.m_textNumStringsMinus1; i++)
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+    CHECK((sei.m_textDescriptionID < 1 || sei.m_textDescriptionID > 16383), "text description id must be in the range 1-16383");
+    xWriteCode(sei.m_textDescriptionID, 13, "txt_descr_id");
+    xWriteFlag(sei.m_textIDCancelFlag, "txt_id_cancel_flag");
+    if (!sei.m_textIDCancelFlag) 
     {
-      CHECK(sei.m_textDescriptionStringLang[i].length() > 49, "The length of the text description language string must be in the range 0-49");
-      xWriteString(sei.m_textDescriptionStringLang[i], "txt_descr_string_lang[i]");
-      xWriteString(sei.m_textDescriptionString[i], "txt_descr_string[i]");
+#endif
+      xWriteFlag(sei.m_textPersistenceFlag, "txt_persistence_flag");
+#if !JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
+      CHECK(sei.m_textDescriptionPurpose>5, "txt_descr_purpose shall be in the range 0-5");
+      xWriteCode(sei.m_textDescriptionPurpose, 8, "txt_descr_purpose");
+#endif
+      xWriteCode(sei.m_textNumStringsMinus1, 8, "txt_num_strings_minus1");
+      for (int i=0; i<=sei.m_textNumStringsMinus1; i++)
+      {
+        CHECK(sei.m_textDescriptionStringLang[i].length() > 49, "The length of the text description language string must be in the range 0-49");
+        xWriteString(sei.m_textDescriptionStringLang[i], "txt_descr_string_lang[i]");
+        xWriteString(sei.m_textDescriptionString[i], "txt_descr_string[i]");
+      }
+#if JVET_AI0059_TXTDESCRINFO_SEI_PERSISTANCE
     }
+#endif
   }
 }
 #endif
@@ -2239,4 +2268,26 @@ void SEIWriter::xWriteSEISourcePictureTimingInfo(const SEISourcePictureTimingInf
   }
 }
 #endif
+
+#if JVET_AG0322_MODALITY_INFORMATION
+void SEIWriter::xWriteSEIModalityInfo(const SEIModalityInfo& sei)
+{
+  xWriteFlag( sei.m_miCancelFlag,                                            "mi_modality_info_cancel_flag" );
+  if(!sei.m_miCancelFlag)
+  {
+    xWriteFlag( sei.m_miPersistenceFlag,                                     "mi_modality_info_persistence_flag" );
+    xWriteCode( (uint32_t)sei.m_miModalityType, 5,                           "mi_modality_type");
+    xWriteFlag( sei.m_miSpectrumRangePresentFlag,                            "mi_spectrum_range_present_flag" );
+    if (sei.m_miSpectrumRangePresentFlag)
+    {
+      xWriteCode( (uint32_t)sei.m_miMinWavelengthMantissa, 11,               "mi_min_wavelength_mantissa ");
+      xWriteCode( (uint32_t)sei.m_miMinWavelengthExponentPlus15, 5,          "mi_min_wavelength_exponent_plus15 ");
+      xWriteCode( (uint32_t)sei.m_miMaxWavelengthMantissa, 11,               "mi_max_wavelength_mantissa ");
+      xWriteCode( (uint32_t)sei.m_miMaxWavelengthExponentPlus15, 5,          "mi_max_wavelength_exponent_plus15 ");
+    }
+    xWriteUvlc(0, "mi_modality_type_extension_bits");   // mi_modality_type_extension_bits shall be equal to 0 in the current edition 
+  }
+}
+#endif 
+
 //! \}
diff --git a/source/Lib/EncoderLib/SEIwrite.h b/source/Lib/EncoderLib/SEIwrite.h
index 82c5755a03b5627a93b555e694790e56b6efa9ce..bbf4034026662db0960b7aee1ad623709f1b72ed 100644
--- a/source/Lib/EncoderLib/SEIwrite.h
+++ b/source/Lib/EncoderLib/SEIwrite.h
@@ -54,7 +54,7 @@ public:
   void writeSEImessages(OutputBitstream& bs, const SEIMessages &seiList, HRD &hrd, bool isNested, const uint32_t temporalId);
 
 protected:
-  void xWriteSEIuserDataUnregistered(const SEIuserDataUnregistered &sei);
+  void xWriteSEIuserDataUnregistered(const SEIUserDataUnregistered& sei);
   void xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& dui, const SEIBufferingPeriod& bp,
                                  const uint32_t temporalId);
   void xWriteSEIDecodedPictureHash(const SEIDecodedPictureHash& sei);
@@ -127,6 +127,9 @@ protected:
 #if JVET_AG2034_SPTI_SEI
   void xWriteSEISourcePictureTimingInfo(const SEISourcePictureTimingInfo& sei);
 #endif
+#if JVET_AG0322_MODALITY_INFORMATION
+  void xWriteSEIModalityInfo(const SEIModalityInfo &sei);
+#endif
 protected:
   HRD m_nestingHrd;
 };
diff --git a/source/Lib/Utilities/VideoIOYuv.cpp b/source/Lib/Utilities/VideoIOYuv.cpp
index e49e08832341ecafe776e4da181743099b729094..bba8f90bd19019d6a885ce88cb3f8cd71f5dccb5 100644
--- a/source/Lib/Utilities/VideoIOYuv.cpp
+++ b/source/Lib/Utilities/VideoIOYuv.cpp
@@ -1478,8 +1478,10 @@ bool VideoIOYuv::writeUpscaledPicture(const SPS &sps, const PPS &pps, const CPel
     else
     {
       const Window &conf = pps.getConformanceWindow();
+      int curPicWidth = maxWidth   - SPS::getWinUnitX( sps.getChromaFormatIdc() ) * ( afterScaleWindowFullResolution.getWindowLeftOffset() + afterScaleWindowFullResolution.getWindowRightOffset() );
+      int curPicHeight = maxHeight - SPS::getWinUnitY( sps.getChromaFormatIdc() ) * ( afterScaleWindowFullResolution.getWindowTopOffset()  + afterScaleWindowFullResolution.getWindowBottomOffset() );
 
-      ret = write(maxWidth, maxHeight, pic, ipCSC,
+      ret = write(curPicWidth, curPicHeight, pic, ipCSC,
                   packedYuvOutputMode, conf.getWindowLeftOffset() * SPS::getWinUnitX(chromaFormatIdc),
                   conf.getWindowRightOffset() * SPS::getWinUnitX(chromaFormatIdc),
                   conf.getWindowTopOffset() * SPS::getWinUnitY(chromaFormatIdc),