diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index d08941ec269763550a7100dd176a1e3831aeb339..a2881df31554040e244d372d2ca78c24a3912e29 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -1204,6 +1204,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setMaxNumGeoCand ( m_maxNumGeoCand ); #if JVET_AG0164_AFFINE_GPM m_cEncLib.setMaxNumGpmAffCand ( m_maxNumGpmAffCand ); +#if JVET_AJ0274_GPM_AFFINE_TM + m_cEncLib.setMaxNumGpmAffTmCand ( m_maxNumGpmAffTmCand ); +#endif #endif m_cEncLib.setMaxNumIBCMergeCand ( m_maxNumIBCMergeCand ); #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 46ed46f41a25fde3a7580bc27a4c0079c75f8d2c..737460da0d59fcf4437eb1a11f688ece2af21650 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1634,6 +1634,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) #endif #if JVET_AG0164_AFFINE_GPM ("MaxNumGPMAffCand", m_maxNumGpmAffCand, 9u, "Maximum number of geometric partitioning mode candidates") +#if JVET_AJ0274_GPM_AFFINE_TM + ("MaxNumGPMAffTmCand", m_maxNumGpmAffTmCand, 6u, "Maximum number of affine candidates for geometric partitioning mode with TM") +#endif #endif #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND #if NON_ADJACENT_MRG_CAND @@ -4063,6 +4066,9 @@ bool EncAppCfg::xCheckParameter() #if JVET_AG0164_AFFINE_GPM xConfirmPara( m_maxNumGpmAffCand > GEO_MAX_NUM_UNI_AFF_CANDS, "MaxNumGeoCand must be no more than GEO_MAX_NUM_UNI_CANDS." ); xConfirmPara( 0 < m_maxNumGpmAffCand && m_maxNumGpmAffCand < 2, "MaxNumGeoCand must be no less than 2 unless MaxNumGeoCand is 0." ); +#if JVET_AJ0274_GPM_AFFINE_TM + xConfirmPara( m_maxNumGpmAffTmCand > m_maxNumGpmAffCand, "MaxNumGeoAffTmCand must be no more than MaxNumGeoAffCand." ); +#endif #endif #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND xConfirmPara( m_maxNumMHPCand > GEO_MAX_NUM_UNI_CANDS, "m_maxNumMHPCand must be no more than GEO_MAX_NUM_UNI_CANDS." ); @@ -5557,6 +5563,9 @@ void EncAppCfg::xPrintParameter() msg( DETAILS, "Max Num Geo Merge Candidates : %d\n", m_maxNumGeoCand ); #if JVET_AG0164_AFFINE_GPM msg( DETAILS, "Max Num Gpm Affine Merge Candidates : %d\n", m_maxNumGpmAffCand ); +#if JVET_AJ0274_GPM_AFFINE_TM + msg( DETAILS, "Max Num Gpm Affine Tm Merge Candidates : %d\n", m_maxNumGpmAffTmCand ); +#endif #endif #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index ce2c501cf403d00aeb4aa34255bfce6bde944c50..9a478c16a0901ac17536b60ee3dbf14f38c0769d 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -984,6 +984,9 @@ protected: uint32_t m_maxNumGeoCand; #if JVET_AG0164_AFFINE_GPM uint32_t m_maxNumGpmAffCand; +#if JVET_AJ0274_GPM_AFFINE_TM + uint32_t m_maxNumGpmAffTmCand; +#endif #endif uint32_t m_maxNumIBCMergeCand; ///< Max number of IBC merge candidates #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index 85128bf80394d79b90fb85f59afd1ebf82044ff7..a5a6c32fc81feba3cbfcafb07e19305a1a398b66 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -1474,6 +1474,9 @@ static const int GEO_MAX_NUM_UNI_AFF_CANDS = 11; static const int GEO_MAX_ALL_INTER_UNI_CANDS = GEO_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_UNI_AFF_CANDS; static const int GEO_MAX_NUM_UNI_AFF_CANDS_ARMC = 22; +#if JVET_AJ0274_GPM_AFFINE_TM +static const int GEO_AFF_TM_MAX_AFF_CANDS = 6; +#endif #endif #if JVET_Y0065_GPM_INTRA @@ -1555,8 +1558,12 @@ static const int GEO_MAX_TRY_WEIGHTED_SAD = 140; static const int GEO_MAX_TRY_WEIGHTED_SAD = 70; #endif #if TM_MRG +#if JVET_AJ0274_GPM_AFFINE_TM +static const int GEO_TM_MAX_NUM_CANDS = GEO_MAX_NUM_UNI_CANDS * (GEO_NUM_TM_MV_CAND - 1) + GEO_MAX_NUM_UNI_AFF_CANDS; +#else static const int GEO_TM_MAX_NUM_CANDS = GEO_MAX_NUM_UNI_CANDS * (GEO_NUM_TM_MV_CAND - 1); #endif +#endif #else static const int GEO_MAX_TRY_WEIGHTED_SAD = 60; #endif diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp index cd14376d4e78989092f12946d212faf41521da41..d7884c30f251aaa2e7b090a33bdfd0a41d228652 100644 --- a/source/Lib/CommonLib/ContextModelling.cpp +++ b/source/Lib/CommonLib/ContextModelling.cpp @@ -2458,6 +2458,14 @@ void MergeCtx::setGeoMrgDuplicate( const PredictionUnit& pu ) { int mrgList = mvFieldNeighbours[(mergeCand << 1) + 0].refIdx == -1 ? 1 : 0; int mrgRefIdx = mvFieldNeighbours[(mergeCand << 1) + mrgList].refIdx; +#if JVET_AJ0274_REGRESSION_GPM_TM + if (mrgRefIdx < 0 || mrgRefIdx > MAX_NUM_REF) + { + mrgDuplicated[mergeCand] = true; + pocMrg[mergeCand] = -1; + continue; + } +#endif pocMrg[mergeCand] = slice->getRefPic((RefPicList)mrgList, mrgRefIdx)->getPOC(); mrgMv[mergeCand] = mvFieldNeighbours[(mergeCand << 1) + mrgList].mv; mrgDuplicated[mergeCand] = false; diff --git a/source/Lib/CommonLib/Contexts.h b/source/Lib/CommonLib/Contexts.h index 277ce562fbb42ae5e3515a71251359146c9a4b2f..dfb8a866464d38a71502563f153410df18584909 100644 --- a/source/Lib/CommonLib/Contexts.h +++ b/source/Lib/CommonLib/Contexts.h @@ -568,6 +568,9 @@ public: #endif #if JVET_AG0112_REGRESSION_BASED_GPM_BLENDING static const CtxSet GeoBlendFlag; +#if JVET_AJ0274_REGRESSION_GPM_TM + static const CtxSet GeoBlendTMFlag; +#endif #endif #if JVET_W0097_GPM_MMVD_TM static const CtxSet GeoMmvdFlag; diff --git a/source/Lib/CommonLib/Contexts_ecm14.0.inl b/source/Lib/CommonLib/Contexts_ecm14.0.inl index ed52c9ee4dabe0aae7feb76d0f468994e373cc37..6503c2c742ae8953f9d1a94c36f5625066466343 100644 --- a/source/Lib/CommonLib/Contexts_ecm14.0.inl +++ b/source/Lib/CommonLib/Contexts_ecm14.0.inl @@ -6519,6 +6519,31 @@ const CtxSet ContextSetCfg::SeparateTree = ContextSetCfg::addCtxSet { DWO, DWO, DWO }, }); #endif +#if JVET_AJ0274_REGRESSION_GPM_TM +const CtxSet ContextSetCfg::GeoBlendTMFlag = ContextSetCfg::addCtxSet +({ + { CNU, }, + { CNU, }, + { CNU, }, + { CNU, }, + { DWS, }, + { DWS, }, + { DWS, }, + { DWS, }, + { DWE, }, + { DWE, }, + { DWE, }, + { DWE, }, + { DWO, }, + { DWO, }, + { DWO, }, + { DWO, }, + { DWO, }, + { DWO, }, + { DWO, }, + { DWO, }, + }); +#endif #if JVET_AJ0081_CHROMA_TMRL const CtxSet ContextSetCfg::ChromaTmrlFlag = ContextSetCfg::addCtxSet ({ diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index 5cc6cea10c7e05d19e6d72ea7ee2d29bbf7a3546..21cac60fe204c4183c37a05380d66773e434a59f 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -1523,6 +1523,9 @@ void InterPrediction::xSubPuBio(PredictionUnit& pu, PelUnitBuf& predBuf, const R subPu.mvRefine = pu.mvRefine; #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) subPu.tmMergeFlag = pu.tmMergeFlag; +#endif +#if JVET_AJ0274_REGRESSION_GPM_TM + subPu.geoBlendTmFlag = pu.geoBlendTmFlag; #endif subPu.refIdx[0] = pu.refIdx[0]; subPu.refIdx[1] = pu.refIdx[1]; @@ -8284,6 +8287,9 @@ void InterPrediction::subBlockOBMC(PredictionUnit &pu, PelUnitBuf* pDst) #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) subPu.tmMergeFlag = false; #endif +#if JVET_AJ0274_REGRESSION_GPM_TM + subPu.geoBlendTmFlag = false; +#endif #if MULTI_PASS_DMVR subPu.bdmvrRefine = false; #endif @@ -9203,10 +9209,17 @@ void InterPrediction::deriveGpmSplitMode(PredictionUnit& pu, MergeCtx &geoMrgCtx Pel* pRefLeftPart0[GEO_NUM_TM_MV_CAND] = {nullptr, m_acYuvRefAMLTemplatePart0[1], m_acYuvRefAMLTemplatePart0[3], nullptr }; // For mergeCtx[GEO_TM_SHAPE_AL] and mergeCtx[GEO_TM_SHAPE_A] Pel* pRefTopPart1 [GEO_NUM_TM_MV_CAND] = {nullptr, m_acYuvRefAMLTemplatePart1[0], nullptr, m_acYuvRefAMLTemplatePart1[2]}; // For mergeCtx[GEO_TM_SHAPE_AL] and mergeCtx[GEO_TM_SHAPE_L] Pel* pRefLeftPart1[GEO_NUM_TM_MV_CAND] = {nullptr, m_acYuvRefAMLTemplatePart1[1], nullptr, m_acYuvRefAMLTemplatePart1[3]}; // For mergeCtx[GEO_TM_SHAPE_AL] and mergeCtx[GEO_TM_SHAPE_L] +#if JVET_AJ0274_GPM_AFFINE_TM + fillPartGPMRefTemplate<0, false>(pu, geoTmMrgCtx[GEO_TM_SHAPE_AL], pu.geoMergeIdx0, -1, pRefTopPart0[GEO_TM_SHAPE_AL], pRefLeftPart0[GEO_TM_SHAPE_AL], &affGeoMrgCtx); + fillPartGPMRefTemplate<0, false>(pu, geoTmMrgCtx[GEO_TM_SHAPE_A ], pu.geoMergeIdx0, -1, pRefTopPart0[GEO_TM_SHAPE_A ], pRefLeftPart0[GEO_TM_SHAPE_A ], &affGeoMrgCtx); + fillPartGPMRefTemplate<1, false>(pu, geoTmMrgCtx[GEO_TM_SHAPE_AL], pu.geoMergeIdx1, -1, pRefTopPart1[GEO_TM_SHAPE_AL], pRefLeftPart1[GEO_TM_SHAPE_AL], &affGeoMrgCtx); + fillPartGPMRefTemplate<1, false>(pu, geoTmMrgCtx[GEO_TM_SHAPE_L ], pu.geoMergeIdx1, -1, pRefTopPart1[GEO_TM_SHAPE_L ], pRefLeftPart1[GEO_TM_SHAPE_L ], &affGeoMrgCtx); +#else fillPartGPMRefTemplate<0, false>(pu, geoTmMrgCtx[GEO_TM_SHAPE_AL], pu.geoMergeIdx0, -1, pRefTopPart0[GEO_TM_SHAPE_AL], pRefLeftPart0[GEO_TM_SHAPE_AL]); fillPartGPMRefTemplate<0, false>(pu, geoTmMrgCtx[GEO_TM_SHAPE_A ], pu.geoMergeIdx0, -1, pRefTopPart0[GEO_TM_SHAPE_A ], pRefLeftPart0[GEO_TM_SHAPE_A ]); fillPartGPMRefTemplate<1, false>(pu, geoTmMrgCtx[GEO_TM_SHAPE_AL], pu.geoMergeIdx1, -1, pRefTopPart1[GEO_TM_SHAPE_AL], pRefLeftPart1[GEO_TM_SHAPE_AL]); fillPartGPMRefTemplate<1, false>(pu, geoTmMrgCtx[GEO_TM_SHAPE_L ], pu.geoMergeIdx1, -1, pRefTopPart1[GEO_TM_SHAPE_L ], pRefLeftPart1[GEO_TM_SHAPE_L ]); +#endif // Update split mode getBestGeoTMModeList(pu, numValidInList, modeList, pRefTopPart0, pRefLeftPart0, pRefTopPart1, pRefLeftPart1); @@ -9586,14 +9599,126 @@ void InterPrediction::motionCompensationGeoBlend( CodingUnit& cu, MergeCtx& geoM #endif ) { +#if JVET_AJ0274_REGRESSION_GPM_TM + MergeCtx geoBlendTmCtx; + + uint8_t maxNumBlendTmMrgCand = geoMrgCtx.numValidMergeCand; + geoBlendTmCtx.numValidMergeCand = maxNumBlendTmMrgCand; + + bool mrgDuplicated[GEO_MAX_ALL_INTER_UNI_CANDS]; + int pocMrg[GEO_MAX_ALL_INTER_UNI_CANDS]; + Mv mrgMv[GEO_MAX_ALL_INTER_UNI_CANDS]; + + for (uint8_t mergeCand = 0; mergeCand < maxNumBlendTmMrgCand; mergeCand++) + { + if (!cu.firstPU->geoBlendTmFlag) + { + break; + } + int mrgList = geoMrgCtx.mvFieldNeighbours[(mergeCand << 1) + 0].refIdx == -1 ? 1 : 0; + int mrgRefIdx = geoMrgCtx.mvFieldNeighbours[(mergeCand << 1) + mrgList].refIdx; + + pocMrg[mergeCand] = cu.slice->getRefPic((RefPicList)mrgList, mrgRefIdx)->getPOC(); + + mrgMv[mergeCand] = geoMrgCtx.mvFieldNeighbours[(mergeCand << 1) + mrgList].mv; + + mrgDuplicated[mergeCand] = false; + if (mergeCand) + { + for (int i = 0; i < mergeCand; i++) + { + if (pocMrg[mergeCand] == pocMrg[i] && mrgMv[mergeCand] == mrgMv[i]) + { + mrgDuplicated[mergeCand] = true; + break; + } + } + } + } + + for (int idx = 0; idx < maxNumBlendTmMrgCand; idx++) + { + if (!cu.firstPU->geoBlendTmFlag) + { + break; + } + if (mrgDuplicated[idx]) + { + continue; + } + geoBlendTmCtx.bcwIdx[idx] = BCW_DEFAULT; + geoBlendTmCtx.useAltHpelIf[idx] = false; +#if JVET_AG0276_NLIC + geoBlendTmCtx.altLMFlag[idx] = false; + geoBlendTmCtx.altLMParaNeighbours[idx].resetAltLinearModel(); +#endif +#if INTER_LIC + geoBlendTmCtx.licFlags[idx] = geoMrgCtx.licFlags[idx]; +#if JVET_AH0314_LIC_INHERITANCE_FOR_MRG + geoBlendTmCtx.copyLICParamFromCtx(idx, geoMrgCtx, idx); +#else + geoBlendTmCtx.setDefaultLICParamToCtx(idx); +#endif +#endif + geoBlendTmCtx.interDirNeighbours[idx] = geoMrgCtx.interDirNeighbours[idx]; + geoBlendTmCtx.mvFieldNeighbours[(idx << 1)].mv = geoMrgCtx.mvFieldNeighbours[(idx << 1)].mv; + geoBlendTmCtx.mvFieldNeighbours[(idx << 1) + 1].mv = geoMrgCtx.mvFieldNeighbours[(idx << 1) + 1].mv; + geoBlendTmCtx.mvFieldNeighbours[(idx << 1)].refIdx = geoMrgCtx.mvFieldNeighbours[(idx << 1)].refIdx; + geoBlendTmCtx.mvFieldNeighbours[(idx << 1) + 1].refIdx = geoMrgCtx.mvFieldNeighbours[(idx << 1) + 1].refIdx; + } + + for (auto& pu : CU::traversePUs(cu)) + { + if (!pu.geoBlendTmFlag) + { + break; + } + + pu.geoTmType = GEO_TM_SHAPE_AL; + pu.tmMergeFlag = true; + for (uint8_t mrgIdx = 0; mrgIdx < maxNumBlendTmMrgCand; mrgIdx++) + { + if (mrgDuplicated[mrgIdx]) + { + continue; + } + geoBlendTmCtx.setMergeInfo(pu, mrgIdx); + +#if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE + deriveTMMv(pu, NULL, mrgIdx); +#else + deriveTMMv(pu); +#endif + +#if JVET_AE0046_BI_GPM + geoBlendTmCtx.interDirNeighbours[mrgIdx] = pu.interDir; + geoBlendTmCtx.bcwIdx[mrgIdx] = (pu.interDir != 3) ? BCW_DEFAULT : geoBlendTmCtx.bcwIdx[mrgIdx]; + geoBlendTmCtx.mvFieldNeighbours[(mrgIdx << 1)].refIdx = pu.refIdx[0]; + geoBlendTmCtx.mvFieldNeighbours[(mrgIdx << 1) + 1].refIdx = pu.refIdx[1]; +#endif + geoBlendTmCtx.mvFieldNeighbours[(mrgIdx << 1)].mv = pu.mv[0]; + geoBlendTmCtx.mvFieldNeighbours[(mrgIdx << 1) + 1].mv = pu.mv[1]; + } + pu.tmMergeFlag = false; + } +#endif const int mergeIdx = cu.firstPU->geoMergeIdx0; GeoBlendInfo geoBI; +#if JVET_AJ0274_REGRESSION_GPM_TM +#if JVET_AH0314_LIC_INHERITANCE_FOR_MRG + cu.licFlag = false; + cu.firstPU->geoBlendTmFlag ? geoBlendTmCtx.setLICParamToPu(*cu.firstPU, NOT_VALID, false) : geoMrgCtx.setLICParamToPu(*cu.firstPU, NOT_VALID, false); +#endif + bool bFoundGeoBlendCand; + bFoundGeoBlendCand = cu.firstPU->geoBlendTmFlag ? getGeoBlendCand(cu, geoBlendTmCtx, mergeIdx, geoBI) : getGeoBlendCand(cu, geoMrgCtx, mergeIdx, geoBI); +#else #if JVET_AH0314_LIC_INHERITANCE_FOR_MRG cu.licFlag = false; geoMrgCtx.setLICParamToPu(*cu.firstPU, NOT_VALID, false); #endif bool bFoundGeoBlendCand = getGeoBlendCand( cu, geoMrgCtx, mergeIdx, geoBI ); +#endif if ( !bFoundGeoBlendCand ) { printf("getGeoBlendCand( mergeIdx=%d ) failed.\n", mergeIdx ); @@ -9613,7 +9738,18 @@ void InterPrediction::motionCompensationGeoBlend( CodingUnit& cu, MergeCtx& geoM bool refinePossible0 = false; bool refinePossible1 = false; { +#if JVET_AJ0274_REGRESSION_GPM_TM + if (pu.geoBlendTmFlag) + { + geoBlendTmCtx.setMergeInfo( pu, geoBI.mergeCand[0] ); + } + else + { + geoMrgCtx.setMergeInfo( pu, geoBI.mergeCand[0] ); + } +#else geoMrgCtx.setMergeInfo( pu, geoBI.mergeCand[0] ); +#endif #if JVET_AE0046_BI_GPM refinePossible0 = PU::checkBDMVRCondition(pu, true); @@ -9636,7 +9772,18 @@ void InterPrediction::motionCompensationGeoBlend( CodingUnit& cu, MergeCtx& geoM } { +#if JVET_AJ0274_REGRESSION_GPM_TM + if (pu.geoBlendTmFlag) + { + geoBlendTmCtx.setMergeInfo(pu, geoBI.mergeCand[1]); + } + else + { + geoMrgCtx.setMergeInfo( pu, geoBI.mergeCand[1] ); + } +#else geoMrgCtx.setMergeInfo( pu, geoBI.mergeCand[1] ); +#endif #if JVET_AE0046_BI_GPM refinePossible1 = PU::checkBDMVRCondition(pu, true); @@ -9681,13 +9828,42 @@ void InterPrediction::motionCompensationGeoBlend( CodingUnit& cu, MergeCtx& geoM #if JVET_AG0164_AFFINE_GPM AffineMergeCtx dummyAffineMergeCtx; #if JVET_AI0082_GPM_WITH_INTER_IBC +#if JVET_AJ0274_REGRESSION_GPM_TM + if (pu.geoBlendTmFlag) + { + PU::spanGeoMMVDMotionInfo(pu, geoBlendTmCtx + , dummyAffineMergeCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , dummyAffineMergeCtx +#endif + , geoBlendTmCtx, geoBlendTmCtx, 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, nullptr + , pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, subBdofBuf[geoMergeIdx0], subBdofBuf[geoMergeIdx1]); + } + else + { + PU::spanGeoMMVDMotionInfo(pu, geoMrgCtx + , dummyAffineMergeCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , dummyAffineMergeCtx +#endif + , geoMrgCtx, geoMrgCtx, 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, nullptr + , pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, subBdofBuf[geoMergeIdx0], subBdofBuf[geoMergeIdx1]); + } +#else PU::spanGeoMMVDMotionInfo( pu, geoMrgCtx , dummyAffineMergeCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , dummyAffineMergeCtx +#endif , geoMrgCtx, geoMrgCtx, 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, nullptr , pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, subBdofBuf[geoMergeIdx0], subBdofBuf[geoMergeIdx1] ); +#endif #else PU::spanGeoMMVDMotionInfo( pu, geoMrgCtx , dummyAffineMergeCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , dummyAffineMergeCtx +#endif , geoMrgCtx, geoMrgCtx, 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM , pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, subBdofBuf[geoMergeIdx0], subBdofBuf[geoMergeIdx1] ); #endif @@ -9719,6 +9895,9 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx #endif #if JVET_AG0164_AFFINE_GPM , AffineMergeCtx& gpmAffMrgCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , AffineMergeCtx &gpmAffTmMrgCtx +#endif #endif #if JVET_AE0046_BI_GPM , Mv(&subMvBuf)[MRG_MAX_NUM_CANDS << 1][MAX_NUM_SUBCU_DMVR] @@ -9787,8 +9966,12 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx , geoTmMrgCtx #endif #if JVET_AG0164_AFFINE_GPM +#if JVET_AJ0274_GPM_AFFINE_TM + , (cu.firstPU->geoTmFlag0 && (cu.firstPU->affineGPM[0] || cu.firstPU->affineGPM[1])) ? gpmAffTmMrgCtx : gpmAffMrgCtx +#else , gpmAffMrgCtx #endif +#endif #if JVET_Y0065_GPM_INTRA , pcIntraPred #endif @@ -9910,6 +10093,21 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx #if TM_MRG if (geoTmFlag0) { +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[0]) + { + gpmAffTmMrgCtx.setAffMergeInfo(pu, candIdx0, geoMMVDFlag0 ? geoMMVDIdx0 : -1); + if (pu.refIdx[0] >= 0)// Prepare MV for chroma + { + PU::setAllAffineMv(pu, pu.mvAffi[0][0], pu.mvAffi[0][1], pu.mvAffi[0][2], REF_PIC_LIST_0); + } + if (pu.refIdx[1] >= 0) + { + PU::setAllAffineMv(pu, pu.mvAffi[1][0], pu.mvAffi[1][1], pu.mvAffi[1][2], REF_PIC_LIST_1); + } + } + else +#endif geoTmMrgCtx0.setMergeInfo(pu, candIdx0); } else @@ -10006,6 +10204,10 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx #endif #else PU::spanMotionInfo(pu); +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + if (!geoTmFlag0) + { #endif cu.isobmcMC = true; #if JVET_AJ0161_OBMC_EXT_WITH_INTRA_PRED @@ -10014,6 +10216,9 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx subBlockOBMC(pu, &tmpGeoBuf0); #endif cu.isobmcMC = false; +#if JVET_AJ0274_GPM_AFFINE_TM + } +#endif #if JVET_AG0164_AFFINE_GPM if (pu.affineGPM[0]) { @@ -10085,6 +10290,21 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx #if TM_MRG if (geoTmFlag1) { +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[1]) + { + gpmAffTmMrgCtx.setAffMergeInfo(pu, candIdx1, geoMMVDFlag1? geoMMVDIdx1: -1); + if (pu.refIdx[0] >= 0) + { + PU::setAllAffineMv(pu, pu.mvAffi[0][0], pu.mvAffi[0][1], pu.mvAffi[0][2], REF_PIC_LIST_0); + } + if (pu.refIdx[1] >= 0) + { + PU::setAllAffineMv(pu, pu.mvAffi[1][0], pu.mvAffi[1][1], pu.mvAffi[1][2], REF_PIC_LIST_1); + } + } + else +#endif geoTmMrgCtx1.setMergeInfo(pu, candIdx1); } else @@ -10179,6 +10399,10 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx #endif #else PU::spanMotionInfo(pu); +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + if (!geoTmFlag1) + { #endif cu.isobmcMC = true; #if JVET_AJ0161_OBMC_EXT_WITH_INTRA_PRED @@ -10187,6 +10411,9 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx subBlockOBMC(pu, &tmpGeoBuf1); #endif cu.isobmcMC = false; +#if JVET_AJ0274_GPM_AFFINE_TM + } +#endif #if JVET_AG0164_AFFINE_GPM if (pu.affineGPM[1]) { @@ -13882,9 +14109,13 @@ Distortion InterPrediction::deriveBcwBlending( PredictionUnit& pu, bool bUniDir[ for (int x = 0; x < width; x++) { int posX = x - (iTemp ? AML_MERGE_TEMPLATE_SIZE : 0); - +#if JVET_AJ0274_REGRESSION_GPM_TM + const Pel P0 = bUniDir0 ? ClipPel( (Pel)rightShift((p0[x] + offset), shiftNum), clpRng ) : p0[x]; + const Pel P1 = bUniDir1 ? ClipPel( (Pel)rightShift((p1[x] + offset), shiftNum), clpRng ) : p1[x]; +#else const Pel P0 = ClipPel( (Pel)rightShift((p0[x] + offset), shiftNum), clpRng ); const Pel P1 = ClipPel( (Pel)rightShift((p1[x] + offset), shiftNum), clpRng ); +#endif int iWeight = blendModel.compute( posX, posY ); @@ -19436,6 +19667,17 @@ void InterPrediction::getAffAndSbtmvpRefTemplate(PredictionUnit& pu, PelUnitBuf& Pel *recLeftTemplate = m_acYuvCurAMLTemplate[1][0]; Pel *recAboveTemplate = m_acYuvCurAMLTemplate[0][0]; xGetLICParamGeneral(*pu.cu, COMPONENT_Y, numTemplate, refLeftTemplate, refAboveTemplate, recLeftTemplate, recAboveTemplate, LICshift[refList], scale[refList], offset[refList]); +#if JVET_AH0314_LIC_INHERITANCE_FOR_MRG && JVET_AJ0274_GPM_AFFINE_TM + if (pu.cu->licInheritPara && pu.cu->geoFlag && pu.cs->sps->getMaxNumGpmAffTmCand() > 0) + { + LICshift[0] = m_LICShift; + scale[0] = pu.cu->licScale[0][0]; + offset[0] = pu.cu->licOffset[0][0]; + LICshift[1] = m_LICShift; + scale[1] = pu.cu->licScale[1][0]; + offset[1] = pu.cu->licOffset[1][0]; + } +#endif } #endif } @@ -23982,7 +24224,11 @@ void InterPrediction::deriveTMMv(PredictionUnit& pu, Distortion* tmCost) void InterPrediction::deriveTMMv(PredictionUnit& pu) #endif { +#if JVET_AJ0274_REGRESSION_GPM_TM + if (!pu.tmMergeFlag && !pu.geoBlendTmFlag) +#else if( !pu.tmMergeFlag ) +#endif { return; } @@ -27877,7 +28123,11 @@ bool InterPrediction::processTM4Affine(PredictionUnit& pu, AffineMergeCtx &affin } } #endif +#if JVET_AJ0274_GPM_AFFINE_TM + if (uiCostBest < REFINE_THRESHOLD_AFFINE_MERGE * uiCostOri && !pu.cu->geoFlag) +#else if (uiCostBest < REFINE_THRESHOLD_AFFINE_MERGE * uiCostOri) +#endif { if (!isEncoder && uiAffMergeCand > -1) { diff --git a/source/Lib/CommonLib/InterPrediction.h b/source/Lib/CommonLib/InterPrediction.h index bd92d7aef0143a5acc0ab45fad1c2ba57eb75a7e..4b48043137a3a3c1c2ff9c6a0bc7f85ea49e4271 100644 --- a/source/Lib/CommonLib/InterPrediction.h +++ b/source/Lib/CommonLib/InterPrediction.h @@ -834,6 +834,9 @@ public: #endif #if JVET_AG0164_AFFINE_GPM , AffineMergeCtx &gpmAffMrgCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , AffineMergeCtx &gpmAffTmMrgCtx +#endif #endif #if JVET_AE0046_BI_GPM , Mv(&subMvBuf)[MRG_MAX_NUM_CANDS << 1][MAX_NUM_SUBCU_DMVR] diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 3cb175e8601c35113507d62890fd0d2e839fbe46..7bfe88ad40e95a43ea8488a6ea034ebe4fcf4fd2 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -4417,6 +4417,9 @@ SPS::SPS() , m_maxNumGeoCand(0) #if JVET_AG0164_AFFINE_GPM , m_maxNumGpmAffCand(0) +#if JVET_AJ0274_GPM_AFFINE_TM +, m_maxNumGpmAffTmCand(0) +#endif #endif #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND , m_maxNumMHPCand(0) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 9e017aec4c2ea8163cf0c4aded113d776d23c8c4..b01dc83f23ccbbe8dc85723022eff69c152c357d 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1963,6 +1963,9 @@ private: uint32_t m_maxNumGeoCand; #if JVET_AG0164_AFFINE_GPM uint32_t m_maxNumGpmAffCand; +#if JVET_AJ0274_GPM_AFFINE_TM + uint32_t m_maxNumGpmAffTmCand; +#endif #endif #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND uint32_t m_maxNumMHPCand; @@ -2431,6 +2434,10 @@ void setCCALFEnabledFlag( bool b ) #if JVET_AG0164_AFFINE_GPM uint32_t getMaxNumGpmAffCand() const { CHECK(m_maxNumGpmAffCand > GEO_MAX_NUM_UNI_AFF_CANDS, "Number of GPM Affine candidates exceed GEO_MAX_NUM_UNI_AFF_CANDS"); return m_maxNumGpmAffCand; } void setMaxNumGpmAffCand(uint32_t u) { CHECK(m_maxNumGpmAffCand > GEO_MAX_NUM_UNI_AFF_CANDS, "Number of GPM Affine candidates exceed GEO_MAX_NUM_UNI_AFF_CANDS"); m_maxNumGpmAffCand = u; } +#if JVET_AJ0274_GPM_AFFINE_TM + uint32_t getMaxNumGpmAffTmCand() const { return m_maxNumGpmAffTmCand; } + void setMaxNumGpmAffTmCand(uint32_t u) { m_maxNumGpmAffTmCand = u; } +#endif #endif #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND uint32_t getMaxNumMHPCand() const { CHECK( m_maxNumMHPCand >= GEO_MAX_NUM_UNI_CANDS, "Number of MHP candidates exceed GEO_MAX_NUM_CANDS" ); return m_maxNumMHPCand; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index dd2bbe4da7313e5932129ccac854b592154c7dc6..1ede9be2a2950c0ec242f0ba37d1c63e524a4368 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -345,8 +345,12 @@ #define JVET_AF0159_AFFINE_SUBPU_BDOF_REFINEMENT 1 // JVET-AF0159: Affine subblock BDOF refinement #define JVET_AF0057 1 // JVET-AF0057: Encoder only. DMVR with robust MV derivation. #define JVET_AG0112_REGRESSION_BASED_GPM_BLENDING 1 // JVET-AG0112: Regression-based GPM blending +#define JVET_AJ0274_REGRESSION_GPM_TM 1 // JVET-AJ0274: Regression-based GPM with TM extension #define JVET_AG0135_AFFINE_CIIP 1 // JVET-AG0135: CIIP with affine prediction #define JVET_AG0164_AFFINE_GPM 1 // JVET-AG0164: GPM with affine prediction +#if JVET_AG0164_AFFINE_GPM +#define JVET_AJ0274_GPM_AFFINE_TM 1 // JVET-AJ0274: GPM-affine with TM +#endif #define JVET_AG0098_AMVP_WITH_SBTMVP 1 // JVET-AG0098: AMVP with SbTMVP mode #define JVET_AG0067_DMVR_EXTENSIONS 1 // JVET-AG0067: On DMVR Extensions #define JVET_AH0069_CMVP 1 // JVET-AH0069: Chained motion vector prediction diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index 98d8503763edec102b26c3dd3a4053c9648ab8a1..f5668d98a98cb365544e8830446436b7079f65ea 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -1141,6 +1141,9 @@ void PredictionUnit::initData() geoTmFlag1 = false; #endif #endif +#if JVET_AJ0274_REGRESSION_GPM_TM + geoBlendTmFlag = false; +#endif #if JVET_AA0058_GPM_ADAPTIVE_BLENDING geoBldIdx = MAX_UCHAR; #endif @@ -1372,6 +1375,9 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData) geoTmFlag1 = predData.geoTmFlag1; #endif #endif +#if JVET_AJ0274_REGRESSION_GPM_TM + geoBlendTmFlag = predData.geoBlendTmFlag; +#endif #if JVET_AA0058_GPM_ADAPTIVE_BLENDING geoBldIdx = predData.geoBldIdx; #endif @@ -1612,6 +1618,9 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other ) geoTmFlag1 = other.geoTmFlag1; #endif #endif +#if JVET_AJ0274_REGRESSION_GPM_TM + geoBlendTmFlag = other.geoBlendTmFlag; +#endif #if JVET_AA0058_GPM_ADAPTIVE_BLENDING geoBldIdx = other.geoBldIdx; #endif diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index e62a44e5bcdbe2be7d8fd8d915b961ac97244939..ff1fb6048eea2839f3ef92499c8f3a360c762d51 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -680,6 +680,9 @@ struct InterPredictionData uint8_t geoTmType; #endif #endif +#if JVET_AJ0274_REGRESSION_GPM_TM + bool geoBlendTmFlag; +#endif #if JVET_AA0058_GPM_ADAPTIVE_BLENDING uint8_t geoBldIdx; #endif diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 5c98aea75fe1b5b81408ccadf671668198b623e7..15adfcfcceaa6a51cd40dbadd61671c5f8394bfc 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -197,6 +197,41 @@ bool CU::isOnCtuBottom( const CodingUnit& cu ) return cuBottomY % ctuHeight == 0; } +#if JVET_AJ0274_REGRESSION_GPM_TM +bool CU::checkGeoBlendTmAvail(const CodingUnit& currCU, const CodingStructure* bestCS) +{ + const CodingUnit* bestCUTest = bestCS->getCU(CHANNEL_TYPE_LUMA); + bool skipGeoBlendTM = false; + + if (currCU.slice->getCheckLDC() && !currCU.slice->getCheckLDB() && bestCUTest->skip && !bestCUTest->affine && !bestCUTest->mmvdSkip && !bestCUTest->geoFlag && !bestCUTest->firstPU->tmMergeFlag) + { + skipGeoBlendTM = true; + } + else if (currCU.slice->getCheckLDC() && !currCU.slice->getCheckLDB() && bestCUTest->affine) + { + skipGeoBlendTM = true; + } + else if (currCU.slice->getCheckLDC() && !currCU.slice->getCheckLDB() && !bestCUTest->skip && bestCUTest->geoFlag && bestCUTest->firstPU->gpmIntraFlag) + { + skipGeoBlendTM = true; + } + else if (currCU.slice->getCheckLDB() && !bestCUTest->skip && bestCUTest->geoFlag && (bestCUTest->firstPU->geoMMVDFlag0 || bestCUTest->firstPU->geoMMVDFlag1) + && !bestCUTest->firstPU->gpmIntraFlag && !bestCUTest->firstPU->affineGPM[0] && !bestCUTest->firstPU->affineGPM[1]) + { + skipGeoBlendTM = true; + } + else if (currCU.slice->getCheckLDB() && bestCUTest->skip && !bestCUTest->affine && !bestCUTest->mmvdSkip && !bestCUTest->geoFlag && !bestCUTest->firstPU->tmMergeFlag) + { + skipGeoBlendTM = true; + } + else if (!currCU.slice->getCheckLDC() && bestCUTest->skip && !bestCUTest->affine && !bestCUTest->mmvdSkip && !bestCUTest->geoFlag && !bestCUTest->firstPU->tmMergeFlag) + { + skipGeoBlendTM = true; + } + return skipGeoBlendTM; +} +#endif + #if JVET_AI0136_ADAPTIVE_DUAL_TREE bool CU::isPartitionerOnCtuBottom( const CodingUnit& cu, const Partitioner& partitioner ) { @@ -29638,6 +29673,9 @@ void PU::spanGeoIBCMotionInfo(PredictionUnit &pu, MergeCtx &geoMrgCtx) void PU::spanGeoMMVDMotionInfo(PredictionUnit& pu, MergeCtx& geoMrgCtx #if JVET_AG0164_AFFINE_GPM , AffineMergeCtx& geoAffMrgCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , AffineMergeCtx& geoAffTmMrgCtx +#endif #endif , MergeCtx& geoTmMrgCtx0, MergeCtx& geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx, const uint8_t *intraMPM, #if JVET_AI0082_GPM_WITH_INTER_IBC @@ -29990,12 +30028,21 @@ void PU::spanGeoMMVDMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const u int affMvBufStride = MAX_CU_SIZE >> 2; if (pu.affineGPM[0]) { +#if JVET_AJ0274_GPM_AFFINE_TM + pu.gpmPartAffType[0] = tmFlag0 ? geoAffTmMrgCtx.affineType[mergeIdx0] : geoAffMrgCtx.affineType[mergeIdx0]; +#else pu.gpmPartAffType[0] = geoAffMrgCtx.affineType[mergeIdx0]; +#endif CHECK(pu.gpmPartAffType[0] == AFFINE_MODEL_NUM, "Invalid affine type"); pu.gpmPartRefIdx[0][0] = pu.gpmPartRefIdx[0][1] = -1; +#if JVET_AJ0274_GPM_AFFINE_TM + pu.cu->affineType = tmFlag0 ? geoAffTmMrgCtx.affineType[mergeIdx0] : geoAffMrgCtx.affineType[mergeIdx0]; + MvField* cpmvMvField0 = tmFlag0 ? geoAffTmMrgCtx.mvFieldNeighbours[mergeIdx0 << 1] : geoAffMrgCtx.mvFieldNeighbours[mergeIdx0 << 1]; +#else pu.cu->affineType = geoAffMrgCtx.affineType[mergeIdx0]; MvField* cpmvMvField0 = geoAffMrgCtx.mvFieldNeighbours[mergeIdx0 << 1]; +#endif if (cpmvMvField0[0].refIdx >= 0) { PU::setAllAffineMv(pu, cpmvMvField0[0].mv + deltaMv, cpmvMvField0[1].mv + deltaMv, cpmvMvField0[2].mv + deltaMv, REF_PIC_LIST_0); @@ -30006,7 +30053,11 @@ void PU::spanGeoMMVDMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const u pu.gpmPartmvAffi[0][0][2] = cpmvMvField0[2].mv + deltaMv; } +#if JVET_AJ0274_GPM_AFFINE_TM + MvField* cpmvMvField1 = tmFlag0 ? geoAffTmMrgCtx.mvFieldNeighbours[(mergeIdx0 << 1) + 1] : geoAffMrgCtx.mvFieldNeighbours[(mergeIdx0 << 1) + 1]; +#else MvField* cpmvMvField1 = geoAffMrgCtx.mvFieldNeighbours[(mergeIdx0 << 1) + 1]; +#endif if (cpmvMvField1[0].refIdx >= 0) { PU::setAllAffineMv(pu, cpmvMvField1[0].mv + deltaMv, cpmvMvField1[1].mv + deltaMv, cpmvMvField1[2].mv + deltaMv, REF_PIC_LIST_1); @@ -30033,12 +30084,21 @@ void PU::spanGeoMMVDMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const u } if (pu.affineGPM[1]) { +#if JVET_AJ0274_GPM_AFFINE_TM + pu.gpmPartAffType[1] = tmFlag0 ? geoAffTmMrgCtx.affineType[mergeIdx1] : geoAffMrgCtx.affineType[mergeIdx1]; +#else pu.gpmPartAffType[1] = geoAffMrgCtx.affineType[mergeIdx1]; +#endif CHECK(pu.gpmPartAffType[1] == AFFINE_MODEL_NUM, "Invalid affine type"); pu.gpmPartRefIdx[1][0] = pu.gpmPartRefIdx[1][1] = -1; +#if JVET_AJ0274_GPM_AFFINE_TM + pu.cu->affineType = tmFlag0 ? geoAffTmMrgCtx.affineType[mergeIdx1] : geoAffMrgCtx.affineType[mergeIdx1]; + MvField* cpmvMvField0 = tmFlag0 ? geoAffTmMrgCtx.mvFieldNeighbours[(mergeIdx1 << 1)] : geoAffMrgCtx.mvFieldNeighbours[(mergeIdx1 << 1)]; +#else pu.cu->affineType = geoAffMrgCtx.affineType[mergeIdx1]; MvField* cpmvMvField0 = geoAffMrgCtx.mvFieldNeighbours[(mergeIdx1 << 1)]; +#endif if (cpmvMvField0[0].refIdx >= 0) { PU::setAllAffineMv(pu, cpmvMvField0[0].mv + deltaMv, cpmvMvField0[1].mv + deltaMv, cpmvMvField0[2].mv + deltaMv, REF_PIC_LIST_0); @@ -30048,7 +30108,11 @@ void PU::spanGeoMMVDMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const u pu.gpmPartmvAffi[1][0][1] = cpmvMvField0[1].mv + deltaMv; pu.gpmPartmvAffi[1][0][2] = cpmvMvField0[2].mv + deltaMv; } +#if JVET_AJ0274_GPM_AFFINE_TM + MvField* cpmvMvField1 = tmFlag0 ? geoAffTmMrgCtx.mvFieldNeighbours[(mergeIdx1 << 1) + 1] : geoAffMrgCtx.mvFieldNeighbours[(mergeIdx1 << 1) + 1]; +#else MvField* cpmvMvField1 = geoAffMrgCtx.mvFieldNeighbours[(mergeIdx1 << 1) + 1]; +#endif if (cpmvMvField1[0].refIdx >= 0) { PU::setAllAffineMv(pu, cpmvMvField1[0].mv + deltaMv, cpmvMvField1[1].mv + deltaMv, cpmvMvField1[2].mv + deltaMv, REF_PIC_LIST_1); @@ -30264,9 +30328,15 @@ void PU::spanGeoMMVDMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const u #if JVET_AG0164_AFFINE_GPM if (pu.affineGPM[0]) { +#if JVET_AJ0274_GPM_AFFINE_TM + mb.at(x, y).interDir = tmFlag0 ? geoAffTmMrgCtx.interDirNeighbours[mergeIdx0] : geoAffMrgCtx.interDirNeighbours[mergeIdx0]; + mb.at(x, y).refIdx[0] = tmFlag0 ? geoAffTmMrgCtx.mvFieldNeighbours[mergeIdx0 << 1][0].refIdx : geoAffMrgCtx.mvFieldNeighbours[mergeIdx0 << 1][0].refIdx; + mb.at(x, y).refIdx[1] = tmFlag0 ? geoAffTmMrgCtx.mvFieldNeighbours[(mergeIdx0 << 1) + 1][0].refIdx :geoAffMrgCtx.mvFieldNeighbours[(mergeIdx0 << 1) + 1][0].refIdx; +#else mb.at(x, y).interDir = geoAffMrgCtx.interDirNeighbours[mergeIdx0]; mb.at(x, y).refIdx[0] = geoAffMrgCtx.mvFieldNeighbours[mergeIdx0 << 1][0].refIdx; mb.at(x, y).refIdx[1] = geoAffMrgCtx.mvFieldNeighbours[(mergeIdx0 << 1) + 1][0].refIdx; +#endif mb.at(x, y).mv[0] = pMvBufP0L0[x]; mb.at(x, y).mv[1] = pMvBufP0L1[x]; } @@ -30344,9 +30414,15 @@ void PU::spanGeoMMVDMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const u #if JVET_AG0164_AFFINE_GPM if (pu.affineGPM[1]) { +#if JVET_AJ0274_GPM_AFFINE_TM + mb.at(x, y).interDir = tmFlag0 ? geoAffTmMrgCtx.interDirNeighbours[mergeIdx1] : geoAffMrgCtx.interDirNeighbours[mergeIdx1]; + mb.at(x, y).refIdx[0] = tmFlag0 ? geoAffTmMrgCtx.mvFieldNeighbours[mergeIdx1 << 1][0].refIdx : geoAffMrgCtx.mvFieldNeighbours[mergeIdx1 << 1][0].refIdx; + mb.at(x, y).refIdx[1] = tmFlag0 ? geoAffTmMrgCtx.mvFieldNeighbours[(mergeIdx1 << 1) + 1][0].refIdx : geoAffMrgCtx.mvFieldNeighbours[(mergeIdx1 << 1) + 1][0].refIdx; +#else mb.at(x, y).interDir = geoAffMrgCtx.interDirNeighbours[mergeIdx1]; mb.at(x, y).refIdx[0] = geoAffMrgCtx.mvFieldNeighbours[mergeIdx1 << 1][0].refIdx; mb.at(x, y).refIdx[1] = geoAffMrgCtx.mvFieldNeighbours[(mergeIdx1 << 1) + 1][0].refIdx; +#endif mb.at(x, y).mv[0] = pMvBufP1L0[x]; mb.at(x, y).mv[1] = pMvBufP1L1[x]; } @@ -33280,6 +33356,25 @@ bool PU::isAffineGPMValid(const PredictionUnit& pu) return true; } +#if JVET_AJ0274_GPM_AFFINE_TM +bool PU::isAffineGpmTmValid(const PredictionUnit& pu) +{ + if (pu.cu->slice->getSPS()->getMaxNumGpmAffTmCand() <= 0) + { + return false; + } + if (pu.lwidth() * pu.lheight() >= 4096) + { + return false; + } + if ((pu.cs->slice->getTLayer() <= 1 && !pu.cs->slice->getCheckLDC()) || pu.cs->slice->getTLayer() >= 5) + { + return false; + } + return true; +} +#endif + void PU::getGeoAffMergeCandidates(PredictionUnit& pu, AffineMergeCtx& gpmAffMrgCtx, InterPrediction* pcInterPred #if !JVET_AH0314_LIC_INHERITANCE_FOR_MRG , AffineMergeCtx* affMergeCtx @@ -33436,6 +33531,13 @@ void PU::getGeoAffMergeCandidates(PredictionUnit& pu, AffineMergeCtx& gpmAffMrgC #if JVET_AH0314_LIC_INHERITANCE_FOR_MRG && JVET_AG0164_AFFINE_GPM #if JVET_AG0276_NLIC bool isLic = tmpMergeCtx.licFlags[i]; +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + bool useInheritedOrig = useInherited; + if (tmpMergeCtx.interDirNeighbours[i] == 3 && pu.cs->sps->getMaxNumGpmAffTmCand() > 0) + { + useInherited = false; + } #endif gpmAffMrgCtx.licFlags[gpmAffMrgCtx.numValidMergeCand] = false; gpmAffMrgCtx.licInheritPara[gpmAffMrgCtx.numValidMergeCand] = false; @@ -33461,6 +33563,9 @@ void PU::getGeoAffMergeCandidates(PredictionUnit& pu, AffineMergeCtx& gpmAffMrgC #endif } #endif +#if JVET_AJ0274_GPM_AFFINE_TM + useInherited = useInheritedOrig; +#endif if (gpmAffMrgCtx.xCheckSimilarMotion(gpmAffMrgCtx.numValidMergeCand)) { @@ -33491,6 +33596,13 @@ void PU::getGeoAffMergeCandidates(PredictionUnit& pu, AffineMergeCtx& gpmAffMrgC #if JVET_AH0314_LIC_INHERITANCE_FOR_MRG && JVET_AG0164_AFFINE_GPM #if JVET_AG0276_NLIC bool isLic = tmpMergeCtx.licFlags[i]; +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + bool useInheritedOrig = useInherited; + if (tmpMergeCtx.interDirNeighbours[i] == 3 && pu.cs->sps->getMaxNumGpmAffTmCand() > 0) + { + useInherited = false; + } #endif gpmAffMrgCtx.licFlags[gpmAffMrgCtx.numValidMergeCand] = false; gpmAffMrgCtx.licInheritPara[gpmAffMrgCtx.numValidMergeCand] = false; @@ -33515,6 +33627,9 @@ void PU::getGeoAffMergeCandidates(PredictionUnit& pu, AffineMergeCtx& gpmAffMrgC } #endif } +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + useInherited = useInheritedOrig; #endif if (gpmAffMrgCtx.xCheckSimilarMotion(gpmAffMrgCtx.numValidMergeCand)) { diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 287548ad3a70a7d8b1819dedf0ff8b45f0b59f16..cee2761cc416394ccd0ec33fb7f2cfe96fc753f0 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -172,6 +172,9 @@ namespace CU uint8_t numSbtModeRdo (uint8_t sbtAllowed); bool isSbtMode (const uint8_t sbtInfo); bool isSameSbtSize (const uint8_t sbtInfo1, const uint8_t sbtInfo2); +#if JVET_AJ0274_REGRESSION_GPM_TM + bool checkGeoBlendTmAvail (const CodingUnit& currCU, const CodingStructure* bestCS); +#endif #if JVET_AI0050_SBT_LFNST void getSBTPosAndSize (const CodingUnit &cu, Position& pos, Size& size, uint8_t sbtMode); #endif @@ -822,6 +825,9 @@ namespace PU bool isAffineGPMSizeValid(const PredictionUnit& pu); int getAffGPMCtxOffset(const PredictionUnit& pu); +#if JVET_AJ0274_GPM_AFFINE_TM + bool isAffineGpmTmValid(const PredictionUnit& pu); +#endif #endif #if JVET_W0097_GPM_MMVD_TM #if TM_MRG @@ -852,6 +858,9 @@ namespace PU void spanGeoMMVDMotionInfo(PredictionUnit& pu, MergeCtx& geoMrgCtx #if JVET_AG0164_AFFINE_GPM , AffineMergeCtx& geoAffMrgCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , AffineMergeCtx& geoAffTmMrgCtx +#endif #endif , MergeCtx& geoTmMrgCtx0, MergeCtx& geoTmMrgCtx1, const uint8_t splitDir, const uint8_t mergeIdx0, const uint8_t mergeIdx1, const bool tmFlag0, const bool mmvdFlag0, const uint8_t mmvdIdx0, const bool tmFlag1, const bool mmvdFlag1, const uint8_t mmvdIdx1, const uint8_t bldIdx,const uint8_t *intraMPM, #if JVET_AI0082_GPM_WITH_INTER_IBC diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index c5745f088570646040f59417a12f5754e3bd5b37..920b902b64ad4ef254b8913d4ab439144bc97ebd 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -5888,6 +5888,9 @@ void CABACReader::merge_data( PredictionUnit& pu ) pu.cu->geoFlag = true; #if JVET_AG0112_REGRESSION_BASED_GPM_BLENDING pu.cu->geoBlendFlag = false; +#if JVET_AJ0274_REGRESSION_GPM_TM + pu.geoBlendTmFlag = false; +#endif #endif #if JVET_AE0046_BI_GPM PU::setGpmDirMode(pu); @@ -6009,6 +6012,9 @@ void CABACReader::merge_idx( PredictionUnit& pu ) pu.gpmIntraFlag = false; #if JVET_AI0082_GPM_WITH_INTER_IBC pu.gpmInterIbcFlag = false; +#endif +#if JVET_AJ0274_REGRESSION_GPM_TM + pu.geoBlendTmFlag = m_BinDecoder.decodeBin(Ctx::GeoBlendTMFlag()); #endif return; } @@ -6101,6 +6107,9 @@ void CABACReader::merge_idx( PredictionUnit& pu ) pu.gpmInterIbcFlag = (isIbc0 || isIbc1); #endif #endif +#if JVET_AJ0274_GPM_AFFINE_TM + bool affGpmTmValid = isAffGPMValid && PU::isAffineGpmTmValid(pu); +#endif #if TM_MRG if (!pu.geoMMVDFlag0 && !pu.geoMMVDFlag1) @@ -6112,12 +6121,20 @@ void CABACReader::merge_idx( PredictionUnit& pu ) } else #endif +#if JVET_AJ0274_GPM_AFFINE_TM + if (!affGpmTmValid && (pu.affineGPM[0] || pu.affineGPM[1])) + { + pu.tmMergeFlag = false; + } + else +#else #if JVET_AG0164_AFFINE_GPM if (pu.affineGPM[0] || pu.affineGPM[1]) { pu.tmMergeFlag = false; } else +#endif #endif tm_merge_flag(pu); if (pu.tmMergeFlag) @@ -6455,6 +6472,12 @@ void CABACReader::geo_merge_idx(PredictionUnit& pu) int maxNumGeoCand = pu.affineGPM[0] ? pu.cs->sps->getMaxNumGpmAffCand() : pu.cs->sps->getMaxNumGeoCand(); #else const int maxNumGeoCand = pu.cs->sps->getMaxNumGeoCand(); +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[0] && pu.tmMergeFlag) + { + maxNumGeoCand = pu.cs->sps->getMaxNumGpmAffTmCand(); + } #endif CHECK(maxNumGeoCand < 2, "Incorrect max number of geo candidates"); CHECK(pu.cu->lheight() > 64 || pu.cu->lwidth() > 64, "Incorrect block size of geo flag"); @@ -6481,6 +6504,12 @@ void CABACReader::geo_merge_idx(PredictionUnit& pu) #if JVET_AG0164_AFFINE_GPM maxNumGeoCand = pu.affineGPM[1] ? pu.cs->sps->getMaxNumGpmAffCand() : pu.cs->sps->getMaxNumGeoCand(); +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[1] && pu.tmMergeFlag) + { + maxNumGeoCand = pu.cs->sps->getMaxNumGpmAffTmCand(); + } +#endif numCandminus2 = maxNumGeoCand - 2; #endif @@ -6541,6 +6570,12 @@ void CABACReader::geo_merge_idx1(PredictionUnit& pu) #endif #if JVET_AG0164_AFFINE_GPM int maxNumGeoCand = pu.affineGPM[0] ? pu.cs->sps->getMaxNumGpmAffCand() : pu.cs->sps->getMaxNumGeoCand(); +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[0] && pu.tmMergeFlag) + { + maxNumGeoCand = pu.cs->sps->getMaxNumGpmAffTmCand(); + } +#endif #else const int maxNumGeoCand = pu.cs->sps->getMaxNumGeoCand(); #endif @@ -6615,6 +6650,12 @@ void CABACReader::geo_merge_idx1(PredictionUnit& pu) #if JVET_AG0164_AFFINE_GPM maxNumGeoCand = pu.affineGPM[1] ? pu.cs->sps->getMaxNumGpmAffCand() : pu.cs->sps->getMaxNumGeoCand(); +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[1] && pu.tmMergeFlag) + { + maxNumGeoCand = pu.cs->sps->getMaxNumGpmAffTmCand(); + } +#endif numCandminus2 = maxNumGeoCand - 2; #endif diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index ab9ed528cfedc512bac4a1b9ee543b66ab62fbef..855ef3a4d52665b351077c5222667a0289f58441 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -1974,6 +1974,9 @@ void DecCu::xReconInter(CodingUnit &cu) #endif #if JVET_AG0164_AFFINE_GPM , m_geoAffMrgCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , m_geoAffTmMrgCtx +#endif #endif #if JVET_AE0046_BI_GPM , m_mvBufBDMVR @@ -1998,6 +2001,9 @@ void DecCu::xReconInter(CodingUnit &cu) ( *cu.firstPU, m_geoMrgCtx #if JVET_AG0164_AFFINE_GPM , m_geoAffMrgCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , m_geoAffTmMrgCtx +#endif #endif #if JVET_W0097_GPM_MMVD_TM && TM_MRG , m_geoTmMrgCtx0, m_geoTmMrgCtx1 @@ -3041,6 +3047,9 @@ void DecCu::xDeriveCUMV(CodingUnit &cu) m_geoAffMrgCtx.numValidMergeCand = std::min(m_geoAffMrgCtx.numValidMergeCand, (int)pu.cs->sps->getMaxNumGpmAffCand()); m_geoAffMrgCtx.maxNumMergeCand = m_geoAffMrgCtx.numValidMergeCand; +#if JVET_AJ0274_GPM_AFFINE_TM + m_geoAffTmMrgCtx = m_geoAffMrgCtx; +#endif } } if (!pu.affineGPM[0] || !pu.affineGPM[1]) @@ -3064,6 +3073,39 @@ void DecCu::xDeriveCUMV(CodingUnit &cu) #if JVET_W0097_GPM_MMVD_TM && TM_MRG if (pu.geoTmFlag0) { +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[0]) + { + for (int i = 0; i < 3; i++) + { + m_mvBufBDMVR[0][i].setZero(); + m_mvBufBDMVR[1][i].setZero(); + } + int uiAffMergeCand = pu.geoMergeIdx0 - m_geoAffTmMrgCtx.m_indexOffset; + m_geoAffTmMrgCtx.setAffMergeInfo(pu, pu.geoMergeIdx0); + m_pcInterPred->setFillCurTplAboveARMC(false); + m_pcInterPred->setBdmvrSubPuMvBuf(m_mvBufBDMVR[0], m_mvBufBDMVR[1]); + pu.bdmvrRefine = false; + m_pcInterPred->processTM4Affine(pu, m_geoAffTmMrgCtx, 0, false +#if JVET_AH0119_SUBBLOCK_TM + , pu.cs->slice->getCheckLDB() ? true : false +#endif +#if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE + , uiAffMergeCand +#endif + ); + pu.cu->affine = false; + m_pcInterPred->setFillCurTplAboveARMC(false); + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 0][0].mv += m_mvBufBDMVR[0][0]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 0][1].mv += m_mvBufBDMVR[0][1]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 0][2].mv += m_mvBufBDMVR[0][2]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 1][0].mv += m_mvBufBDMVR[1][0]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 1][1].mv += m_mvBufBDMVR[1][1]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 1][2].mv += m_mvBufBDMVR[1][2]; + } + else + { +#endif #if JVET_Z0056_GPM_SPLIT_MODE_REORDERING MergeCtx& m_geoTmMrgCtx0 = m_geoTmMrgCtx[GEO_TM_SHAPE_AL]; #endif @@ -3130,10 +3172,46 @@ void DecCu::xDeriveCUMV(CodingUnit &cu) m_pcInterPred->deriveTMMv(pu); m_geoTmMrgCtx0.mvFieldNeighbours[(pu.geoMergeIdx0 << 1)].mv.set(pu.mv[0].getHor(), pu.mv[0].getVer()); m_geoTmMrgCtx0.mvFieldNeighbours[(pu.geoMergeIdx0 << 1) + 1].mv.set(pu.mv[1].getHor(), pu.mv[1].getVer()); +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + } #endif } if (pu.geoTmFlag1) { +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[1]) + { + for (int i = 0; i < 3; i++) + { + m_mvBufBDMVR[0][i].setZero(); + m_mvBufBDMVR[1][i].setZero(); + } + int uiAffMergeCand = pu.geoMergeIdx1 - m_geoAffTmMrgCtx.m_indexOffset; + m_geoAffTmMrgCtx.setAffMergeInfo(pu, pu.geoMergeIdx1); + m_pcInterPred->setBdmvrSubPuMvBuf(m_mvBufBDMVR[0], m_mvBufBDMVR[1]); + pu.bdmvrRefine = false; + m_pcInterPred->setFillCurTplAboveARMC(false); + m_pcInterPred->processTM4Affine(pu, m_geoAffTmMrgCtx, 0, false +#if JVET_AH0119_SUBBLOCK_TM + , pu.cs->slice->getCheckLDB() ? true : false +#endif +#if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE + , uiAffMergeCand +#endif + ); + pu.cu->affine = false; + m_pcInterPred->setFillCurTplAboveARMC(false); + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 0][0].mv += m_mvBufBDMVR[0][0]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 0][1].mv += m_mvBufBDMVR[0][1]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 0][2].mv += m_mvBufBDMVR[0][2]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 1][0].mv += m_mvBufBDMVR[1][0]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 1][1].mv += m_mvBufBDMVR[1][1]; + m_geoAffTmMrgCtx.mvFieldNeighbours[(uiAffMergeCand << 1) + 1][2].mv += m_mvBufBDMVR[1][2]; + } + else + { +#endif #if JVET_Z0056_GPM_SPLIT_MODE_REORDERING MergeCtx& m_geoTmMrgCtx1 = m_geoTmMrgCtx[GEO_TM_SHAPE_AL]; #endif @@ -3202,6 +3280,9 @@ void DecCu::xDeriveCUMV(CodingUnit &cu) m_geoTmMrgCtx1.mvFieldNeighbours[(pu.geoMergeIdx1 << 1) + 1].mv.set(pu.mv[1].getHor(), pu.mv[1].getVer()); #endif } +#if JVET_AJ0274_GPM_AFFINE_TM + } +#endif #endif } else diff --git a/source/Lib/DecoderLib/DecCu.h b/source/Lib/DecoderLib/DecCu.h index c74e55597f0142be3e214b4bc27e46d0a3d2259b..4f8010841ebf1b4ea69bc43da0bc79bd9c1d1d99 100644 --- a/source/Lib/DecoderLib/DecCu.h +++ b/source/Lib/DecoderLib/DecCu.h @@ -130,6 +130,9 @@ private: MergeCtx m_geoMrgCtx; #if JVET_AG0164_AFFINE_GPM AffineMergeCtx m_geoAffMrgCtx; +#if JVET_AJ0274_GPM_AFFINE_TM + AffineMergeCtx m_geoAffTmMrgCtx; +#endif #endif #if JVET_AI0082_GPM_WITH_INTER_IBC Mv m_geoBvList[GEO_MAX_NUM_IBC_CANDS]; diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 285e856913e07830b05a180ba4b8ed8fcc506ab8..f974db44538cd4898d9ee7e5f2a9a49e3424a7e4 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -2680,6 +2680,13 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) READ_UVLC(uiCode, "max_num_aff_merge_cand_minus_max_num_gpm_aff_cand"); pcSPS->setMaxNumGpmAffCand((uint32_t)(pcSPS->getMaxNumAffineMergeCand() - uiCode)); } +#if JVET_AJ0274_GPM_AFFINE_TM + if (pcSPS->getMaxNumGpmAffCand() > 0) + { + READ_UVLC(uiCode, "max_num_gpm_aff_tm_cand"); + pcSPS->setMaxNumGpmAffTmCand((uint32_t)uiCode); + } +#endif #endif #if JVET_AA0132_CONFIGURABLE_TM_TOOLS && JVET_W0097_GPM_MMVD_TM && TM_MRG diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index a3a12b0b42e11c8d2066511f8f7f3f0be5f7d07e..3c5c6027663a50e40b9c1e720e64bdc6c865d5f6 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -5671,6 +5671,9 @@ void CABACWriter::merge_idx( const PredictionUnit& pu ) unary_max_eqprob( candIdx0 - 1, maxNumGeoCand ); } DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.geoMergeIdx0 ); +#if JVET_AJ0274_REGRESSION_GPM_TM + m_BinEncoder.encodeBin(pu.geoBlendTmFlag, Ctx::GeoBlendTMFlag()); +#endif return; } #endif @@ -5787,6 +5790,9 @@ void CABACWriter::merge_idx( const PredictionUnit& pu ) CHECK( pu.gpmInterIbcFlag != (isIbc0 || isIbc1), "gpmInterIbcFlag shall be equal to (isIbc0 || isIbc1)" ); #endif #endif +#if JVET_AJ0274_GPM_AFFINE_TM + bool affGpmTmValid = isAffGPMValid && PU::isAffineGpmTmValid(pu); +#endif #if TM_MRG if (!pu.geoMMVDFlag0 && !pu.geoMMVDFlag1) @@ -5794,17 +5800,25 @@ void CABACWriter::merge_idx( const PredictionUnit& pu ) #if JVET_Y0065_GPM_INTRA if (!isIntra0 && !isIntra1) #endif +#if JVET_AJ0274_GPM_AFFINE_TM + if ((affGpmTmValid && (pu.affineGPM[0] || pu.affineGPM[1])) || (!pu.affineGPM[0] && !pu.affineGPM[1])) +#else #if JVET_AG0164_AFFINE_GPM if( !pu.affineGPM[0] && !pu.affineGPM[1]) +#endif #endif tm_merge_flag(pu); if (pu.tmMergeFlag) { +#if !JVET_AJ0274_GPM_AFFINE_TM #if JVET_AG0164_AFFINE_GPM CHECK(pu.affineGPM[0] || pu.affineGPM[1], "Affine GPM cannot be used with TM"); +#endif #endif CHECK(!pu.geoTmFlag0 || !pu.geoTmFlag1, "both must be true"); +#if !JVET_AJ0274_GPM_AFFINE_TM CHECK(pu.geoMergeIdx0 == pu.geoMergeIdx1, "Incorrect geoMergeIdx0 and geoMergeIdx1"); +#endif geo_merge_idx(pu); } else @@ -6293,6 +6307,12 @@ void CABACWriter::geo_merge_idx(const PredictionUnit& pu) #endif #if JVET_AG0164_AFFINE_GPM int maxNumGeoCand = pu.affineGPM[0] ? pu.cs->sps->getMaxNumGpmAffCand() : pu.cs->sps->getMaxNumGeoCand(); +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[0] && pu.tmMergeFlag) + { + maxNumGeoCand = pu.cs->sps->getMaxNumGpmAffTmCand(); + } +#endif #else const int maxNumGeoCand = pu.cs->sps->getMaxNumGeoCand(); #endif @@ -6322,6 +6342,12 @@ void CABACWriter::geo_merge_idx(const PredictionUnit& pu) #if JVET_AG0164_AFFINE_GPM maxNumGeoCand = pu.affineGPM[1] ? pu.cs->sps->getMaxNumGpmAffCand() : pu.cs->sps->getMaxNumGeoCand(); +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[1] && pu.tmMergeFlag) + { + maxNumGeoCand = pu.cs->sps->getMaxNumGpmAffTmCand(); + } +#endif numCandminus2 = maxNumGeoCand - 2; #endif if (numCandminus2 > 0 @@ -6394,6 +6420,12 @@ void CABACWriter::geo_merge_idx1(const PredictionUnit& pu) #if JVET_AG0164_AFFINE_GPM int maxNumGeoCand = pu.affineGPM[0] ? pu.cs->sps->getMaxNumGpmAffCand(): pu.cs->sps->getMaxNumGeoCand(); +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[0] && pu.tmMergeFlag) + { + maxNumGeoCand = pu.cs->sps->getMaxNumGpmAffTmCand(); + } +#endif #else const int maxNumGeoCand = pu.cs->sps->getMaxNumGeoCand(); #endif @@ -6467,6 +6499,12 @@ void CABACWriter::geo_merge_idx1(const PredictionUnit& pu) #if JVET_AG0164_AFFINE_GPM maxNumGeoCand = pu.affineGPM[1] ? pu.cs->sps->getMaxNumGpmAffCand() : pu.cs->sps->getMaxNumGeoCand(); +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[1] && pu.tmMergeFlag) + { + maxNumGeoCand = pu.cs->sps->getMaxNumGpmAffTmCand(); + } +#endif numCandminus2 = maxNumGeoCand - 2; #endif diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index a399a22add3fc1b162a4a0e474c017e22ce6c5b7..616369020a22ab7bf9eddaa436d81378558df2ae 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -968,6 +968,9 @@ protected: uint32_t m_maxNumGeoCand; #if JVET_AG0164_AFFINE_GPM uint32_t m_maxNumGpmAffCand; +#if JVET_AJ0274_GPM_AFFINE_TM + uint32_t m_maxNumGpmAffTmCand; +#endif #endif #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND uint32_t m_maxNumMHPCand; @@ -2675,6 +2678,10 @@ public: #if JVET_AG0164_AFFINE_GPM void setMaxNumGpmAffCand(uint32_t u) { m_maxNumGpmAffCand = u; } uint32_t getMaxNumGpmAffCand() { return m_maxNumGpmAffCand; } +#if JVET_AJ0274_GPM_AFFINE_TM + void setMaxNumGpmAffTmCand(uint32_t u) { m_maxNumGpmAffTmCand = u; } + uint32_t getMaxNumGpmAffTmCand() { return m_maxNumGpmAffTmCand; } +#endif #endif #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND void setMaxNumMHPCand ( uint32_t u ) { m_maxNumMHPCand = u; } diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 01bdfccc3ed57b650c748fb9b21abb7c883a21ef..4b27948fbd737786ae9a2356c6f0043142b9d13e 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -104,6 +104,9 @@ EncCu::EncCu() : m_GeoModeTest #if JVET_W0097_GPM_MMVD_TM m_fastGpmMmvdSearch = false; m_fastGpmMmvdRelatedCU = false; +#if JVET_AJ0274_GPM_AFFINE_TM + m_fastGpmAffSearch = 0x00; +#endif m_includeMoreMMVDCandFirstPass = false; m_maxNumGPMDirFirstPass = 64; m_numCandPerPar = 5; @@ -342,6 +345,9 @@ void EncCu::create( EncCfg* encCfg ) m_fastGpmMmvdRelatedCU = ((encCfg->getIntraPeriod() < 0) && ((sourceWidth * sourceHeight) >= (1280 * 720))) && !encCfg->getIBCMode(); } #endif +#if JVET_AJ0274_GPM_AFFINE_TM + m_fastGpmAffSearch = encCfg->getIntraPeriod() < 0 ? (sourceWidth * sourceHeight <= 832 * 480 ? 0x01 : 0x03) : (sourceWidth * sourceHeight >= 3840 * 2160 ? 0x02 : 0x04); +#endif m_includeMoreMMVDCandFirstPass = ((encCfg->getIntraPeriod() > 0) || ((encCfg->getIntraPeriod() < 0) && m_fastGpmMmvdSearch)); m_maxNumGPMDirFirstPass = ((encCfg->getIntraPeriod() < 0) ? 50 : (m_fastGpmMmvdSearch ? 36 : 64)); @@ -351,6 +357,9 @@ void EncCu::create( EncCfg* encCfg ) { m_acGeoMergeTmpBuffer[ui].create(chromaFormat, Area(0, 0, uiMaxWidth, uiMaxHeight)); m_acGeoSADTmpBuffer[ui].create(chromaFormat, Area(0, 0, uiMaxWidth, uiMaxHeight)); +#if JVET_AJ0274_REGRESSION_GPM_TM + m_acGeoBlendTMBuffer[ui].create(chromaFormat, Area(0, 0, uiMaxWidth, uiMaxHeight)); +#endif } #endif #endif @@ -551,6 +560,9 @@ void EncCu::destroy() { m_acGeoMergeTmpBuffer[ui].destroy(); m_acGeoSADTmpBuffer[ui].destroy(); +#if JVET_AJ0274_REGRESSION_GPM_TM + m_acGeoBlendTMBuffer[ui].destroy(); +#endif } #endif #endif @@ -9850,6 +9862,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if JVET_Z0056_GPM_SPLIT_MODE_REORDERING MergeCtx& mergeCtxRegular = mergeCtx; #endif +#endif +#if JVET_AJ0274_REGRESSION_GPM_TM + MergeCtx geoBlendTmCtx; #endif const SPS &sps = *tempCS->sps; CodedCUInfo& relatedCU = ((EncModeCtrlMTnoRQT *)m_modeCtrl)->getBlkInfo(pm.currArea()); @@ -9865,7 +9880,13 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct for (int j = 0; j < SUB_TMVP_NUM; j++) { mergeCtx[i].subPuMvpMiBuf[j] = MotionBuf(m_subPuMiBuf[j], bufSize); - } +#if JVET_AJ0274_REGRESSION_GPM_TM + if (i == 0) + { + geoBlendTmCtx.subPuMvpMiBuf[j] = MotionBuf(m_subPuMiBuf[j], bufSize); + } +#endif + } #else mergeCtx[i].subPuMvpMiBuf = MotionBuf(m_subPuMiBuf, bufSize); #endif @@ -9878,8 +9899,17 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if JVET_AE0046_BI_GPM std::array<bool, GEO_MAX_NUM_UNI_CANDS> refinePossible; refinePossible.fill(false); +#if JVET_AJ0274_REGRESSION_GPM_TM + std::array<bool, GEO_MAX_NUM_UNI_CANDS> refinePossibleTM; + refinePossibleTM.fill(false); +#endif #endif +#if JVET_AJ0274_REGRESSION_GPM_TM + int isGeoTmMCAvail[GEO_TM_MAX_NUM_CANDS]; + std::memset(isGeoTmMCAvail, 0, GEO_TM_MAX_NUM_CANDS * sizeof(int)); + PelUnitBuf geoTmBuffer[GEO_TM_MAX_NUM_CANDS]; +#endif #if JVET_AI0082_GPM_WITH_INTER_IBC bool testGeoInterIbc = sps.getUseGeoInterIbc(); #endif @@ -9905,6 +9935,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #endif #if JVET_AG0164_AFFINE_GPM double geoAffMergeIdxCost[GEO_MAX_NUM_UNI_AFF_CANDS]; +#if JVET_AJ0274_GPM_AFFINE_TM + double geoAffTmMergeIdxCost[GEO_AFF_TM_MAX_AFF_CANDS]; +#endif uint8_t maxNumGpmAffMergeCandidates = tempCS->sps->getMaxNumGpmAffCand(); CHECK(maxNumGpmAffMergeCandidates > GEO_MAX_NUM_UNI_AFF_CANDS, "Maximum GPM Affine Num is too large"); #endif @@ -9935,6 +9968,17 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct uint64_t fracBits = m_CABACEstimator->geo_mergeIdx_est(ctxStart, idx, maxNumGpmAffMergeCandidates, 1); geoAffMergeIdxCost[idx] = (double)fracBits * sqrtLambdaFracBits; } +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + int numAffTmAffCands = tempCS->sps->getMaxNumGpmAffTmCand(); + if (numAffTmAffCands > 0) + { + for (int idx = 0; idx < numAffTmAffCands; idx++) + { + uint64_t fracBits = m_CABACEstimator->geo_mergeIdx_est(ctxStart, idx, numAffTmAffCands, 1); + geoAffTmMergeIdxCost[idx] = (double)fracBits * sqrtLambdaFracBits; + } + } #endif for (int idx = 0; idx < 2; idx++) { @@ -10044,6 +10088,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if JVET_X0049_ADAPT_DMVR pu.bmMergeFlag = false; #endif +#if JVET_AJ0274_REGRESSION_GPM_TM + pu.geoBlendTmFlag = false; +#endif #if JVET_AG0164_AFFINE_GPM double geoAffineFlagCost[2] = { 0.0, 0.0 }; @@ -10058,6 +10105,10 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct } bool affGPMValid = PU::isAffineGPMValid(pu); +#if JVET_AJ0274_GPM_AFFINE_TM + bool affGpmTmValid = affGPMValid && PU::isAffineGpmTmValid(pu); + affGpmTmValid &= (pu.lx() > 0 || pu.ly() > 0); +#endif pu.affineGPM[0]= pu.affineGPM[1] = 0; if (!affGPMValid) @@ -10121,6 +10172,13 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct if (!isSecondPass) { +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.cs->sps->getMaxNumGpmAffTmCand() > 0 && (m_fastGpmAffSearch & 0x01)) + { + numSATDCands += 1; + } + else +#endif numSATDCands += affMergeCtx.numValidMergeCand + 1; } } @@ -10130,6 +10188,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct affMergeCtx.m_indexOffset = numRegularGpmMergeCand; } +#if JVET_AJ0274_GPM_AFFINE_TM + AffineMergeCtx affTmMergeCtx = affMergeCtx; +#endif PelUnitBuf geoBuffer[GEO_MAX_ALL_INTER_UNI_CANDS]; PelUnitBuf geoTempBuf[GEO_MAX_ALL_INTER_UNI_CANDS]; @@ -10224,7 +10285,12 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #endif #endif #if TM_MRG +#if JVET_AJ0274_GPM_AFFINE_TM + uint8_t isGeoTmChromaAvail[GEO_TM_MAX_NUM_CANDS]; + memset(isGeoTmChromaAvail, 0, sizeof(uint8_t) * GEO_TM_MAX_NUM_CANDS); +#else bool isGeoTmChromaAvail[GEO_TM_MAX_NUM_CANDS]; +#endif memset(isGeoTmChromaAvail, false, sizeof(bool) * GEO_TM_MAX_NUM_CANDS); #endif @@ -10981,7 +11047,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct if (sps.getUseGPMTMMode() #if JVET_AG0164_AFFINE_GPM +#if JVET_AJ0274_GPM_AFFINE_TM + && ((sps.getMaxNumGpmAffTmCand() > 0) || (sps.getMaxNumGpmAffTmCand() <= 0 && !isAffine0 && !isAffine1)) +#else && (!isAffine0 && !isAffine1) +#endif && mergeCand0 < GEO_MAX_ALL_INTER_UNI_CANDS&& mergeCand1 < GEO_MAX_ALL_INTER_UNI_CANDS #else #if JVET_Y0065_GPM_INTRA @@ -11229,7 +11299,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct && !isIntra0 && !isIntra1 #endif #if JVET_AG0164_AFFINE_GPM +#if JVET_AJ0274_GPM_AFFINE_TM + && ((sps.getMaxNumGpmAffTmCand() > 0) || (sps.getMaxNumGpmAffTmCand() <= 0 && !isAffine0 && !isAffine1)) +#else && ( !isAffine0 && !isAffine1) +#endif #endif ) #else @@ -11912,6 +11986,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct pu.geoSplitDir = geoSplitDirList[candidateIdx]; pu.geoMergeIdx0 = geoMergeCand0[candidateIdx]; pu.geoMergeIdx1 = geoMergeCand1[candidateIdx]; +#if JVET_AJ0274_REGRESSION_GPM_TM + pu.geoBlendTmFlag = false; +#endif #if JVET_AE0046_BI_GPM PU::setGpmDirMode(pu); #endif @@ -12045,6 +12122,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF] #if JVET_AG0164_AFFINE_GPM , affMergeCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , affTmMergeCtx +#endif #endif , *mergeTmCtx0, *mergeTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx, m_pcIntraSearch->m_intraMPM, #if JVET_AI0082_GPM_WITH_INTER_IBC @@ -12103,17 +12183,46 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct CodingUnit *bestCU = bestCS->getCU(CHANNEL_TYPE_LUMA); bool skipGPMMMVD = false; +#if JVET_AJ0274_GPM_AFFINE_TM + bool skipGpmMmvdButNotTm = false; +#endif if (geoNumMrgSATDCand > 0) { if (bestCU->skip && !bestCU->geoFlag && !bestCU->affine && !bestCU->mmvdSkip && !bestCU->firstPU->mmvdMergeFlag) { skipGPMMMVD = true; } +#if JVET_AJ0274_REGRESSION_GPM_TM + else if (m_pcEncCfg->getIntraPeriod() > 0 && bestCU->affine && bestCU->skip) + { + skipGPMMMVD = true; + } +#endif else if (bestCU->affine && bestCU->skip && (bestCU->lwidth() >= 16 || bestCU->lheight() >= 16)) { skipGPMMMVD = true; +#if JVET_AJ0274_GPM_AFFINE_TM + if (!isSecondPass && m_fastGpmAffSearch >= 0x02) + { + skipGpmMmvdButNotTm = true; + } +#endif + } + } +#if JVET_AJ0274_REGRESSION_GPM_TM + bool skipGPMTM = false; + if (geoNumMrgSATDCand > 0 && cu.slice->getCheckLDC() && m_pcEncCfg->getIntraPeriod() > 0) + { + if (bestCU->geoFlag && bestCU->firstPU->gpmIntraFlag) + { + skipGPMTM = true; + } + else if (!bestCU->skip && !bestCU->firstPU->mmvdMergeFlag && !bestCU->firstPU->tmMergeFlag && !bestCU->geoFlag) + { + skipGPMTM = true; } } +#endif #if JVET_AG0164_AFFINE_GPM bool isBaseMergeCandIncluded[GEO_MAX_ALL_INTER_UNI_CANDS]; std::memset(isBaseMergeCandIncluded, false, GEO_MAX_ALL_INTER_UNI_CANDS * sizeof(bool)); @@ -12128,6 +12237,12 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct { skipGPMMMVD = (selGeoModeRDList[0] > (bestNormalMrgCost * 1.1)); } +#if JVET_AJ0274_GPM_AFFINE_TM + if (skipGPMMMVD && skipGpmMmvdButNotTm) + { + skipGPMMMVD = false; + } +#endif if (!skipGPMMMVD) { @@ -12267,6 +12382,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if JVET_AG0164_AFFINE_GPM pu.affineGPM[0] = pu.affineGPM[1] = 0; #endif +#if JVET_AJ0274_REGRESSION_GPM_TM + pu.geoBlendTmFlag = false; +#endif bool simpleGPMMMVDStep = (m_pcEncCfg->getIntraPeriod() == -1); #if JVET_AG0164_AFFINE_GPM @@ -12275,7 +12393,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct double mmvdMrgCost[GEO_MAX_NUM_UNI_CANDS][GPM_EXT_MMVD_MAX_REFINE_NUM]; #endif #if JVET_AG0164_AFFINE_GPM +#if JVET_AJ0274_GPM_AFFINE_TM + for (uint8_t mergeCand = 0; mergeCand < (skipGpmMmvdButNotTm ? 0 : numRegularGpmMergeCand); mergeCand++) +#else for (uint8_t mergeCand = 0; mergeCand < numRegularGpmMergeCand; mergeCand++) +#endif #else for (uint8_t mergeCand = 0; mergeCand < maxNumMergeCandidates; mergeCand++) #endif @@ -12374,7 +12496,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct sadMask = &g_geoEncSadMask[g_angle2mask[g_geoParams[splitDir][0]]][g_weightOffset[splitDir][hIdx][wIdx][1] * GEO_WEIGHT_MASK_SIZE + g_weightOffset[splitDir][hIdx][wIdx][0]]; } #if JVET_AG0164_AFFINE_GPM +#if JVET_AJ0274_GPM_AFFINE_TM + for (uint8_t mergeCand = 0; mergeCand < (skipGpmMmvdButNotTm ? 0 : numRegularGpmMergeCand); mergeCand++) +#else for (uint8_t mergeCand = 0; mergeCand < numRegularGpmMergeCand; mergeCand++) +#endif #else for (uint8_t mergeCand = 0; mergeCand < maxNumMergeCandidates; mergeCand++) #endif @@ -12426,6 +12552,10 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct } } +#if JVET_AJ0274_GPM_AFFINE_TM + if (!skipGpmMmvdButNotTm) + { +#endif for (int splitDir = 0; splitDir < GEO_NUM_PARTITION_MODE; splitDir++) { #if JVET_Y0065_GPM_INTRA @@ -12516,7 +12646,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct if (sps.getUseGPMTMMode() #if JVET_AG0164_AFFINE_GPM && mergeCand0 < GEO_MAX_ALL_INTER_UNI_CANDS && mergeCand1 < GEO_MAX_ALL_INTER_UNI_CANDS +#if JVET_AJ0274_GPM_AFFINE_TM + && ((sps.getMaxNumGpmAffTmCand() > 0) || (sps.getMaxNumGpmAffTmCand() <= 0 && !isAffine0 && !isAffine1)) +#else && !isAffine0 && !isAffine1 +#endif #else #if JVET_Y0065_GPM_INTRA && mergeCand0 < GEO_MAX_NUM_UNI_CANDS && mergeCand1 < GEO_MAX_NUM_UNI_CANDS @@ -12539,6 +12673,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct } } } +#if JVET_AJ0274_GPM_AFFINE_TM + } +#endif #if JVET_AG0164_AFFINE_GPM pu.affineGPM[0] = 0; pu.affineGPM[1] = 0; @@ -12549,7 +12686,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #else uint8_t maxNumTmMrgCand = maxNumMergeCandidates; #endif +#if !JVET_AJ0274_REGRESSION_GPM_TM PelUnitBuf geoTmBuffer[GEO_TM_MAX_NUM_CANDS]; +#endif PelUnitBuf geoTmTempBuf[GEO_TM_MAX_NUM_CANDS]; #if JVET_AE0046_BI_GPM bool tmRefinePossible[GEO_TM_MAX_NUM_CANDS]; @@ -12562,6 +12701,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct if (sps.getUseGPMTMMode() #if JVET_Y0065_GPM_INTRA && !bUseOnlyOneVector +#endif +#if JVET_AJ0274_REGRESSION_GPM_TM + && !skipGPMTM #endif ) #else @@ -12659,9 +12801,66 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct distParamWholeBlk.cur.buf = geoTmTempBuf[mergeCand].Y().buf; distParamWholeBlk.cur.stride = geoTmTempBuf[mergeCand].Y().stride; sadTmWholeBlk[mergeCand] = distParamWholeBlk.distFunc(distParamWholeBlk); +#if JVET_AJ0274_REGRESSION_GPM_TM + if (tmType == GEO_TM_SHAPE_AL) + { + isGeoTmMCAvail[mergeCand] = 1; + } +#endif } } pu.tmMergeFlag = false; +#if JVET_AJ0274_GPM_AFFINE_TM + if (affGpmTmValid) + { + if ((CU::isInter(*bestCU)) && bestCU->firstPU->interDir == 3) + { + numAffTmAffCands -= ((m_fastGpmAffSearch & 0x01) ? (numAffTmAffCands -= m_fastGpmAffSearch) : (m_fastGpmAffSearch <= 0x02 ? 3 : 2)); + numAffTmAffCands -= (isSecondPass && (m_fastGpmAffSearch & 0x01) == 0) ? 2 : 0; + } +#if JVET_AH0119_SUBBLOCK_TM + EAffineModel affType[AFFINE_MRG_MAX_NUM_CANDS]; +#endif + m_pcInterSearch->setFillCurTplAboveARMC(false); + for (uint8_t mrgIdx = numRegularGpmMergeCand; mrgIdx < numRegularGpmMergeCand + numAffTmAffCands; mrgIdx++) + { + uint8_t uiAffMergeCand = mrgIdx - numRegularGpmMergeCand; + uint8_t mergeCand = uiAffMergeCand + 3 * GEO_MAX_NUM_UNI_CANDS; + affTmMergeCtx.setAffMergeInfo(pu, mrgIdx); + m_pcInterSearch->processTM4Affine(pu, affTmMergeCtx, uiAffMergeCand, true +#if JVET_AH0119_SUBBLOCK_TM + , pu.cs->slice->getCheckLDB() ? true : false +#endif +#if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE + , uiAffMergeCand +#endif + ); +#if JVET_AH0119_SUBBLOCK_TM + affType[uiAffMergeCand] = (EAffineModel)pu.cu->affineType; +#endif + affTmMergeCtx.affineType[uiAffMergeCand]= affType[uiAffMergeCand]; + + affTmMergeCtx.setAffMergeInfo(pu, mrgIdx); + if (m_pcEncCfg->getMCTSEncConstraint() && (!(MCTSHelper::checkMvBufferForMCTSConstraint(pu)))) + { + tempCS->initStructData(encTestMode.qp); + return; + } + geoTmBuffer[mergeCand] = m_acGeoMergeTmpBuffer[mergeCand].getBuf(localUnitArea); + m_pcInterSearch->motionCompensation(pu, geoTmBuffer[mergeCand], REF_PIC_LIST_X, true, false); + pu.cu->affine = false; + + // calculate SAD for each candidate + geoTmTempBuf[mergeCand] = m_acGeoSADTmpBuffer[mergeCand].getBuf(localUnitArea); + geoTmTempBuf[mergeCand].Y().copyFrom(geoTmBuffer[mergeCand].Y()); + geoTmTempBuf[mergeCand].Y().roundToOutputBitdepth(geoTmTempBuf[mergeCand].Y(), cu.slice->clpRng(COMPONENT_Y)); + distParamWholeBlk.cur.buf = geoTmTempBuf[mergeCand].Y().buf; + distParamWholeBlk.cur.stride = geoTmTempBuf[mergeCand].Y().stride; + sadTmWholeBlk[mergeCand] = distParamWholeBlk.distFunc(distParamWholeBlk); + } + m_pcInterSearch->setFillCurTplAboveARMC(false); + } +#endif for (int splitDir = 0; splitDir < GEO_NUM_PARTITION_MODE; splitDir++) { @@ -12687,12 +12886,20 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct maskStride2 = -(int)cu.lwidth(); sadMask = &g_geoEncSadMask[g_angle2mask[g_geoParams[splitDir][0]]][g_weightOffset[splitDir][hIdx][wIdx][1] * GEO_WEIGHT_MASK_SIZE + g_weightOffset[splitDir][hIdx][wIdx][0]]; } +#if JVET_AJ0274_GPM_AFFINE_TM + for (uint8_t mergeCand = 0; mergeCand < (affGpmTmValid ? maxNumTmMrgCand + numAffTmAffCands : maxNumTmMrgCand); mergeCand++) +#else for (uint8_t mergeCand = 0; mergeCand < maxNumTmMrgCand; mergeCand++) +#endif { if (mrgDuplicated[mergeCand]) { continue; } +#if JVET_AJ0274_GPM_AFFINE_TM + if (mergeCand < maxNumTmMrgCand) + { +#endif uint8_t mergeCand0 = mergeCand + (g_geoTmShape[0][g_geoParams[splitDir][0]] - 1) * GEO_MAX_NUM_UNI_CANDS; m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), geoTmTempBuf[mergeCand0].Y().buf, geoTmTempBuf[mergeCand0].Y().stride, sadMask, maskStride, stepX, maskStride2, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y); @@ -12705,18 +12912,41 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct sadSmall = sadTmWholeBlk[mergeCand1] - distParam.distFunc(distParam); tempCost = (double)sadSmall + geoMergeIdxCost[mergeCand] + geoMMVDFlagCost[0]; m_geoMMVDCostList.insert(splitDir, 1, mergeCand, (GPM_EXT_MMVD_MAX_REFINE_NUM + 1), tempCost); +#if JVET_AJ0274_GPM_AFFINE_TM + } + else + { + uint8_t mergeCand0 = mergeCand - maxNumTmMrgCand + 3 * GEO_MAX_NUM_UNI_CANDS; + m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), geoTmTempBuf[mergeCand0].Y().buf, geoTmTempBuf[mergeCand0].Y().stride, sadMask, maskStride, stepX, maskStride2, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y); + sadLarge = distParam.distFunc(distParam); + double tempCost = (double)sadLarge + geoAffTmMergeIdxCost[mergeCand - maxNumTmMrgCand] + geoMMVDFlagCost[0]; + m_geoMMVDCostList.insert(splitDir, 0, mergeCand, (GPM_EXT_MMVD_MAX_REFINE_NUM + 1), tempCost); + + sadSmall = sadTmWholeBlk[mergeCand0] - sadLarge; + tempCost = (double)sadSmall + geoAffTmMergeIdxCost[mergeCand - maxNumTmMrgCand] + geoMMVDFlagCost[0]; + m_geoMMVDCostList.insert(splitDir, 1, mergeCand, (GPM_EXT_MMVD_MAX_REFINE_NUM + 1), tempCost); + } +#endif } } for (int splitDir = 0; splitDir < GEO_NUM_PARTITION_MODE; splitDir++) { +#if JVET_AJ0274_GPM_AFFINE_TM + for (int mergeCand0 = 0; mergeCand0 < (affGpmTmValid ? maxNumTmMrgCand + numAffTmAffCands : maxNumTmMrgCand); mergeCand0++) +#else for (int mergeCand0 = 0; mergeCand0 < maxNumTmMrgCand; mergeCand0++) +#endif { if (mrgDuplicated[mergeCand0]) { continue; } +#if JVET_AJ0274_GPM_AFFINE_TM + for (int mergeCand1 = 0; mergeCand1 < (affGpmTmValid ? maxNumTmMrgCand + numAffTmAffCands : maxNumTmMrgCand); mergeCand1++) +#else for (int mergeCand1 = 0; mergeCand1 < maxNumTmMrgCand; mergeCand1++) +#endif { if (mrgDuplicated[mergeCand1]) { @@ -12726,13 +12956,24 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct { continue; } +#if JVET_AJ0274_GPM_AFFINE_TM + int isAffine0 = (mergeCand0 >= numRegularGpmMergeCand && mergeCand0 < GEO_MAX_ALL_INTER_UNI_CANDS) ? 1 : 0; + int isAffine1 = (mergeCand1 >= numRegularGpmMergeCand && mergeCand1 < GEO_MAX_ALL_INTER_UNI_CANDS) ? 1 : 0; + pu.affineGPM[0] = isAffine0; + pu.affineGPM[1] = isAffine1; +#endif #if JVET_Z0056_GPM_SPLIT_MODE_REORDERING int geoSyntaxMode = std::numeric_limits<uint8_t>::max(); if(sps.getUseAltGPMSplitModeCode()) { +#if JVET_AJ0274_GPM_AFFINE_TM + m_pcInterSearch->setGeoTMSplitModeToSyntaxTable(pu, mergeCtx, affTmMergeCtx, mergeCand0, mergeCand1, tmMmvdBufIdx0 - 1, tmMmvdBufIdx1 - 1); + geoSyntaxMode = m_pcInterSearch->convertGeoSplitModeToSyntax(splitDir, mergeCand0, mergeCand1, tmMmvdBufIdx0 - 1, tmMmvdBufIdx1 - 1); +#else m_pcInterSearch->setGeoTMSplitModeToSyntaxTable(pu, mergeCtx, mergeCand0, mergeCand1, tmMmvdBufIdx0 - 1, tmMmvdBufIdx1 - 1); geoSyntaxMode = m_pcInterSearch->convertGeoSplitModeToSyntax(splitDir, mergeCand0, mergeCand1, tmMmvdBufIdx0 - 1, tmMmvdBufIdx1 - 1); +#endif if (geoSyntaxMode == std::numeric_limits<uint8_t>::max()) { continue; @@ -12755,6 +12996,10 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct } } #endif +#if JVET_AJ0274_GPM_AFFINE_TM + pu.affineGPM[0] = 0; + pu.affineGPM[1] = 0; +#endif int numberGeoCandChecked = (int)geoSADCostList.size(); if (numberGeoCandChecked == 0) @@ -12775,6 +13020,10 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct int splitDir = geoSplitDirList[candidateIdx]; int mergeCand0 = geoMergeCand0[candidateIdx]; int mergeCand1 = geoMergeCand1[candidateIdx]; +#if JVET_AJ0274_GPM_AFFINE_TM + int isAffine0 = (mergeCand0 >= numRegularGpmMergeCand && mergeCand0 < GEO_MAX_ALL_INTER_UNI_CANDS) ? 1 : 0; + int isAffine1 = (mergeCand1 >= numRegularGpmMergeCand && mergeCand1 < GEO_MAX_ALL_INTER_UNI_CANDS) ? 1 : 0; +#endif #if TM_MRG bool tmFlag0 = (geoMmvdCand0[candidateIdx] == (GPM_EXT_MMVD_MAX_REFINE_NUM + 1)); bool tmFlag1 = (geoMmvdCand1[candidateIdx] == (GPM_EXT_MMVD_MAX_REFINE_NUM + 1)); @@ -12804,8 +13053,10 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct } #endif #if JVET_AG0164_AFFINE_GPM +#if !JVET_AJ0274_GPM_AFFINE_TM int isAffine0 = (mergeCand0 >= numRegularGpmMergeCand && mergeCand0 < GEO_MAX_ALL_INTER_UNI_CANDS && !tmFlag0) ? 1 : 0; int isAffine1 = (mergeCand1 >= numRegularGpmMergeCand && mergeCand1 < GEO_MAX_ALL_INTER_UNI_CANDS && !tmFlag1) ? 1 : 0; +#endif pu.affineGPM[0] = isAffine0; pu.affineGPM[1] = isAffine1; CHECK(mmvdFlag0&& isAffine0, "Aff GPM MMVD is not allowed"); @@ -12969,7 +13220,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if TM_MRG if (tmFlag0) { +#if JVET_AJ0274_GPM_AFFINE_TM + int mrgTmCand0 = isAffine0 ? (mergeCand0 - numRegularGpmMergeCand + 3 * GEO_MAX_NUM_UNI_CANDS) : (mergeCand0 + (g_geoTmShape[0][g_geoParams[splitDir][0]] - 1) * GEO_MAX_NUM_UNI_CANDS); +#else int mrgTmCand0 = mergeCand0 + (g_geoTmShape[0][g_geoParams[splitDir][0]] - 1) * GEO_MAX_NUM_UNI_CANDS; +#endif predSrc0 = geoTmBuffer[mrgTmCand0]; } else if (mmvdFlag0) @@ -12983,7 +13238,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct if (tmFlag1) { +#if JVET_AJ0274_GPM_AFFINE_TM + int mrgTmCand1 = isAffine1 ? (mergeCand1 - numRegularGpmMergeCand + 3 * GEO_MAX_NUM_UNI_CANDS) : (mergeCand1 + (g_geoTmShape[1][g_geoParams[splitDir][0]] - 1) * GEO_MAX_NUM_UNI_CANDS); +#else int mrgTmCand1 = mergeCand1 + (g_geoTmShape[1][g_geoParams[splitDir][0]] - 1) * GEO_MAX_NUM_UNI_CANDS; +#endif predSrc1 = geoTmBuffer[mrgTmCand1]; } else if (mmvdFlag1) @@ -13033,7 +13292,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct { updateCost += geoIntraFlag0Cost[isIntra0]; } +#if JVET_AJ0274_GPM_AFFINE_TM + updateCost += (isIntra0 ? geoIntraIdxCost[intraIdx0] : (isAffine0 ? (tmFlag0 ? geoAffTmMergeIdxCost[mergeCand0 - numRegularGpmMergeCand] : geoAffMergeIdxCost[mergeCand0 - numRegularGpmMergeCand]) : geoMergeIdxCost[mergeCand0])); +#else updateCost += (isIntra0 ? geoIntraIdxCost[intraIdx0] : (isAffine0 ? geoAffMergeIdxCost[mergeCand0 - numRegularGpmMergeCand] : geoMergeIdxCost[mergeCand0])); +#endif if (!bUseOnlyOneVector || isIntra0) { if (mmvdFlag1) @@ -13044,7 +13307,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct { updateCost += geoIntraFlag1Cost[isIntra0][isIntra1]; } +#if JVET_AJ0274_GPM_AFFINE_TM + updateCost += (isIntra1 ? geoIntraIdxCost[intraIdx1] : (isAffine1 ? (tmFlag1 ? geoAffTmMergeIdxCost[mergeCand1 - numRegularGpmMergeCand] : geoAffMergeIdxCost[mergeCand1 - numRegularGpmMergeCand]) : geoMergeIdxCost[mergeCand1])); +#else updateCost += (isIntra1 ? geoIntraIdxCost[intraIdx1] : (isAffine1 ? geoAffMergeIdxCost[mergeCand1 - numRegularGpmMergeCand] : geoMergeIdxCost[mergeCand1])); +#endif } #else double updateCost = @@ -13086,7 +13353,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if JVET_Y0065_GPM_INTRA if (!mmvdFlag0 && !mmvdFlag1 && !isIntra0 && !isIntra1 #if JVET_AG0164_AFFINE_GPM +#if JVET_AJ0274_GPM_AFFINE_TM + && ((sps.getMaxNumGpmAffTmCand() > 0) || (sps.getMaxNumGpmAffTmCand() <= 0 && !isAffine0 && !isAffine1)) +#else && !isAffine0 && !isAffine1 +#endif #endif ) #else @@ -13335,8 +13606,13 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct bool tmFlag1 = (geoMmvdCand1[candidateIdx] == (GPM_EXT_MMVD_MAX_REFINE_NUM + 1)); bool mmvdFlag0 = (geoMmvdCand0[candidateIdx] >= 1 && geoMmvdCand0[candidateIdx] <= GPM_EXT_MMVD_MAX_REFINE_NUM); bool mmvdFlag1 = (geoMmvdCand1[candidateIdx] >= 1 && geoMmvdCand1[candidateIdx] <= GPM_EXT_MMVD_MAX_REFINE_NUM); +#if JVET_AJ0274_GPM_AFFINE_TM + int mmvdCand0 = (mmvdFlag0 ? (geoMmvdCand0[candidateIdx] - 1) : -1); + int mmvdCand1 = (mmvdFlag1 ? (geoMmvdCand1[candidateIdx] - 1) : -1); +#else int mmvdCand0 = (mmvdFlag0 ? (geoMmvdCand0[candidateIdx] - 1) : MAX_INT); int mmvdCand1 = (mmvdFlag1 ? (geoMmvdCand1[candidateIdx] - 1) : MAX_INT); +#endif int mrgTmCand0 = MAX_INT, mrgTmCand1 = MAX_INT; #else int mmvdCand0 = geoMmvdCand0[candidateIdx] - 1; @@ -13349,13 +13625,20 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if JVET_AG0164_AFFINE_GPM int isIntra0 = (mergeCand0 >= GEO_MAX_ALL_INTER_UNI_CANDS) ? 1 : 0; int isIntra1 = (mergeCand1 >= GEO_MAX_ALL_INTER_UNI_CANDS) ? 1 : 0; +#if JVET_AJ0274_GPM_AFFINE_TM + int isAffine0 = (mergeCand0 >= numRegularGpmMergeCand && mergeCand0 < GEO_MAX_ALL_INTER_UNI_CANDS) ? 1 : 0; + int isAffine1 = (mergeCand1 >= numRegularGpmMergeCand && mergeCand1 < GEO_MAX_ALL_INTER_UNI_CANDS) ? 1 : 0; +#else int isAffine0 = (mergeCand0 >= numRegularGpmMergeCand && mergeCand0 < GEO_MAX_ALL_INTER_UNI_CANDS && !tmFlag0) ? 1 : 0; int isAffine1 = (mergeCand1 >= numRegularGpmMergeCand && mergeCand1 < GEO_MAX_ALL_INTER_UNI_CANDS && !tmFlag1) ? 1 : 0; +#endif pu.affineGPM[0] = isAffine0; pu.affineGPM[1] = isAffine1; +#if !JVET_AJ0274_GPM_AFFINE_TM CHECK(isAffine0 && tmFlag0, "GPM affine cannot be used together with GPM TM"); CHECK(isAffine1 && tmFlag1, "GPM affine cannot be used together with GPM TM"); +#endif #else int isIntra0 = (mergeCand0 >= GEO_MAX_NUM_UNI_CANDS) ? 1 : 0; int isIntra1 = (mergeCand1 >= GEO_MAX_NUM_UNI_CANDS) ? 1 : 0; @@ -13422,6 +13705,29 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if TM_MRG else if (tmFlag0) { +#if JVET_AJ0274_GPM_AFFINE_TM + if (isAffine0) + { + mrgTmCand0 = mergeCand0 - numRegularGpmMergeCand + 3 * GEO_MAX_NUM_UNI_CANDS; + if (isChromaEnabled(pu.chromaFormat) && !isGeoTmChromaAvail[mrgTmCand0]) + { + affTmMergeCtx.setAffMergeInfo(pu, mergeCand0); + if (pu.refIdx[0] >= 0) + { + PU::setAllAffineMv(pu, pu.mvAffi[0][0], pu.mvAffi[0][1], pu.mvAffi[0][2], REF_PIC_LIST_0); + } + if (pu.refIdx[1] >= 0) + { + PU::setAllAffineMv(pu, pu.mvAffi[1][0], pu.mvAffi[1][1], pu.mvAffi[1][2], REF_PIC_LIST_1); + } + m_pcInterSearch->motionCompensation(pu, geoTmBuffer[mrgTmCand0], REF_PIC_LIST_X, false, true); + pu.cu->affine = false; + isGeoTmChromaAvail[mrgTmCand0] = 1; + } + } + else + { +#endif int geoTmType = g_geoTmShape[0][g_geoParams[splitDir][0]]; mrgTmCand0 = mergeCand0 + (geoTmType - 1) * GEO_MAX_NUM_UNI_CANDS; if (isChromaEnabled(pu.chromaFormat) && !isGeoTmChromaAvail[mrgTmCand0]) @@ -13447,6 +13753,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct m_pcInterSearch->setLumaBdofReady(false); #endif } +#if JVET_AJ0274_GPM_AFFINE_TM + } +#endif } #endif #if JVET_AG0164_AFFINE_GPM @@ -13577,6 +13886,29 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if TM_MRG else if (tmFlag1) { +#if JVET_AJ0274_GPM_AFFINE_TM + if (isAffine1) + { + mrgTmCand1 = mergeCand1 - numRegularGpmMergeCand + 3 * GEO_MAX_NUM_UNI_CANDS; + if (isChromaEnabled(pu.chromaFormat) && !isGeoTmChromaAvail[mrgTmCand1]) + { + affTmMergeCtx.setAffMergeInfo(pu, mergeCand1); + if (pu.refIdx[0] >= 0) + { + PU::setAllAffineMv(pu, pu.mvAffi[0][0], pu.mvAffi[0][1], pu.mvAffi[0][2], REF_PIC_LIST_0); + } + if (pu.refIdx[1] >= 0) + { + PU::setAllAffineMv(pu, pu.mvAffi[1][0], pu.mvAffi[1][1], pu.mvAffi[1][2], REF_PIC_LIST_1); + } + m_pcInterSearch->motionCompensation(pu, geoTmBuffer[mrgTmCand1], REF_PIC_LIST_X, false, true); + pu.cu->affine = false; + isGeoTmChromaAvail[mrgTmCand1] = 1; + } + } + else + { +#endif int geoTmType = g_geoTmShape[1][g_geoParams[splitDir][0]]; mrgTmCand1 = mergeCand1 + (geoTmType - 1) * GEO_MAX_NUM_UNI_CANDS; if (isChromaEnabled(pu.chromaFormat) && !isGeoTmChromaAvail[mrgTmCand1]) @@ -13602,6 +13934,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #endif isGeoTmChromaAvail[mrgTmCand1] = true; } +#if JVET_AJ0274_GPM_AFFINE_TM + } +#endif } #endif #if JVET_AG0164_AFFINE_GPM @@ -13722,6 +14057,10 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct int geoTmType = g_geoTmShape[0][g_geoParams[splitDir][0]]; mergeCtx[geoTmType].setMergeInfo(pu, mergeCand0); } +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + chromaAvailPtr0 = &isGeoTmChromaAvail[mrgTmCand0]; + predSrcTemp0 = geoTmTempBuf[mrgTmCand0]; #endif } #endif @@ -13806,7 +14145,19 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct predSrc1 = geoTmBuffer[mrgTmCand1]; #if JVET_AH0314_LIC_INHERITANCE_FOR_MRG int geoTmType = g_geoTmShape[1][g_geoParams[splitDir][0]]; +#if JVET_AJ0274_GPM_AFFINE_TM + if (isAffine1) + { + affTmMergeCtx.setAffMergeInfo(pu, mergeCand1); + pu.cu->affine = false; + } + else +#endif mergeCtx[geoTmType].setMergeInfo(pu, mergeCand1); +#endif +#if JVET_AJ0274_GPM_AFFINE_TM + chromaAvailPtr1 = &isGeoTmChromaAvail[mrgTmCand1]; + predSrcTemp1 = geoTmTempBuf[mrgTmCand1]; #endif } #endif @@ -14073,9 +14424,36 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct } int geoCombIdx = candidateIdx * GEO_BLENDING_NUM + bldIdx; +#if JVET_AJ0274_GPM_AFFINE_TM + if (tmFlag0 || tmFlag1) + { + predSrcTemp0 = geoTmTempBuf[mrgTmCand0]; + predSrcTemp1 = geoTmTempBuf[mrgTmCand1]; + } + else + { +#endif predSrcTemp0 = mmvdFlag0? geoMMVDTempBuf[mergeCand0][mmvdCand0]: geoTempBuf[mergeCand0]; predSrcTemp1 = mmvdFlag1? geoMMVDTempBuf[mergeCand1][mmvdCand1]: geoTempBuf[mergeCand1]; +#if JVET_AJ0274_GPM_AFFINE_TM + } +#endif + +#if JVET_AJ0274_GPM_AFFINE_TM + if (tmFlag0) + { +#if JVET_AA0058_GPM_ADAPTIVE_BLENDING + m_pcInterSearch->weightedGeoBlkRounded(pu, splitDir, bldIdx, CHANNEL_TYPE_LUMA, geoCombinations[geoCombIdx], predSrcTemp0, predSrcTemp1); + m_pcInterSearch->weightedGeoBlkRounded(pu, splitDir, bldIdx, CHANNEL_TYPE_CHROMA, geoCombinations[geoCombIdx], predSrcTemp0, predSrcTemp1); +#else + m_pcInterSearch->weightedGeoBlkRounded(pu, splitDir, CHANNEL_TYPE_LUMA, geoCombinations[candidateIdx], predSrc0, predSrc1); + m_pcInterSearch->weightedGeoBlkRounded(pu, splitDir, CHANNEL_TYPE_CHROMA, geoCombinations[candidateIdx], predSrc0, predSrc1); +#endif + } + else + { +#endif PelUnitBuf obmcBuf0 = m_ciipBuffer[0].getBuf(localUnitArea); // Borrow the CIIP buffer PelUnitBuf obmcBuf1 = m_ciipBuffer[1].getBuf(localUnitArea); // Borrow the CIIP buffer @@ -14089,6 +14467,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct m_pcInterSearch->weightedGeoBlkRounded(pu, splitDir, CHANNEL_TYPE_LUMA, geoCombinations[candidateIdx], predSrc0, predSrc1); m_pcInterSearch->weightedGeoBlkRounded(pu, splitDir, CHANNEL_TYPE_CHROMA, geoCombinations[candidateIdx], predSrc0, predSrc1); #endif +#if JVET_AJ0274_GPM_AFFINE_TM + } +#endif } #endif else @@ -14308,6 +14689,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct pu.geoSplitDir = geoSplitDirList[candidateIdx]; pu.geoMergeIdx0 = geoMergeCand0[candidateIdx]; pu.geoMergeIdx1 = geoMergeCand1[candidateIdx]; +#if JVET_AJ0274_REGRESSION_GPM_TM + pu.geoBlendTmFlag = false; +#endif #if JVET_AE0046_BI_GPM PU::setGpmDirMode(pu); #endif @@ -14366,12 +14750,20 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if JVET_AG0164_AFFINE_GPM pu.affineGPM[0] = pu.affineGPM[1] = 0; +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.geoMergeIdx0 < GEO_MAX_ALL_INTER_UNI_CANDS && pu.geoMergeIdx0 >= numRegularGpmMergeCand) +#else if (!pu.geoTmFlag0 && pu.geoMergeIdx0 < GEO_MAX_ALL_INTER_UNI_CANDS && pu.geoMergeIdx0 >= numRegularGpmMergeCand) +#endif { pu.geoMergeIdx0 -= numRegularGpmMergeCand; pu.affineGPM[0] = 1; } +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.geoMergeIdx1 < GEO_MAX_ALL_INTER_UNI_CANDS && pu.geoMergeIdx1 >= numRegularGpmMergeCand) +#else if (!pu.geoTmFlag1 && pu.geoMergeIdx1 < GEO_MAX_ALL_INTER_UNI_CANDS && pu.geoMergeIdx1 >= numRegularGpmMergeCand) +#endif { pu.geoMergeIdx1 -= numRegularGpmMergeCand; pu.affineGPM[1] = 1; @@ -14384,7 +14776,21 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if JVET_W0097_GPM_MMVD_TM && TM_MRG if(pu.tmMergeFlag) { +#if JVET_AJ0274_GPM_AFFINE_TM + int cand0 = pu.geoMergeIdx0; + int cand1 = pu.geoMergeIdx1; + if (pu.affineGPM[0]) + { + cand0 += numRegularGpmMergeCand; + } + if (pu.affineGPM[1]) + { + cand1 += numRegularGpmMergeCand; + } + int geoSyntaxMode = m_pcInterSearch->convertGeoSplitModeToSyntax(pu.geoSplitDir, cand0, cand1, tmMmvdBufIdx0 - 1, tmMmvdBufIdx1 - 1); +#else int geoSyntaxMode = m_pcInterSearch->convertGeoSplitModeToSyntax(pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, tmMmvdBufIdx0 - 1, tmMmvdBufIdx1 - 1); +#endif CHECK(geoSyntaxMode < 0 || geoSyntaxMode >= GEO_NUM_SIG_PARTMODE, "Invalid GEO split direction!"); CHECK(pu.geoMMVDFlag0 || pu.geoMMVDFlag1, "GPM MMVD should not be used in GPM-TM mode"); pu.geoSyntaxMode = (uint8_t)geoSyntaxMode; @@ -14491,6 +14897,14 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if TM_MRG if (pu.geoTmFlag0) { +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[0]) + { + affTmMergeCtx.setAffMergeInfo(pu, pu.geoMergeIdx0); + pu.cu->affine = false; + } + else +#endif mrgTmCtx0->setMergeInfo(pu, pu.geoMergeIdx0); } else @@ -14518,6 +14932,14 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct #if TM_MRG if (pu.geoTmFlag1) { +#if JVET_AJ0274_GPM_AFFINE_TM + if (pu.affineGPM[1]) + { + affTmMergeCtx.setAffMergeInfo(pu, pu.geoMergeIdx1); + pu.cu->affine = false; + } + else +#endif mrgTmCtx1->setMergeInfo(pu, pu.geoMergeIdx1); } else @@ -14553,6 +14975,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF] #if JVET_AG0164_AFFINE_GPM , affMergeCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , affTmMergeCtx +#endif #endif , *mrgTmCtx0, *mrgTmCtx1, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, pu.geoBldIdx, m_pcIntraSearch->m_intraMPM, #if JVET_AI0082_GPM_WITH_INTER_IBC @@ -14719,6 +15144,9 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct pu.mmvdMergeFlag = false; pu.mmvdMergeIdx = MAX_UCHAR; +#if JVET_AJ0274_REGRESSION_GPM_TM + pu.geoBlendTmFlag = false; +#endif if (noResidualPass == iterationBegin) { // do chroma (luma has been done yet) @@ -14726,7 +15154,11 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct { const int mergeCand = geoBI.mergeCand[k]; mergeCtx[GEO_TM_OFF].setMergeInfo(pu, mergeCand); +#if JVET_AJ0274_REGRESSION_GPM_TM + if (isGeoChromaAvail[mergeCand]) +#else if (isGeoChromaAvail[mergeCand] == 2) +#endif { continue; } @@ -14779,12 +15211,22 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct uint8_t intraMPM[2] = { PLANAR_IDX, PLANAR_IDX }; #if JVET_AG0164_AFFINE_GPM #if JVET_AI0082_GPM_WITH_INTER_IBC +#if JVET_AJ0274_GPM_AFFINE_TM + PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], affMergeCtx, affTmMergeCtx, mergeCtx[GEO_TM_OFF], mergeCtx[GEO_TM_OFF], 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, geoBvList, + pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx1] : nullptr); +#else PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], affMergeCtx, mergeCtx[GEO_TM_OFF], mergeCtx[GEO_TM_OFF], 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, geoBvList, pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx1] : nullptr); +#endif +#else +#if JVET_AJ0274_GPM_AFFINE_TM + PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], affMergeCtx, affTmMergeCtx, mergeCtx[GEO_TM_OFF], mergeCtx[GEO_TM_OFF], 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, + pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx1] : nullptr); #else PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], affMergeCtx, mergeCtx[GEO_TM_OFF], mergeCtx[GEO_TM_OFF], 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx1] : nullptr); #endif +#endif #else #if JVET_AI0082_GPM_WITH_INTER_IBC PU::spanGeoMMVDMotionInfo(pu, mergeCtx[GEO_TM_OFF], mergeCtx[GEO_TM_OFF], mergeCtx[GEO_TM_OFF], 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, geoBvList, @@ -14794,7 +15236,6 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4GPM[GEO_TM_OFF][geoMergeIdx1] : nullptr); #endif #endif - tempCS->getPredBuf().copyFrom(blendBuffer); #if ENABLE_OBMC @@ -14827,6 +15268,7 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct tempCS->initStructData(encTestMode.qp); bIsBestCost |= lastBestCost > bestCS->cost; + if (!bIsBestCost && (i + 1) >= 2) { bStopRdoLoop = true; @@ -14835,6 +15277,465 @@ void EncCu::xCheckRDCostMergeGeoComb2Nx2N(CodingStructure *&tempCS, CodingStruct } // i (numGeoBlendInfoCand) #endif +#if JVET_AJ0274_REGRESSION_GPM_TM + double bestEstimGeoBlendTmPredCost = MAX_DOUBLE; + uint8_t isGeoBlendTmChromaAvail[GEO_TM_MAX_NUM_CANDS]; + memset(isGeoBlendTmChromaAvail, 0, sizeof(uint8_t) * GEO_TM_MAX_NUM_CANDS); + { + int idxBufGeoTm = idxBlendGeoFirst; +#if JVET_AG0164_AFFINE_GPM + uint8_t maxNumBlendTmMrgCand = numRegularGpmMergeCand; +#else + uint8_t maxNumBlendTmMrgCand = maxNumMergeCandidates; +#endif + PelUnitBuf geoBlendTmBuffer[GEO_TM_MAX_NUM_CANDS]; + geoBlendTmCtx.numValidMergeCand = maxNumBlendTmMrgCand; + GeoBlendInfo geoBlendTmInfo[GEO_BLEND_MAX_NUM_CANDS]; + int numGeoBlendTmInfoCand = 0; + GeoBlendInfo geoTmBIdst; + + bool skipGeoBlendTM = CU::checkGeoBlendTmAvail(cu, bestCS); + + if (!skipGeoBlendTM) + { + tempCS->initStructData(encTestMode.qp); + CodingUnit& cu = tempCS->addCU(tempCS->area, pm.chType); + pm.setCUData(cu); + cu.predMode = MODE_INTER; + cu.slice = tempCS->slice; + cu.tileIdx = tempCS->pps->getTileIdx(tempCS->area.lumaPos()); + cu.qp = encTestMode.qp; + cu.affine = false; + cu.mtsFlag = false; +#if INTER_LIC + cu.licFlag = false; +#if JVET_AH0314_LIC_INHERITANCE_FOR_MRG + cu.licInheritPara = false; +#endif +#endif + cu.bcwIdx = BCW_DEFAULT; + cu.geoFlag = true; +#if JVET_AG0112_REGRESSION_BASED_GPM_BLENDING + cu.geoBlendFlag = true; +#endif +#if JVET_AG0061_INTER_LFNST_NSPT + cu.lfnstFlag = false; + cu.lfnstIdx = 0; +#if JVET_AI0050_INTER_MTSS + cu.lfnstIntra = 0; +#endif +#endif + cu.imv = 0; + cu.mmvdSkip = false; + cu.skip = false; + cu.mipFlag = false; + cu.bdpcmMode = 0; + + PredictionUnit& pu = tempCS->addPU(cu, pm.chType); + pu.mergeFlag = true; + pu.regularMergeFlag = false; +#if JVET_AJ0274_REGRESSION_GPM_TM + pu.geoBlendTmFlag = false; +#endif +#if JVET_AE0046_BI_GPM + PU::setGpmDirMode(pu); +#endif +#if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) + pu.tmMergeFlag = false; +#endif +#if JVET_AG0164_AFFINE_GPM + pu.affineGPM[0] = pu.affineGPM[1] = 0; +#endif + + for (int idx = 0; idx < maxNumBlendTmMrgCand; idx++) + { + if (mrgDuplicated[idx]) + { + continue; + } + geoBlendTmCtx.bcwIdx[idx] = BCW_DEFAULT; + geoBlendTmCtx.useAltHpelIf[idx] = false; +#if JVET_AG0276_NLIC + geoBlendTmCtx.altLMFlag[idx] = false; + geoBlendTmCtx.altLMParaNeighbours[idx].resetAltLinearModel(); +#endif +#if INTER_LIC + geoBlendTmCtx.licFlags[idx] = mergeCtx[GEO_TM_OFF].licFlags[idx]; +#if JVET_AH0314_LIC_INHERITANCE_FOR_MRG + geoBlendTmCtx.copyLICParamFromCtx(idx, mergeCtx[GEO_TM_OFF], idx); +#else + geoBlendTmCtx.setDefaultLICParamToCtx(idx); +#endif +#endif + geoBlendTmCtx.interDirNeighbours[idx] = mergeCtx[GEO_TM_OFF].interDirNeighbours[idx]; + geoBlendTmCtx.mvFieldNeighbours[(idx << 1)].mv = mergeCtx[GEO_TM_OFF].mvFieldNeighbours[(idx << 1)].mv; + geoBlendTmCtx.mvFieldNeighbours[(idx << 1) + 1].mv = mergeCtx[GEO_TM_OFF].mvFieldNeighbours[(idx << 1) + 1].mv; + geoBlendTmCtx.mvFieldNeighbours[(idx << 1)].refIdx = mergeCtx[GEO_TM_OFF].mvFieldNeighbours[(idx << 1)].refIdx; + geoBlendTmCtx.mvFieldNeighbours[(idx << 1) + 1].refIdx = mergeCtx[GEO_TM_OFF].mvFieldNeighbours[(idx << 1) + 1].refIdx; + } + + pu.geoTmType = GEO_TM_SHAPE_AL; + pu.geoBlendTmFlag = true; + pu.cu->geoBlendFlag = true; + pu.tmMergeFlag = true; + bool tempBdvrFlag = pu.bdmvrRefine; + + for (uint8_t mrgIdx = 0; mrgIdx < maxNumBlendTmMrgCand; mrgIdx++) + { + if (mrgDuplicated[mrgIdx]) + { + continue; + } + uint8_t mergeCand = mrgIdx + (GEO_TM_SHAPE_AL - 1) * GEO_MAX_NUM_UNI_CANDS; + if (isGeoTmMCAvail[mergeCand]) + { + mergeCtx[GEO_TM_SHAPE_AL].setMergeInfo(pu, mrgIdx); + } + else + { + geoBlendTmCtx.setMergeInfo(pu, mrgIdx); +#if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE + m_pcInterSearch->deriveTMMv(pu, NULL, mrgIdx); +#else + m_pcInterSearch->deriveTMMv(pu); +#endif + } + geoBlendTmCtx.interDirNeighbours[mrgIdx] = pu.interDir; + geoBlendTmCtx.bcwIdx[mrgIdx] = (pu.interDir != 3) ? BCW_DEFAULT : geoBlendTmCtx.bcwIdx[mrgIdx]; + geoBlendTmCtx.mvFieldNeighbours[(mrgIdx << 1)].refIdx = pu.refIdx[0]; + geoBlendTmCtx.mvFieldNeighbours[(mrgIdx << 1) + 1].refIdx = pu.refIdx[1]; + geoBlendTmCtx.mvFieldNeighbours[(mrgIdx << 1)].mv = pu.mv[0]; + geoBlendTmCtx.mvFieldNeighbours[(mrgIdx << 1) + 1].mv = pu.mv[1]; + } + pu.bdmvrRefine = tempBdvrFlag; + pu.tmMergeFlag = false; +#if JVET_AH0314_LIC_INHERITANCE_FOR_MRG + cu.licFlag = false; + geoBlendTmCtx.setLICParamToPu(*cu.firstPU, NOT_VALID, false); +#endif + m_pcInterSearch->getGeoBlendCand(cu, geoBlendTmCtx, -1, geoTmBIdst, geoBlendTmInfo, &numGeoBlendTmInfoCand); + for (int i = 0; i < numGeoBlendTmInfoCand; i++) + { + for (int j = 0; j < 2; j++) + { + auto mergeCand = geoBlendTmInfo[i].mergeCand[j]; + + if (mrgDuplicated[mergeCand]) + { + continue; + } + if (isGeoTmMCAvail[mergeCand] == 2) + { + continue; + } + geoBlendTmCtx.setMergeInfo(pu, mergeCand); + geoBlendTmBuffer[mergeCand] = m_acGeoBlendTMBuffer[mergeCand].getBuf(localUnitArea); + +#if JVET_AE0046_BI_GPM + if (PU::checkBDMVRCondition(pu, true)) + { + pu.bdmvrRefine = true; + refinePossibleTM[mergeCand] = true; + pu.gpmDmvrRefinePart0 = pu.bdmvrRefine; + PU::spanPuMv2DmvrBuffer(pu, m_mvBufBDMVR4GPM[0], m_mvBufBDMVR4GPM[1]); + } +#endif + if (isGeoTmMCAvail[mergeCand] == 1) + { + geoBlendTmBuffer[mergeCand].copyFrom(geoTmBuffer[mergeCand]); + isGeoBlendTmChromaAvail[mergeCand] = 1; + } + else + { + m_pcInterSearch->motionCompensation(pu, geoBlendTmBuffer[mergeCand], REF_PIC_LIST_X, true, false); + } + +#if JVET_AE0046_BI_GPM + if (pu.bdmvrRefine) + { + pu.bdmvrRefine = false; + pu.gpmDmvrRefinePart0 = pu.bdmvrRefine; + if (isGeoTmMCAvail[mergeCand] == 1) + { + ::memcpy(m_mvBufEncBDOF4TMBlend[mergeCand], m_mvBufEncBDOF4GPM[GEO_TM_SHAPE_AL][mergeCand], sizeof(Mv) * BDOF_SUBPU_MAX_NUM); + } + else + { + ::memcpy(m_mvBufEncBDOF4TMBlend[mergeCand], m_pcInterSearch->getBdofSubPuMvOffset(), sizeof(Mv) * BDOF_SUBPU_MAX_NUM); + } + } +#endif + isGeoTmMCAvail[mergeCand] = 2; + } + } + idxBufGeoTm = idxBlendGeoFirst; + for (int i = 0; i < numGeoBlendTmInfoCand; i++) + { + GeoBlendInfo& geoBI = geoBlendTmInfo[i]; + + pu.cu->blendModel.copy(geoBI.blendModel); + + int mergeCand0 = geoBI.mergeCand[0]; + int mergeCand1 = geoBI.mergeCand[1]; + + PelUnitBuf blendBuffer = m_acMergeBuffer[idxBufGeoTm].getBuf(localUnitArea); + m_pcInterSearch->weightedBlend(pu, blendBuffer, geoBlendTmBuffer[mergeCand0], geoBlendTmBuffer[mergeCand1], false, true, true); + + DistParam& distParamGeo = distParamWholeBlkGeoBlend; // SAD + + distParamGeo.cur.buf = blendBuffer.Y().buf; + distParamGeo.cur.stride = blendBuffer.Y().stride; + Distortion sad = distParamGeo.distFunc(distParamGeo); + + geoBI.sad = sad; // sad bi-prediction geo-blended distortion + geoBI.idxBufGeo = idxBufGeoTm; + } + + for (int idx = 0; idx < numGeoBlendTmInfoCand; idx++) + { +#if JVET_AG0164_AFFINE_GPM + geoBlendCandCost[idx] = geoMergeIdxCost[std::min(idx, numRegularGpmMergeCand - 1)]; +#else + geoBlendCandCost[idx] = geoMergeIdxCost[std::min(idx, maxNumMergeCandidates - 1)]; +#endif + GeoBlendInfo& geoBI = geoBlendTmInfo[idx]; + + geoBI.uiCost = (double)geoBI.sad + geoBlendCandCost[idx] + geoBlendFlagCost[1] + geoTMFlagCost[1]; + + bestEstimGeoBlendTmPredCost = std::min(geoBI.uiCost, bestEstimGeoBlendTmPredCost); + + geoBI.iMergeIdx = idx; + } + + pu.geoBldIdx = 0; + + // encoder re-order with uiCost + for (int i = 0; i < (numGeoBlendTmInfoCand - 1); i++) + { + for (int j = (i + 1); j < numGeoBlendTmInfoCand; j++) + { + if (geoBlendTmInfo[j].uiCost < geoBlendTmInfo[i].uiCost) + { + std::swap(geoBlendTmInfo[i], geoBlendTmInfo[j]); + } + } + } + + bStopRdoLoop = false; + bIsBestCost = false; // current CU-geoBlend is best + tempCS->initStructData(encTestMode.qp); + + for (uint8_t i = 0; i < numGeoBlendTmInfoCand && !bStopRdoLoop; i++) + { + double geoBlendFastRatio = MRG_FAST_RATIO; + double geoBlendFastRatioBest = 1.0; + geoBlendFastRatioBest = 1.25; + if (geoBlendTmInfo[i].uiCost > geoBlendFastRatio * bestEstimGeoBlendTmPredCost || geoBlendTmInfo[i].uiCost > geoBlendFastRatioBest * getMergeBestSATDCost()) + { + continue; + } + + bool geoBlendCandHasNoResidual = false; + for (uint8_t noResidualPass = iterationBegin; noResidualPass < iteration; ++noResidualPass) + { + if (((noResidualPass != 0) && geoBlendCandHasNoResidual) + // || ((noResidualPass == 0) && bestIsSkip) + ) + { + continue; + } + + GeoBlendInfo& geoBI = geoBlendTmInfo[i]; + + PelUnitBuf blendBuffer = m_acMergeBuffer[geoBI.idxBufGeo].getBuf(localUnitArea); + + CodingUnit& cu = tempCS->addCU(tempCS->area, pm.chType); + pm.setCUData(cu); + cu.predMode = MODE_INTER; + cu.slice = tempCS->slice; + cu.tileIdx = tempCS->pps->getTileIdx(tempCS->area.lumaPos()); + cu.qp = encTestMode.qp; + cu.affine = false; + cu.mtsFlag = false; +#if INTER_LIC + cu.licFlag = false; +#if JVET_AH0314_LIC_INHERITANCE_FOR_MRG + cu.licInheritPara = false; +#endif +#endif + cu.bcwIdx = BCW_DEFAULT; + cu.geoBlendFlag = true; + cu.blendModel.copy(geoBI.blendModel); + cu.geoFlag = true; + cu.imv = 0; + cu.mmvdSkip = false; + cu.skip = false; + cu.mipFlag = false; + cu.bdpcmMode = 0; + PredictionUnit& pu = tempCS->addPU(cu, pm.chType); + pu.mergeFlag = true; + pu.regularMergeFlag = false; + pu.geoSplitDir = 0; + pu.geoMergeIdx0 = geoBI.iMergeIdx; + pu.geoMergeIdx1 = geoBI.iMergeIdx; +#if JVET_AG0164_AFFINE_GPM + pu.affineGPM[0] = 0; + pu.affineGPM[1] = 0; +#endif + pu.geoBlendTmFlag = true; +#if JVET_AE0046_BI_GPM + PU::setGpmDirMode(pu); +#endif +#if JVET_Y0065_GPM_INTRA + pu.gpmIntraFlag = false; +#if ENABLE_DIMD + cu.dimdMode = dimdMode; +#endif +#if JVET_W0123_TIMD_FUSION + cu.timdMode = timdMode; +#if JVET_AC0094_REF_SAMPLES_OPT + cu.timdModeCheckWA = timdModeCheckWA; +#endif +#endif +#endif +#if JVET_AA0058_GPM_ADAPTIVE_BLENDING + pu.geoBldIdx = -1; +#endif +#if JVET_Z0056_GPM_SPLIT_MODE_REORDERING + if (sps.getUseAltGPMSplitModeCode()) + { + pu.geoSyntaxMode = 0; + } +#endif +#if TM_MRG + pu.tmMergeFlag = false; + pu.geoTmFlag0 = false; + pu.geoTmFlag1 = false; +#endif + pu.geoMMVDFlag0 = false; + pu.geoMMVDFlag1 = false; + + pu.mmvdMergeFlag = false; + pu.mmvdMergeIdx = MAX_UCHAR; + + if (noResidualPass == iterationBegin) + { + // do chroma (luma has been done yet) + for (int k = 0; k < 2; k++) + { + const int mergeCand = geoBI.mergeCand[k]; + if ((isGeoBlendTmChromaAvail[mergeCand] == 1 && isGeoTmChromaAvail[mergeCand]) || isGeoBlendTmChromaAvail[mergeCand] == 2) + { + continue; + } + geoBlendTmCtx.setMergeInfo(pu, mergeCand); + +#if JVET_AE0046_BI_GPM + if (refinePossibleTM[mergeCand]) + { + pu.bdmvrRefine = true; + PU::spanPuMv2DmvrBuffer(pu, m_mvBufBDMVR4GPM[0], m_mvBufBDMVR4GPM[1]); + ::memcpy(m_pcInterSearch->getBdofSubPuMvOffset(), m_mvBufEncBDOF4TMBlend[mergeCand], sizeof(Mv) * BDOF_SUBPU_MAX_NUM); + m_pcInterSearch->setLumaBdofReady(true); + } +#endif + m_pcInterSearch->motionCompensation(pu, geoBlendTmBuffer[mergeCand], REF_PIC_LIST_X, false, true); + +#if JVET_AE0046_BI_GPM + pu.bdmvrRefine = false; + m_pcInterSearch->setLumaBdofReady(false); +#endif + isGeoBlendTmChromaAvail[mergeCand] = 2; + } + } + +#if JVET_AH0314_LIC_INHERITANCE_FOR_MRG + geoBlendTmCtx.setMergeInfo(pu, geoBI.mergeCand[1]); +#else + geoBlendTmCtx.setMergeInfo(pu, 0); +#endif + + pu.interDir = 3; + pu.mergeIdx = MAX_UCHAR; + pu.geoMergeIdx0 = geoBI.mergeCand[0]; + pu.geoMergeIdx1 = geoBI.mergeCand[1]; + + pu.cu->blendModel.copy(geoBI.blendModel); + + if (noResidualPass == iterationBegin) + { + m_pcInterSearch->weightedBlend(pu, blendBuffer, geoBlendTmBuffer[geoBI.mergeCand[0]], geoBlendTmBuffer[geoBI.mergeCand[1]], false, false, true); // do again luma since OBMC has been applied + } + + int geoMergeIdx0 = geoBI.mergeCand[0]; + int geoMergeIdx1 = geoBI.mergeCand[1]; + + pu.gpmDmvrRefinePart0 = refinePossibleTM[geoMergeIdx0]; + pu.gpmDmvrRefinePart1 = refinePossibleTM[geoMergeIdx1]; + + CHECK(pu.geoTmFlag0 || pu.geoMMVDFlag0 || pu.geoTmFlag1 || pu.geoMMVDFlag1, "spanGeoMMVDMotionInfo() failed"); + + uint8_t intraMPM[2] = { PLANAR_IDX, PLANAR_IDX }; +#if JVET_AG0164_AFFINE_GPM +#if JVET_AI0082_GPM_WITH_INTER_IBC +#if JVET_AJ0274_GPM_AFFINE_TM + PU::spanGeoMMVDMotionInfo(pu, geoBlendTmCtx, affMergeCtx, affTmMergeCtx, geoBlendTmCtx, geoBlendTmCtx, 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, geoBvList, + pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4TMBlend[geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4TMBlend[geoMergeIdx1] : nullptr); +#else + PU::spanGeoMMVDMotionInfo(pu, geoBlendTmCtx, affMergeCtx, geoBlendTmCtx, geoBlendTmCtx, 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, geoBvList, + pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4TMBlend[geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4TMBlend[geoMergeIdx1] : nullptr); +#endif +#else + PU::spanGeoMMVDMotionInfo(pu, geoBlendTmCtx, affMergeCtx, geoBlendTmCtx, geoBlendTmCtx, 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, + pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4TMBlend[geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4TMBlend[geoMergeIdx1] : nullptr); +#endif +#else + PU::spanGeoMMVDMotionInfo(pu, geoBlendTmCtx, geoBlendTmCtx, geoBlendTmCtx, 0, geoMergeIdx0, geoMergeIdx1, pu.geoTmFlag0, pu.geoMMVDFlag0, pu.geoMMVDIdx0, pu.geoTmFlag1, pu.geoMMVDFlag1, pu.geoMMVDIdx1, 0, intraMPM, + pu.gpmDmvrRefinePart0, pu.gpmDmvrRefinePart1, pu.gpmDmvrRefinePart0 ? m_mvBufEncBDOF4GPM[GEO_TM_SHAPE_AL][geoMergeIdx0] : nullptr, pu.gpmDmvrRefinePart1 ? m_mvBufEncBDOF4GPM[GEO_TM_SHAPE_AL][geoMergeIdx1] : nullptr); +#endif + + tempCS->getPredBuf().copyFrom(blendBuffer); + +#if ENABLE_OBMC + if (!pu.gpmIntraFlag) + { + cu.isobmcMC = true; + cu.obmcFlag = true; +#if JVET_AJ0161_OBMC_EXT_WITH_INTRA_PRED + m_pcInterSearch->subBlockOBMC(pu, nullptr, m_pcIntraSearch); +#else + m_pcInterSearch->subBlockOBMC(pu); +#endif + cu.isobmcMC = false; + } +#endif + + pu.mergeIdx = MAX_UCHAR; + pu.geoMergeIdx0 = geoBI.iMergeIdx; + pu.geoMergeIdx1 = MAX_UCHAR; + CHECK(i >= pu.cs->sps->getMaxNumGeoCand(), "geoBlend idx should be < sps->getMaxNumGeoCand()"); + + double lastBestCost = bestCS->cost; + + xEncodeInterResidual(tempCS, bestCS, pm, encTestMode, noResidualPass, (noResidualPass == 0 ? &geoBlendCandHasNoResidual : NULL)); + + if (m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip) + { + bestIsSkip = bestCS->getCU(pm.chType)->rootCbf == 0; + } + tempCS->initStructData(encTestMode.qp); + + bIsBestCost |= lastBestCost > bestCS->cost; + if (!bIsBestCost && (i + 1) >= 2) + { + bStopRdoLoop = true; + } + } // noResidualPass + } // i (numGeoBlendInfoCand) + } + } +#endif + if (m_bestModeUpdated && bestCS->cost != MAX_DOUBLE) { xCalDebCost(*bestCS, pm); diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h index 8f16a4d7074e8f83b4dff429e665bc4c6c121613..ae0e5cff63e62f7adcde06d4cf039a105afea21c 100644 --- a/source/Lib/EncoderLib/EncCu.h +++ b/source/Lib/EncoderLib/EncCu.h @@ -371,6 +371,9 @@ private: #endif FastGeoMMVDCostList m_geoMMVDCostList; bool m_fastGpmMmvdSearch; +#if JVET_AJ0274_GPM_AFFINE_TM + int m_fastGpmAffSearch; +#endif bool m_fastGpmMmvdRelatedCU; bool m_includeMoreMMVDCandFirstPass; int m_maxNumGPMDirFirstPass; @@ -379,6 +382,9 @@ private: PelStorage m_acGeoMergeTmpBuffer[GEO_TM_MAX_NUM_CANDS]; PelStorage m_acGeoSADTmpBuffer[GEO_TM_MAX_NUM_CANDS]; #endif +#endif +#if JVET_AJ0274_REGRESSION_GPM_TM + PelStorage m_acGeoBlendTMBuffer[GEO_TM_MAX_NUM_CANDS]; #endif double m_AFFBestSATDCost; double m_mergeBestSATDCost; @@ -405,6 +411,9 @@ private: #endif Mv m_mvBufEncBDOF[MRG_MAX_NUM_CANDS][BDOF_SUBPU_MAX_NUM]; Mv m_mvBufEncBDOF4TM[MRG_MAX_NUM_CANDS][BDOF_SUBPU_MAX_NUM]; +#if JVET_AJ0274_REGRESSION_GPM_TM + Mv m_mvBufEncBDOF4TMBlend[MRG_MAX_NUM_CANDS][BDOF_SUBPU_MAX_NUM]; +#endif #if JVET_X0049_ADAPT_DMVR #if JVET_AA0093_REFINED_MOTION_FOR_ARMC Mv m_mvBufBDMVR4BM[(BM_MRG_MAX_NUM_INIT_CANDS << 1)<<1][MAX_NUM_SUBCU_DMVR]; diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index c0e5728573c5e154c23a9c52d4eb082707f1b75d..0450da4efcf484a8300309d836a727c4c99b3d9b 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1879,8 +1879,13 @@ void EncLib::xInitSPS( SPS& sps ) sps.setMaxNumIBCMergeCand(getMaxNumIBCMergeCand()); sps.setMaxNumGeoCand(getMaxNumGeoCand()); #if JVET_AG0164_AFFINE_GPM +#if JVET_AJ0274_GPM_AFFINE_TM + sps.setMaxNumGpmAffCand (getMaxNumGpmAffCand()); + sps.setMaxNumGpmAffTmCand (m_intraPeriod == -1 ? (m_sourceWidth * m_sourceHeight >= 1920 * 1080 ? 0 : getMaxNumGpmAffTmCand() - 2) : getMaxNumGpmAffTmCand()); +#else sps.setMaxNumGpmAffCand (((m_sourceWidth * m_sourceHeight) > (m_intraPeriod == -1 ? 1280 * 720 : 0)) ? getMaxNumGpmAffCand() : 0); #endif +#endif #if JVET_Z0127_SPS_MHP_MAX_MRG_CAND sps.setMaxNumMHPCand(getMaxNumMHPCand()); #endif diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index 2a99a0f3db75e27deea79a272361019b8298469e..2c6d16ed975d5ecf6a75fbe9798a774f1501ca7c 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -8351,7 +8351,11 @@ void InterSearch::setGeoSplitModeToSyntaxTable(PredictionUnit& pu, MergeCtx& mer } #if JVET_W0097_GPM_MMVD_TM && TM_MRG +#if JVET_AJ0274_GPM_AFFINE_TM +void InterSearch::setGeoTMSplitModeToSyntaxTable(PredictionUnit& pu, MergeCtx(&mergeCtx)[GEO_NUM_TM_MV_CAND], const AffineMergeCtx& affMergeCtx, int mergeCand0, int mergeCand1, int mmvdCand0, int mmvdCand1) +#else void InterSearch::setGeoTMSplitModeToSyntaxTable(PredictionUnit& pu, MergeCtx(&mergeCtx)[GEO_NUM_TM_MV_CAND], int mergeCand0, int mergeCand1, int mmvdCand0, int mmvdCand1) +#endif { const int idx0 = mmvdCand0 + 1; const int idx1 = mmvdCand1 + 1; @@ -8364,6 +8368,9 @@ void InterSearch::setGeoTMSplitModeToSyntaxTable(PredictionUnit& pu, MergeCtx(&m , m_gpmPartTplCost[idx0][mergeCand0] , m_gpmPartTplCost[idx1][mergeCand1] , mergeCtx +#if JVET_AJ0274_GPM_AFFINE_TM + , affMergeCtx +#endif , mergeCand0 , mergeCand1 , numValidInList @@ -8472,10 +8479,17 @@ bool InterSearch::selectGeoSplitModes(PredictionUnit &pu, } #if JVET_W0097_GPM_MMVD_TM && TM_MRG -bool InterSearch::selectGeoTMSplitModes (PredictionUnit &pu, +#if JVET_AJ0274_GPM_AFFINE_TM +bool InterSearch::selectGeoTMSplitModes (PredictionUnit &pu, + uint32_t (&gpmTplCostPart0)[2][GEO_NUM_PARTITION_MODE], + uint32_t (&gpmTplCostPart1)[2][GEO_NUM_PARTITION_MODE], + MergeCtx (&mergeCtx)[GEO_NUM_TM_MV_CAND], const AffineMergeCtx& affMergeCtx,int mergeCand0, int mergeCand1, uint8_t& numValidInList, uint8_t (&modeList)[GEO_NUM_SIG_PARTMODE]) +#else +bool InterSearch::selectGeoTMSplitModes (PredictionUnit &pu, uint32_t (&gpmTplCostPart0)[2][GEO_NUM_PARTITION_MODE], uint32_t (&gpmTplCostPart1)[2][GEO_NUM_PARTITION_MODE], MergeCtx (&mergeCtx)[GEO_NUM_TM_MV_CAND], int mergeCand0, int mergeCand1, uint8_t& numValidInList, uint8_t (&modeList)[GEO_NUM_SIG_PARTMODE]) +#endif { if (!m_bAMLTemplateAvailabe[0] && !m_bAMLTemplateAvailabe[1]) { @@ -8483,7 +8497,11 @@ bool InterSearch::selectGeoTMSplitModes (PredictionUnit &pu, return false; } +#if JVET_AJ0274_GPM_AFFINE_TM + if (PU::checkRprRefExistingInGpm(pu, mergeCtx[GEO_TM_OFF], mergeCand0, mergeCtx[GEO_TM_OFF], mergeCand1, affMergeCtx)) +#else if (PU::checkRprRefExistingInGpm(pu, mergeCtx[GEO_TM_OFF], mergeCand0, mergeCtx[GEO_TM_OFF], mergeCand1)) +#endif { bool backupTplValid[2] = {m_bAMLTemplateAvailabe[0], m_bAMLTemplateAvailabe[1]}; m_bAMLTemplateAvailabe[0] = false; @@ -8504,15 +8522,25 @@ bool InterSearch::selectGeoTMSplitModes (PredictionUnit &pu, // First partition if (fillRefTplPart0) { +#if JVET_AJ0274_GPM_AFFINE_TM + fillPartGPMRefTemplate<0, false>(pu, mergeCtx[GEO_TM_SHAPE_AL], mergeCand0, -1, pRefTopPart0[GEO_TM_SHAPE_AL], pRefLeftPart0[GEO_TM_SHAPE_AL], &affMergeCtx); + fillPartGPMRefTemplate<0, false>(pu, mergeCtx[GEO_TM_SHAPE_A ], mergeCand0, -1, pRefTopPart0[GEO_TM_SHAPE_A ], pRefLeftPart0[GEO_TM_SHAPE_A ], &affMergeCtx); +#else fillPartGPMRefTemplate<0, false>(pu, mergeCtx[GEO_TM_SHAPE_AL], mergeCand0, -1, pRefTopPart0[GEO_TM_SHAPE_AL], pRefLeftPart0[GEO_TM_SHAPE_AL]); fillPartGPMRefTemplate<0, false>(pu, mergeCtx[GEO_TM_SHAPE_A ], mergeCand0, -1, pRefTopPart0[GEO_TM_SHAPE_A ], pRefLeftPart0[GEO_TM_SHAPE_A ]); +#endif } // Second if (fillRefTplPart1) { +#if JVET_AJ0274_GPM_AFFINE_TM + fillPartGPMRefTemplate<1, false>(pu, mergeCtx[GEO_TM_SHAPE_AL], mergeCand1, -1, pRefTopPart1[GEO_TM_SHAPE_AL], pRefLeftPart1[GEO_TM_SHAPE_AL], &affMergeCtx); + fillPartGPMRefTemplate<1, false>(pu, mergeCtx[GEO_TM_SHAPE_L ], mergeCand1, -1, pRefTopPart1[GEO_TM_SHAPE_L ], pRefLeftPart1[GEO_TM_SHAPE_L ], &affMergeCtx); +#else fillPartGPMRefTemplate<1, false>(pu, mergeCtx[GEO_TM_SHAPE_AL], mergeCand1, -1, pRefTopPart1[GEO_TM_SHAPE_AL], pRefLeftPart1[GEO_TM_SHAPE_AL]); fillPartGPMRefTemplate<1, false>(pu, mergeCtx[GEO_TM_SHAPE_L ], mergeCand1, -1, pRefTopPart1[GEO_TM_SHAPE_L ], pRefLeftPart1[GEO_TM_SHAPE_L ]); +#endif } // Get mode lists diff --git a/source/Lib/EncoderLib/InterSearch.h b/source/Lib/EncoderLib/InterSearch.h index ed5b1b10d60118da84584a0e3e55bc14630e4381..a4cd38d844534d97e2e39373d73424a856fda1cf 100644 --- a/source/Lib/EncoderLib/InterSearch.h +++ b/source/Lib/EncoderLib/InterSearch.h @@ -1368,7 +1368,11 @@ public: #endif , int mmvdCand0 = -1, int mmvdCand1 = -1); // mmvdCandX = -1: regular, 0~GPM_EXT_MMVD_MAX_REFINE_NUM-1: MMVD, >=GPM_EXT_MMVD_MAX_REFINE_NUM: TM #if JVET_W0097_GPM_MMVD_TM && TM_MRG +#if JVET_AJ0274_GPM_AFFINE_TM + void setGeoTMSplitModeToSyntaxTable(PredictionUnit& pu, MergeCtx (&mergeCtx)[GEO_NUM_TM_MV_CAND], const AffineMergeCtx &affMergeCtx, int mergeCand0, int mergeCand1, int mmvdCand0 = -1, int mmvdCand1 = -1); // mmvdCandX = -1: regular, 0~GPM_EXT_MMVD_MAX_REFINE_NUM-1: MMVD, >=GPM_EXT_MMVD_MAX_REFINE_NUM: TM +#else void setGeoTMSplitModeToSyntaxTable(PredictionUnit& pu, MergeCtx (&mergeCtx)[GEO_NUM_TM_MV_CAND], int mergeCand0, int mergeCand1, int mmvdCand0 = -1, int mmvdCand1 = -1); // mmvdCandX = -1: regular, 0~GPM_EXT_MMVD_MAX_REFINE_NUM-1: MMVD, >=GPM_EXT_MMVD_MAX_REFINE_NUM: TM +#endif #endif int convertGeoSplitModeToSyntax(int splitDir, int mergeCand0, int mergeCand1, int mmvdCand0 = -1, int mmvdCand1 = -1); // mmvdCandX = -1: regular, 0~GPM_EXT_MMVD_MAX_REFINE_NUM-1: MMVD, >=GPM_EXT_MMVD_MAX_REFINE_NUM: TM #if JVET_AE0169_BIPREDICTIVE_IBC @@ -1508,10 +1512,17 @@ protected: uint32_t (&gpmTplCostPart0)[2][GEO_NUM_PARTITION_MODE], uint32_t (&gpmTplCostPart1)[2][GEO_NUM_PARTITION_MODE]); #if JVET_W0097_GPM_MMVD_TM && TM_MRG - bool selectGeoTMSplitModes (PredictionUnit &pu, +#if JVET_AJ0274_GPM_AFFINE_TM + bool selectGeoTMSplitModes (PredictionUnit &pu, + uint32_t (&gpmTplCostPart0)[2][GEO_NUM_PARTITION_MODE], + uint32_t (&gpmTplCostPart1)[2][GEO_NUM_PARTITION_MODE], + MergeCtx (&mergeCtx)[GEO_NUM_TM_MV_CAND], const AffineMergeCtx& affMergeCtx, int mergeCand0, int mergeCand1, uint8_t& numValidInList, uint8_t (&modeList)[GEO_NUM_SIG_PARTMODE]); +#else + bool selectGeoTMSplitModes (PredictionUnit &pu, uint32_t (&gpmTplCostPart0)[2][GEO_NUM_PARTITION_MODE], uint32_t (&gpmTplCostPart1)[2][GEO_NUM_PARTITION_MODE], MergeCtx (&mergeCtx)[GEO_NUM_TM_MV_CAND], int mergeCand0, int mergeCand1, uint8_t& numValidInList, uint8_t (&modeList)[GEO_NUM_SIG_PARTMODE]); +#endif void getBestGeoTMModeListEncoder (PredictionUnit &pu, uint8_t& numValidInList, uint8_t (&modeList)[GEO_NUM_SIG_PARTMODE], Pel* (&pRefTopPart0)[GEO_NUM_TM_MV_CAND], Pel* (&pRefLeftPart0)[GEO_NUM_TM_MV_CAND], diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 350d72e713be3ddde1b1462e6d888496d9500830..bdb2d71d23654628a9d1001ee3451c316293773d 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -1708,6 +1708,12 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) { WRITE_UVLC(pcSPS->getMaxNumAffineMergeCand() - pcSPS->getMaxNumGpmAffCand(), "max_num_aff_merge_cand_minus_max_num_gpm_aff_cand"); } +#if JVET_AJ0274_GPM_AFFINE_TM + if (pcSPS->getMaxNumGpmAffCand() > 0) + { + WRITE_UVLC(pcSPS->getMaxNumGpmAffTmCand(), "max_num_gpm_aff_tm_cand"); + } +#endif #endif #if JVET_AA0132_CONFIGURABLE_TM_TOOLS && JVET_W0097_GPM_MMVD_TM && TM_MRG