diff --git a/cfg/sei/generalized_cubemap_projection.cfg b/cfg/sei/generalized_cubemap_projection.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..82cd6d8a491d7df90875bf3cd40bd1b74cce9a83
--- /dev/null
+++ b/cfg/sei/generalized_cubemap_projection.cfg
@@ -0,0 +1,16 @@
+#======== Generalized Cubemap Projection SEI message =====================
+SEIGcmpEnabled                           : 1
+SEIGcmpCancelFlag                        : 0
+SEIGcmpPersistenceFlag                   : 1
+SEIGcmpPackingType                       : 2
+SEIGcmpMappingFunctionType               : 2
+SEIGcmpFaceIndex                         : 5 0 4 3 1 2
+SEIGcmpFaceRotation                      : 2 2 2 2 2 2
+SEIGcmpFunctionCoeffU                    : 0.28 0.28 0.28 0.28 0.28 0.28
+SEIGcmpFunctionUAffectedByVFlag          : 0 0 0 0 0 0
+SEIGcmpFunctionCoeffV                    : 0.4 0.4 0.4 0.28 0.4 0.28
+SEIGcmpFunctionVAffectedByUFlag          : 1 1 1 0 1 0
+SEIGcmpGuardBandFlag                     : 1
+SEIGcmpGuardBandBoundaryType             : 1
+SEIGcmpGuardBandSamplesMinus1            : 15
+
diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index c6f7c693ffa617d8564d41e59ec94af841350544..718b22377a0d3085ee02150dc9d4c4c9433a7cb0 100755
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -2684,6 +2684,7 @@ The table below lists the SEI messages defined for Version 1 and Range-Extension
   148 & Ambient viewing environment              & Table \ref{tab:sei-ambient-viewing-environment}\\
   149 & Content colour volume                    & Table \ref{tab:sei-content-colour-volume}\\
   150 & Equirectangular projection               & Table \ref{tab:sei-erp} \\
+  153 & Generalized cubemap projection           & Table \ref{tab:sei-gcmp} \\
   154 & Sphere rotation                          & Table \ref{tab:sei-sphere-rotation} \\
   155 & Region-wise packing                      & Table \ref{tab:sei-rwp} \\
   156 & Omni viewport                            & Table \ref{tab:sei-omni-viewport} \\  
@@ -3378,6 +3379,96 @@ Inicates the width of the guard band on the right side of the onstituent picture
 \\
 \end{OptionTableNoShorthand}
 
+\begin{OptionTableNoShorthand}{Generalized Cubemap Projection SEI message encoder parameters}{tab:sei-gcmp}
+\Option{SEIGcmpEnabled} &
+\Default{false} &
+Enables (true) or disables (false) the insertion of generalized cubemap projection SEI message.
+\\
+\Option{SEIGcmpCancelFlag} &
+\Default{true} &
+Indicates that generalized cubemap projection SEI message cancels the persistence (true) or follows (false).
+\\
+\Option{SEIGcmpPersistenceFlag} &
+\Default{false} &
+Specifies the persistence of the generalized cubemap projection SEI message.
+\\
+\Option{SEIGcmpPackingType} &
+\Default{0} &
+Specifies the packing type.
+\par
+\begin{tabular}{cp{0.35\textwidth}}
+ 0 & 6 rows and 1 columns \\
+ 1 & 3 rows and 2 columns \\
+ 2 & 2 rows and 3 columns \\
+ 3 & 1 rows and 6 columns \\
+ 4 & 1 rows and 5 columns (hemisphere cubemap) \\
+ 5 & 5 rows and 1 columns (hemisphere cubemap) \\
+\end{tabular}
+\\
+\Option{SEIGcmpMappingFunctionType} &
+\Default{0} &
+Specifies the mapping function used to adjust the sample locations.
+\par
+\begin{tabular}{cp{0.35\textwidth}}
+ 0 & Disabled (conventional cubemap projection) \\
+ 1 & Equi-angular mapping function \\
+ 2 & Defined by SEIGcmpFunctionCoeffU, SEIGcmpFunctionUAffectedByVFlag, SEIGcmpFunctionCoeffV, and SEIGcmpFunctionVAffectedByUFlag \\
+\end{tabular}
+\\
+\Option{SEIGcmpFaceIndex} &
+\Default{} &
+An array that specifies the face index for the faces packed in the cubemap projected picture.
+\par
+\begin{tabular}{cp{0.35\textwidth}}
+ 0 & Front face \\
+ 1 & Back face \\
+ 2 & Top face \\
+ 3 & Bottom face \\
+ 4 & Right face \\
+ 5 & Left face \\
+\end{tabular}
+\\
+\Option{SEIGcmpFaceRotation} &
+\Default{} &
+An array that specifies the rotation to be applied to the faces.
+\par
+\begin{tabular}{cp{0.35\textwidth}}
+ 0 & No rotation \\
+ 1 & 90 degree anticlockwise \\
+ 2 & 180 degree anticlockwise \\
+ 3 & 270 degree anticlockwise \\
+\end{tabular}
+\\
+\Option{SEIGcmpFunctionCoeffU} &
+\Default{} &
+An array that specifies the coefficients used in the cubemap mapping function of the u-axis for the faces when SEIGcmpMappingFunctionType is set to 2.
+\\
+\Option{SEIGcmpFunctionUAffectedByVFlag} &
+\Default{} &
+An array that specifies whether the cubemap mapping function of the u-axis refers to the v position of the sample location for the faces when SEIGcmpMappingFunctionType is set to 2.
+\\
+\Option{SEIGcmpFunctionCoeffV} &
+\Default{} &
+An array that specifies the coefficients used in the cubemap mapping function of the v-axis for the faces when SEIGcmpMappingFunctionType is set to 2.
+\\
+\Option{SEIGcmpFunctionVAffectedByUFlag} &
+\Default{} &
+An array that specifies whether the cubemap mapping function of the v-axis refers to the u position of the sample location for the faces when SEIGcmpMappingFunctionType is set to 2.
+\\
+\Option{SEIGcmpGuardBandFlag} &
+\Default{false} &
+Indicates the existence of guard band areas in the picture.
+\\
+\Option{SEIGcmpGuardBandBoundaryType} &
+\Default{false} &
+Enables (true) or disables (false) the boundary guard bands.
+\\
+\Option{SEIGcmpGuardBandSamplesMinus1} &
+\Default{0} &
+Specifies the number of guard band samples minus 1 used in the cubemap projected picture.
+\\
+\end{OptionTableNoShorthand}
+
 \begin{OptionTableNoShorthand}{Sphere Rotation SEI message encoder parameters}{tab:sei-sphere-rotation}
 \Option{SEISphereRotationEnabled} &
 \Default{false} &
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index c5b0eced7feeb87248bb0ebd53c4dc8cb15edab5..baf182c6bae220d1c4627111fe1a071bd951f1a6 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -737,6 +737,22 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setRwpSEIRwpGuardBandNotUsedForPredFlag              (m_rwpSEIRwpGuardBandNotUsedForPredFlag);
   m_cEncLib.setRwpSEIRwpGuardBandType                            (m_rwpSEIRwpGuardBandType);
 #endif
