Commit a7f149c0 authored by Tung Nguyen's avatar Tung Nguyen Committed by Frank Bossen

M0464: UniMTS

parent 1090b2ce
......@@ -51,6 +51,7 @@ SAO : 1 # Sample adaptive offset (0: OFF, 1
AMP : 1 # Asymmetric motion partitions (0: OFF, 1: ON)
TransformSkip : 1 # Transform skipping (0: OFF, 1: ON)
TransformSkipFast : 1 # Fast Transform skipping (0: OFF, 1: ON)
TransformSkipLog2MaxSize : 5
SAOLcuBoundary : 0 # SAOLcuBoundary using non-deblocked pixels (0: OFF, 1: ON)
#============ Slices ================
......@@ -101,8 +102,9 @@ MaxBTDepthISliceL : 3
MaxBTDepthISliceC : 3
MTT : 1
EMT : 1
EMTFast : 1
MTS : 1
MTSIntraMaxCand : 3
MTSInterMaxCand : 4
Affine : 1
SubPuMvp : 1
MaxNumMergeCand : 6
......
......@@ -59,6 +59,7 @@ SAO : 1 # Sample adaptive offset (0: OFF, 1
AMP : 1 # Asymmetric motion partitions (0: OFF, 1: ON)
TransformSkip : 1 # Transform skipping (0: OFF, 1: ON)
TransformSkipFast : 1 # Fast Transform skipping (0: OFF, 1: ON)
TransformSkipLog2MaxSize : 5
SAOLcuBoundary : 0 # SAOLcuBoundary using non-deblocked pixels (0: OFF, 1: ON)
#============ Slices ================
......@@ -117,8 +118,9 @@ MaxBTDepthISliceL : 3
MaxBTDepthISliceC : 3
MTT : 1
EMT : 1
EMTFast : 1
MTS : 1
MTSIntraMaxCand : 3
MTSInterMaxCand : 4
Affine : 1
SubPuMvp : 1
MaxNumMergeCand : 6
......
......@@ -59,6 +59,7 @@ SAO : 1 # Sample adaptive offset (0: OFF, 1
AMP : 1 # Asymmetric motion partitions (0: OFF, 1: ON)
TransformSkip : 1 # Transform skipping (0: OFF, 1: ON)
TransformSkipFast : 1 # Fast Transform skipping (0: OFF, 1: ON)
TransformSkipLog2MaxSize : 5
SAOLcuBoundary : 0 # SAOLcuBoundary using non-deblocked pixels (0: OFF, 1: ON)
#============ Slices ================
......@@ -117,8 +118,9 @@ MaxBTDepthISliceL : 3
MaxBTDepthISliceC : 3
MTT : 1
EMT : 1
EMTFast : 1
MTS : 1
MTSIntraMaxCand : 3
MTSInterMaxCand : 4
Affine : 1
SubPuMvp : 1
MaxNumMergeCand : 6
......
......@@ -73,6 +73,7 @@ SAO : 1 # Sample adaptive offset (0: OFF, 1
AMP : 1 # Asymmetric motion partitions (0: OFF, 1: ON)
TransformSkip : 1 # Transform skipping (0: OFF, 1: ON)
TransformSkipFast : 1 # Fast Transform skipping (0: OFF, 1: ON)
TransformSkipLog2MaxSize : 5
SAOLcuBoundary : 0 # SAOLcuBoundary using non-deblocked pixels (0: OFF, 1: ON)
#============ Slices ================
......@@ -131,8 +132,9 @@ MaxBTDepthISliceL : 3
MaxBTDepthISliceC : 3
MTT : 1
EMT : 1
EMTFast : 1
MTS : 1
MTSIntraMaxCand : 3
MTSInterMaxCand : 4
Affine : 1
SubPuMvp : 1
MaxNumMergeCand : 6
......
......@@ -227,10 +227,17 @@ void EncApp::xInitLibCfg()
#if ENABLE_WPP_PARALLELISM
m_cEncLib.setUseAltDQPCoding ( m_AltDQPCoding );
#endif
#if JVET_M0464_UNI_MTS
m_cEncLib.setIntraMTS ( m_MTS & 1 );
m_cEncLib.setIntraMTSMaxCand ( m_MTSIntraMaxCand );
m_cEncLib.setInterMTS ( ( m_MTS >> 1 ) & 1 );
m_cEncLib.setInterMTSMaxCand ( m_MTSInterMaxCand );
#else
m_cEncLib.setIntraEMT ( m_EMT & 1 );
m_cEncLib.setFastIntraEMT ( m_FastEMT & m_EMT & 1 );
m_cEncLib.setInterEMT ( ( m_EMT >> 1 ) & 1 );
m_cEncLib.setFastInterEMT ( ( m_FastEMT >> 1 ) & ( m_EMT >> 1 ) & 1 );
#endif
m_cEncLib.setUseCompositeRef ( m_compositeRefEnabled );
m_cEncLib.setUseGBi ( m_GBi );
m_cEncLib.setUseGBiFast ( m_GBiFast );
......
......@@ -828,6 +828,15 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
("LMChroma", m_LMChroma, 1, " LMChroma prediction "
"\t0: Disable LMChroma\n"
"\t1: Enable LMChroma\n")
#if JVET_M0464_UNI_MTS
("MTS", m_MTS, 0, "Multiple Transform Set (MTS)\n"
"\t0: Disable MTS\n"
"\t1: Enable only Intra MTS\n"
"\t2: Enable only Inter MTS\n"
"\t3: Enable both Intra & Inter MTS\n")
("MTSIntraMaxCand", m_MTSIntraMaxCand, 3, "Number of additional candidates to test in encoder search for MTS in intra slices\n")
("MTSInterMaxCand", m_MTSInterMaxCand, 4, "Number of additional candidates to test in encoder search for MTS in inter slices\n")
#else
("EMT,-emt", m_EMT, 0, "Enhanced Multiple Transform (EMT)\n"
"\t0: Disable EMT\n"
"\t1: Enable only Intra EMT\n"
......@@ -838,6 +847,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
"\t1: Enable fast methods only for Intra EMT\n"
"\t2: Enable fast methods only for Inter EMT\n"
"\t3: Enable fast methods for both Intra & Inter EMT\n")
#endif
("CompositeLTReference", m_compositeRefEnabled, false, "Enable Composite Long Term Reference Frame")
("GBi", m_GBi, false, "Enable Generalized Bi-prediction(GBi)")
("GBiFast", m_GBiFast, false, "Fast methods for Generalized Bi-prediction(GBi)\n")
......@@ -989,8 +999,13 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
("SaoLumaOffsetBitShift", saoOffsetBitShift[CHANNEL_TYPE_LUMA], 0, "Specify the luma SAO bit-shift. If negative, automatically calculate a suitable value based upon bit depth and initial QP")
("SaoChromaOffsetBitShift", saoOffsetBitShift[CHANNEL_TYPE_CHROMA], 0, "Specify the chroma SAO bit-shift. If negative, automatically calculate a suitable value based upon bit depth and initial QP")
("TransformSkip", m_useTransformSkip, false, "Intra transform skipping")
#if JVET_M0464_UNI_MTS
("TransformSkipFast", m_useTransformSkipFast, false, "Fast encoder search for transform skipping, winner takes it all mode.")
("TransformSkipLog2MaxSize", m_log2MaxTransformSkipBlockSize, 5U, "Specify transform-skip maximum size. Minimum 2, Maximum 5. (not valid in V1 profiles)")
#else
("TransformSkipFast", m_useTransformSkipFast, false, "Fast intra transform skipping")
("TransformSkipLog2MaxSize", m_log2MaxTransformSkipBlockSize, 2U, "Specify transform-skip maximum size. Minimum 2. (not valid in V1 profiles)")
#endif
("ImplicitResidualDPCM", m_rdpcmEnabledFlag[RDPCM_SIGNAL_IMPLICIT], false, "Enable implicitly signalled residual DPCM for intra (also known as sample-adaptive intra predict) (not valid in V1 profiles)")
("ExplicitResidualDPCM", m_rdpcmEnabledFlag[RDPCM_SIGNAL_EXPLICIT], false, "Enable explicitly signalled residual DPCM for inter (not valid in V1 profiles)")
("ResidualRotation", m_transformSkipRotationEnabledFlag, false, "Enable rotation of transform-skipped and transquant-bypassed TUs through 180 degrees prior to entropy coding (not valid in V1 profiles)")
......@@ -1919,8 +1934,14 @@ bool EncAppCfg::xCheckParameter()
xConfirmPara( m_ImvMode, "IMV is only allowed with NEXT profile" );
xConfirmPara(m_CPRMode, "CPR Mode only allowed with NEXT profile");
xConfirmPara( m_useFastLCTU, "Fast large CTU can only be applied when encoding with NEXT profile" );
#if JVET_M0464_UNI_MTS
xConfirmPara( m_MTS, "MTS only allowed with NEXT profile" );
xConfirmPara( m_MTSIntraMaxCand, "MTS only allowed with NEXT profile" );
xConfirmPara( m_MTSInterMaxCand, "MTS only allowed with NEXT profile" );
#else
xConfirmPara( m_EMT, "EMT only allowed with NEXT profile" );
xConfirmPara( m_FastEMT, "EMT only allowed with NEXT profile" );
#endif
xConfirmPara( m_compositeRefEnabled, "Composite Reference Frame is only allowed with NEXT profile" );
xConfirmPara( m_GBi, "GBi is only allowed with NEXT profile" );
xConfirmPara( m_GBiFast, "GBiFast is only allowed with NEXT profile" );
......@@ -2049,7 +2070,11 @@ bool EncAppCfg::xCheckParameter()
xConfirmPara(m_profile == Profile::MAINSTILLPICTURE && m_framesToBeEncoded > 1, "Number of frames to be encoded must be 1 when main still picture profile is used.");
xConfirmPara(m_crossComponentPredictionEnabledFlag==true, "CrossComponentPrediction must not be used for non main-RExt profiles.");
#if JVET_M0464_UNI_MTS
xConfirmPara(m_log2MaxTransformSkipBlockSize>=6, "Transform Skip Log2 Max Size must be less or equal to 5.");
#else
xConfirmPara(m_log2MaxTransformSkipBlockSize!=2, "Transform Skip Log2 Max Size must be 2 for V1 profiles.");
#endif
xConfirmPara(m_transformSkipRotationEnabledFlag==true, "UseResidualRotation must not be enabled for non main-RExt profiles.");
xConfirmPara(m_transformSkipContextEnabledFlag==true, "UseSingleSignificanceMapContext must not be enabled for non main-RExt profiles.");
xConfirmPara(m_rdpcmEnabledFlag[RDPCM_SIGNAL_IMPLICIT]==true, "ImplicitResidualDPCM must not be enabled for non main-RExt profiles.");
......@@ -2138,6 +2163,7 @@ bool EncAppCfg::xCheckParameter()
xConfirmPara (m_log2MaxTransformSkipBlockSize < 2, "Transform Skip Log2 Max Size must be at least 2 (4x4)");
#if !JVET_M0464_UNI_MTS
if (m_log2MaxTransformSkipBlockSize!=2 && m_useTransformSkipFast)
{
msg( WARNING, "***************************************************************************\n");
......@@ -2146,6 +2172,7 @@ bool EncAppCfg::xCheckParameter()
msg( WARNING, "** It may be better to disable transform skip fast mode **\n");
msg( WARNING, "***************************************************************************\n");
}
#endif
xConfirmPara( m_quadtreeTULog2MaxSize * m_tuLog2MaxSize >= 0, "Setting of TULog2MaxSize and QuadtreeTULog2MaxSize is mutually exclusive - use only one of the parameters" );
......@@ -2258,8 +2285,14 @@ bool EncAppCfg::xCheckParameter()
m_maxNumAffineMergeCand = m_SubPuMvpMode;
}
#if JVET_M0464_UNI_MTS
xConfirmPara( m_MTS < 0 || m_MTS > 3, "MTS must be greater than 0 smaller than 4" );
xConfirmPara( m_MTSIntraMaxCand < 0 || m_MTSIntraMaxCand > 5, "m_MTSIntraMaxCand must be greater than 0 and smaller than 6" );
xConfirmPara( m_MTSInterMaxCand < 0 || m_MTSInterMaxCand > 5, "m_MTSInterMaxCand must be greater than 0 and smaller than 6" );
#else
xConfirmPara( m_EMT < 0 || m_EMT >3, "EMT must be 0, 1, 2 or 3" );
xConfirmPara( m_FastEMT < 0 || m_FastEMT >3, "FEMT must be 0, 1, 2 or 3" );
#endif
if( m_usePCM)
{
for (uint32_t channelType = 0; channelType < MAX_NUM_CHANNEL_TYPE; channelType++)
......@@ -3091,8 +3124,12 @@ void EncAppCfg::xPrintParameter()
msg( VERBOSE, "AltDQPCoding:%d ", m_AltDQPCoding );
#endif
msg( VERBOSE, "LMChroma:%d ", m_LMChroma );
#if JVET_M0464_UNI_MTS
msg( VERBOSE, "MTS: %1d(intra) %1d(inter) ", m_MTS & 1, ( m_MTS >> 1 ) & 1 );
#else
msg( VERBOSE, "EMT: %1d(intra) %1d(inter) ", m_EMT & 1, ( m_EMT >> 1 ) & 1 );
msg(VERBOSE, "CompositeLTReference:%d ", m_compositeRefEnabled);
#endif
msg( VERBOSE, "CompositeLTReference:%d ", m_compositeRefEnabled);
msg( VERBOSE, "GBi:%d ", m_GBi );
msg( VERBOSE, "GBiFast:%d ", m_GBiFast );
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
......@@ -3117,7 +3154,11 @@ void EncAppCfg::xPrintParameter()
msg( VERBOSE, "FastMrg:%d ", m_useFastMrg );
msg( VERBOSE, "PBIntraFast:%d ", m_usePbIntraFast );
if( m_ImvMode == 2 ) msg( VERBOSE, "IMV4PelFast:%d ", m_Imv4PelFast );
#if JVET_M0464_UNI_MTS
if( m_MTS ) msg( VERBOSE, "MTSMaxCand: %1d(intra) %1d(inter) ", m_MTSIntraMaxCand, m_MTSInterMaxCand );
#else
if( m_EMT ) msg( VERBOSE, "EMTFast: %1d(intra) %1d(inter) ", ( m_FastEMT & m_EMT & 1 ), ( m_FastEMT >> 1 ) & ( m_EMT >> 1 ) & 1 );
#endif
msg( VERBOSE, "AMaxBT:%d ", m_useAMaxBT );
msg( VERBOSE, "E0023FastEnc:%d ", m_e0023FastEnc );
msg( VERBOSE, "ContentBasedFastQtbt:%d ", m_contentBasedFastQtbt );
......
......@@ -214,8 +214,14 @@ protected:
bool m_AltDQPCoding;
#endif
int m_LMChroma;
#if JVET_M0464_UNI_MTS
int m_MTS; ///< XZ: Multiple Transform Set
int m_MTSIntraMaxCand; ///< XZ: Number of additional candidates to test
int m_MTSInterMaxCand; ///< XZ: Number of additional candidates to test
#else
int m_EMT; ///< XZ: Enhanced Multiple Transform
int m_FastEMT; ///< XZ: Fast Methods of Enhanced Multiple Transform
#endif
bool m_compositeRefEnabled;
bool m_GBi;
......
......@@ -211,8 +211,14 @@ static const int DM_CHROMA_IDX = NUM_INTRA_MODE; ///< chro
static const uint8_t INTER_MODE_IDX = 255; ///< index for inter modes
#if JVET_M0464_UNI_MTS
static const uint32_t NUM_TRAFO_MODES_MTS = 6; ///< Max Intra CU size applying EMT, supported values: 8, 16, 32, 64, 128
static const uint32_t MTS_INTRA_MAX_CU_SIZE = 32; ///< Max Intra CU size applying EMT, supported values: 8, 16, 32, 64, 128
static const uint32_t MTS_INTER_MAX_CU_SIZE = 32; ///< Max Inter CU size applying EMT, supported values: 8, 16, 32, 64, 128
#else
static const uint32_t EMT_INTRA_MAX_CU_WITH_QTBT = 32; ///< Max Intra CU size applying EMT, supported values: 8, 16, 32, 64, 128
static const uint32_t EMT_INTER_MAX_CU_WITH_QTBT = 32; ///< Max Inter CU size applying EMT, supported values: 8, 16, 32, 64, 128
#endif
static const int NUM_MOST_PROBABLE_MODES = 6;
static const int LM_SYMBOL_NUM = (1 + NUM_LMC_MODE);
......@@ -321,7 +327,9 @@ static const int MAX_ENCODER_DEBLOCKING_QUALITY_LAYERS = 8 ;
static const uint32_t LUMA_LEVEL_TO_DQP_LUT_MAXSIZE = 1024; ///< max LUT size for QP offset based on luma
#endif
#if !JVET_M0464_UNI_MTS
static const int NUM_EMT_CU_FLAG_CTX = 6; ///< number of context models for EMT CU-level flag
#endif
//QTBT high level parameters
//for I slice luma CTB configuration para.
......
......@@ -81,7 +81,11 @@ CoeffCodingContext::CoeffCodingContext(const TransformUnit& tu, ComponentID comp
, m_lastOffsetY (0)
, m_lastShiftX (0)
, m_lastShiftY (0)
#if JVET_M0464_UNI_MTS
, m_TrafoBypass (tu.cs->sps->getSpsRangeExtension().getTransformSkipContextEnabledFlag() && (tu.cu->transQuantBypass || tu.mtsIdx==1))
#else
, m_TrafoBypass (tu.cs->sps->getSpsRangeExtension().getTransformSkipContextEnabledFlag() && (tu.cu->transQuantBypass || tu.transformSkip[m_compID]))
#endif
, m_scanPosLast (-1)
, m_subSetId (-1)
, m_subSetPos (-1)
......@@ -96,7 +100,9 @@ CoeffCodingContext::CoeffCodingContext(const TransformUnit& tu, ComponentID comp
, m_parFlagCtxSet ( Ctx::ParFlag[m_chType] )
, m_gtxFlagCtxSet { Ctx::GtxFlag[m_chType], Ctx::GtxFlag[m_chType+2] }
, m_sigCoeffGroupFlag ()
#if !JVET_M0464_UNI_MTS
, m_emtNumSigCoeff (0)
#endif
{
// LOGTODO
unsigned log2sizeX = m_log2BlockWidth;
......
......@@ -183,8 +183,10 @@ public:
return std::min(sum, 31);
}
#if !JVET_M0464_UNI_MTS
unsigned emtNumSigCoeff() const { return m_emtNumSigCoeff; }
void setEmtNumSigCoeff( unsigned val ) { m_emtNumSigCoeff = val; }
#endif
private:
// constant
......@@ -235,7 +237,9 @@ private:
CtxSet m_parFlagCtxSet;
CtxSet m_gtxFlagCtxSet[2];
std::bitset<MLS_GRP_NUM> m_sigCoeffGroupFlag;
#if !JVET_M0464_UNI_MTS
unsigned m_emtNumSigCoeff;
#endif
};
......
......@@ -1080,6 +1080,7 @@ const CtxSet ContextSetCfg::SaoTypeIdx = ContextSetCfg::addCtxSet
#endif
});
#if !JVET_M0464_UNI_MTS
const CtxSet ContextSetCfg::TransformSkipFlag = ContextSetCfg::addCtxSet
({
#if JVET_M0453_CABAC_ENGINE
......@@ -1093,6 +1094,7 @@ const CtxSet ContextSetCfg::TransformSkipFlag = ContextSetCfg::addCtxSet
{ 109, 42, },
#endif
});
#endif
const CtxSet ContextSetCfg::TransquantBypassFlag = ContextSetCfg::addCtxSet
({
......@@ -1124,6 +1126,21 @@ const CtxSet ContextSetCfg::RdpcmDir = ContextSetCfg::addCtxSet
#endif
});
#if JVET_M0464_UNI_MTS
const CtxSet ContextSetCfg::MTSIndex = ContextSetCfg::addCtxSet
({
#if JVET_M0453_CABAC_ENGINE
{ CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, },
{ CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, },
{ CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, },
{ DWS, DWS, DWS, DWS, DWS, DWS, DWS, DWS, DWS, DWS, DWS, },
#else
{ CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, },
{ CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, },
{ CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, CNU, },
#endif
});
#else
const CtxSet ContextSetCfg::EMTTuIndex = ContextSetCfg::addCtxSet
({
#if JVET_M0453_CABAC_ENGINE
......@@ -1151,6 +1168,7 @@ const CtxSet ContextSetCfg::EMTCuFlag = ContextSetCfg::addCtxSet
{ CNU, CNU, 140, 155, 155, CNU, },
#endif
});
#endif
const CtxSet ContextSetCfg::CrossCompPred = ContextSetCfg::addCtxSet
({
......
......@@ -282,12 +282,18 @@ public:
static const CtxSet MVPIdx;
static const CtxSet SaoMergeFlag;
static const CtxSet SaoTypeIdx;
#if JVET_M0464_UNI_MTS
static const CtxSet MTSIndex;
#else
static const CtxSet TransformSkipFlag;
#endif
static const CtxSet TransquantBypassFlag;
static const CtxSet RdpcmFlag;
static const CtxSet RdpcmDir;
#if !JVET_M0464_UNI_MTS
static const CtxSet EMTTuIndex;
static const CtxSet EMTCuFlag;
#endif
static const CtxSet CrossCompPred;
static const CtxSet ChromaQpAdjFlag;
static const CtxSet ChromaQpAdjIdc;
......
......@@ -642,7 +642,11 @@ namespace DQIntern
const int channelBitDepth = sps.getBitDepth( chType );
const int maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange( chType );
const int nomTransformShift = getTransformShift( channelBitDepth, area.size(), maxLog2TrDynamicRange );
#if JVET_M0464_UNI_MTS
const bool clipTransformShift = ( tu.mtsIdx==1 && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag() );
#else
const bool clipTransformShift = ( tu.transformSkip[ compID ] && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag() );
#endif
const int transformShift = ( clipTransformShift ? std::max<int>( 0, nomTransformShift ) : nomTransformShift );
// quant parameters
......@@ -726,7 +730,11 @@ namespace DQIntern
const TCoeff minTCoeff = -( 1 << maxLog2TrDynamicRange );
const TCoeff maxTCoeff = ( 1 << maxLog2TrDynamicRange ) - 1;
const int nomTransformShift = getTransformShift( channelBitDepth, area.size(), maxLog2TrDynamicRange );
#if JVET_M0464_UNI_MTS
const bool clipTransformShift = ( tu.mtsIdx==1 && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag() );
#else
const bool clipTransformShift = ( tu.transformSkip[ compID ] && sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag() );
#endif
const int transformShift = ( clipTransformShift ? std::max<int>( 0, nomTransformShift ) : nomTransformShift );
#if HM_QTBT_AS_IN_JEM_QUANT
Intermediate_Int shift = IQUANT_SHIFT + 1 - qpPer - transformShift + ( TU::needsBlockSizeTrafoScale( area ) ? ADJ_DEQUANT_SHIFT : 0 );
......
......@@ -301,7 +301,11 @@ void Quant::dequant(const TransformUnit &tu,
CHECK(uiWidth > m_uiMaxTrSize, "Unsupported transformation size");
// Represents scaling through forward transform
#if JVET_M0464_UNI_MTS
const bool bClipTransformShiftTo0 = tu.mtsIdx!=1 && sps->getSpsRangeExtension().getExtendedPrecisionProcessingFlag();
#else
const bool bClipTransformShiftTo0 = (tu.transformSkip[compID] != 0) && sps->getSpsRangeExtension().getExtendedPrecisionProcessingFlag();
#endif
const int originalTransformShift = getTransformShift(channelBitDepth, area.size(), maxLog2TrDynamicRange);
const int iTransformShift = bClipTransformShiftTo0 ? std::max<int>(0, originalTransformShift) : originalTransformShift;
......@@ -717,7 +721,11 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
const CCoeffBuf &piCoef = pSrc;
CoeffBuf piQCoef = tu.getCoeffs(compID);
#if JVET_M0464_UNI_MTS
const bool useTransformSkip = tu.mtsIdx==1;
#else
const bool useTransformSkip = tu.transformSkip[compID];
#endif
const int maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange(toChannelType(compID));
{
......@@ -820,7 +828,11 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff
const CCoeffBuf piCoef = pSrc;
#if JVET_M0464_UNI_MTS
const bool useTransformSkip = tu.mtsIdx==1;
#else
const bool useTransformSkip = tu.transformSkip[compID];
#endif
const int maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange(toChannelType(compID));
#if HEVC_USE_SCALING_LISTS
......
......@@ -542,7 +542,11 @@ void QuantRDOQ::quant(TransformUnit &tu, const ComponentID &compID, const CCoeff
const CCoeffBuf &piCoef = pSrc;
CoeffBuf piQCoef = tu.getCoeffs(compID);
#if JVET_M0464_UNI_MTS
const bool useTransformSkip = tu.mtsIdx==1;
#else
const bool useTransformSkip = tu.transformSkip[compID];
#endif
bool useRDOQ = useTransformSkip ? m_useRDOQTS : m_useRDOQ;
......@@ -598,7 +602,11 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
// Represents scaling through forward transform
int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange);
#if JVET_M0464_UNI_MTS
if (tu.mtsIdx==1 && extendedPrecision)
#else
if (tu.transformSkip[compID] && extendedPrecision)
#endif
{
iTransformShift = std::max<int>(0, iTransformShift);
}
......
......@@ -113,7 +113,9 @@ extern const uint8_t g_chroma422IntraAngleMappingTable[NUM_INTRA_MODE];
extern const TMatrixCoeff g_as_DST_MAT_4 [TRANSFORM_NUMBER_OF_DIRECTIONS][4][4];
#endif
#if !JVET_M0464_UNI_MTS
extern const uint32_t g_EmtSigNumThr;
#endif
extern const TMatrixCoeff g_trCoreDCT2P2 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 2][ 2];
extern const TMatrixCoeff g_trCoreDCT2P4 [TRANSFORM_NUMBER_OF_DIRECTIONS][ 4][ 4];
......
......@@ -1738,8 +1738,13 @@ SPSNext::SPSNext( SPS& sps )
, m_BIO ( false )
, m_DisableMotionCompression ( false )
, m_LMChroma ( false )
#if JVET_M0464_UNI_MTS
, m_IntraMTS ( false )
, m_InterMTS ( false )
#else
, m_IntraEMT ( false )
, m_InterEMT ( false )
#endif
, m_Affine ( false )
, m_AffineType ( false )
, m_MTTEnabled ( false )
......
......@@ -804,8 +804,13 @@ private:
bool m_BIO;
bool m_DisableMotionCompression; // 13
bool m_LMChroma; // 17
#if JVET_M0464_UNI_MTS
bool m_IntraMTS; // 18
bool m_InterMTS; // 19
#else
bool m_IntraEMT; // 18
bool m_InterEMT; // 19
#endif
bool m_Affine;
bool m_AffineType;
bool m_GBi; //
......@@ -872,10 +877,17 @@ public:
#endif
void setUseLMChroma ( bool b ) { m_LMChroma = b; }
bool getUseLMChroma () const { return m_LMChroma; }
#if JVET_M0464_UNI_MTS
void setUseIntraMTS ( bool b ) { m_IntraMTS = b; }
bool getUseIntraMTS () const { return m_IntraMTS; }
void setUseInterMTS ( bool b ) { m_InterMTS = b; }
bool getUseInterMTS () const { return m_InterMTS; }
#else
void setUseIntraEMT ( bool b ) { m_IntraEMT = b; }
bool getUseIntraEMT () const { return m_IntraEMT; }
void setUseInterEMT ( bool b ) { m_InterEMT = b; }
bool getUseInterEMT () const { return m_InterEMT; }
#endif
void setUseGBi ( bool b ) { m_GBi = b; }
bool getUseGBi () const { return m_GBi; }
#if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
......
......@@ -91,7 +91,13 @@ TrQuant::TrQuant() : m_quant( nullptr )
{
// allocate temporary buffers
m_plTempCoeff = (TCoeff*) xMalloc( TCoeff, MAX_CU_SIZE * MAX_CU_SIZE );
#if JVET_M0464_UNI_MTS
m_mtsCoeffs = new TCoeff*[ NUM_TRAFO_MODES_MTS ];
for( int i = 0; i < NUM_TRAFO_MODES_MTS; i++ )
{
m_mtsCoeffs[i] = (TCoeff*) xMalloc( TCoeff, MAX_CU_SIZE * MAX_CU_SIZE );
}
#endif
}
TrQuant::~TrQuant()
......@@ -108,6 +114,17 @@ TrQuant::~TrQuant()
xFree( m_plTempCoeff );
m_plTempCoeff = nullptr;
}
#if JVET_M0464_UNI_MTS
if( m_mtsCoeffs )
{
for( int i = 0; i < NUM_TRAFO_MODES_MTS; i++ )
{
xFree( m_mtsCoeffs[i] );
m_mtsCoeffs[i] = nullptr;
}
m_mtsCoeffs = nullptr;
}
#endif
}
#if ENABLE_SPLIT_PARALLELISM
......@@ -187,8 +204,11 @@ void TrQuant::invTransformNxN( TransformUnit &tu, const ComponentID &compID, Pel
DTRACE_COEFF_BUF( D_TCOEFF, tempCoeff, tu, tu.cu->predMode, compID );
#if JVET_M0464_UNI_MTS
if( tu.mtsIdx == 1 )
#else
if( tu.transformSkip[compID] )
#endif
{
xITransformSkip( tempCoeff, pResi, tu, compID );
}
......@@ -207,7 +227,11 @@ void TrQuant::invRdpcmNxN(TransformUnit& tu, const ComponentID &compID, PelBuf &
{
const CompArea &area = tu.blocks[compID];
#if JVET_M0464_UNI_MTS
if (CU::isRDPCMEnabled(*tu.cu) && (tu.mtsIdx==1 || tu.cu->transQuantBypass))
#else
if (CU::isRDPCMEnabled(*tu.cu) && ((tu.transformSkip[compID] != 0) || tu.cu->transQuantBypass))
#endif
{
const uint32_t uiWidth = area.width;
const uint32_t uiHeight = area.height;
......@@ -267,19 +291,34 @@ void TrQuant::invRdpcmNxN(TransformUnit& tu, const ComponentID &compID, PelBuf &
void TrQuant::getTrTypes ( TransformUnit tu, const ComponentID compID, int &trTypeHor, int &trTypeVer )
{
#if JVET_M0464_UNI_MTS
bool mtsActivated = CU::isIntra( *tu.cu ) ? tu.cs->sps->getSpsNext().getUseIntraMTS() : tu.cs->sps->getSpsNext().getUseInterMTS();
#else
bool emtActivated = CU::isIntra( *tu.cu ) ? tu.cs->sps->getSpsNext().getUseIntraEMT() : tu.cs->sps->getSpsNext().getUseInterEMT();
#endif
trTypeHor = DCT2;
trTypeVer = DCT2;
#if JVET_M0464_UNI_MTS
if ( mtsActivated )
#else
if ( emtActivated )
#endif
{
if( compID == COMPONENT_Y )
{
#if JVET_M0464_UNI_MTS
if ( tu.mtsIdx > 1 )
{
int indHor = ( tu.mtsIdx - 2 ) & 1;
int indVer = ( tu.mtsIdx - 2 ) >> 1;
#else
if ( tu.cu->emtFlag )
{
int indHor = tu.emtIdx & 1;
int indVer = tu.emtIdx >> 1;
#endif
trTypeHor = indHor ? DCT8 : DST7;
trTypeVer = indVer ? DCT8 : DST7;
......@@ -437,7 +476,67 @@ void TrQuant::xQuant(TransformUnit &tu, const ComponentID &compID, const CCoeffB
m_quant->quant( tu, compID, pSrc, uiAbsSum, cQP, ctx );
}
#if JVET_M0464_UNI_MTS
void TrQuant::transformNxN(TransformUnit &tu, const ComponentID &compID, const QpParam &cQP, std::vector<TrMode>* trModes, const int maxCand)
{
CodingStructure &cs = *tu.cs;
const SPS &sps = *cs.sps;
const CompArea &rect = tu.blocks[compID];
const uint32_t width = rect.width;
const uint32_t height = rect.height;
const CPelBuf resiBuf = cs.getResiBuf(rect);
CHECK( sps.getMaxTrSize() < width, "Unsupported transformation size" );
int pos = 0;
std::vector<TrCost> trCosts;
std::vector<TrMode>::iterator it = trModes->begin();
const double facBB[] = { 1.2, 1.3, 1.3, 1.4, 1.5 };
while( it != trModes->end() )
{
tu.mtsIdx = it->first;
CoeffBuf tempCoeff( m_mtsCoeffs[tu.mtsIdx], rect );
if( tu.mtsIdx == 1 )
{
xTransformSkip( tu, compID, resiBuf, tempCoeff.buf );
}
else
{
xT( tu, compID, resiBuf, tempCoeff, width, height );
}
int sumAbs = 0;
for( int pos = 0; pos < width*height; pos++ )
{
sumAbs += abs( tempCoeff.buf[pos] );
}
trCosts.push_back( TrCost( sumAbs, pos++ ) );
it++;
}
int numTests = 0;
std::vector<TrCost>::iterator itC = trCosts.begin();
const double fac = facBB[g_aucLog2[std::max(width, height)]-2];
const double thr = fac * trCosts.begin()->first;
const double thrTS = trCosts.begin()->first;
while( itC != trCosts.end() )
{
const bool testTr = itC->first <= ( itC->second == 1 ? thrTS : thr ) && numTests <= maxCand;
trModes->at( itC->second ).second = testTr;
numTests += testTr;
itC++;
}
}
#endif
#if JVET_M0464_UNI_MTS
void TrQuant::transformNxN(TransformUnit &tu, const ComponentID &compID, const QpParam &cQP, TCoeff &uiAbsSum, const Ctx &ctx, const bool loadTr)
#else
void TrQuant::transformNxN(TransformUnit &tu, const ComponentID &compID, const QpParam &cQP, TCoeff &uiAbsSum, const Ctx &ctx)
#endif
{
CodingStructure &cs = *tu.cs;
const SPS &sps = *cs.sps;
......@@ -483,11 +582,21 @@ void TrQuant::transformNxN(TransformUnit &tu, const ComponentID &compID, const Q
{
CHECK( sps.getMaxTrSize() < uiWidth, "Unsupported transformation size" );
#if JVET_M0464_UNI_MTS
CoeffBuf tempCoeff( loadTr ? m_mtsCoeffs[tu.mtsIdx] : m_plTempCoeff, rect );
#else
CoeffBuf tempCoeff( m_plTempCoeff, rect );
#endif
DTRACE_PEL_BUF( D_RESIDUALS, resiBuf, tu, tu.cu->predMode, compID );
#if JVET_M0464_UNI_MTS
if( !loadTr )
{
if( tu.mtsIdx == 1 )
#else
if( tu.transformSkip[compID] )
#endif
{
xTransformSkip( tu, compID, resiBuf, tempCoeff.buf );
}
......@@ -495,6 +604,9 @@ void TrQuant::transformNxN(TransformUnit &tu, const ComponentID &compID, const Q
{
xT( tu, compID, resiBuf, tempCoeff, uiWidth, uiHeight );
}
#if JVET_M0464_UNI_MTS
}
#endif
DTRACE_COEFF_BUF( D_TCOEFF, tempCoeff, tu, tu.cu->predMode, compID );
......@@ -567,7 +679,11 @@ void TrQuant::applyForwardRDPCM(TransformUnit &tu, const ComponentID &compID, co
void TrQuant::rdpcmNxN(TransformUnit &tu, const ComponentID &compID, const QpParam &cQP, TCoeff &uiAbsSum, RDPCMMode &rdpcmMode)
{
#if JVET_M0464_UNI_MTS
if (!CU::isRDPCMEnabled(*tu.cu) || (tu.mtsIdx!=1 && !tu.cu->transQuantBypass))
#else
if (!CU::isRDPCMEnabled(*tu.cu) ||