diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp index 6a503fec6b227a776a27de68ffc805b5852714d5..7c13731dfb649bfe2a75a885963504ccdac65f1a 100644 --- a/source/App/DecoderApp/DecApp.cpp +++ b/source/App/DecoderApp/DecApp.cpp @@ -158,6 +158,18 @@ uint32_t DecApp::decode() } #endif +#if JVET_AH0161_REGION_PACKING_INFORMATION_SEI + if (!m_packedRegionsInfoSEIFileName.empty()) + { + std::ofstream ofile(m_packedRegionsInfoSEIFileName.c_str()); + if (!ofile.good() || !ofile.is_open()) + { + fprintf(stderr, "\nUnable to open file '%s' for writing packed regions info SEI\n", m_packedRegionsInfoSEIFileName.c_str()); + exit(EXIT_FAILURE); + } + } +#endif + // main decoder loop bool loopFiltered[MAX_VPS_LAYERS] = { false }; @@ -1325,6 +1337,12 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId ) { xOutputObjectMaskInfos(pcPic); } +#endif +#if JVET_AH0161_REGION_PACKING_INFORMATION_SEI + if (!m_packedRegionsInfoSEIFileName.empty()) + { + xOutputPackedRegionsInfo(pcPic); + } #endif // update POC of display order m_iPOCLastDisplay = pcPic->getPOC(); @@ -1581,7 +1599,13 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId ) xOutputObjectMaskInfos(pcPic); } #endif - // update POC of display order +#if JVET_AH0161_REGION_PACKING_INFORMATION_SEI + if (!m_packedRegionsInfoSEIFileName.empty()) + { + xOutputPackedRegionsInfo(pcPic); + } +#endif + // update POC of display order m_iPOCLastDisplay = pcPic->getPOC(); // erase non-referenced picture in the reference picture list after display @@ -1887,6 +1911,66 @@ void DecApp::xOutputObjectMaskInfos(Picture* pcPic) } #endif +#if JVET_AH0161_REGION_PACKING_INFORMATION_SEI +void DecApp::xOutputPackedRegionsInfo(Picture* pcPic) +{ + SEIMessages seis = getSeisByType(pcPic->SEIs, SEI::PayloadType::PACKED_REGIONS_INFO); + if (!seis.empty()) + { + const SEIPackedRegionsInfo& sei = *((SEIPackedRegionsInfo*)seis.front()); + FILE* fp = fopen(m_packedRegionsInfoSEIFileName.c_str(), "a"); + if (fp == nullptr) + { + std::cout << "Not able to open file for writing packed regions info SEI messages" << std::endl; + } + else + { + fprintf(fp, "SEIPRICancelFlag : %d\n", sei.m_cancelFlag); + fprintf(fp, "SEIPRIPersistenceFlag : %d\n", sei.m_persistenceFlag); + fprintf(fp, "SEIPRINumRegionsMinus1 : %d\n", sei.m_numRegionsMinus1); + fprintf(fp, "SEIPRIUseMaxDimensionsFlag : %d\n", sei.m_useMaxDimensionsFlag); + fprintf(fp, "SEIPRILog2UnitSize : %d\n", sei.m_log2UnitSize); + fprintf(fp, "SEIPRIRegionSizeLenMinus1 : %d\n", sei.m_regionSizeLenMinus1); + fprintf(fp, "SEIPRIRegionIdPresentFlag : %d\n", sei.m_regionIdPresentFlag); + fprintf(fp, "SEIPRITargetPicParamsPresentFlag : %d\n", sei.m_targetPicParamsPresentFlag); + if (sei.m_targetPicParamsPresentFlag) + { + fprintf(fp, "SEIPRITargetPicWidthMinus1 : %d\n", sei.m_targetPicWidthMinus1); + fprintf(fp, "SEIPRITargetPicHeightMinus1 : %d\n", sei.m_targetPicHeightMinus1); + } + fprintf(fp, "SEIPRINumResamplingRatiosMinus1 : %d\n", sei.m_numResamplingRatiosMinus1); + xOutputPackedRegionsInfoVector(fp, "SEIPRIResamplingWidthNumMinus1 :", sei.m_resamplingWidthNumMinus1); + xOutputPackedRegionsInfoVector(fp, "SEIPRIResamplingWidthDenomMinus1 :", sei.m_resamplingWidthDenomMinus1); + xOutputPackedRegionsInfoVector(fp, "SEIPRIResamplingHeightNumMinus1 :", sei.m_resamplingHeightNumMinus1); + xOutputPackedRegionsInfoVector(fp, "SEIPRIResamplingHeightDenomMinus1 :", sei.m_resamplingHeightDenomMinus1); + xOutputPackedRegionsInfoVector(fp, "SEIPRIRegionId :", sei.m_regionId); + xOutputPackedRegionsInfoVector(fp, "SEIPRIRegionTopLeftInUnitsX :", sei.m_regionTopLeftInUnitsX); + xOutputPackedRegionsInfoVector(fp, "SEIPRIRegionTopLeftInUnitsY :", sei.m_regionTopLeftInUnitsY); + xOutputPackedRegionsInfoVector(fp, "SEIPRIRegionWidthInUnitsMinus1 :", sei.m_regionWidthInUnitsMinus1); + xOutputPackedRegionsInfoVector(fp, "SEIPRIRegionHeightInUnitsMinus1 :", sei.m_regionHeightInUnitsMinus1); + xOutputPackedRegionsInfoVector(fp, "SEIPRIResamplingRatioIdx :", sei.m_resamplingRatioIdx); + if (sei.m_targetPicParamsPresentFlag) + { + xOutputPackedRegionsInfoVector(fp, "SEIPRITargetRegionTopLeftX :", sei.m_targetRegionTopLeftX); + xOutputPackedRegionsInfoVector(fp, "SEIPRITargetRegionTopLeftY :", sei.m_targetRegionTopLeftY); + } + fclose(fp); + } + } +} + +void DecApp::xOutputPackedRegionsInfoVector(FILE* fp, char* paramName, const std::vector<uint32_t>& l) +{ + fprintf(fp, paramName); + for (auto it : l) + { + fprintf(fp, " %d", it); + } + fprintf(fp, "\n"); +} + +#endif + /** \param nalu Input nalu to check whether its LayerId is within targetDecLayerIdSet */ bool DecApp::xIsNaluWithinTargetDecLayerIdSet( const InputNALUnit* nalu ) const diff --git a/source/App/DecoderApp/DecApp.h b/source/App/DecoderApp/DecApp.h index 68be62618c8d5e850e8a51d838d1482a1037693a..6193799f73d04d02c5fd39ce96bd195a06774ec4 100644 --- a/source/App/DecoderApp/DecApp.h +++ b/source/App/DecoderApp/DecApp.h @@ -138,6 +138,10 @@ private: #if JVET_AF0088_OMI_SEI void xOutputObjectMaskInfos(Picture* pcPic); #endif +#if JVET_AH0161_REGION_PACKING_INFORMATION_SEI + void xOutputPackedRegionsInfo(Picture* pcPic); + void xOutputPackedRegionsInfoVector(FILE* fp, char* paramName, const std::vector<uint32_t>& v); +#endif }; //! \} diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp index f18ca29b14a29245f587f4d88d548113b008b794..5a332537ff8263a225acb4ccd503497eebca7d79 100644 --- a/source/App/DecoderApp/DecAppCfg.cpp +++ b/source/App/DecoderApp/DecAppCfg.cpp @@ -108,6 +108,9 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] ) ("OutputDecodedSEIMessagesFilename", m_outputDecodedSEIMessagesFilename, std::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, std::string(""), "When non empty, output decoded 360 SEI messages to the indicated file.\n") +#endif +#if JVET_AH0161_REGION_PACKING_INFORMATION_SEI + ("SEIPackedRegionsInfoFilename", m_packedRegionsInfoSEIFileName, std::string(""), "Packed regions info output file name. If empty, no object information will be saved\n") #endif ("ClipOutputVideoToRec709Range", m_clipOutputVideoToRec709Range, 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.") diff --git a/source/App/DecoderApp/DecAppCfg.h b/source/App/DecoderApp/DecAppCfg.h index 9a4171e9e2c4226252ab065dfba7fbf0519314ea..5cdb8e3e8c51cfad17021a56c0b0253c75ce51ed 100644 --- a/source/App/DecoderApp/DecAppCfg.h +++ b/source/App/DecoderApp/DecAppCfg.h @@ -86,6 +86,9 @@ protected: #if JVET_S0257_DUMP_360SEI_MESSAGE std::string m_outputDecoded360SEIMessagesFilename; ///< filename to output decoded 360 SEI messages to. #endif +#if JVET_AH0161_REGION_PACKING_INFORMATION_SEI + std::string m_packedRegionsInfoSEIFileName; ///< packed regions file name +#endif std::string m_shutterIntervalPostFileName; ///< output Post Filtering file name #if JVET_AF0167_MULTI_PLANE_IMAGE_INFO_SEI