diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index 784f97a68dd23ce55b9e2defa361163538b98fb7..cbbafd2112fda9f2ffa06c8b5448e993782cbd4b 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -5752,6 +5752,9 @@ void InterPrediction::sortAffineMergeCandidates(PredictionUnit pu, AffineMergeC pu.ciipFlag = false; MvField mvfMmvd[2][3]; PU::getAfMmvdMvf(pu, affMrgCtx, mvfMmvd, pu.mergeIdx, pu.afMmvdStep, pu.afMmvdDir); +#if JVET_Z0067_RPR_ENABLE + bool bIsRefScaled = false; +#endif for (int i = 0; i < 2; i++) { if( pu.cs->slice->getNumRefIdx( RefPicList( i ) ) > 0 ) @@ -5764,8 +5767,22 @@ void InterPrediction::sortAffineMergeCandidates(PredictionUnit pu, AffineMergeC pu.mvAffi[i][1] = mvfMmvd[i][1].mv; pu.mvAffi[i][2] = mvfMmvd[i][2].mv; } +#if JVET_Z0067_RPR_ENABLE + if ( !bIsRefScaled && pu.refIdx[i]>=0 && pu.cu->slice->getRefPic(i ? REF_PIC_LIST_1 : REF_PIC_LIST_0, pu.refIdx[i])->isRefScaled(pu.cs->pps) ) + { + bIsRefScaled = true; + } +#endif } uiCost = 0; +#if JVET_Z0067_RPR_ENABLE + if ( bIsRefScaled ) + { + uiCost = std::numeric_limits<Distortion>::max(); + } + else + { +#endif PelUnitBuf pcBufPredRefTop = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvRefAMLTemplate[0][0], nWidth, AML_MERGE_TEMPLATE_SIZE))); PelUnitBuf pcBufPredCurTop = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvCurAMLTemplate[0][0], nWidth, AML_MERGE_TEMPLATE_SIZE))); PelUnitBuf pcBufPredRefLeft = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvRefAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight))); @@ -5785,7 +5802,10 @@ void InterPrediction::sortAffineMergeCandidates(PredictionUnit pu, AffineMergeC uiCost += cDistParam.distFunc(cDistParam); } - +#if JVET_Z0067_RPR_ENABLE + } +#endif + // update part uint32_t i; uint32_t shift = 0; @@ -6781,6 +6801,9 @@ void InterPrediction::getAffAMLRefTemplate(PredictionUnit &pu, PelUnitBuf &pcBuf Pel * refAboveTemplate = m_acYuvRefAMLTemplate[0][0]; int numTemplate[2] = { 0, 0 }; // 0:Above, 1:Left const RefPicList eRefPicList = REF_PIC_LIST_0; +#if JVET_Z0067_RPR_ENABLE + CHECK(pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[eRefPicList])->isRefScaled(pu.cs->pps), "getAffAMLRefTemplate not supported with ref scaled."); +#endif xPredAffineTpl(pu, eRefPicList, numTemplate, refLeftTemplate, refAboveTemplate); #if INTER_LIC if (pu.cu->LICFlag) @@ -6814,6 +6837,9 @@ void InterPrediction::getAffAMLRefTemplate(PredictionUnit &pu, PelUnitBuf &pcBuf } RefPicList eRefPicList = (refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0); CHECK(pu.refIdx[refList] >= pu.cu->slice->getNumRefIdx(eRefPicList), "Invalid reference index"); +#if JVET_Z0067_RPR_ENABLE + CHECK(pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[eRefPicList])->isRefScaled(pu.cs->pps), "getAffAMLRefTemplate not supported with ref scaled."); +#endif Pel *refLeftTemplate = m_acYuvRefLeftTemplate[refList][0]; Pel *refAboveTemplate = m_acYuvRefAboveTemplate[refList][0]; int numTemplate[2] = { 0, 0 }; // 0:Above, 1:Left @@ -8555,6 +8581,12 @@ TplMatchingCtrl::TplMatchingCtrl( const PredictionUnit& pu, , m_maxSearchRounds (maxSearchRounds) , m_compID (compID) { +#if JVET_Z0067_RPR_ENABLE + if ( refPic.isRefScaled(pu.cs->pps) ) + { + return; + } +#endif // Initialization const bool tplAvalableAbove = xFillCurTemplate<TM_TPL_SIZE, true >((fillCurTpl ? curTplAbove : nullptr)); const bool tplAvalableLeft = xFillCurTemplate<TM_TPL_SIZE, false>((fillCurTpl ? curTplLeft : nullptr)); @@ -11002,16 +11034,21 @@ void InterPrediction::reorderRefCombList(PredictionUnit &pu, std::vector<RefList tmpPU.mvAffi[eRefList][1] = mvRT; tmpPU.mvAffi[eRefList][2] = mvLB; +#if !JVET_Z0067_RPR_ENABLE getAffAMLRefTemplate(tmpPU, pcBufPredRefTop, pcBufPredRefLeft); +#endif uiCost = 0; bool bRefIsRescaled = (tmpPU.refIdx[eRefList] >= 0) ? tmpPU.cu->slice->getRefPic(eRefList, tmpPU.refIdx[eRefList])->isRefScaled(pu.cs->pps) : false; if (bRefIsRescaled) { - uiCost = 0; + uiCost = std::numeric_limits<Distortion>::max(); } else { +#if JVET_Z0067_RPR_ENABLE + getAffAMLRefTemplate(tmpPU, pcBufPredRefTop, pcBufPredRefLeft); +#endif if (m_bAMLTemplateAvailabe[0]) { m_pcRdCost->setDistParam(cDistParam, pcBufPredCurTop.Y(), pcBufPredRefTop.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, false); @@ -11089,13 +11126,15 @@ void InterPrediction::reorderRefCombList(PredictionUnit &pu, std::vector<RefList getBlkAMLRefTemplate(tmpPU, pcBufPredRefTop, pcBufPredRefLeft); uiCost = 0; +#if !JVET_Z0067_RPR_ENABLE bool bRefIsRescaled = (tmpPU.refIdx[eRefList] >= 0) ? tmpPU.cu->slice->getRefPic(eRefList, tmpPU.refIdx[eRefList])->isRefScaled(pu.cs->pps) : false; if (bRefIsRescaled) { - uiCost = 0; + uiCost = std::numeric_limits<Distortion>::max(); } else { +#endif if (m_bAMLTemplateAvailabe[0]) { m_pcRdCost->setDistParam(cDistParam, pcBufPredCurTop.Y(), pcBufPredRefTop.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, false); @@ -11109,7 +11148,9 @@ void InterPrediction::reorderRefCombList(PredictionUnit &pu, std::vector<RefList uiCost += cDistParam.distFunc(cDistParam); } +#if !JVET_Z0067_RPR_ENABLE } +#endif #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED MotionInfoPred miPred; @@ -11468,7 +11509,9 @@ void InterPrediction::reorderRefPairList(PredictionUnit &pu, std::vector<RefPicP miPred.mvAffi[refList][2] = tmpPU.mvAffi[refList][2]; #endif +#if !JVET_Z0067_RPR_ENABLE getAffAMLRefTemplate(tmpPU, pcBufPredRefTop, pcBufPredRefLeft); +#endif uiCost = 0; bool bRefIsRescaled = false; @@ -11479,10 +11522,13 @@ void InterPrediction::reorderRefPairList(PredictionUnit &pu, std::vector<RefPicP } if (bRefIsRescaled) { - uiCost = 0; + uiCost = std::numeric_limits<Distortion>::max(); } else { +#if JVET_Z0067_RPR_ENABLE + getAffAMLRefTemplate(tmpPU, pcBufPredRefTop, pcBufPredRefLeft); +#endif if (m_bAMLTemplateAvailabe[0]) { m_pcRdCost->setDistParam(cDistParam, pcBufPredCurTop.Y(), pcBufPredRefTop.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, false); @@ -11571,6 +11617,7 @@ void InterPrediction::reorderRefPairList(PredictionUnit &pu, std::vector<RefPicP getBlkAMLRefTemplate(tmpPU, pcBufPredRefTop, pcBufPredRefLeft); uiCost = 0; +#if !JVET_Z0067_RPR_ENABLE bool bRefIsRescaled = false; for (uint32_t refList = 0; refList < NUM_REF_PIC_LIST_01; refList++) { @@ -11579,10 +11626,11 @@ void InterPrediction::reorderRefPairList(PredictionUnit &pu, std::vector<RefPicP } if (bRefIsRescaled) { - uiCost = 0; + uiCost = std::numeric_limits<Distortion>::max(); } else { +#endif if (m_bAMLTemplateAvailabe[0]) { m_pcRdCost->setDistParam(cDistParam, pcBufPredCurTop.Y(), pcBufPredRefTop.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, false); @@ -11596,7 +11644,9 @@ void InterPrediction::reorderRefPairList(PredictionUnit &pu, std::vector<RefPicP uiCost += cDistParam.distFunc(cDistParam); } - } +#if !JVET_Z0067_RPR_ENABLE + } +#endif #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED miPred.cost = uiCost; @@ -12090,6 +12140,16 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e #endif std::vector<std::pair<Mv, Distortion>> aMvCostVec(patternsNum); +#if JVET_Z0067_RPR_ENABLE + bool bIsRefScaled = pu.cu->slice->getRefPic(eRefList, refIdx)->isRefScaled( pu.cs->pps ); + for (int n = 0; n < patternsNum; ++n) + { + auto cMvdTest = cMvdDerived[n]; + Mv cMvTest = cMvPred + cMvdTest; + Distortion uiCost = bIsRefScaled ? std::numeric_limits<Distortion>::max() : tplCtrl.xGetTempMatchError<TM_TPL_SIZE>(cMvTest); + aMvCostVec[n] = { cMvdTest, uiCost }; + } +#else for (int n = 0; n < patternsNum; ++n) { auto cMvdTest = cMvdDerived[n]; @@ -12097,7 +12157,8 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e Distortion uiCost = tplCtrl.xGetTempMatchError<TM_TPL_SIZE>(cMvTest); aMvCostVec[n] = { cMvdTest, uiCost }; } - +#endif + std::stable_sort(aMvCostVec.begin(), aMvCostVec.end(), [](const std::pair<Mv, Distortion> & l, const std::pair<Mv, Distortion> & r) {return l.second < r.second; }); for (int n = 0; n < patternsNum; ++n) @@ -12233,6 +12294,16 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e TplMatchingCtrl tplCtrl(pu, interRes, refPic, true, COMPONENT_Y, true, 0, m_pcCurTplAbove, m_pcCurTplLeft, m_pcRefTplAbove, m_pcRefTplLeft, Mv(0, 0), nullptr, 0); +#if JVET_Z0067_RPR_ENABLE + bool bIsRefScaled = pu.cu->slice->getRefPic(REF_PIC_LIST_0, refIdx)->isRefScaled(pu.cs->pps); + for (int n = 0; n < patternsNum; ++n) + { + auto cMvdTest = cMvdDerived[n]; + Mv cMvTest = cMvPred + cMvdTest; + Distortion uiCost = bIsRefScaled ? std::numeric_limits<Distortion>::max() : tplCtrl.xGetTempMatchError<TM_TPL_SIZE>(cMvTest); + aMvCostVec[n] = { cMvdTest, uiCost }; + } +#else for (int n = 0; n < patternsNum; ++n) { auto cMvdTest = cMvdDerived[n]; @@ -12240,7 +12311,8 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e Distortion uiCost = tplCtrl.xGetTempMatchError<TM_TPL_SIZE>(cMvTest); aMvCostVec[n] = { cMvdTest, uiCost }; } - +#endif + std::stable_sort(aMvCostVec.begin(), aMvCostVec.end(), [](const std::pair<Mv, Distortion> & l, const std::pair<Mv, Distortion> & r) {return l.second < r.second; }); for (int n = 0; n < patternsNum; ++n) @@ -12641,6 +12713,18 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e std::vector<std::pair<int, Distortion>> aMvCostVec(patternsNum); Distortion uiCost = 0; +#if JVET_Z0067_RPR_ENABLE + bool bIsRefScaled = pu.cu->slice->getRefPic(eRefList, refIdx)->isRefScaled( pu.cs->pps ); + if ( bIsRefScaled ) + { + for (int n = 0; n < patternsNum; ++n) + { + aMvCostVec[n] = { n, uiCost }; + } + } + else + { +#endif for (int n = 0; n < patternsNum; ++n) { uiCost = 0; @@ -12708,6 +12792,9 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e } aMvCostVec[n] = { n, uiCost }; } +#if JVET_Z0067_RPR_ENABLE + } +#endif //--------------------------------------------------------------------------------// ///////////////////////////////////////////////////////////////// std::stable_sort(aMvCostVec.begin(), aMvCostVec.end(), [](const std::pair<int, Distortion> & l, const std::pair<int, Distortion> & r) {return l.second < r.second; }); @@ -12734,6 +12821,9 @@ void InterPrediction::deriveMVDcandAffine(const PredictionUnit& pu, RefPicList e Pel* recLeftTemplate, Pel* recAboveTemplate) { +#if JVET_Z0067_RPR_ENABLE + CHECK(refPic.isRefScaled(cu.cs->pps), "xGetSublkTemplateCost ref Scaled not supported"); +#endif const int bitDepth = cu.cs->sps->getBitDepth(toChannelType(compID)); const int precShift = std::max(0, bitDepth - 12); Distortion cost = 0; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 6dd036c8bbdaf6fbb31da2c5c9846b7d54df78a0..841d2d384b4086bc13fb7111796044565dd731d4 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -254,9 +254,9 @@ #endif // tools // Software extensions -#define RPR_ENABLE 1 // JVET-X0121: Fixes for RRP +#define RPR_ENABLE 1 // JVET-X0121: Fixes for RPR #define JVET_Y0128_NON_CTC 1 // JVET-Y0128: Fixing issues for RPR enabling and non-CTC configuration in ECM - +#define JVET_Z0067_RPR_ENABLE 1 // JVET_Z0067: Fixes for RPR diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 3dcfaa343995fe3c8b9796495da0714c38b3d100..2c1471c334686e7750b571945e955f0104f27b07 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -10805,32 +10805,53 @@ void PU::spanGeoMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const uint8 PosY.x = pu.Y().x + (x << MIN_CU_LOG2) + cMv.getHor(); PosY.y = pu.Y().y + (y << MIN_CU_LOG2) + cMv.getVer(); clipColPos(PosY.x, PosY.y, pu); +#if JVET_Z0067_RPR_ENABLE + scalePositionInRef(pu, *pu.cs->pps, RefPicList(list), refIdx, PosY); + PosY.x = (PosY.x & mask); + PosY.y = (PosY.y & mask); + ipm = pu.cu->slice->getRefPic(RefPicList(list), refIdx)->unscaledPic->cs->getIpmInfo(PosY); +#else PosY.x = (PosY.x & mask); PosY.y = (PosY.y & mask); ipm = pu.cu->slice->getRefPic(RefPicList(list), refIdx)->cs->getIpmInfo(PosY); +#endif } else { +#if JVET_Z0067_RPR_ENABLE + const Picture* pRefPic0 = pu.cu->slice->getRefPic(REF_PIC_LIST_0, tempMi.refIdx[0])->unscaledPic; +#else Picture* pRefPic0 = pu.cu->slice->getRefPic(REF_PIC_LIST_0, tempMi.refIdx[0]); +#endif Mv cMv0 = tempMi.mv[0]; cMv0.changePrecision(MV_PRECISION_SIXTEENTH, MV_PRECISION_INT); Position PosY0; PosY0.x = pu.Y().x + (x << MIN_CU_LOG2) + cMv0.getHor(); PosY0.y = pu.Y().y + (y << MIN_CU_LOG2) + cMv0.getVer(); clipColPos(PosY0.x, PosY0.y, pu); +#if JVET_Z0067_RPR_ENABLE + scalePositionInRef(pu, *pu.cs->pps, REF_PIC_LIST_0, tempMi.refIdx[0], PosY0); +#endif PosY0.x = (PosY0.x & mask); PosY0.y = (PosY0.y & mask); MotionInfo mi0 = pRefPic0->cs->getMotionInfo(PosY0); int ipm0 = pRefPic0->cs->getIpmInfo(PosY0); int pocDiff0 = abs(pRefPic0->getPOC() - pu.cu->slice->getPOC()); +#if JVET_Z0067_RPR_ENABLE + const Picture* pRefPic1 = pu.cu->slice->getRefPic(REF_PIC_LIST_1, tempMi.refIdx[1])->unscaledPic; +#else Picture* pRefPic1 = pu.cu->slice->getRefPic(REF_PIC_LIST_1, tempMi.refIdx[1]); +#endif Mv cMv1 = tempMi.mv[1]; cMv1.changePrecision(MV_PRECISION_SIXTEENTH, MV_PRECISION_INT); Position PosY1; PosY1.x = pu.Y().x + (x << MIN_CU_LOG2) + cMv1.getHor(); PosY1.y = pu.Y().y + (y << MIN_CU_LOG2) + cMv1.getVer(); clipColPos(PosY1.x, PosY1.y, pu); +#if JVET_Z0067_RPR_ENABLE + scalePositionInRef(pu, *pu.cs->pps, REF_PIC_LIST_1, tempMi.refIdx[1], PosY1); +#endif PosY1.x = (PosY1.x & mask); PosY1.y = (PosY1.y & mask); MotionInfo mi1 = pRefPic1->cs->getMotionInfo(PosY1); @@ -11189,32 +11210,53 @@ void PU::spanGeoMMVDMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const u PosY.x = pu.Y().x + (x << MIN_CU_LOG2) + cMv.getHor(); PosY.y = pu.Y().y + (y << MIN_CU_LOG2) + cMv.getVer(); clipColPos(PosY.x, PosY.y, pu); +#if JVET_Z0067_RPR_ENABLE + scalePositionInRef(pu, *pu.cs->pps, RefPicList(list), refIdx, PosY); + PosY.x = (PosY.x & mask); + PosY.y = (PosY.y & mask); + ipm = pu.cu->slice->getRefPic(RefPicList(list), refIdx)->unscaledPic->cs->getIpmInfo(PosY); +#else PosY.x = (PosY.x & mask); PosY.y = (PosY.y & mask); ipm = pu.cu->slice->getRefPic(RefPicList(list), refIdx)->cs->getIpmInfo(PosY); +#endif } else { +#if JVET_Z0067_RPR_ENABLE + const Picture* pRefPic0 = pu.cu->slice->getRefPic(REF_PIC_LIST_0, tempMi.refIdx[0])->unscaledPic; +#else Picture* pRefPic0 = pu.cu->slice->getRefPic(REF_PIC_LIST_0, tempMi.refIdx[0]); +#endif Mv cMv0 = tempMi.mv[0]; cMv0.changePrecision(MV_PRECISION_SIXTEENTH, MV_PRECISION_INT); Position PosY0; PosY0.x = pu.Y().x + (x << MIN_CU_LOG2) + cMv0.getHor(); PosY0.y = pu.Y().y + (y << MIN_CU_LOG2) + cMv0.getVer(); clipColPos(PosY0.x, PosY0.y, pu); +#if JVET_Z0067_RPR_ENABLE + scalePositionInRef(pu, *pu.cs->pps, REF_PIC_LIST_0, tempMi.refIdx[0], PosY0); +#endif PosY0.x = (PosY0.x & mask); PosY0.y = (PosY0.y & mask); MotionInfo mi0 = pRefPic0->cs->getMotionInfo(PosY0); int ipm0 = pRefPic0->cs->getIpmInfo(PosY0); int pocDiff0 = abs(pRefPic0->getPOC() - pu.cu->slice->getPOC()); +#if JVET_Z0067_RPR_ENABLE + const Picture* pRefPic1 = pu.cu->slice->getRefPic(REF_PIC_LIST_1, tempMi.refIdx[1])->unscaledPic; +#else Picture* pRefPic1 = pu.cu->slice->getRefPic(REF_PIC_LIST_1, tempMi.refIdx[1]); +#endif Mv cMv1 = tempMi.mv[1]; cMv1.changePrecision(MV_PRECISION_SIXTEENTH, MV_PRECISION_INT); Position PosY1; PosY1.x = pu.Y().x + (x << MIN_CU_LOG2) + cMv1.getHor(); PosY1.y = pu.Y().y + (y << MIN_CU_LOG2) + cMv1.getVer(); clipColPos(PosY1.x, PosY1.y, pu); +#if JVET_Z0067_RPR_ENABLE + scalePositionInRef(pu, *pu.cs->pps, REF_PIC_LIST_1, tempMi.refIdx[1], PosY1); +#endif PosY1.x = (PosY1.x & mask); PosY1.y = (PosY1.y & mask); MotionInfo mi1 = pRefPic1->cs->getMotionInfo(PosY1);