diff --git a/cfg/encoder_intra_vtm.cfg b/cfg/encoder_intra_vtm.cfg index 1b99e0e8dbc12cdf6f69fea33f2ad7c92ed00f6d..15be552017abcc28f6d20a59eb91ec2d96e82ec0 100644 --- a/cfg/encoder_intra_vtm.cfg +++ b/cfg/encoder_intra_vtm.cfg @@ -98,6 +98,7 @@ MTS : 1 MTSIntraMaxCand : 3 MTSInterMaxCand : 4 SBT : 1 +ISP : 1 Affine : 1 SubPuMvp : 1 MaxNumMergeCand : 6 diff --git a/cfg/encoder_lowdelay_P_vtm.cfg b/cfg/encoder_lowdelay_P_vtm.cfg index e56edd9a6c39beadab9e0419a3b0c12aacab2b67..4cdf507662492284131234caa2e418ff716aa66c 100644 --- a/cfg/encoder_lowdelay_P_vtm.cfg +++ b/cfg/encoder_lowdelay_P_vtm.cfg @@ -114,6 +114,7 @@ MTS : 1 MTSIntraMaxCand : 3 MTSInterMaxCand : 4 SBT : 1 +ISP : 1 Affine : 1 SubPuMvp : 1 MaxNumMergeCand : 6 diff --git a/cfg/encoder_lowdelay_vtm.cfg b/cfg/encoder_lowdelay_vtm.cfg index d5bd1e79e40d53acf68de48d3adfbb28d127f15e..bbf67b4ed0bc05ef1ea6c726c4d51face92bcd5e 100644 --- a/cfg/encoder_lowdelay_vtm.cfg +++ b/cfg/encoder_lowdelay_vtm.cfg @@ -114,6 +114,7 @@ MTS : 1 MTSIntraMaxCand : 3 MTSInterMaxCand : 4 SBT : 1 +ISP : 1 Affine : 1 SubPuMvp : 1 MaxNumMergeCand : 6 diff --git a/cfg/encoder_randomaccess_vtm.cfg b/cfg/encoder_randomaccess_vtm.cfg index 2fdc284ae68c0f15c29469395d9a288c6ae54b10..7bfe101b0ddf8249a48e716f08f9596fd7cf3633 100644 --- a/cfg/encoder_randomaccess_vtm.cfg +++ b/cfg/encoder_randomaccess_vtm.cfg @@ -128,6 +128,7 @@ MTS : 1 MTSIntraMaxCand : 3 MTSInterMaxCand : 4 SBT : 1 +ISP : 1 Affine : 1 SubPuMvp : 1 MaxNumMergeCand : 6 diff --git a/doc/software-manual.tex b/doc/software-manual.tex index 85fa51c79b802b4c7806ce613e3b0b4715758839..5676da3a67e9db953a514f897c538badd7ca333a 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -1771,6 +1771,20 @@ Enables or disables the use of a deblocking across tile boundaries. Enables or disables the use of asymmetric motion partitions. \\ +\Option{ISP} & +%\ShortOption{\None} & +\Default{false} & +Enables or disables the Intra Sub-Partitions coding mode. +\\ + +\Option{ISPFast} & +%\ShortOption{\None} & +\Default{false} & +Enables or disables reduced testing of non-DCT-II transforms if ISP is likely to become the best mode for a given CU. +\par +This option has no effect if either ISP or MTS are disabled. +\\ + \Option{SAO} & %\ShortOption{\None} & \Default{true} & diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index cfda65bae7212fe3750aba37133e546aaa0d3ae2..30e1560ad73e2a509ecf9d164a67689c848fef5d 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -346,6 +346,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setUseBLambdaForNonKeyLowDelayPictures ( m_bUseBLambdaForNonKeyLowDelayPictures ); m_cEncLib.setPCMLog2MinSize ( m_uiPCMLog2MinSize); m_cEncLib.setUsePCM ( m_usePCM ); +#if INCLUDE_ISP_CFG_FLAG + m_cEncLib.setUseISP ( m_ISP ); +#endif m_cEncLib.setUseFastISP ( m_useFastISP ); // set internal bit-depth and constants diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 9ba6eecc0f39e1da55a49d6653ea20a33cc90e56..0ce37b0db16cca1870c6722203ab268e4a8271e3 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -857,6 +857,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("MTSInterMaxCand", m_MTSInterMaxCand, 4, "Number of additional candidates to test in encoder search for MTS in inter slices\n") ("MTSImplicit", m_MTSImplicit, 0, "Enable implicit MTS (when explicit MTS is off)\n") ( "SBT", m_SBT, false, "Enable Sub-Block Transform for inter blocks\n" ) +#if INCLUDE_ISP_CFG_FLAG + ( "ISP", m_ISP, false, "Enable Intra Sub-Partitions\n" ) +#endif #if JVET_N0235_SMVD_SPS ("SMVD", m_SMVD, false, "Enable Symmetric MVD\n") #endif @@ -3147,6 +3150,9 @@ void EncAppCfg::xPrintParameter() } msg( VERBOSE, "MTS: %1d(intra) %1d(inter) ", m_MTS & 1, ( m_MTS >> 1 ) & 1 ); msg( VERBOSE, "SBT:%d ", m_SBT ); +#if INCLUDE_ISP_CFG_FLAG + msg( VERBOSE, "ISP:%d ", m_ISP ); +#endif #if JVET_N0235_SMVD_SPS msg( VERBOSE, "SMVD:%d ", m_SMVD ); #endif @@ -3188,7 +3194,11 @@ void EncAppCfg::xPrintParameter() msg( VERBOSE, "PBIntraFast:%d ", m_usePbIntraFast ); if( m_ImvMode ) msg( VERBOSE, "IMV4PelFast:%d ", m_Imv4PelFast ); if( m_MTS ) msg( VERBOSE, "MTSMaxCand: %1d(intra) %1d(inter) ", m_MTSIntraMaxCand, m_MTSInterMaxCand ); +#if INCLUDE_ISP_CFG_FLAG + if( m_ISP ) msg( VERBOSE, "ISPFast:%d ", m_useFastISP ); +#else msg( VERBOSE, "ISPFast:%d ", m_useFastISP ); +#endif msg( VERBOSE, "AMaxBT:%d ", m_useAMaxBT ); msg( VERBOSE, "E0023FastEnc:%d ", m_e0023FastEnc ); msg( VERBOSE, "ContentBasedFastQtbt:%d ", m_contentBasedFastQtbt ); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 51ae1a97415fd332811fef84cddedd8b3237a59c..32cd865f1fda9f995017a2d7ab2813081d349593 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -178,6 +178,9 @@ protected: bool m_rdpcmEnabledFlag[NUMBER_OF_RDPCM_SIGNALLING_MODES];///< control flags for residual DPCM bool m_persistentRiceAdaptationEnabledFlag; ///< control flag for Golomb-Rice parameter adaptation over each slice bool m_cabacBypassAlignmentEnabledFlag; +#if INCLUDE_ISP_CFG_FLAG + bool m_ISP; +#endif bool m_useFastISP; ///< flag for enabling fast methods for ISP // coding quality diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index dfdd7feb87b28840b0fe0d6fa8d415e83f32fcdb..d1d8b8ccf45efa257ff84f87d061e0f2c2af5dd3 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1788,6 +1788,9 @@ SPS::SPS() , m_DMVR ( false ) , m_SBT ( false ) , m_MaxSbtSize ( 32 ) +#if INCLUDE_ISP_CFG_FLAG +, m_ISP ( false ) +#endif #if HEVC_VPS , m_VPSId ( 0) #endif diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 2d6e84a6c9c7dd33fdba750b69decb4d673a0995..4d8c2b443b34cfa662de87a8ee83f586baca4d35 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1014,6 +1014,9 @@ private: bool m_DMVR; bool m_SBT; uint8_t m_MaxSbtSize; +#if INCLUDE_ISP_CFG_FLAG + bool m_ISP; +#endif #if HEVC_VPS int m_VPSId; #endif @@ -1357,6 +1360,10 @@ public: unsigned getIBCFlag() const { return m_IBCFlag; } void setUseSBT( bool b ) { m_SBT = b; } bool getUseSBT() const { return m_SBT; } +#if INCLUDE_ISP_CFG_FLAG + void setUseISP( bool b ) { m_ISP = b; } + bool getUseISP() const { return m_ISP; } +#endif void setMaxSbtSize( uint8_t val ) { m_MaxSbtSize = val; } uint8_t getMaxSbtSize() const { return m_MaxSbtSize; } diff --git a/source/Lib/CommonLib/TrQuant.cpp b/source/Lib/CommonLib/TrQuant.cpp index 8c701503e3009991f614e59fe2978e5dec32badd..5fb8639cec53913731a467c5d858552654fb307f 100644 --- a/source/Lib/CommonLib/TrQuant.cpp +++ b/source/Lib/CommonLib/TrQuant.cpp @@ -705,8 +705,11 @@ void TrQuant::transformNxN( TransformUnit &tu, const ComponentID &compID, const void TrQuant::xGetCoeffEnergy( TransformUnit &tu, const ComponentID &compID, const CoeffBuf& coeffs, double* diagRatio, double* horVerRatio ) { if( nullptr == diagRatio || nullptr == horVerRatio ) return; - +#if INCLUDE_ISP_CFG_FLAG + if( tu.cu->predMode == MODE_INTRA && !tu.cu->ispMode && isLuma( compID ) && tu.cs->sps->getUseISP() && CU::canUseISPSplit( *tu.cu, compID ) != NOT_INTRA_SUBPARTITIONS ) +#else if( tu.cu->predMode == MODE_INTRA && !tu.cu->ispMode && isLuma( compID ) && CU::canUseISPSplit( *tu.cu, compID ) != NOT_INTRA_SUBPARTITIONS ) +#endif { const int width = tu.cu->blocks[compID].width; const int height = tu.cu->blocks[compID].height; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 0733b52db2f6f57b5fa7aaa573556322da778452..a886796cee8af1698c4b39aa667de54f43073995 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -152,6 +152,7 @@ typedef std::pair<int, bool> TrMode; typedef std::pair<int, int> TrCost; // clang-format off +#define INCLUDE_ISP_CFG_FLAG 1 #define ENABLE_JVET_L0283_MRL 1 // 1: Enable MRL, 0: Disable MRL #define JVET_L0090_PAIR_AVG 1 // Add pairwise average candidates, replace HEVC combined candidates #define REUSE_CU_RESULTS 1 diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index b06830023aa24aedb7733c3ab8366bf55a0f581e..657c4afcb6a5270a4fbc6ef80bd3b476c0da4928 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -2562,7 +2562,11 @@ void CABACReader::mts_coding( TransformUnit& tu, ComponentID compID ) void CABACReader::isp_mode( CodingUnit& cu ) { +#if INCLUDE_ISP_CFG_FLAG + if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm || !cu.cs->sps->getUseISP() ) +#else if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm ) +#endif { cu.ispMode = NOT_INTRA_SUBPARTITIONS; return; diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 463e93473d2d20f212822cf2f37b4d7761aecd8b..941614bd558db9a9a5408e49008a7e11eb95d475 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1143,6 +1143,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) } // KJS: not in draft yet READ_FLAG(uiCode, "sps_reshaper_enable_flag"); pcSPS->setUseReshaper(uiCode == 1); +#if INCLUDE_ISP_CFG_FLAG + READ_FLAG(uiCode, "isp_enable_flag"); pcSPS->setUseISP(uiCode != 0); +#endif #if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET READ_FLAG( uiCode, "sps_ladf_enabled_flag" ); pcSPS->setLadfEnabled( uiCode != 0 ); diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index ce9c579f52f8d7d3e3c83c8fa61c924a1b32dbd1..c4c4238fea67a49615cfb23c7ea7f85ae17936e4 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -2467,7 +2467,11 @@ void CABACWriter::mts_coding( const TransformUnit& tu, ComponentID compID ) void CABACWriter::isp_mode( const CodingUnit& cu ) { +#if INCLUDE_ISP_CFG_FLAG + if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm || !cu.cs->sps->getUseISP() ) +#else if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm ) +#endif { CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "error: cu.intraSubPartitions != 0" ); return; diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 50bef16364872900d5563b8163ce61109b852b93..d4934fe5ab225370875316ad109b37eb77e32864 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -373,6 +373,9 @@ protected: int* m_aidQP; uint32_t m_uiDeltaQpRD; bool m_bFastDeltaQP; +#if INCLUDE_ISP_CFG_FLAG + bool m_ISP; +#endif bool m_useFastISP; bool m_bUseConstrainedIntraPred; @@ -799,7 +802,10 @@ public: unsigned getWrapAroundOffset () const { return m_wrapAroundOffset; } // ADD_NEW_TOOL : (encoder lib) add access functions here - +#if INCLUDE_ISP_CFG_FLAG + void setUseISP ( bool b ) { m_ISP = b; } + bool getUseISP () const { return m_ISP; } +#endif void setReshaper ( bool b ) { m_lumaReshapeEnable = b; } bool getReshaper () const { return m_lumaReshapeEnable; } void setReshapeSignalType ( uint32_t signalType ) { m_reshapeSignalType = signalType; } diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 97d0d66e3cfa966286acaabf92a79ad478ee1134..58979e064384b022f7a07d096af4fbf75c183f7c 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -987,6 +987,9 @@ void EncLib::xInitSPS(SPS &sps) sps.setWrapAroundEnabledFlag ( m_wrapAround ); sps.setWrapAroundOffset ( m_wrapAroundOffset ); // ADD_NEW_TOOL : (encoder lib) set tool enabling flags and associated parameters here +#if INCLUDE_ISP_CFG_FLAG + sps.setUseISP ( m_ISP ); +#endif sps.setUseReshaper ( m_lumaReshapeEnable ); int minCUSize = sps.getMaxCUWidth() >> sps.getLog2DiffMaxMinCodingBlockSize(); int log2MinCUSize = 0; diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp index a1817bf964c2af31427d7bfa5b0c3c9bbb62d805..87ac113447830320251095ade9fcb601ff375a12 100644 --- a/source/Lib/EncoderLib/IntraSearch.cpp +++ b/source/Lib/EncoderLib/IntraSearch.cpp @@ -292,7 +292,11 @@ void IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, const int width = partitioner.currArea().lwidth(); const int height = partitioner.currArea().lheight(); +#if INCLUDE_ISP_CFG_FLAG + int nOptionsForISP = sps.getUseISP() ? NUM_INTRA_SUBPARTITIONS_MODES : 1; +#else int nOptionsForISP = NUM_INTRA_SUBPARTITIONS_MODES; +#endif double bestCurrentCost = bestCostSoFar; int ispOptions[NUM_INTRA_SUBPARTITIONS_MODES] = { 0 }; @@ -1607,7 +1611,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp const bool bUseCrossCPrediction = pps.getPpsRangeExtension().getCrossComponentPredictionEnabledFlag() && isChroma( compID ) && PU::isChromaIntraModeCrossCheckMode( pu ) && checkCrossCPrediction; const bool ccUseRecoResi = m_pcEncCfg->getUseReconBasedCrossCPredictionEstimate(); +#if INCLUDE_ISP_CFG_FLAG + const bool ispSplitIsAllowed = sps.getUseISP() && CU::canUseISPSplit( *tu.cu, compID ); +#else const bool ispSplitIsAllowed = CU::canUseISPSplit( *tu.cu, compID ); +#endif //===== init availability pattern ===== @@ -1752,9 +1760,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp tu.mtsIdx = trModes->at(0).first; } m_pcTrQuant->transformNxN( tu, compID, cQP, uiAbsSum, m_CABACEstimator->getCtx(), loadTr, &diagRatio, &horVerRatio ); - if (!tu.cu->ispMode && isLuma(compID) && ispSplitIsAllowed && - tu.mtsIdx == 0 - ) +#if INCLUDE_ISP_CFG_FLAG + if ( !tu.cu->ispMode && isLuma(compID) && ispSplitIsAllowed && tu.mtsIdx == 0 && ispSplitIsAllowed ) +#else + if ( !tu.cu->ispMode && isLuma(compID) && ispSplitIsAllowed && tu.mtsIdx == 0 ) +#endif { m_intraModeDiagRatio .push_back(diagRatio); m_intraModeHorVerRatio .push_back(horVerRatio); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index b88af1ea55adfb4d8cd6ef50d8a7489faff52551..7e565d6594c283f005b9f5d371ca75436bc9c4bb 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -794,6 +794,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) } // KJS: not in draft yet WRITE_FLAG(pcSPS->getUseReshaper() ? 1 : 0, "sps_reshaper_enable_flag"); +#if INCLUDE_ISP_CFG_FLAG + WRITE_FLAG( pcSPS->getUseISP() ? 1 : 0, "isp_enable_flag"); +#endif #if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET WRITE_FLAG( pcSPS->getLadfEnabled() ? 1 : 0, "sps_ladf_enabled_flag" );