diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp
index 998482946fcca60775f9be513738ebfa23277730..91d9db036ad27a847d8c6585c891e82f8f4a9473 100644
--- a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp
+++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp
@@ -634,7 +634,11 @@ uint32_t BitstreamExtractorApp::decode()
           // decoding a SEI
           SEIMessages SEIs;
           HRD hrd;
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+          m_seiReader.parseSEImessage(&(nalu.getBitstream()), SEIs, nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId, vps, m_parameterSetManager.getActiveSPS(), hrd, &std::cout, std::string(""));
+#else
           m_seiReader.parseSEImessage(&(nalu.getBitstream()), SEIs, nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId, vps, m_parameterSetManager.getActiveSPS(), hrd, &std::cout);
+#endif
           for (auto sei : SEIs)
           {
             // remove unqualiified scalable nesting SEI
diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp
index a1e1abf51dcd5f57323bc02391543750a22ab153..77107502437eb5a3f7c96e81f156528145229b36 100644
--- a/source/App/DecoderApp/DecApp.cpp
+++ b/source/App/DecoderApp/DecApp.cpp
@@ -371,6 +371,10 @@ void DecApp::xCreateDecLib()
     std::ostream &os=m_seiMessageFileStream.is_open() ? m_seiMessageFileStream : std::cout;
     m_cDecLib.setDecodedSEIMessageOutputStream(&os);
   }
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  if (!m_outputDecoded360SEIMessagesFilename.empty())
+    m_cDecLib.setDecoded360SEIMessageFileName(m_outputDecoded360SEIMessagesFilename);
+#endif
   m_cDecLib.m_targetSubPicIdx = this->m_targetSubPicIdx;
   m_cDecLib.initScalingList();
 }
diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp
index 602f949ab9ca2c16c60df75d173484ec5206b59b..6e95abb7490b528857241b043d8f8300eea2d7e3 100644
--- a/source/App/DecoderApp/DecAppCfg.cpp
+++ b/source/App/DecoderApp/DecAppCfg.cpp
@@ -97,6 +97,9 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
   ("TarDecLayerIdSetFile,l",    cfg_TargetDecLayerIdSetFile,           string(""), "targetDecLayerIdSet file name. The file should include white space separated LayerId values to be decoded. Omitting the option or a value of -1 in the file decodes all layers.")
   ("SEIColourRemappingInfoFilename",  m_colourRemapSEIFileName,        string(""), "Colour Remapping YUV output file name. If empty, no remapping is applied (ignore SEI message)\n")
   ("OutputDecodedSEIMessagesFilename",  m_outputDecodedSEIMessagesFilename,    string(""), "When non empty, output decoded SEI messages to the indicated file. If file is '-', then output to stdout\n")
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  ("360DumpFile",  m_outputDecoded360SEIMessagesFilename, string(""), "When non empty, output decoded 360 SEI messages to the indicated file.\n")
+#endif
   ("ClipOutputVideoToRec709Range",      m_bClipOutputVideoToRec709Range,  false,   "If true then clip output video to the Rec. 709 Range on saving")
   ("PYUV",                      m_packedYUVMode,                       false,      "If true then output 10-bit and 12-bit YUV data as 5-byte and 3-byte (respectively) packed YUV data. Ignored for interlaced output.")
 #if ENABLE_TRACING
@@ -235,6 +238,9 @@ DecAppCfg::DecAppCfg()
 , m_colourRemapSEIFileName()
 , m_targetDecLayerIdSet()
 , m_outputDecodedSEIMessagesFilename()
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+, m_outputDecoded360SEIMessagesFilename()
+#endif
 , m_bClipOutputVideoToRec709Range(false)
 , m_packedYUVMode(false)
 , m_statMode(0)
