From 049964e0634f291f574583abd0e44f5569bbf350 Mon Sep 17 00:00:00 2001 From: Tobias Hinz <tobias.hinz@hhi.fraunhofer.de> Date: Wed, 30 Jan 2019 11:08:05 +0100 Subject: [PATCH] merged M0055 changes --- source/App/EncoderApp/EncApp.cpp | 3 ++ source/App/EncoderApp/EncAppCfg.cpp | 3 ++ source/App/EncoderApp/EncAppCfg.h | 3 ++ source/Lib/CommonLib/CodingStructure.cpp | 11 ++++++ source/Lib/CommonLib/TypeDef.h | 2 ++ source/Lib/DecoderLib/DecLib.cpp | 45 ++++++++++++++++++++++++ source/Lib/DecoderLib/DecLib.h | 17 +++++++-- source/Lib/DecoderLib/DecSlice.cpp | 12 +++++++ source/Lib/DecoderLib/DecSlice.h | 4 +++ source/Lib/EncoderLib/EncCfg.h | 8 ++++- source/Lib/EncoderLib/EncGOP.cpp | 18 ++++++++++ source/Lib/EncoderLib/EncSlice.cpp | 20 ++++++++++- 12 files changed, 142 insertions(+), 4 deletions(-) diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index eee3ac264..a091bd770 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -536,6 +536,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setForceDecodeBitstream1 ( m_forceDecodeBitstream1 ); m_cEncLib.setStopAfterFFtoPOC ( m_stopAfterFFtoPOC ); m_cEncLib.setBs2ModPOCAndType ( m_bs2ModPOCAndType ); +#if JVET_M0055_DEBUG_CTU + m_cEncLib.setDebugCTU ( m_debugCTU ); +#endif #if ENABLE_SPLIT_PARALLELISM m_cEncLib.setNumSplitThreads ( m_numSplitThreads ); m_cEncLib.setForceSingleSplitThread ( m_forceSplitSequential ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index a1709b0d3..a432e0fba 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1289,6 +1289,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("ForceSingleSplitThread", m_forceSplitSequential, false, "Force single thread execution even if taking the parallelized path") ("NumWppThreads", m_numWppThreads, 1, "Number of threads used to run WPP-style parallelization") ("NumWppExtraLines", m_numWppExtraLines, 0, "Number of additional wpp lines to switch when threads are blocked") +#if JVET_M0055_DEBUG_CTU + ("DebugCTU", m_debugCTU, -1, "If DebugBitstream is present, load frames up to this POC from this bitstream. Starting with DebugPOC-frame at CTUline containin debug CTU.") +#endif #if ENABLE_WPP_PARALLELISM ("EnsureWppBitEqual", m_ensureWppBitEqual, true, "Ensure the results are equal to results with WPP-style parallelism, even if WPP is off") #else diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index b1910b56b..7bc2e0413 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -526,6 +526,9 @@ protected: int m_verbosity; std::string m_decodeBitstreams[2]; ///< filename for decode bitstreams. +#if JVET_M0055_DEBUG_CTU + int m_debugCTU; +#endif int m_switchPOC; ///< dbg poc. int m_switchDQP; ///< switch DQP. int m_fastForwardToPOC; ///< get to encoding the specified POC as soon as possible by skipping temporal layers irrelevant for the specified POC diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp index 8d5013fcc..759587a55 100644 --- a/source/Lib/CommonLib/CodingStructure.cpp +++ b/source/Lib/CommonLib/CodingStructure.cpp @@ -966,6 +966,17 @@ void CodingStructure::copyStructure( const CodingStructure& other, const Channel // copy data to picture picture->getRecoBuf( area ).copyFrom( recoBuf ); +#if JVET_M0055_DEBUG_CTU + + // required for DebugCTU + int numCh = ::getNumberValidChannels( area.chromaFormat ); + for( int i = 0; i < numCh; i++ ) + { + const size_t _area = unitScale[i].scaleArea( area.blocks[i].area() ); + + memcpy( m_isDecomp[i], other.m_isDecomp[i], sizeof( *m_isDecomp[0] ) * _area ); + } +#endif } } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index cb70e1dce..089b76b31 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_M0055_DEBUG_CTU 1 // DebugCTU encoder debug option + #define JVET_M0116_ATMVP_LEFT_NB_FOR_OFFSET 1 // Only use left neighbor for ATMVP offset derivation, from M0273, M0240, M0116, M0338, M0204 #define JVET_M0063_BDOF_FIX 1 // BDOF bitdepth bugfix diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 09b493dd5..668ba3d37 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -56,7 +56,11 @@ #include "CommonLib/CodingStatistics.h" #endif +#if JVET_M0055_DEBUG_CTU +bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::string& bitstreamFileName, bool bDecodeUntilPocFound /* = false */, int debugCTU /* = -1*/, int debugPOC /* = -1*/ ) +#else bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::string& bitstreamFileName, bool bDecodeUntilPocFound /* = false */ ) +#endif { int poc; PicList* pcListPic = NULL; @@ -91,6 +95,10 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri #endif ); +#if JVET_M0055_DEBUG_CTU + pcDecLib->setDebugCTU( debugCTU ); + pcDecLib->setDebugPOC( debugPOC ); +#endif pcDecLib->setDecodedPictureHashSEIEnabled( true ); bFirstCall = false; @@ -156,6 +164,9 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri CHECK( expectedPoc != poc, "mismatch in POC - check encoder configuration" ); +#if JVET_M0055_DEBUG_CTU + if( debugCTU < 0 || poc != debugPOC ) +#endif for( int i = 0; i < pic->slices.size(); i++ ) { if( pcEncPic->slices.size() <= i ) @@ -168,6 +179,29 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri pcEncPic->cs->slice = pcEncPic->slices.back(); +#if JVET_M0055_DEBUG_CTU + if( debugCTU >= 0 && poc == debugPOC ) + { + pcEncPic->cs->initStructData(); + + pcEncPic->cs->copyStructure( *pic->cs, CH_L, true, true ); + + if( CS::isDualITree( *pcEncPic->cs ) ) + { + pcEncPic->cs->copyStructure( *pic->cs, CH_C, true, true ); + } + + for( auto &cu : pcEncPic->cs->cus ) + { + cu->slice = pcEncPic->cs->slice; + } +#if JVET_L0266_HMVP + pcEncPic->cs->slice->copyMotionLUTs( pic->slices.back()->getMotionLUTs(), pcEncPic->slices.back()->getMotionLUTs()); +#endif + } + else + { +#endif if ( pic->cs->sps->getSAOEnabledFlag() ) { pcEncPic->copySAO( *pic, 0 ); @@ -198,6 +232,9 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri { pcEncPic->cs->copyStructure( *pic->cs, CH_C, true, true ); } +#if JVET_M0055_DEBUG_CTU + } +#endif goOn = false; // exit the loop return bRet = true; break; @@ -370,6 +407,10 @@ DecLib::DecLib() , m_numberOfChecksumErrorsDetected(0) , m_warningMessageSkipPicture(false) , m_prefixSEINALUs() +#if JVET_M0055_DEBUG_CTU + , m_debugPOC( -1 ) + , m_debugCTU( -1 ) +#endif { #if ENABLE_SIMD_OPT_BUFFER g_pelBufOP.initPelBufOpsX86(); @@ -1235,7 +1276,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl // Decode a picture +#if JVET_M0055_DEBUG_CTU + m_cSliceDecoder.decompressSlice( pcSlice, &( nalu.getBitstream() ), ( m_pcPic->poc == getDebugPOC() ? getDebugCTU() : -1 ) ); +#else m_cSliceDecoder.decompressSlice( pcSlice, &(nalu.getBitstream()) ); +#endif m_bFirstSliceInPicture = false; if (pcSlice->getSPS()->getSpsNext().getIBCMode()) diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h index 687ea822a..c43ae4fcb 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -59,8 +59,11 @@ class InputNALUnit; //! \ingroup DecoderLib //! \{ -bool tryDecodePicture( Picture* pcPic, const int expectedPoc, const std::string& bitstreamFileName, bool bDecodeUntilPocFound = false ); -// ==================================================================================================================== +#if JVET_M0055_DEBUG_CTU +bool tryDecodePicture( Picture* pcPic, const int expectedPoc, const std::string& bitstreamFileName, bool bDecodeUntilPocFound = false, int debugCTU = -1, int debugPOC = -1 ); +#else + bool tryDecodePicture( Picture* pcPic, const int expectedPoc, const std::string& bitstreamFileName, bool bDecodeUntilPocFound = false ); +#endif// ==================================================================================================================== // Class definition // ==================================================================================================================== @@ -122,6 +125,10 @@ private: bool m_warningMessageSkipPicture; std::list<InputNALUnit*> m_prefixSEINALUs; /// Buffered up prefix SEI NAL Units. +#if JVET_M0055_DEBUG_CTU + int m_debugPOC; + int m_debugCTU; +#endif public: DecLib(); virtual ~DecLib(); @@ -152,6 +159,12 @@ public: void setDecodedSEIMessageOutputStream(std::ostream *pOpStream) { m_pDecodedSEIOutputStream = pOpStream; } uint32_t getNumberOfChecksumErrorsDetected() const { return m_numberOfChecksumErrorsDetected; } +#if JVET_M0055_DEBUG_CTU + int getDebugCTU( ) const { return m_debugCTU; } + void setDebugCTU( int debugCTU ) { m_debugCTU = debugCTU; } + int getDebugPOC( ) const { return m_debugPOC; }; + void setDebugPOC( int debugPOC ) { m_debugPOC = debugPOC; }; +#endif protected: void xUpdateRasInit(Slice* slice); diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp index 9f53af255..13be91a5c 100644 --- a/source/Lib/DecoderLib/DecSlice.cpp +++ b/source/Lib/DecoderLib/DecSlice.cpp @@ -70,7 +70,11 @@ void DecSlice::init( CABACDecoder* cabacDecoder, DecCu* pcCuDecoder ) m_pcCuDecoder = pcCuDecoder; } +#if JVET_M0055_DEBUG_CTU +void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int debugCTU ) +#else void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream ) +#endif { //-- For time output for each slice slice->startProcessingTimer(); @@ -231,6 +235,14 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream ) cs.slice->resetMotionLUTs(); } +#if JVET_M0055_DEBUG_CTU + + if( ctuRsAddr == debugCTU ) + { + isLastCtuOfSliceSegment = true; // get out here + break; + } +#endif isLastCtuOfSliceSegment = cabacReader.coding_tree_unit( cs, ctuArea, pic->m_prevQP, ctuRsAddr ); m_pcCuDecoder->decompressCtu( cs, ctuArea ); diff --git a/source/Lib/DecoderLib/DecSlice.h b/source/Lib/DecoderLib/DecSlice.h index 10304cf0e..f4a14e5b7 100644 --- a/source/Lib/DecoderLib/DecSlice.h +++ b/source/Lib/DecoderLib/DecSlice.h @@ -77,7 +77,11 @@ public: void create (); void destroy (); +#if JVET_M0055_DEBUG_CTU + void decompressSlice ( Slice* slice, InputBitstream* bitstream, int debugCTU ); +#else void decompressSlice ( Slice* slice, InputBitstream* bitstream ); +#endif }; //! \} diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 24561541a..ce5c46ea5 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -549,6 +549,9 @@ protected: int m_switchDQP; ///< dqp applied to switchPOC and subsequent pictures. int m_fastForwardToPOC; ///< bool m_stopAfterFFtoPOC; ///< +#if JVET_M0055_DEBUG_CTU + int m_debugCTU; ///< dbg ctu +#endif bool m_bs2ModPOCAndType; @@ -1425,7 +1428,10 @@ public: bool getStopAfterFFtoPOC() const { return m_stopAfterFFtoPOC; } void setBs2ModPOCAndType( bool b ) { m_bs2ModPOCAndType = b; } bool getBs2ModPOCAndType() const { return m_bs2ModPOCAndType; } - +#if JVET_M0055_DEBUG_CTU + void setDebugCTU( int i ) { m_debugCTU = i; } + int getDebugCTU() const { return m_debugCTU; } +#endif #if ENABLE_SPLIT_PARALLELISM void setNumSplitThreads( int n ) { m_numSplitThreads = n; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index bc863bb6c..6ab53a217 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1207,11 +1207,29 @@ void trySkipOrDecodePicture( bool& decPic, bool& encPic, const EncCfg& cfg, Pict else { // update decode decision +#if JVET_M0055_DEBUG_CTU + bool dbgCTU = cfg.getDebugCTU() != -1 && cfg.getSwitchPOC() == pcPic->getPOC(); + + if( ( bDecode1stPart = ( cfg.getSwitchPOC() != pcPic->getPOC() ) || dbgCTU ) && ( bDecode1stPart = tryDecodePicture( pcPic, pcPic->getPOC(), cfg.getDecodeBitstream( 0 ), false, cfg.getDebugCTU(), cfg.getSwitchPOC() ) ) ) + { + if( dbgCTU ) + { + encPic = true; + decPic = false; + bDecode1stPart = false; + + return; + } + decPic = bDecode1stPart; + return; + } +#else if( ( bDecode1stPart = ( cfg.getSwitchPOC() != pcPic->getPOC() )) && ( bDecode1stPart = tryDecodePicture( pcPic, pcPic->getPOC(), cfg.getDecodeBitstream( 0 ), false ) ) ) { decPic = bDecode1stPart; return; } +#endif else if( pcPic->getPOC() ) { // reset decoder if used and not required any further diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 44bca844f..ee2a8453f 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1255,7 +1255,11 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c cs.slice = pcSlice; - if (startCtuTsAddr == 0) +#if JVET_M0055_DEBUG_CTU + if( startCtuTsAddr == 0 && ( pcSlice->getPOC() != m_pcCfg->getSwitchPOC() || -1 == m_pcCfg->getDebugCTU() ) ) +#else + if( startCtuTsAddr == 0 ) +#endif { cs.initStructData (pcSlice->getSliceQp(), pcSlice->getPPS()->getTransquantBypassEnabledFlag()); } @@ -1490,11 +1494,19 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment) for( uint32_t ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ctuTsAddr++ ) { +#if JVET_M0055_DEBUG_CTU + #if HEVC_TILES_WPP + const int32_t ctuRsAddr = tileMap.getCtuTsToRsAddrMap( ctuTsAddr ); + #else + const int32_t ctuRsAddr = ctuTsAddr; +#endif +#else #if HEVC_TILES_WPP const uint32_t ctuRsAddr = tileMap.getCtuTsToRsAddrMap(ctuTsAddr); #else const uint32_t ctuRsAddr = ctuTsAddr; #endif +#endif #if HEVC_TILES_WPP // update CABAC state @@ -1508,6 +1520,9 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons const UnitArea ctuArea( cs.area.chromaFormat, Area( pos.x, pos.y, pcv.maxCUWidth, pcv.maxCUHeight ) ); DTRACE_UPDATE( g_trace_ctx, std::make_pair( "ctu", ctuRsAddr ) ); +#if JVET_M0055_DEBUG_CTU + if( pCfg->getSwitchPOC() != pcPic->poc || -1 == pCfg->getDebugCTU() ) +#endif if ( pcSlice->getSliceType() != I_SLICE && ctuXPosInCtus == 0) { pcSlice->resetMotionLUTs(); @@ -1613,6 +1628,9 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons m_pcInterSearch->initWeightIdxBits(); } +#if JVET_M0055_DEBUG_CTU + if( pCfg->getSwitchPOC() != pcPic->poc || ctuRsAddr >= pCfg->getDebugCTU() ) +#endif #if ENABLE_WPP_PARALLELISM pEncLib->getCuEncoder( dataId )->compressCtu( cs, ctuArea, ctuRsAddr, prevQP, currQP ); #else -- GitLab