diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp index ff72fa5ae297e6ac9f0fa2f5836c39a67b09f96d..1da885ebc8d7e4e341d93a709d796cca6cbb9921 100644 --- a/source/Lib/CommonLib/ContextModelling.cpp +++ b/source/Lib/CommonLib/ContextModelling.cpp @@ -491,6 +491,9 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx ) #if JVET_M0068_M0171_MMVD_CLEANUP PU::restrictBiPredMergeCandsOne(pu); #endif +#if JVET_M0823_MMVD_ENCOPT + pu.mmvdEncOptMode = 0; +#endif } void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx) { diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index df736258311e33280474aeb0c8030f39aaa76c0f..cd524e4c7d019bf30961f3722be968b92082887a 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -326,7 +326,9 @@ void InterPrediction::xSubPuMC( PredictionUnit& pu, PelUnitBuf& predBuf, const R subPu.UnitArea::operator=(UnitArea(pu.chromaFormat, Area(x, y, dx, dy))); subPu = curMi; PelUnitBuf subPredBuf = predBuf.subBuf(UnitAreaRelative(pu, subPu)); - +#if JVET_M0823_MMVD_ENCOPT + subPu.mmvdEncOptMode = 0; +#endif motionCompensation(subPu, subPredBuf, eRefPicList); secDim = later - secStep; } @@ -396,8 +398,12 @@ void InterPrediction::xPredInterUni(const PredictionUnit& pu, const RefPicList& pu.cu->lumaSize(), sps); - +#if JVET_M0823_MMVD_ENCOPT + int numOfPass = (pu.mmvdMergeFlag && pu.mmvdEncOptMode) ? 1 : (std::min((int)pcYuvPred.bufs.size(), m_maxCompIDToPred + 1)); + for (uint32_t comp = COMPONENT_Y; comp < numOfPass; comp++) +#else for( uint32_t comp = COMPONENT_Y; comp < pcYuvPred.bufs.size() && comp <= m_maxCompIDToPred; comp++ ) +#endif { const ComponentID compID = ComponentID( comp ); if (compID == COMPONENT_Y && !luma) @@ -458,7 +464,11 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred) bioApplied = false; } } - +#if JVET_M0823_MMVD_ENCOPT + if (pu.mmvdEncOptMode == 2 && pu.mmvdMergeFlag) { + bioApplied = false; + } +#endif for (uint32_t refList = 0; refList < NUM_REF_PIC_LIST_01; refList++) { if( pu.refIdx[refList] < 0) diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index da70aafbf1290e28ebc1f12c416f4c49a48df364..7b97b11dc40fb3457264d82a503b98e152f154b3 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -100,6 +100,7 @@ #define JVET_M0464_UNI_MTS 1 #define JVET_M0068_M0171_MMVD_CLEANUP 1 // MMVD cleanup with 1) flip removal, 2) L1 zero vector fix, 3) bi-pred restriction after merge/MMVD #define JVET_M0255_FRACMMVD_SWITCH 1 // disable fractional MVD in MMVD adaptively +#define JVET_M0823_MMVD_ENCOPT 1 // encoder optimization for MMVD #if JVET_M0464_UNI_MTS typedef std::pair<int, bool> TrMode; diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index ed5f3620d2533279b3321ad3cfe5121cc363e1cf..abcb04ae3245f96f581d39f035ff151ffeaca3c9 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -376,6 +376,9 @@ void PredictionUnit::initData() shareParentSize.width = -1; shareParentSize.height = -1; #endif +#if JVET_M0823_MMVD_ENCOPT + mmvdEncOptMode = 0; +#endif } PredictionUnit& PredictionUnit::operator=(const IntraPredictionData& predData) diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index db48ffdc6fa9a1252355b6ce62320c37a295b16f..9d5322234d7465abc72c28e4d7f351bd458140f9 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -382,6 +382,9 @@ struct InterPredictionData #endif Mv bv; // block vector for IBC Mv bvd; // block vector difference for IBC +#if JVET_M0823_MMVD_ENCOPT + uint8_t mmvdEncOptMode; // 0: no action 1: skip chroma MC for MMVD candidate pre-selection 2: skip chroma MC and BIO for MMVD candidate pre-selection +#endif }; struct PredictionUnit : public UnitArea, public IntraPredictionData, public InterPredictionData diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 018eb4d4f00a2ce7dab68fc11d827980bf5a0cb4..1500c9a368c1b8924a0aec9ef59c8b4bcb54b1e6 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -2010,7 +2010,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& cu.mmvdSkip = true; int tempNum = 0; tempNum = MMVD_ADD_NUM; +#if !JVET_M0823_MMVD_ENCOPT bool allowDirection[4] = { true, true, true, true }; +#endif for (uint32_t mergeCand = mergeCtx.numValidMergeCand; mergeCand < mergeCtx.numValidMergeCand + tempNum; mergeCand++) { const int mmvdMergeCand = mergeCand - mergeCtx.numValidMergeCand; @@ -2020,9 +2022,12 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& int bitsCand = 0; int baseIdx; int refineStep; +#if !JVET_M0823_MMVD_ENCOPT int direction; +#endif baseIdx = mmvdMergeCand / MMVD_MAX_REFINE_NUM; refineStep = (mmvdMergeCand - (baseIdx * MMVD_MAX_REFINE_NUM)) / 4; +#if !JVET_M0823_MMVD_ENCOPT direction = (mmvdMergeCand - baseIdx * MMVD_MAX_REFINE_NUM - refineStep * 4) % 4; if (refineStep == 0) { @@ -2032,6 +2037,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& { continue; } +#endif bitsBaseIdx = baseIdx + 1; if (baseIdx == MMVD_BASE_MV_NUM - 1) { @@ -2051,13 +2057,20 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& PU::spanMotionInfo(pu, mergeCtx); distParam.cur = singleMergeTempBuffer->Y(); +#if JVET_M0823_MMVD_ENCOPT + pu.mmvdEncOptMode = (refineStep > 2 ? 2 : 1); +#endif m_pcInterSearch->motionCompensation(pu, *singleMergeTempBuffer); - +#if JVET_M0823_MMVD_ENCOPT + pu.mmvdEncOptMode = 0; +#endif Distortion uiSad = distParam.distFunc(distParam); double cost = (double)uiSad + (double)bitsCand * sqrtLambdaForFirstPass; +#if !JVET_M0823_MMVD_ENCOPT allowDirection[direction] = cost > 1.3 * candCostList[0] ? 0 : 1; +#endif insertPos = -1; updateDoubleCandList(mergeCand, cost, RdModeList, candCostList, RdModeList2, (uint32_t)NUM_LUMA_MODE, uiNumMrgSATDCand, &insertPos); if (insertPos != -1) @@ -2210,6 +2223,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } else { +#if JVET_M0823_MMVD_ENCOPT + if (uiMergeCand >= mergeCtx.numValidMergeCand && uiMergeCand < MRG_MAX_NUM_CANDS + MMVD_ADD_NUM) { + pu.mmvdEncOptMode = 0; + m_pcInterSearch->motionCompensation(pu); + } + else +#endif if (uiNoResidualPass != 0 && uiMergeCand < mergeCtx.numValidMergeCand && RdModeList[uiMrgHADIdx] >= (MRG_MAX_NUM_CANDS + MMVD_ADD_NUM)) { tempCS->getPredBuf().copyFrom(acMergeBuffer[uiMergeCand]);