+#if JVET_P0597_GCMP_SEI
+  m_cEncLib.setGcmpSEIEnabled                                    ( m_gcmpSEIEnabled );
+  m_cEncLib.setGcmpSEICancelFlag                                 ( m_gcmpSEICancelFlag );
+  m_cEncLib.setGcmpSEIPersistenceFlag                            ( m_gcmpSEIPersistenceFlag );                                                              
+  m_cEncLib.setGcmpSEIPackingType                                ( (uint8_t)m_gcmpSEIPackingType );
+  m_cEncLib.setGcmpSEIMappingFunctionType                        ( (uint8_t)m_gcmpSEIMappingFunctionType );                                                              
+  m_cEncLib.setGcmpSEIFaceIndex                                  ( m_gcmpSEIFaceIndex );
+  m_cEncLib.setGcmpSEIFaceRotation                               ( m_gcmpSEIFaceRotation );
+  m_cEncLib.setGcmpSEIFunctionCoeffU                             ( m_gcmpSEIFunctionCoeffU );
+  m_cEncLib.setGcmpSEIFunctionUAffectedByVFlag                   ( m_gcmpSEIFunctionUAffectedByVFlag );
+  m_cEncLib.setGcmpSEIFunctionCoeffV                             ( m_gcmpSEIFunctionCoeffV );
+  m_cEncLib.setGcmpSEIFunctionVAffectedByUFlag                   ( m_gcmpSEIFunctionVAffectedByUFlag );                                                              
+  m_cEncLib.setGcmpSEIGuardBandFlag                              ( m_gcmpSEIGuardBandFlag );
+  m_cEncLib.setGcmpSEIGuardBandBoundaryType                      ( m_gcmpSEIGuardBandBoundaryType );
+  m_cEncLib.setGcmpSEIGuardBandSamplesMinus1                     ( (uint8_t)m_gcmpSEIGuardBandSamplesMinus1 );
+#endif
 #if JVET_P0984_SEI_SUBPIC_LEVEL
   m_cEncLib.setSubpicureLevelInfoSEIEnabled                      (m_subpicureLevelInfoSEIEnabled);
 #endif
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 30e1bb073338abdf307d7f00d324749fa6747466..0a9f80b9ad722c4b2af3803d980c2725fa292ce2 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -913,6 +913,14 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   SMultiValueInput<bool>       cfg_rwpSEIRwpGuardBandNotUsedForPredFlag   (0, 1,   0, std::numeric_limits<uint8_t>::max());
   SMultiValueInput<uint32_t>   cfg_rwpSEIRwpGuardBandType                 (0, 7,   0, 4*std::numeric_limits<uint8_t>::max());
 #endif
+#if JVET_P0597_GCMP_SEI
+  SMultiValueInput<uint32_t>   cfg_gcmpSEIFaceIndex                  (0, 5, 5, 6);
+  SMultiValueInput<uint32_t>   cfg_gcmpSEIFaceRotation               (0, 3, 5, 6);
+  SMultiValueInput<double>     cfg_gcmpSEIFunctionCoeffU             (0.0, 1.0, 5, 6);
+  SMultiValueInput<uint32_t>   cfg_gcmpSEIFunctionUAffectedByVFlag   (0, 1, 5, 6);
+  SMultiValueInput<double>     cfg_gcmpSEIFunctionCoeffV             (0.0, 1.0, 5, 6);
+  SMultiValueInput<uint32_t>   cfg_gcmpSEIFunctionVAffectedByUFlag   (0, 1, 5, 6);
+#endif
 #if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
   const int defaultLadfQpOffset[3] = { 1, 0, 1 };
   const int defaultLadfIntervalLowerBound[2] = { 350, 833 };
@@ -1633,6 +1641,22 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("SEIRwpGuardBandNotUsedForPredFlag",               cfg_rwpSEIRwpGuardBandNotUsedForPredFlag, cfg_rwpSEIRwpGuardBandNotUsedForPredFlag, "Specifies if the guard bands is used in the inter prediction process.")
   ("SEIRwpGuardBandType",                             cfg_rwpSEIRwpGuardBandType,               cfg_rwpSEIRwpGuardBandType,               "Specifies the type of the guard bands for the i-th packed region.")
 #endif
