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);