diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp index a1939413874f994b01d0181ec7eb447e7034e9df..7697fb82f5bb8028eb22790049ea3ed80058b5b8 100644 --- a/source/Lib/CommonLib/ContextModelling.cpp +++ b/source/Lib/CommonLib/ContextModelling.cpp @@ -481,6 +481,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 f9a9da2d516638c304e6b331e089392af0729388..ede8d83edc59b0b1acf952398d651a13cdd9adb1 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 cb70e1dcec69ea1ecc85fef4c8dd0ba875dba20c..cecbc4a8e8656ecca050212767b1493afb8852c6 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -93,6 +93,8 @@ #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_M0312_FRACMMVD_SWITCH_FOR_UHD 1 // disable fractional MVD in MMVD for UHD sequences +#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 ecaf89ca16990d33b31fcee0e1c6c86d1e0c0d15..bb4d9470ca183c7fc17ce36418b3d1db1b967979 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -371,6 +371,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 4eb057dde4a9cfe99bc1f4970d4f1e29e9f9613d..a1e1a75b6e7220573877e6f796ba45b3612b5c49 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -377,6 +377,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 3667f70d95cd8b695aedfdb2dfe64eaf43fb417a..a4fd0463202cd0050276c7dd2597ad3ae430a766 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -1983,7 +1983,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; @@ -1993,9 +1995,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) { @@ -2005,6 +2010,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& { continue; } +#endif bitsBaseIdx = baseIdx + 1; if (baseIdx == MMVD_BASE_MV_NUM - 1) { @@ -2024,13 +2030,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) @@ -2183,6 +2196,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]); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 44bca844fc0e1d485274e811ad2c37a8cbee5007..dae751b02850c032e49a4dd6338a26b43fbe02c0 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1427,6 +1427,10 @@ void EncSlice::checkDisFracMmvd( Picture* pcPic, uint32_t startCtuTsAddr, uint32 { pcSlice->setDisFracMMVD( true ); } +#if JVET_M0312_FRACMMVD_SWITCH_FOR_UHD + bool useIntegerMVD = (pcPic->lwidth()*pcPic->lheight() > 1920 * 1080); + pcSlice->setDisFracMMVD(useIntegerMVD); +#endif } #endif