+#if JVET_P0597_GCMP_SEI
+  ("SEIGcmpEnabled",                                  m_gcmpSEIEnabled,                         false,                                    "Control generation of generalized cubemap projection SEI messages")
+  ("SEIGcmpCancelFlag",                               m_gcmpSEICancelFlag,                      true,                                     "Indicate that generalized cubemap projection SEI message cancels the persistence or follows")
+  ("SEIGcmpPersistenceFlag",                          m_gcmpSEIPersistenceFlag,                 false,                                    "Specifies the persistence of the generalized cubemap projection SEI messages")
+  ("SEIGcmpPackingType",                              m_gcmpSEIPackingType,                     0u,                                       "Specifies the packing type")
+  ("SEIGcmpMappingFunctionType",                      m_gcmpSEIMappingFunctionType,             0u,                                       "Specifies the mapping function used to adjust the sample locations of the cubemap projection")
+  ("SEIGcmpFaceIndex",                                cfg_gcmpSEIFaceIndex,                     cfg_gcmpSEIFaceIndex,                     "Specifies the face index for the i-th face")
+  ("SEIGcmpFaceRotation",                             cfg_gcmpSEIFaceRotation,                  cfg_gcmpSEIFaceRotation,                  "Specifies the rotation to be applied to the i-th face")
+  ("SEIGcmpFunctionCoeffU",                           cfg_gcmpSEIFunctionCoeffU,                cfg_gcmpSEIFunctionCoeffU,                "Specifies the coefficient used in the cubemap mapping function of the u-axis of the i-th face")
+  ("SEIGcmpFunctionUAffectedByVFlag",                 cfg_gcmpSEIFunctionUAffectedByVFlag,      cfg_gcmpSEIFunctionUAffectedByVFlag,      "Specifies whether the cubemap mapping function of the u-axis refers to the v position of the sample location")
+  ("SEIGcmpFunctionCoeffV",                           cfg_gcmpSEIFunctionCoeffV,                cfg_gcmpSEIFunctionCoeffV,                "Specifies the coefficient used in the cubemap mapping function of the v-axis of the i-th face")
+  ("SEIGcmpFunctionVAffectedByUFlag",                 cfg_gcmpSEIFunctionVAffectedByUFlag,      cfg_gcmpSEIFunctionVAffectedByUFlag,      "Specifies whether the cubemap mapping function of the v-axis refers to the u position of the sample location")
+  ("SEIGcmpGuardBandFlag",                            m_gcmpSEIGuardBandFlag,                   false,                                    "Indicate the existence of guard band areas in the picture")
+  ("SEIGcmpGuardBandBoundaryType",                    m_gcmpSEIGuardBandBoundaryType,           false,                                    "Indicate which face boundaries contain guard bands")
+  ("SEIGcmpGuardBandSamplesMinus1",                   m_gcmpSEIGuardBandSamplesMinus1,          0u,                                       "Specifies the number of guard band samples minus1 used in the cubemap projected picture")
+#endif
 #if JVET_P0984_SEI_SUBPIC_LEVEL
   ("SEISubpicureLevelInfo",                           m_subpicureLevelInfoSEIEnabled,           false, "Control generation of Subpicture Level Information SEI messages")
 #endif
@@ -2836,6 +2860,39 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
       }
     }
   }
