From 7f07b046473061c737db1020591c767381b855cf Mon Sep 17 00:00:00 2001 From: Waqas Ahmad <waqas.ahmad@ericsson.com> Date: Thu, 27 Jul 2023 10:08:23 +0200 Subject: [PATCH] JVET-AE0057: MTT split modes early termination The proposal JVET-AE0057 is implemented under the define JVET_AE0057_MTT_ET in VTM software. A config file parameter (MTTSkipping) is also added to turn on or off the MTT early termination. The 64x64 luma CU no-split intra RD cost is compared against a threshold to decide whether to evaluate MTT splitting for current 64x64 luma CU. --- source/App/EncoderApp/EncApp.cpp | 3 +++ source/App/EncoderApp/EncAppCfg.cpp | 3 +++ source/App/EncoderApp/EncAppCfg.h | 3 +++ source/Lib/CommonLib/TypeDef.h | 2 ++ source/Lib/EncoderLib/EncCfg.h | 8 +++++++ source/Lib/EncoderLib/EncCu.cpp | 25 ++++++++++++++++++++++ source/Lib/EncoderLib/EncModeCtrl.cpp | 30 +++++++++++++++++++++++++++ source/Lib/EncoderLib/EncModeCtrl.h | 6 ++++++ 8 files changed, 80 insertions(+) diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 5f6661305..615698d3e 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -865,6 +865,9 @@ void EncApp::xInitLibCfg( int layerIdx ) m_cEncLib.setFastAdaptCostPredMode (m_fastAdaptCostPredMode); m_cEncLib.setDisableFastDecisionTT (m_disableFastDecisionTT); +#if JVET_AE0057_MTT_ET + m_cEncLib.setUseMttSkip (m_useMttSkip); +#endif // set internal bit-depth and constants for (const auto channelType: { ChannelType::LUMA, ChannelType::CHROMA }) { diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index c17b69a2d..e76406e63 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1082,6 +1082,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("PBIntraFast", m_usePbIntraFast, false, "Fast assertion if the intra mode is probable") ("AMaxBT", m_useAMaxBT, false, "Adaptive maximal BT-size") ("E0023FastEnc", m_e0023FastEnc, true, "Fast encoding setting for QTBT (proposal E0023)") +#if JVET_AE0057_MTT_ET + ("MTTSkipping", m_useMttSkip, false, "MTT split modes early termination (proposal JVET-AE0057)") +#endif ("ContentBasedFastQtbt", m_contentBasedFastQtbt, false, "Signal based QTBT speed-up") ("UseNonLinearAlfLuma", m_useNonLinearAlfLuma, true, "Non-linear adaptive loop filters for Luma Channel") ("UseNonLinearAlfChroma", m_useNonLinearAlfChroma, true, "Non-linear adaptive loop filters for Chroma Channels") diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index f394845be..494c39a4d 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -418,6 +418,9 @@ protected: unsigned m_maxCuHeight; ///< max. CU height in pixel unsigned m_log2MinCuSize; ///< min. CU size log2 +#if JVET_AE0057_MTT_ET + bool m_useMttSkip; +#endif bool m_useFastLCTU; bool m_usePbIntraFast; bool m_useAMaxBT; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 66d1f64e0..3258b3709 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -80,6 +80,8 @@ #define JVET_AD0067_INCLUDE_SYNTAX 1 // include nnpfc_full_range_flag syntax element in the nnpfc sei message when nnpfc_separate_colour_description_present_flag is equal to 1 and when nnpfc_out_format_idc is equal to 1. +#define JVET_AE0057_MTT_ET 1 // JVET-AE0057: MTT split modes early termination + #define REUSE_CU_RESULTS 1 #if REUSE_CU_RESULTS #define REUSE_CU_RESULTS_WITH_MULTIPLE_TUS 1 diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 0d12353d8..461f94c6c 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -426,6 +426,9 @@ protected: int m_fastAdaptCostPredMode; bool m_disableFastDecisionTT; uint32_t m_log2MaxTbSize; +#if JVET_AE0057_MTT_ET + bool m_useMttSkip; +#endif //====== Loop/Deblock Filter ======== bool m_deblockingFilterDisable; @@ -1605,6 +1608,11 @@ public: void setDisableFastDecisionTT (bool i) { m_disableFastDecisionTT = i; } bool getDisableFastDecisionTT () const { return m_disableFastDecisionTT; } +#if JVET_AE0057_MTT_ET + void setUseMttSkip (bool i) { m_useMttSkip = i; } + bool getUseMttSkip () const { return m_useMttSkip; } +#endif + void setLog2MaxTbSize ( uint32_t u ) { m_log2MaxTbSize = u; } //====== Loop/Deblock Filter ======== diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 439ae9344..e8507689f 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -830,6 +830,19 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par { xCheckRDCostIntra(tempCS, bestCS, partitioner, currTestMode, false); } +#if JVET_AE0057_MTT_ET + if (partitioner.currQtDepth == 1 && partitioner.currBtDepth == 0 && partitioner.currArea().lwidth() == 64 + && partitioner.currArea().lheight() == 64) + { + if ((ChannelType(0) == ChannelType::LUMA) + && ((partitioner.currArea().Y().x + 63 < bestCS->picture->lwidth()) + && (partitioner.currArea().Y().y + 63 < bestCS->picture->lheight()))) + { + m_modeCtrl->setNoSplitIntraCost(bestCS->cost); + } + } +#endif + splitRdCostBest[CTU_LEVEL] = bestCS->cost; tempCS->splitRdCostBest = splitRdCostBest; } @@ -1201,6 +1214,18 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, CodingStructure *tempSubCS = m_pTempCS[wIdx][hIdx]; CodingStructure *bestSubCS = m_pBestCS[wIdx][hIdx]; +#if JVET_AE0057_MTT_ET + if (partitioner.currQtDepth == 1 && partitioner.currBtDepth == 0 && partitioner.currArea().lwidth() == 64 + && partitioner.currArea().lheight() == 64) + { + if ((ChannelType(0) == ChannelType::LUMA) + && ((partitioner.currArea().Y().x + 63 < bestCS->picture->lwidth()) + && (partitioner.currArea().Y().y + 63 < bestCS->picture->lheight()))) + { + m_modeCtrl->setNoSplitIntraCost(0.0); + } + } +#endif tempCS->initSubStructure( *tempSubCS, partitioner.chType, subCUArea, false ); tempCS->initSubStructure( *bestSubCS, partitioner.chType, subCUArea, false ); tempSubCS->bestParent = bestSubCS->bestParent = bestCS; diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp index 87fd8f45a..632926e84 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.cpp +++ b/source/Lib/EncoderLib/EncModeCtrl.cpp @@ -1424,6 +1424,36 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt { ComprCUCtx& cuECtx = m_ComprCUCtxList.back(); +#if JVET_AE0057_MTT_ET + if (m_pcEncCfg->getUseMttSkip() && partitioner.currQtDepth == 1 && partitioner.currBtDepth == 0 + && partitioner.currArea().lwidth() == 64 + && partitioner.currArea().lheight() == 64) + { + if (((partitioner.currArea().Y().x + 63 < cs.picture->lwidth()) + && (partitioner.currArea().Y().y + 63 < cs.picture->lheight())) + + && (encTestmode.type == ETM_SPLIT_BT_H || encTestmode.type == ETM_SPLIT_BT_V + || encTestmode.type == ETM_SPLIT_TT_H || encTestmode.type == ETM_SPLIT_TT_V) + && partitioner.chType == ChannelType::LUMA) + { + if (m_noSplitIntraRdCost > (120 - ((m_pcEncCfg->getBaseQP() - 22) * 4)) * 1000000) + { + const PartSplit split = getPartSplit(encTestmode); + + if (split == CU_HORZ_SPLIT) + { + cuECtx.set(DID_HORZ_SPLIT, false); + } + if (split == CU_VERT_SPLIT) + { + cuECtx.set(DID_VERT_SPLIT, false); + } + return false; + } + } + } +#endif + // Fast checks, partitioning depended if (cuECtx.isHashPerfectMatch && encTestmode.type != ETM_MERGE_SKIP && encTestmode.type != ETM_INTER_ME) { diff --git a/source/Lib/EncoderLib/EncModeCtrl.h b/source/Lib/EncoderLib/EncModeCtrl.h index e3fb983eb..270beb334 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.h +++ b/source/Lib/EncoderLib/EncModeCtrl.h @@ -296,6 +296,9 @@ protected: bool m_HashMEPOCchecked; int m_HashMEPOC2; +#if JVET_AE0057_MTT_ET + double m_noSplitIntraRdCost; +#endif public: virtual ~EncModeCtrl () {} @@ -334,6 +337,9 @@ public: virtual void setBest ( CodingStructure& cs ); bool anyMode () const; +#if JVET_AE0057_MTT_ET + void setNoSplitIntraCost (double cost) { m_noSplitIntraRdCost = cost; } +#endif const ComprCUCtx& getComprCUCtx () { CHECK( m_ComprCUCtxList.empty(), "Accessing empty list!"); return m_ComprCUCtxList.back(); } #if SHARP_LUMA_DELTA_QP -- GitLab