diff --git a/source/App/DecoderApp/DecAppCfg.h b/source/App/DecoderApp/DecAppCfg.h
index f28b07d77d951287f0e67544dc8cda3fd9bb9e02..607425be31a2556128d12fc0d9c193bdd24121b7 100644
--- a/source/App/DecoderApp/DecAppCfg.h
+++ b/source/App/DecoderApp/DecAppCfg.h
@@ -72,6 +72,9 @@ protected:
   std::string   m_colourRemapSEIFileName;             ///< output Colour Remapping file name
   std::vector<int> m_targetDecLayerIdSet;             ///< set of LayerIds to be included in the sub-bitstream extraction process.
   std::string   m_outputDecodedSEIMessagesFilename;   ///< filename to output decoded SEI messages to. If '-', then use stdout. If empty, do not output details.
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  std::string   m_outputDecoded360SEIMessagesFilename;   ///< filename to output decoded 360 SEI messages to.
+#endif
 
 
   bool          m_bClipOutputVideoToRec709Range;      ///< If true, clip the output video to the Rec 709 range on saving.
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 8057ce0ed8a90685e60f2090f8e0573ce6f44ce4..19d0ffcdc9cb6ebcee1e924ef5cd4ebab750ae8e 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -51,6 +51,8 @@
 #include <cassert>
 
 
+#define JVET_S0257_DUMP_360SEI_MESSAGE                    1 // Software support of 360 SEI messages
+
 //########### place macros to be removed in next cycle below this line ###############
 #define JVET_S0074_SPS_REORDER                            1 // JVET-S0074: aspect 1, rearrange some syntax elements in SPS
 
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 754e86dd1d350f5e64641794026451121774bec0..e94f56cc28f0bcfbb2fdcbc39877f43fa9a722ce 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -436,6 +436,9 @@ DecLib::DecLib()
   , m_sliceLmcsApsId(-1)
   , m_pDecodedSEIOutputStream(NULL)
   , m_audIrapOrGdrAuFlag( false )
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  , m_decoded360SeiDumpFileName()
+#endif
   , m_decodedPictureHashSEIEnabled(false)
   , m_numberOfChecksumErrorsDetected(0)
   , m_warningMessageSkipPicture(false)
@@ -1779,7 +1782,11 @@ void DecLib::xParsePrefixSEImessages()
     m_accessUnitSeiTids.push_back(nalu.m_temporalId);
     const SPS *sps = m_parameterSetManager.getActiveSPS();
     const VPS *vps = m_parameterSetManager.getVPS(sps->getVPSId());
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+    m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_SEIs, nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId, vps, sps, m_HRD, m_pDecodedSEIOutputStream, m_decoded360SeiDumpFileName );
+#else
     m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_SEIs, nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId, vps, sps, m_HRD, m_pDecodedSEIOutputStream );
+#endif
     m_accessUnitSeiPayLoadTypes.push_back(std::tuple<NalUnitType, int, SEI::PayloadType>(nalu.m_nalUnitType, nalu.m_nuhLayerId, m_SEIs.back()->payloadType()));
     delete m_prefixSEINALUs.front();
     m_prefixSEINALUs.pop_front();
@@ -2692,7 +2699,11 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, i
         m_accessUnitSeiTids.push_back(nalu.m_temporalId);
         const SPS *sps = m_parameterSetManager.getActiveSPS();
         const VPS *vps = m_parameterSetManager.getVPS(sps->getVPSId());
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+        m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_pcPic->SEIs, nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId, vps, sps, m_HRD, m_pDecodedSEIOutputStream, m_decoded360SeiDumpFileName );
+#else
         m_seiReader.parseSEImessage( &(nalu.getBitstream()), m_pcPic->SEIs, nalu.m_nalUnitType, nalu.m_nuhLayerId, nalu.m_temporalId, vps, sps, m_HRD, m_pDecodedSEIOutputStream );
+#endif
         m_accessUnitSeiPayLoadTypes.push_back(std::tuple<NalUnitType, int, SEI::PayloadType>(nalu.m_nalUnitType, nalu.m_nuhLayerId, m_pcPic->SEIs.back()->payloadType()));
       }
       else
diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h
index bb721bfca5732bdd884607a8d8b3ae992fa32dae..3f78c4d58c3d066794177fecfe8bf89f33a46db6 100644
--- a/source/Lib/DecoderLib/DecLib.h
+++ b/source/Lib/DecoderLib/DecLib.h
@@ -135,6 +135,9 @@ private:
   int                     m_sliceLmcsApsId;         //value of LmcsApsId, constraint is same id for all slices in one picture
   std::ostream           *m_pDecodedSEIOutputStream;
   uint32_t                m_audIrapOrGdrAuFlag;
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  std::string             m_decoded360SeiDumpFileName;
+#endif
 
   int                     m_decodedPictureHashSEIEnabled;  ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
   uint32_t                m_numberOfChecksumErrorsDetected;
@@ -222,6 +225,9 @@ public:
   bool  getFirstSliceInSequence(int layerId) const { return m_firstSliceInSequence[layerId]; }
   void  setFirstSliceInSequence(bool val, int layerId) { m_firstSliceInSequence[layerId] = val; }
   void  setDecodedSEIMessageOutputStream(std::ostream *pOpStream) { m_pDecodedSEIOutputStream = pOpStream; }
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  void  setDecoded360SEIMessageFileName(std::string &Dump360SeiFileName) { m_decoded360SeiDumpFileName = Dump360SeiFileName; }
+#endif
   uint32_t  getNumberOfChecksumErrorsDetected() const { return m_numberOfChecksumErrorsDetected; }
 
   int  getDebugCTU( )               const { return m_debugCTU; }
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index 363214df267f509bacd25f2cba364d18ee8916dd..22981a509a90f47b867936650ca2c0a59b1fed2c 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -115,14 +115,22 @@ static inline void output_sei_message_header(SEI &sei, std::ostream *pDecodedMes
  * unmarshal a single SEI message from bitstream bs
  */
  // note: for independent parsing no parameter set should not be required here
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+void SEIReader::parseSEImessage(InputBitstream* bs, 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, std::string decoded360MessageFileName)
+#else
 void SEIReader::parseSEImessage(InputBitstream* bs, 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)
+#endif
 {
   setBitstream(bs);
 
   CHECK(m_pcBitstream->getNumBitsUntilByteAligned(), "Bitstream not aligned");
   do
   {
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+    xReadSEImessage(seis, nalUnitType, nuh_layer_id, temporalId, vps, sps, hrd, pDecodedMessageOutputStream, decoded360MessageFileName);
+#else
     xReadSEImessage(seis, nalUnitType, nuh_layer_id, temporalId, vps, sps, hrd, pDecodedMessageOutputStream);
+#endif
 
     /* SEI messages are an integer number of bytes, something has failed
     * in the parsing if bitstream not byte-aligned */
@@ -133,7 +141,11 @@ void SEIReader::parseSEImessage(InputBitstream* bs, SEIMessages& seis, const Nal
   xReadRbspTrailingBits();
 }
 
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+void SEIReader::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, std::string decoded360MessageFileName)
+#else
 void SEIReader::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)
+#endif
 {
 #if ENABLE_TRACING
   xTraceSEIHeader();
@@ -213,7 +225,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       break;
     case SEI::SCALABLE_NESTING:
       sei = new SEIScalableNesting;
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+      xParseSEIScalableNesting((SEIScalableNesting&)*sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, pDecodedMessageOutputStream, decoded360MessageFileName);
+#else
       xParseSEIScalableNesting((SEIScalableNesting&)*sei, nalUnitType, nuh_layer_id, payloadSize, vps, sps, pDecodedMessageOutputStream);
+#endif
       break;
     case SEI::FRAME_FIELD_INFO:
       sei = new SEIFrameFieldInfo;
@@ -244,7 +260,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
 #endif
     case SEI::EQUIRECTANGULAR_PROJECTION:
       sei = new SEIEquirectangularProjection;
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+      xParseSEIEquirectangularProjection((SEIEquirectangularProjection&) *sei, sps, payloadSize, pDecodedMessageOutputStream, decoded360MessageFileName);
+#else
       xParseSEIEquirectangularProjection((SEIEquirectangularProjection&) *sei, payloadSize, pDecodedMessageOutputStream);
+#endif
       break;
     case SEI::SPHERE_ROTATION:
       sei = new SEISphereRotation;
@@ -260,7 +280,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       break;
     case SEI::GENERALIZED_CUBEMAP_PROJECTION:
       sei = new SEIGeneralizedCubemapProjection;
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+      xParseSEIGeneralizedCubemapProjection((SEIGeneralizedCubemapProjection&) *sei, sps, payloadSize, pDecodedMessageOutputStream, decoded360MessageFileName);
+#else
       xParseSEIGeneralizedCubemapProjection((SEIGeneralizedCubemapProjection&) *sei, payloadSize, pDecodedMessageOutputStream);
+#endif
       break;
     case SEI::SUBPICTURE_LEVEL_INFO:
       sei = new SEISubpicureLevelInfo;
@@ -461,7 +485,11 @@ void SEIReader::xParseSEIDecodedPictureHash(SEIDecodedPictureHash& sei, uint32_t
 }
 
 
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS *vps, const SPS *sps, std::ostream *decodedMessageOutputStream, std::string decoded360MessageFileName)
+#else
 void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS *vps, const SPS *sps, std::ostream *decodedMessageOutputStream)