+#endif
+#if JVET_P0597_GCMP_SEI
+  if (m_gcmpSEIEnabled && !m_gcmpSEICancelFlag)
+  {
+    int numFace = m_gcmpSEIPackingType == 4 || m_gcmpSEIPackingType == 5 ? 5 : 6;
+    CHECK (!(cfg_gcmpSEIFaceIndex.values.size()                  == numFace), "Number of SEIGcmpFaceIndex must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
+    CHECK (!(cfg_gcmpSEIFaceRotation.values.size()               == numFace), "Number of SEIGcmpFaceRotation must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
+    m_gcmpSEIFaceIndex.resize(numFace);
+    m_gcmpSEIFaceRotation.resize(numFace);
+    if (m_gcmpSEIMappingFunctionType == 2)
+    {
+      CHECK (!(cfg_gcmpSEIFunctionCoeffU.values.size()           == numFace), "Number of SEIGcmpFunctionCoeffU must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
+      CHECK (!(cfg_gcmpSEIFunctionUAffectedByVFlag.values.size() == numFace), "Number of SEIGcmpFunctionUAffectedByVFlag must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
+      CHECK (!(cfg_gcmpSEIFunctionCoeffV.values.size()           == numFace), "Number of SEIGcmpFunctionCoeffV must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
+      CHECK (!(cfg_gcmpSEIFunctionVAffectedByUFlag.values.size() == numFace), "Number of SEIGcmpFunctionVAffectedByUFlag must be equal to 5 when SEIGcmpPackingType is equal to 4 or 5, otherwise, it must be equal to 6");
+      m_gcmpSEIFunctionCoeffU.resize(numFace);
+      m_gcmpSEIFunctionUAffectedByVFlag.resize(numFace);
+      m_gcmpSEIFunctionCoeffV.resize(numFace);
+      m_gcmpSEIFunctionVAffectedByUFlag.resize(numFace);
+    }
+    for (int i = 0; i < numFace; i++)
+    {
+      m_gcmpSEIFaceIndex[i]                = cfg_gcmpSEIFaceIndex.values[i];
+      m_gcmpSEIFaceRotation[i]             = cfg_gcmpSEIFaceRotation.values[i];
+      if (m_gcmpSEIMappingFunctionType == 2)
+      {
+        m_gcmpSEIFunctionCoeffU[i]           = cfg_gcmpSEIFunctionCoeffU.values[i];
+        m_gcmpSEIFunctionUAffectedByVFlag[i] = cfg_gcmpSEIFunctionUAffectedByVFlag.values[i];
+        m_gcmpSEIFunctionCoeffV[i]           = cfg_gcmpSEIFunctionCoeffV.values[i];
+        m_gcmpSEIFunctionVAffectedByUFlag[i] = cfg_gcmpSEIFunctionVAffectedByUFlag.values[i];
+      }
+    }
+  }
 #endif
   m_reshapeCW.binCW.resize(3);
   m_reshapeCW.rspFps = m_iFrameRate;
@@ -4273,6 +4330,27 @@ bool EncAppCfg::xCheckParameter()
   }
 #endif
 
+#if JVET_P0597_GCMP_SEI
+  if (m_gcmpSEIEnabled && !m_gcmpSEICancelFlag)
+  {
+    xConfirmPara( m_gcmpSEIMappingFunctionType < 0 || m_gcmpSEIMappingFunctionType > 2, "SEIGcmpMappingFunctionType must be in the range of 0 to 2");
+    int numFace = m_gcmpSEIPackingType == 4 || m_gcmpSEIPackingType == 5 ? 5 : 6;
+    for ( int i = 0; i < numFace; i++ )
+    {
+      xConfirmPara( m_gcmpSEIFaceIndex[i] < 0 || m_gcmpSEIFaceIndex[i] > 5,       "SEIGcmpFaceIndex must be in the range of 0 to 5");
+      xConfirmPara( m_gcmpSEIFaceRotation[i] < 0 || m_gcmpSEIFaceRotation[i] > 3, "SEIGcmpFaceRotation must be in the range of 0 to 3");
+      if (m_gcmpSEIMappingFunctionType == 2)
+      {
+        xConfirmPara( m_gcmpSEIFunctionCoeffU[i] <= 0.0 || m_gcmpSEIFunctionCoeffU[i] > 1.0, "SEIGcmpFunctionCoeffU must be in the range (0, 1]");
+        xConfirmPara( m_gcmpSEIFunctionCoeffV[i] <= 0.0 || m_gcmpSEIFunctionCoeffV[i] > 1.0, "SEIGcmpFunctionCoeffV must be in the range (0, 1]");
+      }
+    }
+    if (m_gcmpSEIGuardBandFlag)
+    {
+      xConfirmPara( m_gcmpSEIGuardBandSamplesMinus1 < 0 || m_gcmpSEIGuardBandSamplesMinus1 > 15, "SEIGcmpGuardBandSamplesMinus1 must be in the range of 0 to 15");
+    }
+  }
+#endif
 
 #if HEVC_SEI || JVET_P0337_PORTING_SEI
 #if U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 8f227d1d99144dc5d1198b6f28ddc12c5c23233f..10c9ab465b4fd5c5d0ebe74f6c03b4272f413f4d 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -681,6 +681,23 @@ protected:
   std::vector<uint8_t>  m_rwpSEIRwpGuardBandType;
 #endif
 
+#if JVET_P0597_GCMP_SEI
+  bool                 m_gcmpSEIEnabled;
+  bool                 m_gcmpSEICancelFlag;
+  bool                 m_gcmpSEIPersistenceFlag;
+  uint32_t             m_gcmpSEIPackingType;
+  uint32_t             m_gcmpSEIMappingFunctionType;
+  std::vector<uint8_t> m_gcmpSEIFaceIndex;
+  std::vector<uint8_t> m_gcmpSEIFaceRotation;
+  std::vector<double>  m_gcmpSEIFunctionCoeffU;
+  std::vector<bool>    m_gcmpSEIFunctionUAffectedByVFlag;
+  std::vector<double>  m_gcmpSEIFunctionCoeffV;
+  std::vector<bool>    m_gcmpSEIFunctionVAffectedByUFlag;
+  bool                 m_gcmpSEIGuardBandFlag;
+  bool                 m_gcmpSEIGuardBandBoundaryType;
+  uint32_t             m_gcmpSEIGuardBandSamplesMinus1;
+#endif
+
 #if JVET_P0984_SEI_SUBPIC_LEVEL
   bool m_subpicureLevelInfoSEIEnabled;
 #endif
diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp
index 85959f02e67df5fe79cc1f29fc0261480346ba39..078c00a9cde68d06165b05c4bf9340fc6f1bbd57 100644
--- a/source/Lib/CommonLib/SEI.cpp
+++ b/source/Lib/CommonLib/SEI.cpp
@@ -237,6 +237,9 @@ const char *SEI::getSEIMessageString(SEI::PayloadType payloadType)
     case SEI::REGION_WISE_PACKING:                  return "Region wise packing information";
     case SEI::OMNI_VIEWPORT:                        return "Omni viewport";
 #endif
+#if JVET_P0597_GCMP_SEI
+    case SEI::GENERALIZED_CUBEMAP_PROJECTION:       return "Generalized cubemap projection";
+#endif
 #if JVET_P0450_SEI_SARI
     case SEI::SAMPLE_ASPECT_RATIO_INFO:             return "Sample aspect ratio information";
 #endif
diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h
index 6bb76936944967ac366652eef1edc90a4c5dc9dc..f48890f0202105a59c67b4af4c11273875af4ea1 100644
--- a/source/Lib/CommonLib/SEI.h
+++ b/source/Lib/CommonLib/SEI.h
@@ -111,6 +111,9 @@ public:
     REGION_WISE_PACKING                  = 155,
     OMNI_VIEWPORT                        = 156,
 #endif
+#if JVET_P0597_GCMP_SEI
+    GENERALIZED_CUBEMAP_PROJECTION       = 153,
+#endif
 #if HEVC_SEI && !JVET_P0337_PORTING_SEI
 #if U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI
     ALTERNATIVE_TRANSFER_CHARACTERISTICS = 182,
@@ -229,6 +232,31 @@ public:
 };
 #endif
 
+#if JVET_P0597_GCMP_SEI
+class SEIGeneralizedCubemapProjection : public SEI
+{
+public:
+  PayloadType payloadType() const { return GENERALIZED_CUBEMAP_PROJECTION; }
+
+  SEIGeneralizedCubemapProjection()  {}
+  virtual ~SEIGeneralizedCubemapProjection() {}
+
+  bool                 m_gcmpCancelFlag;
+  bool                 m_gcmpPersistenceFlag;
+  uint8_t              m_gcmpPackingType;
+  uint8_t              m_gcmpMappingFunctionType;
+  std::vector<uint8_t> m_gcmpFaceIndex;
+  std::vector<uint8_t> m_gcmpFaceRotation;
+  std::vector<uint8_t> m_gcmpFunctionCoeffU;
+  std::vector<bool>    m_gcmpFunctionUAffectedByVFlag;
+  std::vector<uint8_t> m_gcmpFunctionCoeffV;
+  std::vector<bool>    m_gcmpFunctionVAffectedByUFlag;
+  bool                 m_gcmpGuardBandFlag;
+  bool                 m_gcmpGuardBandBoundaryType;
+  uint8_t              m_gcmpGuardBandSamplesMinus1;
+};
+#endif
+
 #if JVET_P0450_SEI_SARI
 class SEISampleAspectRatioInfo : public SEI
 {
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 5340737b9e542166660364a638ee0c913c7cee22..1936308a0b54d47bce1c126b0423fdc20239cf67 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -291,6 +291,8 @@
 
 #define JVET_P0184                                        1  //JVET-P0184: Decoding process for generating unavailable reference pictures
 
+#define JVET_P0597_GCMP_SEI                               1 // JVET-P0597: generalized cubemap projection SEI message
+
 #define HEVC_SEI                                          0 // SEI messages that are defined in HEVC, but not in VVC
 
 typedef std::pair<int, bool> TrMode;
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index f8e813497a727385b1d7f68451adcdca12ae0ae1..cc556d2a0a207a8823deb732ee69d689032cd8f4 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -350,6 +350,12 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       xParseSEIRegionWisePacking((SEIRegionWisePacking&) *sei, payloadSize, pDecodedMessageOutputStream);
       break;
 #endif
+#if JVET_P0597_GCMP_SEI
+    case SEI::GENERALIZED_CUBEMAP_PROJECTION:
+      sei = new SEIGeneralizedCubemapProjection;
+      xParseSEIGeneralizedCubemapProjection((SEIGeneralizedCubemapProjection&) *sei, payloadSize, pDecodedMessageOutputStream);
+      break;
+#endif
 #if JVET_P0984_SEI_SUBPIC_LEVEL
     case SEI::SUBPICTURE_LEVEL_INFO:
       sei = new SEISubpicureLevelInfo;
@@ -1857,6 +1863,52 @@ void SEIReader::xParseSEIRegionWisePacking(SEIRegionWisePacking& sei, uint32_t p
 }
 #endif
 
+#if JVET_P0597_GCMP_SEI
+void SEIReader::xParseSEIGeneralizedCubemapProjection(SEIGeneralizedCubemapProjection& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+{
+  uint32_t val;
+  output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
+
+  sei_read_flag( pDecodedMessageOutputStream,          val,    "gcmp_cancel_flag" );                      sei.m_gcmpCancelFlag = val;
+  if (!sei.m_gcmpCancelFlag)
+  {
+    sei_read_flag( pDecodedMessageOutputStream,        val,    "gcmp_persistence_flag"    );              sei.m_gcmpPersistenceFlag = val;
+    sei_read_code( pDecodedMessageOutputStream,     3, val,    "gcmp_packing_type" );                     sei.m_gcmpPackingType = val;
+    sei_read_code( pDecodedMessageOutputStream,     2, val,    "gcmp_mapping_function_type"     );        sei.m_gcmpMappingFunctionType = val;
+
+    int numFace = sei.m_gcmpPackingType == 4 || sei.m_gcmpPackingType == 5 ? 5 : 6;
+    sei.m_gcmpFaceIndex.resize(numFace);
+    sei.m_gcmpFaceRotation.resize(numFace);
+    if (sei.m_gcmpMappingFunctionType == 2)
+    {
+      sei.m_gcmpFunctionCoeffU.resize(numFace);
+      sei.m_gcmpFunctionUAffectedByVFlag.resize(numFace);
+      sei.m_gcmpFunctionCoeffV.resize(numFace);
+      sei.m_gcmpFunctionVAffectedByUFlag.resize(numFace);
+    }
+
+    for (int i = 0; i < numFace; i++)
+    {
+      sei_read_code( pDecodedMessageOutputStream,   3, val,    "gcmp_face_index" );                       sei.m_gcmpFaceIndex[i] = val;
+      sei_read_code( pDecodedMessageOutputStream,   2, val,    "gcmp_face_rotation" );                    sei.m_gcmpFaceRotation[i] = val;
+      if (sei.m_gcmpMappingFunctionType == 2)
+      {
+        sei_read_code( pDecodedMessageOutputStream, 7, val,    "gcmp_function_coeff_u" );                 sei.m_gcmpFunctionCoeffU[i] = val;
+        sei_read_flag( pDecodedMessageOutputStream,    val,    "gcmp_function_u_affected_by_v_flag"    ); sei.m_gcmpFunctionUAffectedByVFlag[i] = val;
+        sei_read_code( pDecodedMessageOutputStream, 7, val,    "gcmp_function_coeff_v" );                 sei.m_gcmpFunctionCoeffV[i] = val;
+        sei_read_flag( pDecodedMessageOutputStream,    val,    "gcmp_function_v_affected_by_u_flag"    ); sei.m_gcmpFunctionVAffectedByUFlag[i] = val;
+      }
+    }
+    sei_read_flag( pDecodedMessageOutputStream,        val,    "gcmp_guard_band_flag" );                  sei.m_gcmpGuardBandFlag = val;
+    if (sei.m_gcmpGuardBandFlag)
+    {
+      sei_read_flag( pDecodedMessageOutputStream,      val,    "gcmp_guard_band_boundary_type" );         sei.m_gcmpGuardBandBoundaryType  = val;
+      sei_read_code( pDecodedMessageOutputStream,   4, val,    "gcmp_guard_band_samples_minus1" );        sei.m_gcmpGuardBandSamplesMinus1 = val;
+    }
+  }
+}
+#endif
+
 #if JVET_P0984_SEI_SUBPIC_LEVEL
 void SEIReader::xParseSEISubpictureLevelInfo(SEISubpicureLevelInfo& sei, const SPS *sps, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
 {
diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h
index b6de66c701dfb111c8b271f45a9a6ce87081b590..a5d95bf9056bb99a74bf7d77e7a1505127e0fda9 100644
--- a/source/Lib/DecoderLib/SEIread.h
+++ b/source/Lib/DecoderLib/SEIread.h
@@ -116,6 +116,9 @@ protected:
   void xParseSEIOmniViewport                  (SEIOmniViewport& sei,                  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIRegionWisePacking             (SEIRegionWisePacking& sei,             uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
 #endif
+#if JVET_P0597_GCMP_SEI
+  void xParseSEIGeneralizedCubemapProjection  (SEIGeneralizedCubemapProjection &sei,  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+#endif
 #if JVET_P0984_SEI_SUBPIC_LEVEL
   void xParseSEISubpictureLevelInfo           (SEISubpicureLevelInfo& sei, const SPS *sps, uint32_t payloadSize,            std::ostream *pDecodedMessageOutputStream);
 #endif
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 03b9f5397c3ab938925ea634fbfd55b04d5000f4..47f5b79d55cbe2fe09e1238b15114c082da25193 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -663,6 +663,22 @@ protected:
   std::vector<bool>     m_rwpSEIRwpGuardBandNotUsedForPredFlag;
   std::vector<uint8_t>  m_rwpSEIRwpGuardBandType;
 #endif
+#if JVET_P0597_GCMP_SEI
+  bool                 m_gcmpSEIEnabled;
+  bool                 m_gcmpSEICancelFlag;
+  bool                 m_gcmpSEIPersistenceFlag;
+  uint8_t              m_gcmpSEIPackingType;
+  uint8_t              m_gcmpSEIMappingFunctionType;
+  std::vector<uint8_t> m_gcmpSEIFaceIndex;
+  std::vector<uint8_t> m_gcmpSEIFaceRotation;
+  std::vector<double>  m_gcmpSEIFunctionCoeffU;
+  std::vector<bool>    m_gcmpSEIFunctionUAffectedByVFlag;
+  std::vector<double>  m_gcmpSEIFunctionCoeffV;
+  std::vector<bool>    m_gcmpSEIFunctionVAffectedByUFlag;
+  bool                 m_gcmpSEIGuardBandFlag;
+  bool                 m_gcmpSEIGuardBandBoundaryType;
+  uint8_t              m_gcmpSEIGuardBandSamplesMinus1;
+#endif
 #if JVET_P0984_SEI_SUBPIC_LEVEL
   bool m_subpicureLevelInfoSEIEnabled;
 #endif
@@ -1815,6 +1831,36 @@ public:
   void     setRwpSEIRwpGuardBandType(const std::vector<uint8_t>& rwpGuardBandType)                          { m_rwpSEIRwpGuardBandType = rwpGuardBandType; }
   uint8_t  getRwpSEIRwpGuardBandType(uint32_t idx) const                                                    { return m_rwpSEIRwpGuardBandType[idx]; }
 #endif
+#if JVET_P0597_GCMP_SEI
+  void    setGcmpSEIEnabled(bool b)                                                                 { m_gcmpSEIEnabled = b; }
+  bool    getGcmpSEIEnabled()                                                                       { return m_gcmpSEIEnabled; }
+  void    setGcmpSEICancelFlag(bool b)                                                              { m_gcmpSEICancelFlag = b; }
+  bool    getGcmpSEICancelFlag()                                                                    { return m_gcmpSEICancelFlag; }
+  void    setGcmpSEIPersistenceFlag(bool b)                                                         { m_gcmpSEIPersistenceFlag = b; }
+  bool    getGcmpSEIPersistenceFlag()                                                               { return m_gcmpSEIPersistenceFlag; }
+  void    setGcmpSEIPackingType(uint8_t u)                                                          { m_gcmpSEIPackingType = u; }
+  uint8_t getGcmpSEIPackingType()                                                                   { return m_gcmpSEIPackingType; }
+  void    setGcmpSEIMappingFunctionType(uint8_t u)                                                  { m_gcmpSEIMappingFunctionType = u; }
+  uint8_t getGcmpSEIMappingFunctionType()                                                           { return m_gcmpSEIMappingFunctionType; }
+  void    setGcmpSEIFaceIndex(const std::vector<uint8_t>& gcmpFaceIndex)                            { m_gcmpSEIFaceIndex = gcmpFaceIndex; }
+  uint8_t getGcmpSEIFaceIndex(int idx) const                                                        { return m_gcmpSEIFaceIndex[idx]; }
+  void    setGcmpSEIFaceRotation(const std::vector<uint8_t>& gcmpFaceRotation)                      { m_gcmpSEIFaceRotation = gcmpFaceRotation; }
+  uint8_t getGcmpSEIFaceRotation(int idx) const                                                     { return m_gcmpSEIFaceRotation[idx]; }
+  void    setGcmpSEIFunctionCoeffU(const std::vector<double>& gcmpFunctionCoeffU)                   { m_gcmpSEIFunctionCoeffU = gcmpFunctionCoeffU; }
+  double  getGcmpSEIFunctionCoeffU(int idx) const                                                   { return m_gcmpSEIFunctionCoeffU[idx]; }
+  void    setGcmpSEIFunctionUAffectedByVFlag(const std::vector<bool>& gcmpFunctionUAffectedByVFlag) { m_gcmpSEIFunctionUAffectedByVFlag = gcmpFunctionUAffectedByVFlag; }
+  bool    getGcmpSEIFunctionUAffectedByVFlag(int idx) const                                         { return m_gcmpSEIFunctionUAffectedByVFlag[idx]; }
+  void    setGcmpSEIFunctionCoeffV(const std::vector<double>& gcmpFunctionCoeffV)                   { m_gcmpSEIFunctionCoeffV = gcmpFunctionCoeffV; }
+  double  getGcmpSEIFunctionCoeffV(int idx) const                                                   { return m_gcmpSEIFunctionCoeffV[idx]; }
+  void    setGcmpSEIFunctionVAffectedByUFlag(const std::vector<bool>& gcmpFunctionVAffectedByUFlag) { m_gcmpSEIFunctionVAffectedByUFlag = gcmpFunctionVAffectedByUFlag; }
+  bool    getGcmpSEIFunctionVAffectedByUFlag(int idx) const                                         { return m_gcmpSEIFunctionVAffectedByUFlag[idx]; }
+  void    setGcmpSEIGuardBandFlag(bool b)                                                           { m_gcmpSEIGuardBandFlag = b; }
+  bool    getGcmpSEIGuardBandFlag()                                                                 { return m_gcmpSEIGuardBandFlag; }
+  void    setGcmpSEIGuardBandBoundaryType(bool b)                                                   { m_gcmpSEIGuardBandBoundaryType = b; }
+  bool    getGcmpSEIGuardBandBoundaryType()                                                         { return m_gcmpSEIGuardBandBoundaryType; }
+  void    setGcmpSEIGuardBandSamplesMinus1( uint8_t u )                                             { m_gcmpSEIGuardBandSamplesMinus1 = u; }
+  uint8_t getGcmpSEIGuardBandSamplesMinus1()                                                        { return m_gcmpSEIGuardBandSamplesMinus1; }
+#endif
 #if JVET_P0984_SEI_SUBPIC_LEVEL
   bool    getSubpicureLevelInfoSEIEnabled() const { return m_subpicureLevelInfoSEIEnabled; }
   void    setSubpicureLevelInfoSEIEnabled(bool val) { m_subpicureLevelInfoSEIEnabled = val; }
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index a631486e03c1cf98bfadbc8dd6b3c4b74029659d..c33a5042eaac498e5d190ce3d2cdc2d5ceee1038 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -806,6 +806,14 @@ void EncGOP::xCreateIRAPLeadingSEIMessages (SEIMessages& seiMessages, const SPS
     seiMessages.push_back(seiRegionWisePacking);
   }
 #endif
+#if JVET_P0597_GCMP_SEI
+  if (m_pcCfg->getGcmpSEIEnabled())
+  {
+    SEIGeneralizedCubemapProjection *sei = new SEIGeneralizedCubemapProjection;
+    m_seiEncoder.initSEIGcmp(sei);
+    seiMessages.push_back(sei);
+  }
+#endif
 #if JVET_P0984_SEI_SUBPIC_LEVEL
   if (m_pcCfg->getSubpicureLevelInfoSEIEnabled())
   {
diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp
index 973f83e18808d5d2fb96c40b4e51bb9a01e8ed06..f88eb966e0134c63e7447315f6aae4ae0698f1d4 100644
--- a/source/Lib/EncoderLib/SEIEncoder.cpp
+++ b/source/Lib/EncoderLib/SEIEncoder.cpp
@@ -454,6 +454,52 @@ void SEIEncoder::initSEIRegionWisePacking(SEIRegionWisePacking *seiRegionWisePac
 }
 #endif
 
+#if JVET_P0597_GCMP_SEI
+void SEIEncoder::initSEIGcmp(SEIGeneralizedCubemapProjection* seiGeneralizedCubemapProjection)
+{
+  CHECK(!(m_isInitialized), "seiGeneralizedCubemapProjection already initialized");
+  CHECK(!(seiGeneralizedCubemapProjection != nullptr), "Need a seiGeneralizedCubemapProjection for initialization (got nullptr)");
+
+  seiGeneralizedCubemapProjection->m_gcmpCancelFlag                      = m_pcCfg->getGcmpSEICancelFlag();
+  if (!seiGeneralizedCubemapProjection->m_gcmpCancelFlag)
+  {
+    seiGeneralizedCubemapProjection->m_gcmpPersistenceFlag               = m_pcCfg->getGcmpSEIPersistenceFlag();
+    seiGeneralizedCubemapProjection->m_gcmpPackingType                   = m_pcCfg->getGcmpSEIPackingType();
+    seiGeneralizedCubemapProjection->m_gcmpMappingFunctionType           = m_pcCfg->getGcmpSEIMappingFunctionType();
+
+    int numFace = seiGeneralizedCubemapProjection->m_gcmpPackingType == 4 || seiGeneralizedCubemapProjection->m_gcmpPackingType == 5 ? 5 : 6;
+    seiGeneralizedCubemapProjection->m_gcmpFaceIndex.resize(numFace);
+    seiGeneralizedCubemapProjection->m_gcmpFaceRotation.resize(numFace);
+    if (seiGeneralizedCubemapProjection->m_gcmpMappingFunctionType == 2)
+    {
+      seiGeneralizedCubemapProjection->m_gcmpFunctionCoeffU.resize(numFace);
+      seiGeneralizedCubemapProjection->m_gcmpFunctionUAffectedByVFlag.resize(numFace);
+      seiGeneralizedCubemapProjection->m_gcmpFunctionCoeffV.resize(numFace);
+      seiGeneralizedCubemapProjection->m_gcmpFunctionVAffectedByUFlag.resize(numFace);
+    }
+    for (int i = 0; i < numFace; i++)
+    {
+      seiGeneralizedCubemapProjection->m_gcmpFaceIndex[i]                = m_pcCfg->getGcmpSEIFaceIndex(i);
+      seiGeneralizedCubemapProjection->m_gcmpFaceRotation[i]             = m_pcCfg->getGcmpSEIFaceRotation(i);
+      if (seiGeneralizedCubemapProjection->m_gcmpMappingFunctionType == 2)
+      {
+        seiGeneralizedCubemapProjection->m_gcmpFunctionCoeffU[i]           = std::max<uint8_t>(1, (uint8_t)(128.0 * m_pcCfg->getGcmpSEIFunctionCoeffU(i) + 0.5)) - 1;
+        seiGeneralizedCubemapProjection->m_gcmpFunctionUAffectedByVFlag[i] = m_pcCfg->getGcmpSEIFunctionUAffectedByVFlag(i);
+        seiGeneralizedCubemapProjection->m_gcmpFunctionCoeffV[i]           = std::max<uint8_t>(1, (uint8_t)(128.0 * m_pcCfg->getGcmpSEIFunctionCoeffV(i) + 0.5)) - 1;
+        seiGeneralizedCubemapProjection->m_gcmpFunctionVAffectedByUFlag[i] = m_pcCfg->getGcmpSEIFunctionVAffectedByUFlag(i);
+      }
+    }
+
+    seiGeneralizedCubemapProjection->m_gcmpGuardBandFlag                 = m_pcCfg->getGcmpSEIGuardBandFlag();
+    if (seiGeneralizedCubemapProjection->m_gcmpGuardBandFlag)
+    {
+      seiGeneralizedCubemapProjection->m_gcmpGuardBandBoundaryType       = m_pcCfg->getGcmpSEIGuardBandBoundaryType();
+      seiGeneralizedCubemapProjection->m_gcmpGuardBandSamplesMinus1      = m_pcCfg->getGcmpSEIGuardBandSamplesMinus1();
+    }
+  }
+}
+#endif
+
 #if JVET_P0450_SEI_SARI
 void SEIEncoder::initSEISampleAspectRatioInfo(SEISampleAspectRatioInfo* seiSampleAspectRatioInfo)
 {
diff --git a/source/Lib/EncoderLib/SEIEncoder.h b/source/Lib/EncoderLib/SEIEncoder.h
index b7e283ce89fe024a361fc1848c9873cf970b1cab..f6c29face2728f708c57d2f31b0d45ca578a573f 100644
--- a/source/Lib/EncoderLib/SEIEncoder.h
+++ b/source/Lib/EncoderLib/SEIEncoder.h
@@ -109,6 +109,9 @@ public:
   void initSEIOmniViewport(SEIOmniViewport *sei);
   void initSEIRegionWisePacking(SEIRegionWisePacking *sei);
 #endif
+#if JVET_P0597_GCMP_SEI
+  void initSEIGcmp(SEIGeneralizedCubemapProjection *sei);
+#endif
 #if JVET_P0984_SEI_SUBPIC_LEVEL
   void initSEISubpictureLevelInfo(SEISubpicureLevelInfo *sei, const SPS *sps);
 #endif
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index 5a300a5dd8435d093a383d5ae08ba785489d1de5..bcb5c04e0c6892da91e3be3dd143cf2e7e4fe6d0 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -177,6 +177,11 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream& bs, const SEI& sei, const
     xWriteSEIRegionWisePacking(*static_cast<const SEIRegionWisePacking*>(&sei));
     break;
 #endif
+#if JVET_P0597_GCMP_SEI
+  case SEI::GENERALIZED_CUBEMAP_PROJECTION:
+    xWriteSEIGeneralizedCubemapProjection(*static_cast<const SEIGeneralizedCubemapProjection*>(&sei));
+    break;
+#endif
 #if JVET_P0337_PORTING_SEI
   case SEI::USER_DATA_REGISTERED_ITU_T_T35:
     xWriteSEIUserDataRegistered(*static_cast<const SEIUserDataRegistered*>(&sei));
@@ -1247,6 +1252,38 @@ void SEIWriter::xWriteSEIRegionWisePacking(const SEIRegionWisePacking &sei)
 }
 #endif
 
+#if JVET_P0597_GCMP_SEI
+void SEIWriter::xWriteSEIGeneralizedCubemapProjection(const SEIGeneralizedCubemapProjection &sei)
+{
+  WRITE_FLAG( sei.m_gcmpCancelFlag,                           "gcmp_cancel_flag" );
+  if (!sei.m_gcmpCancelFlag)
+  {
+    WRITE_FLAG( sei.m_gcmpPersistenceFlag,                    "gcmp_persistence_flag" );
+    WRITE_CODE( sei.m_gcmpPackingType,                     3, "gcmp_packing_type" );  
+    WRITE_CODE( sei.m_gcmpMappingFunctionType,             2, "gcmp_mapping_function_type" );
+    int numFace = sei.m_gcmpPackingType == 4 || sei.m_gcmpPackingType == 5 ? 5 : 6;
+    for (int i = 0; i < numFace; i++)
+    {
+      WRITE_CODE( sei.m_gcmpFaceIndex[i],                  3, "gcmp_face_index" );  
+      WRITE_CODE( sei.m_gcmpFaceRotation[i],               2, "gcmp_face_rotation" );  
+      if (sei.m_gcmpMappingFunctionType == 2)
+      {
+        WRITE_CODE( sei.m_gcmpFunctionCoeffU[i],           7, "gcmp_function_coeff_u" );  
+        WRITE_FLAG( sei.m_gcmpFunctionUAffectedByVFlag[i],    "gcmp_function_u_affected_by_v_flag" );
+        WRITE_CODE( sei.m_gcmpFunctionCoeffV[i],           7, "gcmp_function_coeff_v" );  
+        WRITE_FLAG( sei.m_gcmpFunctionVAffectedByUFlag[i],    "gcmp_function_v_affected_by_u_flag" );
+      }
+    }
+    WRITE_FLAG( sei.m_gcmpGuardBandFlag,                      "gcmp_guard_band_flag" );
+    if (sei.m_gcmpGuardBandFlag)
+    {
+      WRITE_FLAG( sei.m_gcmpGuardBandBoundaryType,            "gcmp_guard_band_boundary_type" );  
+      WRITE_CODE( sei.m_gcmpGuardBandSamplesMinus1,        4, "gcmp_guard_band_samples_minus1" );  
+    }
+  }
+}
+#endif
+
 #if JVET_P0984_SEI_SUBPIC_LEVEL
 void SEIWriter::xWriteSEISubpictureLevelInfo(const SEISubpicureLevelInfo &sei, const SPS* sps)
 {
diff --git a/source/Lib/EncoderLib/SEIwrite.h b/source/Lib/EncoderLib/SEIwrite.h
index 960b6198b82c628bbfc1a65274c277a56fd4639f..d15e91754363666d99c965a5f75370368c20bf47 100644
--- a/source/Lib/EncoderLib/SEIwrite.h
+++ b/source/Lib/EncoderLib/SEIwrite.h
@@ -107,6 +107,9 @@ protected:
   void xWriteSEIOmniViewport                      (const SEIOmniViewport& sei);
   void xWriteSEIRegionWisePacking                 (const SEIRegionWisePacking &sei);
 #endif
+#if JVET_P0597_GCMP_SEI
+  void xWriteSEIGeneralizedCubemapProjection      (const SEIGeneralizedCubemapProjection &sei);
+#endif
 #if JVET_P0984_SEI_SUBPIC_LEVEL
   void xWriteSEISubpictureLevelInfo               (const SEISubpicureLevelInfo &sei, const SPS* sps);
 #endif