diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp index b6584f0754dd08616524ea3096dae8904859a3eb..0e4e9c1f519f4ad843059deafa4a3df886d29d4b 100644 --- a/source/App/DecoderApp/DecApp.cpp +++ b/source/App/DecoderApp/DecApp.cpp @@ -95,6 +95,18 @@ uint32_t DecApp::decode() } } +#if JVET_P2008_OUTPUT_LOG + if (!m_oplFilename.empty() && m_oplFilename!="-") + { + m_oplFilename += ".opl"; + m_oplFileStream.open(m_oplFilename.c_str(), std::ios::out); + if (!m_oplFileStream.is_open() || !m_oplFileStream.good()) + { + EXIT( "Unable to open file "<< m_oplFilename.c_str() << " to write an opl-file for conformance testing (see JVET-P2008 for details)"); + } + } +#endif //JVET_P2008_OUTPUT_LOG + // create & initialize internal classes xCreateDecLib(); @@ -656,6 +668,21 @@ bool DecApp::isNewAccessUnit( bool newPicture, ifstream *bitstreamFile, class In return ret; } +#if JVET_P2008_OUTPUT_LOG +void DecApp::writeLineToOutputLog(Picture * pcPic) +{ + if (m_oplFileStream.is_open() && m_oplFileStream.good()) + { + const SPS* sps = pcPic->cs->sps; + PictureHash recon_digest; + auto numChar = calcMD5(((const Picture*)pcPic)->getRecoBuf(), recon_digest, sps->getBitDepths()); + + + m_oplFileStream << std::setw(8) << pcPic->getPOC() << "," << std::setw(5) << pcPic->Y().width << "," << std::setw(5) << pcPic->Y().height << "," << hashToString(recon_digest, numChar) << "\n"; + } +} +#endif // JVET_P2008_OUTPUT_LOG + // ==================================================================================================================== // Protected member functions // ==================================================================================================================== @@ -802,6 +829,10 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId ) NUM_CHROMA_FORMAT, isTff ); } } +#if JVET_P2008_OUTPUT_LOG + writeLineToOutputLog(pcPicTop); + writeLineToOutputLog(pcPicBottom); +#endif // update POC of display order m_iPOCLastDisplay = pcPicBottom->getPOC(); @@ -860,6 +891,9 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId ) NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range ); } } +#if JVET_P2008_OUTPUT_LOG + writeLineToOutputLog(pcPic); +#endif #if HEVC_SEI if (m_seiMessageFileStream.is_open()) @@ -929,7 +963,10 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId ) conf.getWindowBottomOffset() * SPS::getWinUnitY( pcPicTop->cs->sps->getChromaFormatIdc() ), NUM_CHROMA_FORMAT, isTff ); } - +#if JVET_P2008_OUTPUT_LOG + writeLineToOutputLog(pcPicTop); + writeLineToOutputLog(pcPicBottom); +#endif // update POC of display order m_iPOCLastDisplay = pcPicBottom->getPOC(); @@ -997,7 +1034,9 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId ) NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range ); } } - +#if JVET_P2008_OUTPUT_LOG + writeLineToOutputLog(pcPic); +#endif #if HEVC_SEI if (m_seiMessageFileStream.is_open()) { diff --git a/source/App/DecoderApp/DecApp.h b/source/App/DecoderApp/DecApp.h index 2d5c0fcdae81b11c04f0ca70ac489f23aac9cc86..b355a04e46f4bf74d118980e1cc7255b20f3fd7e 100644 --- a/source/App/DecoderApp/DecApp.h +++ b/source/App/DecoderApp/DecApp.h @@ -66,6 +66,12 @@ private: // for output control int m_iPOCLastDisplay; ///< last POC in display order std::ofstream m_seiMessageFileStream; ///< Used for outputing SEI messages. + +#if JVET_P2008_OUTPUT_LOG + std::ofstream m_oplFileStream; ///< Used to output log file for confomance testing +#endif //JVET_P2008_OUTPUT_LOG + + #if HEVC_SEI ColourRemapping m_cColourRemapping; ///< colour remapping handler #endif @@ -86,6 +92,11 @@ private: bool deriveOutputLayerSet(); ///< derive OLS and layer sets bool isNewPicture(ifstream *bitstreamFile, class InputByteStream *bytestream); ///< check if next NAL unit will be the first NAL unit from a new picture bool isNewAccessUnit(bool newPicture, ifstream *bitstreamFile, class InputByteStream *bytestream); ///< check if next NAL unit will be the first NAL unit from a new access unit + +#if JVET_P2008_OUTPUT_LOG + void writeLineToOutputLog(Picture * pcPic); +#endif // JVET_P2008_OUTPUT_LOG + }; //! \} diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp index 310251e87e3cfcd792d72cd2cfa9336ff1d7ec72..63808add02c8f034a9c3c645afe4c65742a14cc4 100644 --- a/source/App/DecoderApp/DecAppCfg.cpp +++ b/source/App/DecoderApp/DecAppCfg.cpp @@ -77,6 +77,10 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] ) ("BitstreamFile,b", m_bitstreamFileName, string(""), "bitstream input file name") ("ReconFile,o", m_reconFileName, string(""), "reconstructed YUV output file name\n") +#if JVET_P2008_OUTPUT_LOG + ("OplFile,-opl", m_oplFilename , string(""), "opl-file name without extension for conformance testing\n") +#endif //JVET_P2008_OUTPUT_LOG + #if ENABLE_SIMD_OPT ("SIMD", ignore, string(""), "SIMD extension to use (SCALAR, SSE41, SSE42, AVX, AVX2, AVX512), default: the highest supported extension\n") #endif @@ -223,6 +227,10 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] ) DecAppCfg::DecAppCfg() : m_bitstreamFileName() , m_reconFileName() +#if JVET_P2008_OUTPUT_LOG +, m_oplFilename() +#endif //JVET_P2008_OUTPUT_LOG + , m_iSkipFrame(0) // m_outputBitDepth array initialised below , m_outputColourSpaceConvert(IPCOLOURSPACE_UNCHANGED) diff --git a/source/App/DecoderApp/DecAppCfg.h b/source/App/DecoderApp/DecAppCfg.h index cc45bfdd88ffbbf828ae96a755e7a09d9c55b059..1ded0629224d0f5c965ee49206507e8970871885 100644 --- a/source/App/DecoderApp/DecAppCfg.h +++ b/source/App/DecoderApp/DecAppCfg.h @@ -69,6 +69,12 @@ 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_P2008_OUTPUT_LOG + std::string m_oplFilename; ///< filename to output conformance log. +#endif //JVET_P2008_OUTPUT_LOG + + bool m_bClipOutputVideoToRec709Range; ///< If true, clip the output video to the Rec 709 range on saving. bool m_packedYUVMode; ///< If true, output 10-bit and 12-bit YUV data as 5-byte and 3-byte (respectively) packed YUV data std::string m_cacheCfgFile; ///< Config file of cache model diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h index 1c259541cde70d2bdf5b85ed760b00cb80b6dc97..aad5a47fc4b1f207ee4eb6919826411eba2fa8b1 100644 --- a/source/Lib/CommonLib/Picture.h +++ b/source/Lib/CommonLib/Picture.h @@ -299,6 +299,10 @@ public: int calcAndPrintHashStatus(const CPelUnitBuf& pic, const class SEIDecodedPictureHash* pictureHashSEI, const BitDepths &bitDepths, const MsgLevel msgl); +#if JVET_P2008_OUTPUT_LOG +uint32_t calcMD5(const CPelUnitBuf& pic, PictureHash &digest, const BitDepths &bitDepths); +std::string hashToString(const PictureHash &digest, int numChar); +#endif // JVET_P2008_OUTPUT_LOG typedef std::list<Picture*> PicList; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 756850b86b059df6a67a94fd810dd00696bd4a68..fefdbfe7a98263909b0154bed9ca34afe2315584 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,7 @@ #include <assert.h> #include <cassert> +#define JVET_P2008_OUTPUT_LOG 1 // Output log file for conformance tests #define JVET_Q0110_Q0785_CHROMA_BDPCM_420 1 // JVET-Q0110/Q0785: Enable chroma BDPCM for 420, separate contexts for chroma BDPCM and bug-fixes. #define JVET_Q0512_ENC_CHROMA_TS_ACT 1 // JVET-Q0512: encoder-side improvement on enabling chroma transform-skip for ACT