+#endif
 {
   uint32_t symbol;
   SEIMessages seis;
@@ -540,7 +568,11 @@ void SEIReader::xParseSEIScalableNesting(SEIScalableNesting& sei, const NalUnitT
   for (int32_t i=0; i<sei.m_snNumSEIs; i++)
   {
     SEIMessages tmpSEIs;
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+    xReadSEImessage(tmpSEIs, nalUnitType, nuhLayerId, 0, vps, sps, m_nestedHrd, decodedMessageOutputStream, decoded360MessageFileName);
+#else
     xReadSEImessage(tmpSEIs, nalUnitType, nuhLayerId, 0, vps, sps, m_nestedHrd, decodedMessageOutputStream);
+#endif
     if (tmpSEIs.front()->payloadType() == SEI::BUFFERING_PERIOD)
     {
       SEIBufferingPeriod *bp = (SEIBufferingPeriod*) tmpSEIs.front();
@@ -1160,7 +1192,11 @@ void SEIReader::xParseSEIContentColourVolume(SEIContentColourVolume& sei, uint32
     }
   }
 }
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+void SEIReader::xParseSEIEquirectangularProjection(SEIEquirectangularProjection& sei, const SPS *sps, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream, std::string decoded360MessageFileName)
+#else
 void SEIReader::xParseSEIEquirectangularProjection(SEIEquirectangularProjection& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+#endif
 {
   uint32_t val;
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
@@ -1177,6 +1213,33 @@ void SEIReader::xParseSEIEquirectangularProjection(SEIEquirectangularProjection&
       sei_read_code( pDecodedMessageOutputStream, 8, val,     "erp_left_guard_band_width" );   sei.m_erpLeftGuardBandWidth = val;
       sei_read_code( pDecodedMessageOutputStream, 8, val,     "erp_right_guard_band_width");   sei.m_erpRightGuardBandWidth = val;
     }
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+    if (!m_360SEIMessageDumped && !decoded360MessageFileName.empty())
+    {
+      FILE *fp = fopen(decoded360MessageFileName.c_str(), "w");
+      if (fp)
+      {
+        int chromaFormatTable[4] = {400, 420, 422, 444};
+        fprintf(fp, "InputBitDepth                 : %d    # Input bitdepth\n", sps->getBitDepth(CHANNEL_TYPE_LUMA));
+        fprintf(fp, "InputChromaFormat             : %d    # Ratio of luminance to chrominance samples\n", chromaFormatTable[sps->getChromaFormatIdc()]);
+        fprintf(fp, "SourceWidth                   : %d    # Input  frame width\n", sps->getMaxPicWidthInLumaSamples());
+        fprintf(fp, "SourceHeight                  : %d    # Input  frame height\n\n", sps->getMaxPicHeightInLumaSamples());
+
+        fprintf(fp, "InputGeometryType             : 0     # 0: equirectangular; 1: cubemap; 2: equalarea; this should be in the cfg of per sequence.\n");
+        if (sei.m_erpGuardBandFlag == 1)
+        {
+          fprintf(fp, "InputPERP                     : 1     # 0: original ERP input; 1: padded ERP input\n");
+          fprintf(fp, "CodingPERP                    : 0     # 0: coding with original ERP size; 1: coding with padded ERP\n");
+        }
+        fclose(fp);
+        m_360SEIMessageDumped = true;
+      }
+      else
+      {
+        msg( ERROR, "File %s could not be opened.\n", decoded360MessageFileName.c_str() );
+      }
+    }
+#endif
   }
 }
 
@@ -1290,7 +1353,11 @@ void SEIReader::xParseSEIRegionWisePacking(SEIRegionWisePacking& sei, uint32_t p
   }
 }
 
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+void SEIReader::xParseSEIGeneralizedCubemapProjection(SEIGeneralizedCubemapProjection& sei, const SPS *sps, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream, std::string decoded360MessageFileName)
+#else
 void SEIReader::xParseSEIGeneralizedCubemapProjection(SEIGeneralizedCubemapProjection& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+#endif
 {
   uint32_t val;
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
@@ -1313,16 +1380,57 @@ void SEIReader::xParseSEIGeneralizedCubemapProjection(SEIGeneralizedCubemapProje
       sei.m_gcmpFunctionVAffectedByUFlag.resize(numFace);
     }
 
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+    int packingTypeTable[6][2] = {{6, 1}, {3, 2}, {2, 3}, {1, 6}, {1, 5}, {5, 1}};
+    int rotationTable[4] = {0, 90, 180, 270};
+    std::string packingTypeStr = "";
+    std::string gcmpsettingsStr = "";
+    std::ostringstream oss;
+    if (!m_360SEIMessageDumped)
+    {
+      packingTypeStr += "SourceFPStructure                 : " + std::to_string(packingTypeTable[sei.m_gcmpPackingType][0]) + " " + std::to_string(packingTypeTable[sei.m_gcmpPackingType][1]);
+      gcmpsettingsStr += "InputGCMPSettings                 : ";
+    }
+#endif
     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 JVET_S0257_DUMP_360SEI_MESSAGE
+      if (!m_360SEIMessageDumped)
+      {
+        int rotation = rotationTable[sei.m_gcmpFaceRotation[i]];
+        if (sei.m_gcmpFaceIndex[i] == 1)
+          rotation = (rotation + 270) % 360 + 360;
+        else if (sei.m_gcmpFaceIndex[i] == 2)
+          rotation = (rotation + 180) % 360 + 360;
+        else
+          rotation += 360;
+        if (i % packingTypeTable[sei.m_gcmpPackingType][1] == 0)
+          packingTypeStr += "   ";
+        packingTypeStr += std::to_string(sei.m_gcmpFaceIndex[i]) + " " + std::to_string(rotation) + " ";
+      }
+#endif
       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;
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+        if (!m_360SEIMessageDumped)
+        {
+          double a = sei.m_gcmpFunctionCoeffU[i] * 1.0 / 125;
+          double b = sei.m_gcmpFunctionCoeffV[i] * 1.0 / 125;
+          oss.str("");
+          oss<<a;
+          std::string a_str = oss.str();
+          oss.str("");
+          oss<<b;
+          std::string b_str = oss.str();
+          gcmpsettingsStr += a_str + " " + std::to_string(sei.m_gcmpFunctionUAffectedByVFlag[i]) + " " + b_str + " " + std::to_string(sei.m_gcmpFunctionVAffectedByUFlag[i]) + "   ";
+        }
+#endif
       }
     }
     sei_read_flag( pDecodedMessageOutputStream,        val,    "gcmp_guard_band_flag" );                  sei.m_gcmpGuardBandFlag = val;
@@ -1332,6 +1440,42 @@ void SEIReader::xParseSEIGeneralizedCubemapProjection(SEIGeneralizedCubemapProje
       sei_read_flag( pDecodedMessageOutputStream,      val,    "gcmp_guard_band_boundary_exterior_flag" ); sei.m_gcmpGuardBandBoundaryExteriorFlag = val;
       sei_read_code( pDecodedMessageOutputStream,   4, val,    "gcmp_guard_band_samples_minus1" );         sei.m_gcmpGuardBandSamplesMinus1 = val;
     }
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+    if (!m_360SEIMessageDumped && !decoded360MessageFileName.empty())
+    {
+      FILE *fp = fopen(decoded360MessageFileName.c_str(), "w");
+      if (fp)
+      {
+        int chromaFormatTable[4] = {400, 420, 422, 444};
+        fprintf(fp, "InputBitDepth                 : %d    # Input bitdepth\n", sps->getBitDepth(CHANNEL_TYPE_LUMA));
+        fprintf(fp, "InputChromaFormat             : %d    # Ratio of luminance to chrominance samples\n", chromaFormatTable[sps->getChromaFormatIdc()]);
+        fprintf(fp, "SourceWidth                   : %d    # Input  frame width\n", sps->getMaxPicWidthInLumaSamples());
+        fprintf(fp, "SourceHeight                  : %d    # Input  frame height\n\n", sps->getMaxPicHeightInLumaSamples());
+
+        fprintf(fp, "InputGeometryType             : 15    # 0: equirectangular; 1: cubemap; 2: equalarea; this should be in the cfg of per sequence.\n");
+
+        packingTypeStr += " # frame packing order: numRows numCols Row0Idx0 ROT Row0Idx1 ROT ... Row1...";
+        gcmpsettingsStr += " # mapping function parameters for each face: u coefficient, u affected by v flag, v coefficient, v affected by u flag";
+        fprintf(fp, "%s\n", packingTypeStr.c_str());
+        fprintf(fp, "InputGCMPMappingType              : %d                                   # 0: CMP; 1: EAC; 2: parameterized CMP\n", (int)sei.m_gcmpMappingFunctionType);
+        if ((int)sei.m_gcmpMappingFunctionType == 2)
+          fprintf(fp, "%s\n", gcmpsettingsStr.c_str());
+        fprintf(fp, "InputGCMPPaddingFlag              : %d                                  # 0: input without guard bands; 1: input with guard bands\n", sei.m_gcmpGuardBandFlag);
+        if (sei.m_gcmpGuardBandFlag)
+        {
+          fprintf(fp, "InputGCMPPaddingType              : %d                                   # 0: unspecified(repetitive padding is used); 1: repetitive padding; 2: copy from neighboring face; 3: geometry padding\n", (int)sei.m_gcmpGuardBandType);
+          fprintf(fp, "InputGCMPPaddingExteriorFlag      : %d                                  # 0: guard bands only on discontinuous edges; 1: guard bands on both discontinuous edges and frame boundaries\n", sei.m_gcmpGuardBandBoundaryExteriorFlag);
+          fprintf(fp, "InputGCMPPaddingSize              : %d                                   # guard band size for input GCMP\n", (int)sei.m_gcmpGuardBandSamplesMinus1 + 1);
+        }
+        fclose(fp);
+        m_360SEIMessageDumped = true;
+      }
+      else
+      {
+        msg( ERROR, "File %s could not be opened.\n", decoded360MessageFileName.c_str() );
+      }
+    }
+#endif
   }
 }
 
diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h
index 140a064deac148c8901a54592a47e6bfc2a99baa..43b9a7e7bfd397d7619ed32aa60ca9e277b70ac9 100644
--- a/source/Lib/DecoderLib/SEIread.h
+++ b/source/Lib/DecoderLib/SEIread.h
@@ -53,18 +53,37 @@ class InputBitstream;
 class SEIReader: public VLCReader
 {
 public:
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  SEIReader() : m_360SEIMessageDumped(false) {};
+#else
   SEIReader() {};
+#endif
   virtual ~SEIReader() {};
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  void parseSEImessage(InputBitstream* bs, 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, std::string decoded360MessageFileName);
+#else
   void parseSEImessage(InputBitstream* bs, 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);
+#endif
 
 protected:
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  bool m_360SEIMessageDumped;
+#endif
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  void xReadSEImessage                        (SEIMessages& seis, const NalUnitType nalUnitType, const uint32_t nuh_layer_id, const uint32_t temporalId, const VPS *vps, const SPS *sps, HRD &hrd, std::ostream *pDecodedMessageOutputStream, std::string decoded360MessageFileName);
+#else
   void xReadSEImessage                        (SEIMessages& seis, const NalUnitType nalUnitType, const uint32_t nuh_layer_id, const uint32_t temporalId, const VPS *vps, const SPS *sps, HRD &hrd, std::ostream *pDecodedMessageOutputStream);
+#endif
   void xParseSEIuserDataUnregistered          (SEIuserDataUnregistered &sei,          uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIDecodingUnitInfo              (SEIDecodingUnitInfo& sei,              uint32_t payloadSize, const SEIBufferingPeriod& bp, const uint32_t temporalId, std::ostream *pDecodedMessageOutputStream);
   void xParseSEIDecodedPictureHash            (SEIDecodedPictureHash& sei,            uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIBufferingPeriod               (SEIBufferingPeriod& sei,               uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream);
   void xParseSEIPictureTiming                 (SEIPictureTiming& sei,                 uint32_t payloadSize, const uint32_t temporalId, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream);
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  void xParseSEIScalableNesting               (SEIScalableNesting& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS *vps, const SPS *sps, std::ostream *decodedMessageOutputStream, std::string decoded360MessageFileName);
+#else
   void xParseSEIScalableNesting               (SEIScalableNesting& sei, const NalUnitType nalUnitType, const uint32_t nuhLayerId, uint32_t payloadSize, const VPS *vps, const SPS *sps, std::ostream *decodedMessageOutputStream);
+#endif
   void xParseSEIFrameFieldinfo                (SEIFrameFieldInfo& sei, const SEIPictureTiming& pt, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream);
   void xParseSEIDependentRAPIndication        (SEIDependentRAPIndication& sei,        uint32_t payLoadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIFramePacking                  (SEIFramePacking& sei,                  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
@@ -73,11 +92,19 @@ protected:
 #if U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI
   void xParseSEIAlternativeTransferCharacteristics(SEIAlternativeTransferCharacteristics& sei,              uint32_t payLoadSize,                     std::ostream *pDecodedMessageOutputStream);
 #endif
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  void xParseSEIEquirectangularProjection     (SEIEquirectangularProjection &sei, const SPS *sps,     uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream, std::string decoded360MessageFileName);
+#else
   void xParseSEIEquirectangularProjection     (SEIEquirectangularProjection &sei,     uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+#endif
   void xParseSEISphereRotation                (SEISphereRotation &sei,                uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIOmniViewport                  (SEIOmniViewport& sei,                  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIRegionWisePacking             (SEIRegionWisePacking& sei,             uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+#if JVET_S0257_DUMP_360SEI_MESSAGE
+  void xParseSEIGeneralizedCubemapProjection  (SEIGeneralizedCubemapProjection &sei, const SPS *sps,  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream, std::string decoded360MessageFileName);
+#else
   void xParseSEIGeneralizedCubemapProjection  (SEIGeneralizedCubemapProjection &sei,  uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
+#endif
   void xParseSEISubpictureLevelInfo           (SEISubpicureLevelInfo& sei,            uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEISampleAspectRatioInfo         (SEISampleAspectRatioInfo& sei,         uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIUserDataRegistered            (SEIUserDataRegistered& sei,            uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);