diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 1ecc7f781fa16c1f0cf67e42c3e6b9db08701c16..0de8de05b38f3aabd28febba61f70e96effa45f0 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -900,6 +900,15 @@ void EncApp::xInitLibCfg() #if JVET_AA0061_IBC_MBVD m_cEncLib.setIbcMbvd ( m_ibcMbvd ); #endif +#if JVET_AC0112_IBC_CIIP + m_cEncLib.setIbcCiip ( m_ibcCiip ); +#endif +#if JVET_AC0112_IBC_GPM + m_cEncLib.setIbcGpm ( m_ibcGpm ); +#endif +#if JVET_AC0112_IBC_LIC + m_cEncLib.setIbcLic ( m_ibcLic ); +#endif m_cEncLib.setUseWrapAround ( m_wrapAround ); m_cEncLib.setWrapAroundOffset ( m_wrapAroundOffset ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index a537445d401df4ef4cc32fe428ec8ecaf2c41f3e..95cace2f3ef91d609a4bb3ae196504e9178a3b45 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1141,6 +1141,15 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) #if JVET_AA0061_IBC_MBVD ("IBCMBVD", m_ibcMbvd, true, "IBC MMVD mode (0:off, 1:on) [default: on]" ) #endif +#if JVET_AC0112_IBC_CIIP + ("IBCCIIP", m_ibcCiip, true, "IBC CIIP mode (0:off, 1:on) [default: on]" ) +#endif +#if JVET_AC0112_IBC_GPM + ("IBCGPM", m_ibcGpm, true, "IBC GPM mode (0:off, 1:on) [default: on]" ) +#endif +#if JVET_AC0112_IBC_LIC + ("IBCLIC", m_ibcLic, true, "IBC LIC mode (0:off, 1:on) [default: on]" ) +#endif ("WrapAround", m_wrapAround, false, "Enable horizontal wrap-around motion compensation for inter prediction (0:off, 1:on) [default: off]") ("WrapAroundOffset", m_wrapAroundOffset, 0u, "Offset in luma samples used for computing the horizontal wrap-around position") @@ -5153,6 +5162,15 @@ void EncAppCfg::xPrintParameter() msg(VERBOSE, "IBC:%d ", m_IBCMode); #if JVET_AA0061_IBC_MBVD msg( VERBOSE, "IBCMBVD:%d ", m_ibcMbvd ); +#endif +#if JVET_AC0112_IBC_CIIP + msg( VERBOSE, "IBCCIIP:%d ", m_ibcCiip); +#endif +#if JVET_AC0112_IBC_GPM + msg( VERBOSE, "IBCGPM:%d ", m_ibcGpm); +#endif +#if JVET_AC0112_IBC_LIC + msg( VERBOSE, "IBCLIC:%d ", m_ibcLic ); #endif msg( VERBOSE, "HashME:%d ", m_HashME ); msg( VERBOSE, "WrapAround:%d ", m_wrapAround); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index b3f1559ad6b8fe10ffc727d36a52fdf9c85f2dbf..fae85801d2a3fa7bd6e96696e55710aad473574c 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -500,6 +500,15 @@ protected: #if JVET_AA0061_IBC_MBVD bool m_ibcMbvd; #endif +#if JVET_AC0112_IBC_CIIP + bool m_ibcCiip; +#endif +#if JVET_AC0112_IBC_GPM + bool m_ibcGpm; +#endif +#if JVET_AC0112_IBC_LIC + bool m_ibcLic; +#endif bool m_wrapAround; unsigned m_wrapAroundOffset; diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index 514903ab8c5c73f3a9fd1706c6a36ab0eb3dc8e8..9bbbae37b9860782e961431b9bd0ac27291b67c1 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -1047,7 +1047,11 @@ static const int GEO_MAX_NUM_UNI_CANDS = 6; #if JVET_Y0065_GPM_INTRA static const int GEO_MAX_NUM_INTRA_CANDS = 3; static const int GEO_NUM_INTRA_RDO_BUFFER = 23; +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM +static const int GEO_NUM_RDO_BUFFER = GEO_MAX_NUM_UNI_CANDS + 67; +#else static const int GEO_NUM_RDO_BUFFER = GEO_MAX_NUM_UNI_CANDS + GEO_NUM_INTRA_RDO_BUFFER; +#endif static const int GEO_MAX_NUM_CANDS = (GEO_MAX_NUM_UNI_CANDS+GEO_MAX_NUM_INTRA_CANDS) * ((GEO_MAX_NUM_UNI_CANDS+GEO_MAX_NUM_INTRA_CANDS) - 1); #else static const int GEO_MAX_NUM_CANDS = GEO_MAX_NUM_UNI_CANDS * (GEO_MAX_NUM_UNI_CANDS - 1); @@ -1150,6 +1154,20 @@ static const int IBC_MBVD_NUM = IBC_MBVD_BASE_NUM * IBC_MBVD_MAX_REFINE_NUM; static const int IBC_MBVD_SIZE_ENC = 8; static const int ADAPTIVE_SUB_GROUP_SIZE_IBC_MBVD = IBC_MBVD_MAX_REFINE_NUM; #endif +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM +static const int IBC_GPM_MAX_NUM_UNI_CANDS = 15; +#endif +#if JVET_AC0112_IBC_CIIP +static const int IBC_CIIP_MAX_NUM_INTRA_CANDS = 2; +#endif +#if JVET_AC0112_IBC_GPM +static const int IBC_GPM_MAX_NUM_INTRA_CANDS = 3; +static const int IBC_GPM_MAX_TRY_WEIGHTED_SAD = 36; +static const int IBC_GPM_MAX_TRY_WEIGHTED_SATD = 20; +static const int IBC_GPM_MAX_SPLIT_DIR_FIRST_SET_NUM = 8; +static const int IBC_GPM_MAX_SPLIT_DIR_SECOND_SET_NUM = 40; +static const int IBC_GPM_NUM_BLENDING = 1; // 1 or 5 +#endif static constexpr int MV_EXPONENT_BITCOUNT = 4; static constexpr int MV_MANTISSA_BITCOUNT = 6; static constexpr int MV_MANTISSA_UPPER_LIMIT = ((1 << (MV_MANTISSA_BITCOUNT - 1)) - 1); diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp index aaf3f2b64bb129cd347295370129cce5497327c5..1ff03737a41e4769938c43cb5d78036c0e7bf947 100644 --- a/source/Lib/CommonLib/ContextModelling.cpp +++ b/source/Lib/CommonLib/ContextModelling.cpp @@ -532,6 +532,9 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx ) pu.addHypData.clear(); pu.numMergedAddHyps = 0; #endif +#if JVET_AC0112_IBC_LIC + pu.cu->ibcLicFlag = ibcLicFlags[candIdx]; +#endif #if JVET_AA0070_RRIBC pu.cu->rribcFlipType = rribcFlipTypes[candIdx]; } @@ -1426,6 +1429,9 @@ bool MergeCtx::setIbcMbvdMergeCandiInfo(PredictionUnit& pu, int candIdx, int can pu.bv = pu.mv[REF_PIC_LIST_0]; pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); // used for only integer resolution pu.cu->imv = pu.cu->imv == IMV_HPEL ? 0 : pu.cu->imv; +#if JVET_AC0112_IBC_LIC + pu.cu->ibcLicFlag = ibcLicFlags[fPosBaseIdx]; +#endif #if JVET_AA0070_RRIBC pu.cu->rribcFlipType = rribcFlipTypes[fPosBaseIdx]; #endif diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h index db3638d8952c44c4f1ee8cfd72bc9fd81dc72df3..2b5c4ec0061402659a9e3d27424a2c0d044764b0 100644 --- a/source/Lib/CommonLib/ContextModelling.h +++ b/source/Lib/CommonLib/ContextModelling.h @@ -561,6 +561,9 @@ public: #if INTER_LIC bool LICFlags[NUM_MERGE_CANDS]; #endif +#if JVET_AC0112_IBC_LIC + bool ibcLicFlags[NUM_MERGE_CANDS]; +#endif #if JVET_AA0070_RRIBC int rribcFlipTypes[NUM_MERGE_CANDS]; #endif @@ -578,6 +581,9 @@ public: #if INTER_LIC bool LICFlags [ MRG_MAX_NUM_CANDS ]; #endif +#if JVET_AC0112_IBC_LIC + bool ibcLicFlags [ MRG_MAX_NUM_CANDS ]; +#endif #if JVET_AA0070_RRIBC int rribcFlipTypes[MRG_MAX_NUM_CANDS]; #endif diff --git a/source/Lib/CommonLib/Contexts.cpp b/source/Lib/CommonLib/Contexts.cpp index 4323ce25f33ca8745c3f26e87230195a75ff15c5..116ce868b66744364b5cdc1a0c4aba523e55f713 100644 --- a/source/Lib/CommonLib/Contexts.cpp +++ b/source/Lib/CommonLib/Contexts.cpp @@ -2877,6 +2877,117 @@ const CtxSet ContextSetCfg::IBCFlag = ContextSetCfg::addCtxSet { 147, 117, 146, }, }); +#if JVET_AC0112_IBC_CIIP +const CtxSet ContextSetCfg::IbcCiipFlag = ContextSetCfg::addCtxSet +({ + { CNU, CNU, CNU, }, + { CNU, CNU, CNU, }, + { CNU, CNU, CNU, }, + { DWS, DWS, DWS, }, + { DWS, DWS, DWS, }, + { DWS, DWS, DWS, }, + { DWE, DWE, DWE, }, + { DWE, DWE, DWE, }, + { DWE, DWE, DWE, }, + { DWO, DWO, DWO, }, + { DWO, DWO, DWO, }, + }); + +const CtxSet ContextSetCfg::IbcCiipIntraIdx = ContextSetCfg::addCtxSet +({ + { CNU, }, + { CNU, }, + { CNU, }, + { DWS, }, + { DWS, }, + { DWS, }, + { DWE, }, + { DWE, }, + { DWE, }, + { DWO, }, + { DWO, }, + }); +#endif + +#if JVET_AC0112_IBC_GPM +const CtxSet ContextSetCfg::IbcGpmFlag = ContextSetCfg::addCtxSet +({ + { CNU, }, + { CNU, }, + { CNU, }, + { DWS, }, + { DWS, }, + { DWS, }, + { DWE, }, + { DWE, }, + { DWE, }, + { DWO, }, + { DWO, }, + }); + +const CtxSet ContextSetCfg::IbcGpmIntraFlag = ContextSetCfg::addCtxSet +({ + { CNU, }, + { CNU, }, + { CNU, }, + { DWS, }, + { DWS, }, + { DWS, }, + { DWE, }, + { DWE, }, + { DWE, }, + { DWO, }, + { DWO, }, + }); + +const CtxSet ContextSetCfg::IbcGpmSplitDirSetFlag = ContextSetCfg::addCtxSet +({ + { CNU, }, + { CNU, }, + { CNU, }, + { DWS, }, + { DWS, }, + { DWS, }, + { DWE, }, + { DWE, }, + { DWE, }, + { DWO, }, + { DWO, }, + }); + +const CtxSet ContextSetCfg::IbcGpmBldIdx = ContextSetCfg::addCtxSet +({ + { CNU, CNU, CNU, CNU }, + { CNU, CNU, CNU, CNU }, + { CNU, CNU, CNU, CNU }, + { DWS, DWS, DWS, DWS }, + { DWS, DWS, DWS, DWS }, + { DWS, DWS, DWS, DWS }, + { DWE, DWE, DWE, DWE }, + { DWE, DWE, DWE, DWE }, + { DWE, DWE, DWE, DWE }, + { DWO, DWO, DWO, DWO }, + { DWO, DWO, DWO, DWO }, +}); +#endif + +#if JVET_AC0112_IBC_LIC +const CtxSet ContextSetCfg::IbcLicFlag = ContextSetCfg::addCtxSet +({ + { CNU, }, + { CNU, }, + { CNU, }, + { DWS, }, + { DWS, }, + { DWS, }, + { DWE, }, + { DWE, }, + { DWE, }, + { DWO, }, + { DWO, }, + }); +#endif + const CtxSet ContextSetCfg::JointCbCrFlag = ContextSetCfg::addCtxSet ({ { 34, 28, 52, }, diff --git a/source/Lib/CommonLib/Contexts.h b/source/Lib/CommonLib/Contexts.h index 273af587963943a9d42f89d37175d0e2efd66fb7..0d7706c399bef38d0d0c4b3ff5cfafa99c0c35aa 100644 --- a/source/Lib/CommonLib/Contexts.h +++ b/source/Lib/CommonLib/Contexts.h @@ -413,6 +413,19 @@ public: static const CtxSet IbcMbvdMergeIdx; static const CtxSet IbcMbvdStepMvpIdx; #endif +#if JVET_AC0112_IBC_CIIP + static const CtxSet IbcCiipFlag; + static const CtxSet IbcCiipIntraIdx; +#endif +#if JVET_AC0112_IBC_GPM + static const CtxSet IbcGpmFlag; + static const CtxSet IbcGpmIntraFlag; + static const CtxSet IbcGpmSplitDirSetFlag; + static const CtxSet IbcGpmBldIdx; +#endif +#if JVET_AC0112_IBC_LIC + static const CtxSet IbcLicFlag; +#endif #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) static const CtxSet TMMergeFlag; diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index d5937ae5dd41fecb3010bad155f777fe778fb0b5..1f166a441f8b97dc13b5b85cbfae29cec848a484 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -2281,6 +2281,25 @@ void InterPrediction::xPredInterBlk ( const ComponentID& compID, const Predictio m_predictionBeforeLIC.bufs[compID].copyFrom( dstBuf ); } +#if JVET_AC0112_IBC_LIC +#if JVET_AC0112_IBC_GPM && JVET_AC0112_IBC_CIIP + if (pu.cu->ibcLicFlag && !pu.ibcCiipFlag && !pu.ibcGpmFlag) +#else +#if JVET_AC0112_IBC_CIIP + if (pu.cu->ibcLicFlag && !pu.ibcCiipFlag) +#else +#if JVET_AC0112_IBC_GPM + if (pu.cu->ibcLicFlag && !pu.ibcGpmFlag) +#else + if (pu.cu->ibcLicFlag) +#endif +#endif +#endif + { + xLocalIlluComp(pu, compID, pu.bv, dstBuf); + } +#endif + #if JVET_W0090_ARMC_TM || JVET_Z0056_GPM_SPLIT_MODE_REORDERING if (pu.cu->LICFlag && (!pu.ciipFlag || doLic)) #else @@ -4024,10 +4043,50 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu { CHECK(!luma, "IBC only for Chroma is not allowed."); xIntraBlockCopy(pu, predBuf, COMPONENT_Y); +#if JVET_AC0112_IBC_LIC +#if JVET_AC0112_IBC_GPM && JVET_AC0112_IBC_CIIP + if (pu.cu->ibcLicFlag && !pu.ibcCiipFlag && !pu.ibcGpmFlag) +#else +#if JVET_AC0112_IBC_CIIP + if (pu.cu->ibcLicFlag && !pu.ibcCiipFlag) +#else +#if JVET_AC0112_IBC_GPM + if (pu.cu->ibcLicFlag && !pu.ibcGpmFlag) +#else + if (pu.cu->ibcLicFlag) +#endif +#endif +#endif + { + PelBuf dstBuf = predBuf.Y(); + xLocalIlluComp(pu, COMPONENT_Y, pu.bv, dstBuf); + } +#endif if (chroma && isChromaEnabled(pu.chromaFormat)) { xIntraBlockCopy(pu, predBuf, COMPONENT_Cb); xIntraBlockCopy(pu, predBuf, COMPONENT_Cr); +#if JVET_AC0112_IBC_LIC +#if JVET_AC0112_IBC_GPM && JVET_AC0112_IBC_CIIP + if (pu.cu->ibcLicFlag && !pu.ibcCiipFlag && !pu.ibcGpmFlag) +#else +#if JVET_AC0112_IBC_CIIP + if (pu.cu->ibcLicFlag && !pu.ibcCiipFlag) +#else +#if JVET_AC0112_IBC_GPM + if (pu.cu->ibcLicFlag && !pu.ibcGpmFlag) +#else + if (pu.cu->ibcLicFlag) +#endif +#endif +#endif + { + PelBuf dstBufCb = predBuf.Cb(); + xLocalIlluComp(pu, COMPONENT_Cb, pu.bv, dstBufCb); + PelBuf dstBufCr = predBuf.Cr(); + xLocalIlluComp(pu, COMPONENT_Cr, pu.bv, dstBufCr); + } +#endif } return; } @@ -5061,6 +5120,182 @@ void InterPrediction::motionCompensationGeo( CodingUnit &cu, MergeCtx &geoMrgCtx } } +#if JVET_AC0112_IBC_GPM +void InterPrediction::motionCompensationIbcGpm( CodingUnit &cu, MergeCtx &ibcGpmMrgCtx, IntraPrediction* pcIntraPred) +{ + if ((int)(cu.firstPU->ibcGpmMergeIdx0)-IBC_GPM_MAX_NUM_UNI_CANDS > 0 || (int)(cu.firstPU->ibcGpmMergeIdx1)-IBC_GPM_MAX_NUM_UNI_CANDS > 0) + { + pcIntraPred->deriveDimdMode(cu.cs->picture->getRecoBuf(cu.Y()), cu.Y(), cu); + cu.timdMode = pcIntraPred->deriveTimdMode(cu.cs->picture->getRecoBuf(cu.Y()), cu.Y(), cu); + } + + const uint8_t splitDir = cu.firstPU->ibcGpmSplitDir; + const uint8_t candIdx0 = cu.firstPU->ibcGpmMergeIdx0; + const uint8_t candIdx1 = cu.firstPU->ibcGpmMergeIdx1; + const uint8_t bldIdx = cu.firstPU->ibcGpmBldIdx; + + for( auto &pu : CU::traversePUs( cu ) ) + { + const UnitArea localUnitArea( cu.cs->area.chromaFormat, Area( 0, 0, pu.lwidth(), pu.lheight() ) ); + PelUnitBuf tmpGeoBuf0 = m_geoPartBuf[0].getBuf( localUnitArea ); + PelUnitBuf tmpGeoBuf1 = m_geoPartBuf[1].getBuf( localUnitArea ); + PelUnitBuf predBuf = cu.cs->getPredBuf( pu ); + const bool luma = cu.Y().valid(); + const bool chroma = isChromaEnabled(cu.chromaFormat) && cu.Cb().valid(); + int orgMergeIdx = pu.mergeIdx; + + bool isIntra0 = candIdx0 >= IBC_GPM_MAX_NUM_UNI_CANDS; + bool isIntra1 = candIdx1 >= IBC_GPM_MAX_NUM_UNI_CANDS; + if (isIntra0) + { + PU::getGeoIntraMPMs(pu, pu.intraMPM, splitDir, g_geoTmShape[0][g_GeoParams[pu.ibcGpmSplitDir][0]]); + pu.intraDir[0] = pu.intraMPM[candIdx0 - IBC_GPM_MAX_NUM_UNI_CANDS]; + pcIntraPred->initIntraPatternChType(cu, pu.Y()); + pcIntraPred->predIntraAng(COMPONENT_Y, tmpGeoBuf0.Y(), pu); + pu.intraDir[0] = DC_IDX; + pu.intraDir[1] = PLANAR_IDX; + if (chroma) + { + pu.intraDir[1] = pu.intraMPM[candIdx0 - IBC_GPM_MAX_NUM_UNI_CANDS]; + pcIntraPred->initIntraPatternChType(cu, pu.Cb()); + pcIntraPred->predIntraAng(COMPONENT_Cb, tmpGeoBuf0.Cb(), pu); + pcIntraPred->initIntraPatternChType(cu, pu.Cr()); + pcIntraPred->predIntraAng(COMPONENT_Cr, tmpGeoBuf0.Cr(), pu); + pu.intraDir[1] = PLANAR_IDX; + } + } + else + { + ibcGpmMrgCtx.setMergeInfo( pu, candIdx0 ); + if (pu.tmMergeFlag) + { + deriveTMMv(pu); + pu.bv = pu.mv[0]; + pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); + } + if (luma && (chroma || !isChromaEnabled(cu.chromaFormat))) + { + motionCompensation(pu, tmpGeoBuf0, REF_PIC_LIST_X, true, true); + } + else + { + motionCompensation(pu, tmpGeoBuf0, REF_PIC_LIST_X, true, chroma); + } + } + + if (isIntra1) + { + PU::getGeoIntraMPMs(pu, pu.intraMPM+GEO_MAX_NUM_INTRA_CANDS, splitDir, g_geoTmShape[1][g_GeoParams[pu.ibcGpmSplitDir][0]]); + pu.intraDir[0] = pu.intraMPM[candIdx1 - IBC_GPM_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS]; + pcIntraPred->initIntraPatternChType(cu, pu.Y()); + pcIntraPred->predIntraAng(COMPONENT_Y, tmpGeoBuf1.Y(), pu); + pu.intraDir[0] = DC_IDX; + pu.intraDir[1] = PLANAR_IDX; + if (chroma) + { + pu.intraDir[1] = pu.intraMPM[candIdx1 - IBC_GPM_MAX_NUM_UNI_CANDS + GEO_MAX_NUM_INTRA_CANDS]; + pcIntraPred->initIntraPatternChType(cu, pu.Cb()); + pcIntraPred->predIntraAng(COMPONENT_Cb, tmpGeoBuf1.Cb(), pu); + pcIntraPred->initIntraPatternChType(cu, pu.Cr()); + pcIntraPred->predIntraAng(COMPONENT_Cr, tmpGeoBuf1.Cr(), pu); + pu.intraDir[1] = PLANAR_IDX; + } + } + else + { + ibcGpmMrgCtx.setMergeInfo( pu, candIdx1 ); + if (pu.tmMergeFlag) + { + deriveTMMv(pu); + pu.bv = pu.mv[0]; + pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); + } + if (luma && (chroma || !isChromaEnabled(cu.chromaFormat))) + { + motionCompensation(pu, tmpGeoBuf1, REF_PIC_LIST_X, true, true); + } + else + { + motionCompensation(pu, tmpGeoBuf1, REF_PIC_LIST_X, true, chroma); + } + } + +#if JVET_AA0058_GPM_ADP_BLD + weightedGeoBlkRounded(pu, splitDir, bldIdx, CHANNEL_TYPE_LUMA, predBuf, tmpGeoBuf0, tmpGeoBuf1); + if (chroma) + { + weightedGeoBlkRounded(pu, splitDir, bldIdx, CHANNEL_TYPE_CHROMA, predBuf, tmpGeoBuf0, tmpGeoBuf1); + } +#else + weightedGeoBlk(pu, splitDir, isChromaEnabled(pu.chromaFormat)? MAX_NUM_CHANNEL_TYPE : CHANNEL_TYPE_LUMA, predBuf, tmpGeoBuf0, tmpGeoBuf1); +#endif + pu.mergeIdx = orgMergeIdx; + ibcGpmMrgCtx.setMergeInfo( pu, pu.mergeIdx ); + if (pu.tmMergeFlag) + { + deriveTMMv(pu); + pu.bv = pu.mv[0]; + pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); + } + pu.intraDir[0] = DC_IDX; + pu.intraDir[1] = PLANAR_IDX; + } +} + +#if JVET_AA0070_RRIBC +void InterPrediction::adjustIbcMergeRribcCand(PredictionUnit &pu, MergeCtx& mrgCtx, uint32_t startPos, uint32_t endPos) +{ + if (mrgCtx.numValidMergeCand <= 1) + { + return; + } + + uint32_t rdCandList[IBC_MRG_MAX_NUM_CANDS_MEM]; + Distortion candCostList[IBC_MRG_MAX_NUM_CANDS_MEM]; + + for (uint32_t i = 0; i < IBC_MRG_MAX_NUM_CANDS_MEM; i++) + { + rdCandList[i] = i; + candCostList[i] = MAX_UINT; + } + + Distortion uiCost; + int candNumNoRribc = 0; + bool noNeedSort = true; + for (uint32_t uiMergeCand = startPos; uiMergeCand < endPos; ++uiMergeCand) + { + uiCost = 0; + if (mrgCtx.mvFieldNeighbours[(uiMergeCand << 1) + 0].mv.hor == 0 && mrgCtx.mvFieldNeighbours[(uiMergeCand << 1) + 0].mv.ver == 0) + { + break; + } + if (candNumNoRribc >= mrgCtx.numValidMergeCand) + { + break; + } + if (mrgCtx.rribcFlipTypes[uiMergeCand] > 0) + { + uiCost = MAX_UINT - 1; + if (noNeedSort && uiMergeCand < mrgCtx.numValidMergeCand) + { + noNeedSort = false; + } + } + else + { + candNumNoRribc++; + uiCost = uiMergeCand; + } + updateCandList(uiMergeCand, uiCost, IBC_MRG_MAX_NUM_CANDS_MEM, rdCandList, candCostList); + } + if (!noNeedSort) + { + updateIBCCandInfo(pu, mrgCtx, rdCandList, startPos, endPos); + } +} +#endif +#endif + #if JVET_Z0056_GPM_SPLIT_MODE_REORDERING #if JVET_W0097_GPM_MMVD_TM && TM_MRG void InterPrediction::getBestGeoTMModeList(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], Pel* (&pRefTopPart1)[GEO_NUM_TM_MV_CAND], Pel* (&pRefLeftPart1)[GEO_NUM_TM_MV_CAND]) @@ -6109,7 +6344,11 @@ bool InterPrediction::xAMLIBCGetCurBlkTemplate(PredictionUnit& pu, int nCurBlkWi return true; } +#if JVET_AC0112_IBC_LIC +void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight, bool doIbcLic) +#else void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight) +#endif { Mv mvCurr; mvCurr = pu.bv; @@ -6119,6 +6358,247 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, const Picture& currPic = *pu.cs->picture; const CPelBuf recBuf = currPic.getRecoBuf(pu.cs->picture->blocks[COMPONENT_Y]); /* std::vector<Pel>& invLUT = m_pcReshape->getInvLUT();*/ +#if JVET_AC0112_IBC_LIC + Pel* refLeftTemplate = m_pcLICRefLeftTemplate; + Pel* refAboveTemplate = m_pcLICRefAboveTemplate; + Pel* recLeftTemplate = m_pcLICRecLeftTemplate; + Pel* recAboveTemplate = m_pcLICRecAboveTemplate; + int numTemplate[2] = { 0 , 0 }; // 0:Above, 1:Left + const int bitDepth = pu.cs->sps->getBitDepth(toChannelType(COMPONENT_Y)); + const int precShift = std::max(0, bitDepth - 12); + const ClpRng& clpRng = pu.cu->cs->slice->clpRng(COMPONENT_Y); + int shift = 0, scale = 0, offset = 0; + Mv mvTop(0, -AML_MERGE_TEMPLATE_SIZE); + Mv mvLeft(-AML_MERGE_TEMPLATE_SIZE, 0); + if (m_bAMLTemplateAvailabe[0]) + { +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 2) + { + mvTop.setVer(nCurBlkHeight); + } +#endif + mvTop += mvCurr; + + MotionInfo miTop; + miTop.mv[0] = Mv(mvTop.hor <<horShift , mvTop.ver<< verShift); + miTop.refIdx[0] = MAX_NUM_REF; + Mv mvTop2(0, -1); + mvTop2 += mvTop; + MotionInfo miTop2; + miTop2.mv[0] = Mv(mvTop2.hor <<horShift , mvTop2.ver<< verShift); + miTop2.refIdx[0] = MAX_NUM_REF; +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 2) + { + if (!PU::checkIsIBCCandidateValid(pu, miTop, true, true)) + { + mvTop.setVer(mvCurr.getVer() + nCurBlkHeight - AML_MERGE_TEMPLATE_SIZE); + } + } + else +#endif + if (!PU::checkIsIBCCandidateValid(pu, miTop, true, true)) + { + mvTop = mvCurr; + } +#if JVET_AA0070_RRIBC + else if (doIbcLic && pu.cu->ibcLicFlag && pu.cu->rribcFlipType == 0 && PU::checkIsIBCCandidateValid(pu, miTop2, true, true)) +#else + else if (doIbcLic && pu.cu->ibcLicFlag && PU::checkIsIBCCandidateValid(pu, miTop2, true, true)) +#endif + { + xGetIbcLicPredBlkTpl<true>(*pu.cu, COMPONENT_Y, recBuf, mvTop, 0, 0, nCurBlkWidth, refAboveTemplate); + const Pel* rec2 = recBuf.bufAt(pu.blocks[COMPONENT_Y].pos().offset(0, -2)); + for (int k = 0; k < nCurBlkWidth; k++) + { + int refVal = refAboveTemplate[k]; + int recVal = rec2[k]; + recVal >>= precShift; + refVal >>= precShift; + refAboveTemplate[k] = refVal; + recAboveTemplate[k] = recVal; + numTemplate[0]++; + } + } + } + if (m_bAMLTemplateAvailabe[1]) + { +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 1) + { + mvLeft.setHor(nCurBlkWidth); + } +#endif + mvLeft += mvCurr; + + MotionInfo miLeft; + miLeft.mv[0] = Mv(mvLeft.hor <<horShift , mvLeft.ver<< verShift); + miLeft.refIdx[0] = MAX_NUM_REF; + Mv mvLeft2(-1, 0); + mvLeft2 += mvLeft; + MotionInfo miLeft2; + miLeft2.mv[0] = Mv(mvLeft2.hor <<horShift , mvLeft2.ver<< verShift); + miLeft2.refIdx[0] = MAX_NUM_REF; +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 1) + { + if (!PU::checkIsIBCCandidateValid(pu, miLeft, true, false)) + { + mvLeft.setHor(mvCurr.getHor() + nCurBlkWidth - AML_MERGE_TEMPLATE_SIZE); + } + } + else +#endif + if (!PU::checkIsIBCCandidateValid(pu, miLeft, true, false)) + { + mvLeft = mvCurr; + } +#if JVET_AA0070_RRIBC + else if (doIbcLic && pu.cu->ibcLicFlag && pu.cu->rribcFlipType == 0 && PU::checkIsIBCCandidateValid(pu, miLeft2, true, false)) +#else + else if (doIbcLic && pu.cu->ibcLicFlag && PU::checkIsIBCCandidateValid(pu, miLeft2, true, false)) +#endif + { + xGetIbcLicPredBlkTpl<false>(*pu.cu, COMPONENT_Y, recBuf, mvLeft, 0, 0, nCurBlkHeight, refLeftTemplate); + const Pel* rec2 = recBuf.bufAt(pu.blocks[COMPONENT_Y].pos().offset(-2, 0)); + for (int k = 0; k < nCurBlkHeight; k++) + { + int refVal = refLeftTemplate[k]; + int recVal = rec2[recBuf.stride * k]; + recVal >>= precShift; + refVal >>= precShift; + refLeftTemplate[k] = refVal; + recLeftTemplate[k] = recVal; + numTemplate[1]++; + } + } + } + if (numTemplate[0] + numTemplate[1] > 0) + { + xGetLICParamGeneral(*pu.cu, COMPONENT_Y, numTemplate, refLeftTemplate, refAboveTemplate, recLeftTemplate, recAboveTemplate, shift, scale, offset); + } + if (m_bAMLTemplateAvailabe[0]) + { + const Pel* rec = recBuf.bufAt(pu.blocks[COMPONENT_Y].pos().offset(mvTop.hor, mvTop.ver)); + PelBuf pcYBuf = PelBuf(m_acYuvRefAMLTemplate[0][0], nCurBlkWidth, AML_MERGE_TEMPLATE_SIZE); + Pel* pcY = pcYBuf.bufAt(0, 0); + if (numTemplate[0] + numTemplate[1] > 0) + { + for (int k = 0; k < nCurBlkWidth; k++) + { + for (int l = 0; l < AML_MERGE_TEMPLATE_SIZE; l++) + { +#if JVET_AA0070_RRIBC + int recVal; + if (pu.cu->rribcFlipType == 0) + { + recVal = rec[k + l * recBuf.stride]; + } + else if (pu.cu->rribcFlipType == 1) + { + recVal = rec[nCurBlkWidth - 1 - k + l * recBuf.stride]; + } + else + { + recVal = rec[k + (AML_MERGE_TEMPLATE_SIZE - 1 - l) * recBuf.stride]; + } +#else + int recVal = rec[k + l * recBuf.stride]; +#endif + pcY[k + l * nCurBlkWidth] = ClipPel(((recVal * scale) >> shift) + offset, clpRng); + } + } + } + else + { + for (int k = 0; k < nCurBlkWidth; k++) + { + for (int l = 0; l < AML_MERGE_TEMPLATE_SIZE; l++) + { +#if JVET_AA0070_RRIBC + int recVal; + if (pu.cu->rribcFlipType == 0) + { + recVal = rec[k + l * recBuf.stride]; + } + else if (pu.cu->rribcFlipType == 1) + { + recVal = rec[nCurBlkWidth - 1 - k + l * recBuf.stride]; + } + else + { + recVal = rec[k + (AML_MERGE_TEMPLATE_SIZE - 1 - l) * recBuf.stride]; + } +#else + int recVal = rec[k + l * recBuf.stride]; +#endif + pcY[k + l * nCurBlkWidth] = recVal; + } + } + } + } + if (m_bAMLTemplateAvailabe[1]) + { + PelBuf pcYBuf = PelBuf(m_acYuvRefAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nCurBlkHeight); + Pel* pcY = pcYBuf.bufAt(0, 0); + const Pel* rec = recBuf.bufAt(pu.blocks[COMPONENT_Y].pos().offset( mvLeft.hor, mvLeft.ver)); + if (numTemplate[0] + numTemplate[1] > 0) + { + for (int k = 0; k < nCurBlkHeight; k++) + { + for (int l = 0; l < AML_MERGE_TEMPLATE_SIZE; l++) + { +#if JVET_AA0070_RRIBC + int recVal; + if (pu.cu->rribcFlipType == 0) + { + recVal = rec[recBuf.stride * k + l]; + } + else if (pu.cu->rribcFlipType == 1) + { + recVal = rec[recBuf.stride * k + AML_MERGE_TEMPLATE_SIZE - 1 - l]; + } + else + { + recVal = rec[recBuf.stride * (nCurBlkHeight - 1 - k) + l]; + } +#else + int recVal = rec[recBuf.stride * k + l]; +#endif + pcY[AML_MERGE_TEMPLATE_SIZE * k + l] = ClipPel(((recVal * scale) >> shift) + offset, clpRng); + } + } + } + else + { + for (int k = 0; k < nCurBlkHeight; k++) + { + for (int l = 0; l < AML_MERGE_TEMPLATE_SIZE; l++) + { +#if JVET_AA0070_RRIBC + int recVal; + if (pu.cu->rribcFlipType == 0) + { + recVal = rec[recBuf.stride * k + l]; + } + else if (pu.cu->rribcFlipType == 1) + { + recVal = rec[recBuf.stride * k + AML_MERGE_TEMPLATE_SIZE - 1 - l]; + } + else + { + recVal = rec[recBuf.stride * (nCurBlkHeight - 1 - k) + l]; + } +#else + int recVal = rec[recBuf.stride * k + l]; +#endif + pcY[AML_MERGE_TEMPLATE_SIZE * k + l] = recVal; + } + } + } + } +#else if (m_bAMLTemplateAvailabe[0]) { Mv mvTop(0, -AML_MERGE_TEMPLATE_SIZE); @@ -6232,6 +6712,7 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, } } } +#endif } #endif @@ -9237,6 +9718,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u #if INTER_LIC mrgCtxTmp.LICFlags[ui] = false; #endif +#if JVET_AC0112_IBC_LIC + mrgCtxTmp.ibcLicFlags[ui] = false; +#endif #if JVET_AA0070_RRIBC mrgCtxTmp.rribcFlipTypes[ui] = 0; #endif @@ -9262,6 +9746,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u #if INTER_LIC mrgCtxTmp.LICFlags[uiMergeCand] = mrgCtx.LICFlags[uiMergeCand]; #endif +#if JVET_AC0112_IBC_LIC + mrgCtxTmp.ibcLicFlags[uiMergeCand] = mrgCtx.ibcLicFlags[uiMergeCand]; +#endif #if JVET_AA0070_RRIBC mrgCtxTmp.rribcFlipTypes[uiMergeCand] = mrgCtx.rribcFlipTypes[uiMergeCand]; #endif @@ -9288,6 +9775,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u #if INTER_LIC mrgCtx.LICFlags[uiMergeCand] = mrgCtxTmp.LICFlags[RdCandList[uiMergeCand / ADAPTIVE_IBC_SUB_GROUP_SIZE][uiMergeCand%ADAPTIVE_IBC_SUB_GROUP_SIZE]]; #endif +#if JVET_AC0112_IBC_LIC + mrgCtx.ibcLicFlags[uiMergeCand] = mrgCtxTmp.ibcLicFlags[RdCandList[uiMergeCand / ADAPTIVE_IBC_SUB_GROUP_SIZE][uiMergeCand%ADAPTIVE_IBC_SUB_GROUP_SIZE]]; +#endif #if JVET_AA0070_RRIBC mrgCtx.rribcFlipTypes[uiMergeCand] = mrgCtxTmp.rribcFlipTypes[RdCandList[uiMergeCand / ADAPTIVE_IBC_SUB_GROUP_SIZE][uiMergeCand % ADAPTIVE_IBC_SUB_GROUP_SIZE]]; #endif @@ -9345,7 +9835,15 @@ void InterPrediction::adjustIBCMergeCandidates(PredictionUnit &pu, MergeCtx& mr PelBuf pcBufPredRefLeft = PelBuf(m_acYuvRefAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight); PelBuf pcBufPredCurLeft = PelBuf(m_acYuvCurAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight); +#if JVET_AC0112_IBC_LIC +#if JVET_AA0061_IBC_MBVD + getIBCAMLRefTemplate(pu, nWidth, nHeight, !pu.ibcMbvdMergeFlag); +#else + getIBCAMLRefTemplate(pu, nWidth, nHeight, true); +#endif +#else getIBCAMLRefTemplate(pu, nWidth, nHeight); +#endif if (m_bAMLTemplateAvailabe[0]) { @@ -9379,6 +9877,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u #if INTER_LIC mrgCtxTmp.LICFlags[ui] = false; #endif +#if JVET_AC0112_IBC_LIC + mrgCtxTmp.ibcLicFlags[ui] = false; +#endif #if JVET_AA0070_RRIBC mrgCtxTmp.rribcFlipTypes[ui] = 0; #endif @@ -9398,6 +9899,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u #if INTER_LIC mrgCtxTmp.LICFlags[uiMergeCand] = mrgCtx.LICFlags[uiMergeCand]; #endif +#if JVET_AC0112_IBC_LIC + mrgCtxTmp.ibcLicFlags[uiMergeCand] = mrgCtx.ibcLicFlags[uiMergeCand]; +#endif #if JVET_AA0070_RRIBC mrgCtxTmp.rribcFlipTypes[uiMergeCand] = mrgCtx.rribcFlipTypes[uiMergeCand]; #endif @@ -9418,6 +9922,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u #if INTER_LIC mrgCtx.LICFlags[uiMergeCand] = mrgCtxTmp.LICFlags[RdCandList[uiMergeCand -startPos]]; #endif +#if JVET_AC0112_IBC_LIC + mrgCtx.ibcLicFlags[uiMergeCand] = mrgCtxTmp.ibcLicFlags[RdCandList[uiMergeCand -startPos]]; +#endif #if JVET_AA0070_RRIBC mrgCtx.rribcFlipTypes[uiMergeCand] = mrgCtxTmp.rribcFlipTypes[RdCandList[uiMergeCand -startPos]]; #endif @@ -10899,7 +11406,9 @@ void InterPrediction::xGetSublkTemplate(const CodingUnit& cu, } } } +#endif +#if INTER_LIC || JVET_AC0112_IBC_LIC void InterPrediction::xGetLICParamGeneral(const CodingUnit& cu, const ComponentID compID, int* numTemplate, @@ -10999,7 +11508,9 @@ void InterPrediction::xGetLICParamGeneral(const CodingUnit& cu, offset = (sumY - ((scale * sumX) >> shift) + ((1 << (cntShift)) >> 1)) >> cntShift; offset = Clip3(minOffset, maxOffset, offset); } +#endif +#if INTER_LIC template <bool trueAfalseL> void InterPrediction::xGetPredBlkTpl(const CodingUnit& cu, const ComponentID compID, const CPelBuf& refBuf, const Mv& mv, const int posW, const int posH, const int tplSize, Pel* predBlkTpl #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED @@ -11082,6 +11593,171 @@ void InterPrediction::xGetPredBlkTpl(const CodingUnit& cu, const ComponentID com } #endif // INTER_LIC +#if JVET_AC0112_IBC_LIC +void InterPrediction::xLocalIlluComp(const PredictionUnit& pu, + const ComponentID compID, + const Mv& bv, + PelBuf& dstBuf +) +{ + Pel* refLeftTemplate = m_pcLICRefLeftTemplate; + Pel* refAboveTemplate = m_pcLICRefAboveTemplate; + Pel* recLeftTemplate = m_pcLICRecLeftTemplate; + Pel* recAboveTemplate = m_pcLICRecAboveTemplate; + int numTemplate[2] = { 0 , 0 }; // 0:Above, 1:Left + xGetSublkTemplate(*pu.cu, compID, bv, pu.blocks[compID].width, pu.blocks[compID].height, 0, 0, numTemplate, refLeftTemplate, refAboveTemplate, recLeftTemplate, recAboveTemplate); + + int shift = 0, scale = 0, offset = 0; + xGetLICParamGeneral(*pu.cu, compID, numTemplate, refLeftTemplate, refAboveTemplate, recLeftTemplate, recAboveTemplate, shift, scale, offset); + + const ClpRng& clpRng = pu.cu->cs->slice->clpRng(compID); + dstBuf.linearTransform(scale, shift, offset, true, clpRng); +} + +void InterPrediction::xGetSublkTemplate(const CodingUnit& cu, + const ComponentID compID, + const Mv& bv, + const int sublkWidth, + const int sublkHeight, + const int posW, + const int posH, + int* numTemplate, + Pel* refLeftTemplate, + Pel* refAboveTemplate, + Pel* recLeftTemplate, + Pel* recAboveTemplate + ) +{ + const int bitDepth = cu.cs->sps->getBitDepth(toChannelType(compID)); + const int precShift = std::max(0, bitDepth - 12); + const int shiftSampleHor = ::getComponentScaleX(compID, cu.chromaFormat); + const int shiftSampleVer = ::getComponentScaleY(compID, cu.chromaFormat); + Mv _bv = bv; + if( isChroma(compID) ) + { + _bv.hor = (bv.hor >> shiftSampleHor); + _bv.ver = (bv.ver >> shiftSampleVer); + } + + const Picture& currPic = *cu.cs->picture; + const CodingUnit* const cuAbove = cu.cs->getCU(cu.blocks[compID].pos().offset(0, -1), toChannelType(compID)); + const CodingUnit* const cuLeft = cu.cs->getCU(cu.blocks[compID].pos().offset(-1, 0), toChannelType(compID)); + const CPelBuf recBuf = cuAbove || cuLeft ? currPic.getRecoBuf(cu.cs->picture->blocks[compID]) : CPelBuf(); + const CPelBuf refBuf = cuAbove || cuLeft ? currPic.getRecoBuf(cu.cs->picture->blocks[compID]) : CPelBuf(); + + // above + const int lumaShift = 2 + MV_FRACTIONAL_BITS_DIFF; + if (cuAbove && posH == 0) + { + Mv mvTop(0, -(1 << shiftSampleVer)); + mvTop += bv; + MotionInfo miTop; + miTop.mv[0] = Mv(mvTop.hor << lumaShift, mvTop.ver << lumaShift); + miTop.refIdx[0] = MAX_NUM_REF; + bool refBvValid = false; + if (PU::checkIsIBCCandidateValid(*cu.firstPU, miTop, true, true)) + { + refBvValid = true; + } + if (refBvValid) + { + xGetIbcLicPredBlkTpl<true>(cu, compID, refBuf, _bv, posW, posH, sublkWidth, refAboveTemplate); + const Pel* rec = recBuf.bufAt(cu.blocks[compID].pos().offset(0, -1)); + + for (int k = posW; k < posW + sublkWidth; k++) + { + int refVal = refAboveTemplate[k]; + int recVal = rec[k]; + + recVal >>= precShift; + refVal >>= precShift; + + refAboveTemplate[k] = refVal; + recAboveTemplate[k] = recVal; + numTemplate[0]++; + } + } + } + + // left + if (cuLeft && posW == 0) + { + Mv mvLeft(-(1 << shiftSampleHor), 0); + mvLeft += bv; + MotionInfo miLeft; + miLeft.mv[0] = Mv(mvLeft.hor << lumaShift, mvLeft.ver << lumaShift); + miLeft.refIdx[0] = MAX_NUM_REF; + bool refBvValid = false; + if (PU::checkIsIBCCandidateValid(*cu.firstPU, miLeft, true, false)) + { + refBvValid = true; + } + if (refBvValid) + { + xGetIbcLicPredBlkTpl<false>(cu, compID, refBuf, _bv, posW, posH, sublkHeight, refLeftTemplate); + const Pel* rec = recBuf.bufAt(cu.blocks[compID].pos().offset(-1, 0)); + + for (int k = posH; k < posH + sublkHeight; k++) + { + int refVal = refLeftTemplate[k]; + int recVal = rec[recBuf.stride * k]; + + recVal >>= precShift; + refVal >>= precShift; + + refLeftTemplate[k] = refVal; + recLeftTemplate[k] = recVal; + numTemplate[1]++; + } + } + } +} + +template <bool trueAfalseL> +void InterPrediction::xGetIbcLicPredBlkTpl(const CodingUnit& cu, const ComponentID compID, const CPelBuf& refBuf, const Mv& mv, const int posW, const int posH, const int tplSize, Pel* predBlkTpl + ) +{ + const int xInt = mv.getHor(); + const int yInt = mv.getVer(); + const int xFrac = 0; + const int yFrac = 0; + + const Pel* ref; + Pel* dst; + int refStride, dstStride, bw, bh; + if( trueAfalseL ) + { + ref = refBuf.bufAt(cu.blocks[compID].pos().offset(xInt + posW, yInt + posH - 1)); + dst = predBlkTpl + posW; + refStride = refBuf.stride; + dstStride = tplSize; + bw = tplSize; + bh = 1; + } + else + { + ref = refBuf.bufAt(cu.blocks[compID].pos().offset(xInt + posW - 1, yInt + posH)); + dst = predBlkTpl + posH; + refStride = refBuf.stride; + dstStride = 1; + bw = 1; + bh = tplSize; + } + + const int nFilterIdx = 0; + const bool useAltHpelIf = false; + + if ( yFrac == 0 ) + { + m_if.filterHor( compID, (Pel*) ref, refStride, dst, dstStride, bw, bh, xFrac, true, cu.chromaFormat, cu.slice->clpRng(compID), nFilterIdx, false, useAltHpelIf); + } + else if ( xFrac == 0 ) + { + m_if.filterVer( compID, (Pel*) ref, refStride, dst, dstStride, bw, bh, yFrac, true, true, cu.chromaFormat, cu.slice->clpRng(compID), nFilterIdx, false, useAltHpelIf); + } +} +#endif // IBC_LIC + #if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM Distortion InterPrediction::deriveTMMv(const PredictionUnit& pu, bool fillCurTpl, Distortion curBestCost, RefPicList eRefList, int refIdx, int maxSearchRounds, Mv& mv, const MvField* otherMvf) { diff --git a/source/Lib/CommonLib/InterPrediction.h b/source/Lib/CommonLib/InterPrediction.h index 10ef63187eef3d5e18db4adaec81d0d920d61b80..099f5754e618b17b396941086bb717fff85a76cf 100644 --- a/source/Lib/CommonLib/InterPrediction.h +++ b/source/Lib/CommonLib/InterPrediction.h @@ -551,8 +551,12 @@ public: #endif #if JVET_AA0061_IBC_MBVD || (JVET_W0090_ARMC_TM && JVET_Y0058_IBC_LIST_MODIFY) bool xAMLIBCGetCurBlkTemplate(PredictionUnit& pu, int nCurBlkWidth, int nCurBlkHeight); +#if JVET_AC0112_IBC_LIC + void getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight, bool doIbcLic = false); +#else void getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, int nCurBlkHeight); #endif +#endif #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED #if JVET_Z0054_BLK_REF_PIC_REORDER void deriveMVDcand(const PredictionUnit& pu, RefPicList eRefPicList, std::vector<Mv>& cMvdCandList); @@ -689,6 +693,12 @@ public: void updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, uint32_t* RdCandList, uint32_t startPos,uint32_t endPos); #endif #endif +#if JVET_AC0112_IBC_GPM + void motionCompensationIbcGpm(CodingUnit &cu, MergeCtx &ibcGpmMrgCtx, IntraPrediction* pcIntraPred); +#if JVET_AA0070_RRIBC + void adjustIbcMergeRribcCand(PredictionUnit &pu, MergeCtx& mrgCtx, uint32_t startPos, uint32_t endPos); +#endif +#endif #if JVET_Z0056_GPM_SPLIT_MODE_REORDERING template <uint8_t partIdx, bool useDefaultPelBuffer = true> @@ -727,8 +737,10 @@ public: fillPartGPMRefTemplate<partIdx, useDefaultPelBuffer>(pu, bufTop, bufLeft); } #endif -#if INTER_LIC +#if INTER_LIC || JVET_AC0112_IBC_LIC void xGetLICParamGeneral (const CodingUnit& cu, const ComponentID compID, int* numTemplate, Pel* refLeftTemplate, Pel* refAboveTemplate, Pel* recLeftTemplate, Pel* recAboveTemplate, int& shift, int& scale, int& offset); +#endif +#if INTER_LIC #if JVET_AA0146_WRAP_AROUND_FIX void xGetSublkTemplate (const CodingUnit& cu, const ComponentID compID, const Picture& refPic, const Mv& mv, const int sublkWidth, const int sublkHeight, const int posW, const int posH, int* numTemplate, Pel* refLeftTemplate, Pel* refAboveTemplate, Pel* recLeftTemplate, Pel* recAboveTemplate, bool wrapRef = false); void xLocalIlluComp (const PredictionUnit& pu, const ComponentID compID, const Picture& refPic, const Mv& mv, const bool biPred, PelBuf& dstBuf, bool wrapRef = false); @@ -745,6 +757,13 @@ public: ); #endif +#if JVET_AC0112_IBC_LIC + void xGetSublkTemplate (const CodingUnit& cu, const ComponentID compID, const Mv& bv, const int sublkWidth, const int sublkHeight, const int posW, const int posH, int* numTemplate, Pel* refLeftTemplate, Pel* refAboveTemplate, Pel* recLeftTemplate, Pel* recAboveTemplate); + void xLocalIlluComp (const PredictionUnit& pu, const ComponentID compID, const Mv& bv, PelBuf& dstBuf); + template <bool trueAfalseL> + void xGetIbcLicPredBlkTpl(const CodingUnit& cu, const ComponentID compID, const CPelBuf& refBuf, const Mv& mv, const int posW, const int posH, const int tplSize, Pel* predBlkTpl); +#endif + #if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) #if JVET_AA0093_REFINED_MOTION_FOR_ARMC diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index 73492398d58b4d258b13a8dbe125d3e8fc8521c7..3e0eb3ea0cdbf8a2c38f45ed71c06a692516172e 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -336,6 +336,9 @@ void IntraPrediction::init(ChromaFormat chromaFormatIDC, const unsigned bitDepth #if JVET_W0123_TIMD_FUSION && INTRA_TRANS_ENC_OPT m_timdBlending = timdBlending; #endif +#if JVET_AC0112_IBC_CIIP && INTRA_TRANS_ENC_OPT + m_ibcCiipBlending = ibcCiipBlending; +#endif #if JVET_V0130_INTRA_TMP unsigned int blkSize; if( m_pppTarPatch == NULL ) @@ -966,6 +969,18 @@ void IntraPrediction::predIntraAng( const ComponentID compId, PelBuf &piPred, co int weightMode = ((pu.cu->timd && pu.cu->timdIsBlended) || !applyFusion) ? 4 : 3; #else int weightMode = ((pu.cu->timd && pu.cu->timdIsBlended) || !applyFusion || (PU::isSgpm(pu, CHANNEL_TYPE_LUMA))) ? 4 : 3; +#endif +#if JVET_AC0112_IBC_CIIP + if (pu.ibcCiipFlag) + { + weightMode = 4; + } +#endif +#if JVET_AC0112_IBC_GPM + if (pu.ibcGpmFlag) + { + weightMode = 4; + } #endif xPredIntraAng(srcBuf, piPred, channelType, clpRng, bExtIntraDir, srcBuf2nd, pu.cu->ispMode != NOT_INTRA_SUBPARTITIONS, weightMode); break; @@ -2729,9 +2744,44 @@ void IntraPrediction::geneWeightedPred( const ComponentID compId, PelBuf& pred, #endif } +#if JVET_AC0112_IBC_CIIP +void IntraPrediction::geneWeightedPred( const ComponentID compId, PelBuf& pred, const PredictionUnit &pu, const PelBuf& interPred, const PelBuf& intraPred) +{ + const int width = pred.width; + const int height = pred.height; + const Pel* interPredBuf = interPred.buf; + const int interPredStride = interPred.stride; + Pel* intraPredBuf = intraPred.buf; + const int intraPredStride = intraPred.stride; + const int dstStride = pred.stride; + Pel* dstBuf = pred.buf; + int wMerge = 13; + int wIntra = 3; + int shift = 4; + if (!pu.mergeFlag) + { + wMerge = 1; + wIntra = 1; + shift = 1; + } + if (width < 4) + { + ibcCiipBlending(dstBuf, dstStride, interPredBuf, interPredStride, intraPredBuf, intraPredStride, wMerge, wIntra, shift, width, height); + } + else + { + m_ibcCiipBlending(dstBuf, dstStride, interPredBuf, interPredStride, intraPredBuf, intraPredStride, wMerge, wIntra, shift, width, height); + } +} +#endif + void IntraPrediction::geneIntrainterPred(const CodingUnit &cu, PelStorage& pred) { +#if JVET_AC0112_IBC_CIIP + if (!cu.firstPU->ciipFlag && !cu.firstPU->ibcCiipFlag) +#else if (!cu.firstPU->ciipFlag) +#endif { return; } @@ -2743,6 +2793,17 @@ void IntraPrediction::geneIntrainterPred(const CodingUnit &cu, PelStorage& pred) const UnitArea localUnitArea(pu->cs->area.chromaFormat, Area(0, 0, pu->Y().width, pu->Y().height)); PelBuf ciipBuff = pred.getBuf(localUnitArea.Y()); predIntraAng(COMPONENT_Y, ciipBuff, *pu); +#if JVET_AC0112_IBC_CIIP +#if INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS + const bool chroma = !(CS::isDualITree(*pu->cs)); +#else + const bool chroma = !pu.cu->isSepTree(); +#endif + if (cu.firstPU->ibcCiipFlag && !chroma) + { + return; + } +#endif if (isChromaEnabled(pu->chromaFormat)) { @@ -2853,6 +2914,12 @@ void IntraPrediction::initIntraPatternChType(const CodingUnit &cu, const CompAre m_ipaParam.fetchRef2nd &= !(cu.dimd && cu.dimdBlending); m_ipaParam.fetchRef2nd &= !(mrlIndex2D == MULTI_REF_LINE_IDX[MRL_NUM_REF_LINES - 1] && ((cu.block(COMPONENT_Y).y) % ((cu.cs->sps)->getMaxCUWidth()) <= MULTI_REF_LINE_IDX[MRL_NUM_REF_LINES - 1])); m_ipaParam.fetchRef2nd &= !(mrlIndex2D == 0 && ((cu.block(COMPONENT_Y).y) % ((cu.cs->sps)->getMaxCUWidth()) == 0)); +#if JVET_AC0112_IBC_CIIP + m_ipaParam.fetchRef2nd &= !cu.firstPU->ibcCiipFlag; +#endif +#if JVET_AC0112_IBC_GPM + m_ipaParam.fetchRef2nd &= !cu.firstPU->ibcGpmFlag; +#endif #endif if (!forceRefFilterFlag) @@ -5521,6 +5588,28 @@ void IntraPrediction::timdBlending(Pel *pDst, int strideDst, Pel *pSrc, int stri #endif #endif +#if JVET_AC0112_IBC_CIIP +void IntraPrediction::ibcCiipBlending(Pel *pDst, int strideDst, const Pel *pSrc0, int strideSrc0, Pel *pSrc1, int strideSrc1, int w0, int w1, int shift, int width, int height) +{ + Pel *pelPred = pDst; + const Pel *pelPlanar = pSrc0; + Pel *pelPredAng = pSrc1; + int offset = 1 << (shift - 1); + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int blend = pelPlanar[x] * w0; + blend += pelPredAng[x] * w1; + pelPred[x] = (Pel)((blend + offset) >> shift); + } + pelPred += strideDst; + pelPlanar += strideSrc0; + pelPredAng += strideSrc1; + } +} +#endif + #if ENABLE_DIMD void IntraPrediction::deriveDimdMode(const CPelBuf &recoBuf, const CompArea &area, CodingUnit &cu) { @@ -10404,7 +10493,11 @@ void IntraPrediction::getTmrlSearchRange(const PredictionUnit& pu, int8_t* tmrlR } } // left (Inter) +#if JVET_AC0112_IBC_CIIP + if (puLeft && (CU::isInter(*puLeft->cu) || CU::isIBC(*puLeft->cu))) +#else if (puLeft && CU::isInter(*puLeft->cu)) +#endif { tmrlIntraList[sizeMode] = puLeft->getIpmInfo(posL); if (!includedMode[tmrlIntraList[sizeMode]]) @@ -10413,7 +10506,11 @@ void IntraPrediction::getTmrlSearchRange(const PredictionUnit& pu, int8_t* tmrlR } } // above (Inter) +#if JVET_AC0112_IBC_CIIP + if (puAbove && (CU::isInter(*puAbove->cu) || CU::isIBC(*puAbove->cu))) +#else if (puAbove && CU::isInter(*puAbove->cu)) +#endif { tmrlIntraList[sizeMode] = puAbove->getIpmInfo(posA); if (!includedMode[tmrlIntraList[sizeMode]]) @@ -10467,7 +10564,11 @@ void IntraPrediction::getTmrlSearchRange(const PredictionUnit& pu, int8_t* tmrlR } // above left (Inter) +#if JVET_AC0112_IBC_CIIP + if (puAboveLeft && (CU::isInter(*puAboveLeft->cu) || CU::isIBC(*puAboveLeft->cu))) +#else if (puAboveLeft && CU::isInter(*puAboveLeft->cu)) +#endif { tmrlIntraList[sizeMode] = puAboveLeft->getIpmInfo(posAL); if (!includedMode[tmrlIntraList[sizeMode]]) @@ -10477,7 +10578,11 @@ void IntraPrediction::getTmrlSearchRange(const PredictionUnit& pu, int8_t* tmrlR } // left bottom (Inter) +#if JVET_AC0112_IBC_CIIP + if (puLeftBottom && (CU::isInter(*puLeftBottom->cu) || CU::isIBC(*puLeftBottom->cu))) +#else if (puLeftBottom && CU::isInter(*puLeftBottom->cu)) +#endif { tmrlIntraList[sizeMode] = puLeftBottom->getIpmInfo(posLB); if (!includedMode[tmrlIntraList[sizeMode]]) @@ -10487,7 +10592,11 @@ void IntraPrediction::getTmrlSearchRange(const PredictionUnit& pu, int8_t* tmrlR } // above right (Inter) +#if JVET_AC0112_IBC_CIIP + if (puAboveRight && (CU::isInter(*puAboveRight->cu) || CU::isIBC(*puAboveRight->cu))) +#else if (puAboveRight && CU::isInter(*puAboveRight->cu)) +#endif { tmrlIntraList[sizeMode] = puAboveRight->getIpmInfo(posAR); if (!includedMode[tmrlIntraList[sizeMode]]) diff --git a/source/Lib/CommonLib/IntraPrediction.h b/source/Lib/CommonLib/IntraPrediction.h index 96c332be4621d9d50b007c54654a2d198fbd308b..dcbef1761b998c504894beaadc4f252bbbb05312 100644 --- a/source/Lib/CommonLib/IntraPrediction.h +++ b/source/Lib/CommonLib/IntraPrediction.h @@ -317,10 +317,12 @@ protected: #else void xPredIntraAng ( const CPelBuf &pSrc, PelBuf &pDst, const ChannelType channelType, const ClpRng& clpRng); #endif +#if !(JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM) #if JVET_AB0155_SGPM void initPredIntraParams(const PredictionUnit &pu, const CompArea compArea, const SPS &sps, const int partIdx = 0); #else void initPredIntraParams ( const PredictionUnit & pu, const CompArea compArea, const SPS& sps ); +#endif #endif static bool isIntegerSlope(const int absAng) { return (0 == (absAng & 0x1F)); } @@ -510,6 +512,13 @@ public: #endif /// set parameters from CU data for accessing intra data +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM +#if JVET_AB0155_SGPM + void initPredIntraParams(const PredictionUnit &pu, const CompArea compArea, const SPS &sps, const int partIdx = 0); +#else + void initPredIntraParams ( const PredictionUnit & pu, const CompArea compArea, const SPS& sps ); +#endif +#endif #if JVET_AB0155_SGPM void initIntraPatternChType(const CodingUnit &cu, const CompArea &area, const bool forceRefFilterFlag = false, const int partIdx = 0 @@ -539,6 +548,11 @@ public: void geneIntrainterPred (const CodingUnit &cu, PelStorage& pred); #if JVET_Z0050_DIMD_CHROMA_FUSION void geneChromaFusionPred (const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu); +#endif +#if JVET_AC0112_IBC_CIIP + void geneWeightedPred ( const ComponentID compId, PelBuf& pred, const PredictionUnit &pu, const PelBuf& interPred, const PelBuf& intraPred); + void(*m_ibcCiipBlending) ( Pel *pDst, int strideDst, const Pel *pSrc0, int strideSrc0, Pel *pSrc1, int strideSrc1, int w0, int w1, int shift, int width, int height ); + static void ibcCiipBlending ( Pel *pDst, int strideDst, const Pel *pSrc0, int strideSrc0, Pel *pSrc1, int strideSrc1, int w0, int w1, int shift, int width, int height ); #endif void reorderPLT (CodingStructure& cs, Partitioner& partitioner, ComponentID compBegin, uint32_t numComp); #if !MERGE_ENC_OPT diff --git a/source/Lib/CommonLib/MotionInfo.h b/source/Lib/CommonLib/MotionInfo.h index ab4595ae0de29bc8c4ea714c03f2cc856c055753..4fe3a2cc334ca2d394f71f8bbfbc91a06462889b 100644 --- a/source/Lib/CommonLib/MotionInfo.h +++ b/source/Lib/CommonLib/MotionInfo.h @@ -176,6 +176,9 @@ struct MotionInfo #if INTER_LIC bool usesLIC; #endif +#if JVET_AC0112_IBC_LIC + bool useIbcLic; +#endif #if JVET_AA0070_RRIBC int rribcFlipType; Position centerPos; diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp index e48999df884d0478bf08ff2beb7a3c644658f693..19805abed8c3d5f12be97f7818de395cd1c51628 100644 --- a/source/Lib/CommonLib/Rom.cpp +++ b/source/Lib/CommonLib/Rom.cpp @@ -5437,4 +5437,27 @@ const int8_t g_glmPattern[NUM_GLM_PATTERN][6] = #endif }; #endif +#if JVET_AC0112_IBC_GPM +const int8_t g_ibcGpmFirstSetSplitDirToIdx[GEO_NUM_PARTITION_MODE] = { +0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,2,3,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,4,5,0,0, +0,0,0,0,0,0,0,0, +0,0,6,7,0,0,0,0, +0,0,0,0,0,0,0,0 +}; +const int8_t g_ibcGpmFirstSetSplitDir[IBC_GPM_MAX_SPLIT_DIR_FIRST_SET_NUM] = {0, 1, 18, 19, 36, 37, 50, 51}; +const int8_t g_ibcGpmSecondSetSplitDir[GEO_NUM_PARTITION_MODE] = { +0,0,1,1,0,1,1,1, +0,1,1,1,0,1,1,1, +0,1,0,0,1,1,0,1, +1,1,0,1,1,1,0,1, +1,1,0,1,0,0,1,0, +1,1,0,1,1,0,1,1, +0,1,0,0,1,0,1,1, +0,1,1,0,1,1,0,1 +}; +#endif //! \} diff --git a/source/Lib/CommonLib/Rom.h b/source/Lib/CommonLib/Rom.h index ad83eea26461b138a12b4b2fd2db7b86ee4180ed..d6d0bf97cdb75e7f5c852da950bba55bbbb15106 100644 --- a/source/Lib/CommonLib/Rom.h +++ b/source/Lib/CommonLib/Rom.h @@ -398,5 +398,10 @@ extern int g_rmvfMultApproxTbl[3 << sizeof(int64_t)]; #if JVET_AA0126_GLM extern const int8_t g_glmPattern[NUM_GLM_PATTERN][6]; #endif +#if JVET_AC0112_IBC_GPM +extern const int8_t g_ibcGpmFirstSetSplitDirToIdx[GEO_NUM_PARTITION_MODE]; +extern const int8_t g_ibcGpmFirstSetSplitDir[IBC_GPM_MAX_SPLIT_DIR_FIRST_SET_NUM]; +extern const int8_t g_ibcGpmSecondSetSplitDir[GEO_NUM_PARTITION_MODE]; +#endif #endif //__TCOMROM__ diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 4c61ba0096d8e72b381252e9f29ef9225ebe53d2..e2eab4150831654411a6a161f7e5e7c24869355e 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -3590,6 +3590,15 @@ SPS::SPS() #if JVET_AA0061_IBC_MBVD , m_ibcMbvd ( false ) #endif +#if JVET_AC0112_IBC_CIIP + , m_ibcCiip ( false ) +#endif +#if JVET_AC0112_IBC_GPM + , m_ibcGpm ( false ) +#endif +#if JVET_AC0112_IBC_LIC + , m_ibcLic ( false ) +#endif #if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM || MULTI_PASS_DMVR , m_DMVDMode ( false ) #endif diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 27de480ca42497a2e08eaf0be98209e4fe34f239..3173e436cce291f44abb8b384569e23cca223e2e 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1530,6 +1530,15 @@ private: #if JVET_AA0061_IBC_MBVD bool m_ibcMbvd; #endif +#if JVET_AC0112_IBC_CIIP + bool m_ibcCiip; +#endif +#if JVET_AC0112_IBC_GPM + bool m_ibcGpm; +#endif +#if JVET_AC0112_IBC_LIC + bool m_ibcLic; +#endif #if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM || MULTI_PASS_DMVR bool m_DMVDMode; #endif @@ -2056,6 +2065,18 @@ void setCCALFEnabledFlag( bool b ) void setUseIbcMbvd(bool b) { m_ibcMbvd = b; } bool getUseIbcMbvd() const { return m_ibcMbvd; } #endif +#if JVET_AC0112_IBC_CIIP + void setUseIbcCiip(bool b) { m_ibcCiip = b; } + bool getUseIbcCiip() const { return m_ibcCiip; } +#endif +#if JVET_AC0112_IBC_GPM + void setUseIbcGpm(bool b) { m_ibcGpm = b; } + bool getUseIbcGpm() const { return m_ibcGpm; } +#endif +#if JVET_AC0112_IBC_LIC + void setUseIbcLic(bool b) { m_ibcLic = b; } + bool getUseIbcLic() const { return m_ibcLic; } +#endif #if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM || MULTI_PASS_DMVR void setUseDMVDMode(bool b) { m_DMVDMode = b; } bool getUseDMVDMode() const { return m_DMVDMode; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index bbfec32d3485547f865d34b4625d4a55d749d318..49147eb747e9e9e918fdaaa58a146334f90afa95 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -175,6 +175,9 @@ #define JVET_AA0106_IBCBUF_CTU256 1 // JVET-AA0106: Adjust IBC reference area to 2*128 rows above the current CTU #define JVET_AA0061_IBC_MBVD 1 // JVET-AA0061: IBC merge mode with block vector differences #define JVET_AA0070_RRIBC 1 // JVET-AA0070: Reconstruction-Reordered IBC +#define JVET_AC0112_IBC_CIIP 1 // JVET-AC0112: Combined IBC and intra prediction (IBC-CIIP) +#define JVET_AC0112_IBC_GPM 1 // JVET-AC0112: IBC with geometry partitioning mode (IBC-GPM) +#define JVET_AC0112_IBC_LIC 1 // JVET-AC0112: IBC with local illumination compensation (IBC-LIC) // Inter #define CIIP_PDPC 1 // Apply pdpc to megre prediction as a new CIIP mode (CIIP_PDPC) additional to CIIP mode diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index 3f2d00b06d4ffe1126cfbfe6ea490e3070d19b40..91f75776c71193fd8b9f6419ddf7d6360ecfa5a0 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -352,6 +352,9 @@ CodingUnit& CodingUnit::operator=( const CodingUnit& other ) #if INTER_LIC LICFlag = other.LICFlag; #endif +#if JVET_AC0112_IBC_LIC + ibcLicFlag = other.ibcLicFlag; +#endif #if JVET_AA0070_RRIBC rribcFlipType = other.rribcFlipType; #endif @@ -490,6 +493,9 @@ void CodingUnit::initData() #if INTER_LIC LICFlag = false; #endif +#if JVET_AC0112_IBC_LIC + ibcLicFlag = false; +#endif #if JVET_AA0070_RRIBC rribcFlipType = 0; #endif @@ -801,6 +807,13 @@ void PredictionUnit::initData() #if JVET_AA0093_REFINED_MOTION_FOR_ARMC reduceTplSize = false; #endif +#if JVET_AC0112_IBC_GPM + ibcGpmFlag = false; + ibcGpmSplitDir = MAX_UCHAR; + ibcGpmMergeIdx0 = MAX_UCHAR; + ibcGpmMergeIdx1 = MAX_UCHAR; + ibcGpmBldIdx = MAX_UCHAR; +#endif #if JVET_Z0054_BLK_REF_PIC_REORDER refIdxLC = -1; @@ -831,6 +844,10 @@ void PredictionUnit::initData() ciipFlag = false; #if CIIP_PDPC ciipPDPC = false; +#endif +#if JVET_AC0112_IBC_CIIP + ibcCiipFlag = false; + ibcCiipIntraIdx = 0; #endif mmvdEncOptMode = 0; #if MULTI_HYP_PRED @@ -939,6 +956,13 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData) #if JVET_AA0093_REFINED_MOTION_FOR_ARMC reduceTplSize = predData.reduceTplSize; #endif +#if JVET_AC0112_IBC_GPM + ibcGpmFlag = predData.ibcGpmFlag; + ibcGpmSplitDir = predData.ibcGpmSplitDir; + ibcGpmMergeIdx0 = predData.ibcGpmMergeIdx0; + ibcGpmMergeIdx1 = predData.ibcGpmMergeIdx1; + ibcGpmBldIdx = predData.ibcGpmBldIdx; +#endif for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) { @@ -970,6 +994,10 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData) #if CIIP_PDPC ciipPDPC = predData.ciipPDPC; #endif +#if JVET_AC0112_IBC_CIIP + ibcCiipFlag = predData.ibcCiipFlag; + ibcCiipIntraIdx = predData.ibcCiipIntraIdx; +#endif #if MULTI_HYP_PRED addHypData = predData.addHypData; numMergedAddHyps = predData.numMergedAddHyps; @@ -1073,6 +1101,13 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other ) #if JVET_AA0093_REFINED_MOTION_FOR_ARMC reduceTplSize = other.reduceTplSize; #endif +#if JVET_AC0112_IBC_GPM + ibcGpmFlag = other.ibcGpmFlag; + ibcGpmSplitDir = other.ibcGpmSplitDir; + ibcGpmMergeIdx0 = other.ibcGpmMergeIdx0; + ibcGpmMergeIdx1 = other.ibcGpmMergeIdx1; + ibcGpmBldIdx = other.ibcGpmBldIdx; +#endif for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) { @@ -1104,6 +1139,10 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other ) #if CIIP_PDPC ciipPDPC = other.ciipPDPC; #endif +#if JVET_AC0112_IBC_CIIP + ibcCiipFlag = other.ibcCiipFlag; + ibcCiipIntraIdx = other.ibcCiipIntraIdx; +#endif #if MULTI_HYP_PRED addHypData = other.addHypData; numMergedAddHyps = other.numMergedAddHyps; diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index f953b73293c673f4ee84c1613fe1ef635036dfb1..18be8cd365eb7c4802bb6e85d465fa8801e2d1a6 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -386,6 +386,9 @@ struct CodingUnit : public UnitArea #if INTER_LIC bool LICFlag; #endif +#if JVET_AC0112_IBC_LIC + bool ibcLicFlag; +#endif #if JVET_AA0070_RRIBC int rribcFlipType; #endif @@ -526,6 +529,17 @@ struct InterPredictionData bool ibcMbvdMergeFlag; int ibcMbvdMergeIdx; #endif +#if JVET_AC0112_IBC_CIIP + bool ibcCiipFlag; + int ibcCiipIntraIdx; +#endif +#if JVET_AC0112_IBC_GPM + bool ibcGpmFlag; + uint8_t ibcGpmSplitDir; + uint8_t ibcGpmMergeIdx0; + uint8_t ibcGpmMergeIdx1; + uint8_t ibcGpmBldIdx; +#endif #if AFFINE_MMVD bool afMmvdFlag; uint8_t afMmvdBaseIdx; // base vector's merge index at the affine merge list, excluding sbTmvp diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 3dede761adb5658efb8e19097529aa8ab3f96b79..757acf84656932d78dbf6b131478f6d192152b6e 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -877,7 +877,11 @@ int PU::getIntraMPMs(const PredictionUnit &pu, unsigned* mpm, const ChannelType #if SECONDARY_MPM #if JVET_W0123_TIMD_FUSION +#if JVET_AC0112_IBC_CIIP + if (puLeft && (CU::isInter(*puLeft->cu) || CU::isIBC(*puLeft->cu))) +#else if (puLeft && CU::isInter(*puLeft->cu)) +#endif { mpm[numValidMPM] = puLeft->getIpmInfo(pu.lheight() >= pu.lwidth() ? posRT.offset(0, -1) : posLB.offset(-1, 0)); if( !includedMode[mpm[numValidMPM]] ) @@ -885,7 +889,11 @@ int PU::getIntraMPMs(const PredictionUnit &pu, unsigned* mpm, const ChannelType includedMode[mpm[numValidMPM++]] = true; } } +#if JVET_AC0112_IBC_CIIP + if (puAbove && (CU::isInter(*puAbove->cu) || CU::isIBC(*puAbove->cu))) +#else if (puAbove && CU::isInter(*puAbove->cu)) +#endif { mpm[numValidMPM] = puAbove->getIpmInfo(pu.lheight() >= pu.lwidth() ? posLB.offset(-1, 0) : posRT.offset(0, -1)); if( !includedMode[mpm[numValidMPM]] ) @@ -940,7 +948,11 @@ int PU::getIntraMPMs(const PredictionUnit &pu, unsigned* mpm, const ChannelType } } #if JVET_W0123_TIMD_FUSION +#if JVET_AC0112_IBC_CIIP + if (puBelowLeft && (CU::isInter(*puBelowLeft->cu) || CU::isIBC(*puBelowLeft->cu))) +#else if (puBelowLeft && CU::isInter(*puBelowLeft->cu)) +#endif { mpm[numValidMPM] = puBelowLeft->getIpmInfo(posLB.offset(-1, 1)); if( !includedMode[mpm[numValidMPM]] ) @@ -948,7 +960,11 @@ int PU::getIntraMPMs(const PredictionUnit &pu, unsigned* mpm, const ChannelType includedMode[mpm[numValidMPM++]] = true; } } +#if JVET_AC0112_IBC_CIIP + if (puAboveRight && (CU::isInter(*puAboveRight->cu) || CU::isIBC(*puAboveRight->cu))) +#else if (puAboveRight && CU::isInter(*puAboveRight->cu)) +#endif { mpm[numValidMPM] = puAboveRight->getIpmInfo(posRT.offset(1, -1)); if( !includedMode[mpm[numValidMPM]] ) @@ -956,7 +972,11 @@ int PU::getIntraMPMs(const PredictionUnit &pu, unsigned* mpm, const ChannelType includedMode[mpm[numValidMPM++]] = true; } } +#if JVET_AC0112_IBC_CIIP + if (puAboveLeft && (CU::isInter(*puAboveLeft->cu) || CU::isIBC(*puAboveLeft->cu))) +#else if (puAboveLeft && CU::isInter(*puAboveLeft->cu)) +#endif { mpm[numValidMPM] = puAboveLeft->getIpmInfo(posTL.offset(-1, -1)); if( !includedMode[mpm[numValidMPM]] ) @@ -1636,7 +1656,11 @@ void PU::getSgpmIntraMPMs(const PredictionUnit &pu, uint8_t *mpm, uint8_t splitD if (shape == GEO_TM_SHAPE_L || shape == GEO_TM_SHAPE_AL) { const PredictionUnit *puLeft = pu.cs->getPURestricted(posL, pu, CHANNEL_TYPE_LUMA); +#if JVET_AC0112_IBC_CIIP + if (puLeft && (CU::isInter(*puLeft->cu) || CU::isIBC(*puLeft->cu))) +#else if (puLeft && CU::isInter(*puLeft->cu)) +#endif { mpm[numValidMPM] = puLeft->getIpmInfo(posL); if (!includedMode[mpm[numValidMPM]]) @@ -1653,7 +1677,11 @@ void PU::getSgpmIntraMPMs(const PredictionUnit &pu, uint8_t *mpm, uint8_t splitD if (shape == GEO_TM_SHAPE_A || shape == GEO_TM_SHAPE_AL) { const PredictionUnit *puAbove = pu.cs->getPURestricted(posA, pu, CHANNEL_TYPE_LUMA); +#if JVET_AC0112_IBC_CIIP + if (puAbove && (CU::isInter(*puAbove->cu) || CU::isIBC(*puAbove->cu))) +#else if (puAbove && CU::isInter(*puAbove->cu)) +#endif { mpm[numValidMPM] = puAbove->getIpmInfo(posA); if (!includedMode[mpm[numValidMPM]]) @@ -1737,7 +1765,11 @@ void PU::getSgpmIntraMPMs(const PredictionUnit &pu, uint8_t *mpm, uint8_t splitD if (shape == GEO_TM_SHAPE_L || shape == GEO_TM_SHAPE_AL) { const PredictionUnit *puBelowLeft = pu.cs->getPURestricted(posBL, pu, CHANNEL_TYPE_LUMA); +#if JVET_AC0112_IBC_CIIP + if (puBelowLeft && (CU::isInter(*puBelowLeft->cu) || CU::isIBC(*puBelowLeft->cu))) +#else if (puBelowLeft && CU::isInter(*puBelowLeft->cu)) +#endif { mpm[numValidMPM] = puBelowLeft->getIpmInfo(posBL); if (!includedMode[mpm[numValidMPM]]) @@ -1754,7 +1786,11 @@ void PU::getSgpmIntraMPMs(const PredictionUnit &pu, uint8_t *mpm, uint8_t splitD if (shape == GEO_TM_SHAPE_A || shape == GEO_TM_SHAPE_AL) { const PredictionUnit *puAboveRight = pu.cs->getPURestricted(posAR, pu, CHANNEL_TYPE_LUMA); +#if JVET_AC0112_IBC_CIIP + if (puAboveRight && (CU::isInter(*puAboveRight->cu) || CU::isIBC(*puAboveRight->cu))) +#else if (puAboveRight && CU::isInter(*puAboveRight->cu)) +#endif { mpm[numValidMPM] = puAboveRight->getIpmInfo(posAR); if (!includedMode[mpm[numValidMPM]]) @@ -1770,7 +1806,11 @@ void PU::getSgpmIntraMPMs(const PredictionUnit &pu, uint8_t *mpm, uint8_t splitD { const PredictionUnit *puAboveLeft = pu.cs->getPURestricted(posAL, pu, CHANNEL_TYPE_LUMA); +#if JVET_AC0112_IBC_CIIP + if (puAboveLeft && (CU::isInter(*puAboveLeft->cu) || CU::isIBC(*puAboveLeft->cu))) +#else if (puAboveLeft && CU::isInter(*puAboveLeft->cu)) +#endif { mpm[numValidMPM] = puAboveLeft->getIpmInfo(posAL); if (!includedMode[mpm[numValidMPM]]) @@ -2407,6 +2447,13 @@ bool PU::addMergeHMVPCand(const CodingStructure &cs, MergeCtx &mrgCtx, const int CHECK(mrgCtx.LICFlags[cnt], "addMergeHMVPCand: LIC is not used with IBC mode") } #endif +#endif +#if JVET_AC0112_IBC_LIC +#if JVET_AA0070_RRIBC + mrgCtx.ibcLicFlags [cnt] = mrgCtx.rribcFlipTypes[cnt] ? false : miNeighbor.useIbcLic; +#else + mrgCtx.ibcLicFlags [cnt] = miNeighbor.useIbcLic; +#endif #endif mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miNeighbor.mv[0], miNeighbor.refIdx[0]); @@ -2684,6 +2731,9 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const #if INTER_LIC mrgCtx.LICFlags[ui] = false; #endif +#if JVET_AC0112_IBC_LIC + mrgCtx.ibcLicFlags[ui] =false; +#endif #if JVET_AA0070_RRIBC mrgCtx.rribcFlipTypes[ui] = 0; #endif @@ -2744,6 +2794,13 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const mrgCtx.rribcFlipTypes[cnt] = miLeft.isIBCmot ? miLeft.rribcFlipType : 0; #endif #endif +#endif +#if JVET_AC0112_IBC_LIC +#if JVET_AA0070_RRIBC + mrgCtx.ibcLicFlags[cnt] = miLeft.isIBCmot && mrgCtx.rribcFlipTypes[cnt] == 0 ? miLeft.useIbcLic : false; +#else + mrgCtx.ibcLicFlags[cnt] = miLeft.isIBCmot? miLeft.useIbcLic : false; +#endif #endif if (mrgCandIdx == cnt) { @@ -2801,6 +2858,13 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const #endif #endif #endif +#if JVET_AC0112_IBC_LIC +#if JVET_AA0070_RRIBC + mrgCtx.ibcLicFlags[cnt] = miAbove.isIBCmot && mrgCtx.rribcFlipTypes[cnt] == 0 ? miAbove.useIbcLic : false; +#else + mrgCtx.ibcLicFlags[cnt] = miAbove.isIBCmot ? miAbove.useIbcLic : false; +#endif +#endif #if JVET_Z0084_IBC_TM if( !mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) ) @@ -2863,6 +2927,13 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const #endif #endif #endif +#if JVET_AC0112_IBC_LIC +#if JVET_AA0070_RRIBC + mrgCtx.ibcLicFlags[cnt] = miAboveRight.isIBCmot && mrgCtx.rribcFlipTypes[cnt] == 0 ? miAboveRight.useIbcLic : false; +#else + mrgCtx.ibcLicFlags[cnt] = miAboveRight.isIBCmot? miAboveRight.useIbcLic : false; +#endif +#endif #if JVET_Z0084_IBC_TM if( !mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) ) @@ -2921,6 +2992,13 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const #endif #endif #endif +#if JVET_AC0112_IBC_LIC +#if JVET_AA0070_RRIBC + mrgCtx.ibcLicFlags[cnt] = miBelowLeft.isIBCmot && mrgCtx.rribcFlipTypes[cnt] == 0 ? miBelowLeft.useIbcLic : false; +#else + mrgCtx.ibcLicFlags[cnt] = miBelowLeft.isIBCmot ? miBelowLeft.useIbcLic : false; +#endif +#endif #if JVET_Z0084_IBC_TM if( !mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) ) @@ -2989,6 +3067,13 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const #endif #endif #endif +#if JVET_AC0112_IBC_LIC +#if JVET_AA0070_RRIBC + mrgCtx.ibcLicFlags[cnt] = miAboveLeft.isIBCmot && mrgCtx.rribcFlipTypes[cnt] == 0 ? miAboveLeft.useIbcLic : false; +#else + mrgCtx.ibcLicFlags[cnt] = miAboveLeft.isIBCmot ? miAboveLeft.useIbcLic : false; +#endif +#endif #if JVET_Z0084_IBC_TM if( !mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) ) @@ -3183,6 +3268,9 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const miCand.mv[0] = mvp; mrgCtx.mvFieldNeighbours[cnt * 2].setMvField(mvp, MAX_NUM_REF); mrgCtx.interDirNeighbours[cnt] = 1; +#if JVET_AC0112_IBC_LIC + mrgCtx.ibcLicFlags[cnt] = false; +#endif #if JVET_AA0070_RRIBC mrgCtx.rribcFlipTypes[cnt] = 0; #endif @@ -3207,6 +3295,9 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const { mrgCtx.interDirNeighbours[cnt] = 1; mrgCtx.mvFieldNeighbours[cnt * 2].setMvField(Mv(0, 0), MAX_NUM_REF); +#if JVET_AC0112_IBC_LIC + mrgCtx.ibcLicFlags[cnt] = false; +#endif #if JVET_AA0070_RRIBC mrgCtx.rribcFlipTypes[cnt] = 0; #endif @@ -3627,6 +3718,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, #if INTER_LIC mrgCtx.LICFlags[ui] = false; #endif +#if JVET_AC0112_IBC_LIC + mrgCtx.ibcLicFlags[ui] = false; +#endif #if JVET_AA0070_RRIBC mrgCtx.rribcFlipTypes[ui] = 0; #endif @@ -12673,6 +12767,9 @@ void PU::spanMotionInfo( PredictionUnit &pu, const MergeCtx &mrgCtx ) #if INTER_LIC mi.usesLIC = pu.cu->LICFlag; #endif +#if JVET_AC0112_IBC_LIC + mi.useIbcLic = mi.isIBCmot ? pu.cu->ibcLicFlag : 0; +#endif #if JVET_AA0070_RRIBC mi.rribcFlipType = mi.isIBCmot ? pu.cu->rribcFlipType : 0; #endif @@ -12760,6 +12857,13 @@ void PU::spanMotionInfo( PredictionUnit &pu, const MergeCtx &mrgCtx ) #endif ) { +#if JVET_AC0112_IBC_CIIP + if (mi.isIBCmot) + { + spanIpmInfoIBC(pu, ib, mi.bv.getHor(), mi.bv.getVer()); + } + else +#endif ib.fill(PLANAR_IDX); } else @@ -14314,6 +14418,36 @@ void PU::spanGeoMMVDMotionInfo( PredictionUnit &pu, MergeCtx &geoMrgCtx, const u spanIpmInfoInter( pu, mb, ib ); #endif } + +#if JVET_AC0112_IBC_CIIP +void PU::spanIpmInfoIBC( PredictionUnit &pu, IpmBuf &ib, int bvx, int bvy ) +{ + uint8_t* ii = ib.buf; + int ibH = ib.height; + int ibW = ib.width; + const unsigned scale = 4 * std::max<int>(1, 4 * AMVP_DECIMATION_FACTOR / 4); + const unsigned mask = ~(scale - 1); + Position PosY; + PosY.x = pu.Y().x + bvx; + PosY.y = pu.Y().y + bvy; + PosY.x = (PosY.x & mask); + PosY.y = (PosY.y & mask); + CodingStructure *cs = pu.cs; + while (cs != NULL && !cs->area.Y().contains(PosY)) + { + cs = cs->parent; + } + const uint8_t ipm = cs->getIpmInfo(PosY); + for (int y = 0; y < ibH; y++) + { + for (int x = 0; x < ibW; x++) + { + ii[x] = ipm; + } + ii += ib.stride; + } +} +#endif #endif #if JVET_Z0054_BLK_REF_PIC_REORDER @@ -15698,4 +15832,4 @@ bool CU::isDirectionalPlanarAvailable(const CodingUnit &cu) return false; } -#endif \ No newline at end of file +#endif diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 69be809784e319d7d92d8786ea6521fcee990b92..90182f6fde82a2af4c428dd3d1450ed73d28b852 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -364,6 +364,9 @@ namespace PU #endif void spanIpmInfoIntra ( PredictionUnit &pu ); void spanIpmInfoInter ( PredictionUnit &pu, MotionBuf &mb, IpmBuf &ib ); +#if JVET_AC0112_IBC_CIIP + void spanIpmInfoIBC ( PredictionUnit &pu, IpmBuf &ib, int bvx, int bvy ); +#endif #endif #if JVET_AB0155_SGPM void spanIpmInfoSgpm ( PredictionUnit &pu); @@ -798,6 +801,77 @@ uint32_t updateGeoMMVDCandList(double uiCost, int splitDir, int mergeCand0, int return 0; } +#if JVET_AC0112_IBC_GPM +template<size_t N> +uint32_t updateGeoIbcCandList(double uiCost, int splitDir, int mergeCand0, int mergeCand1, int mmvdCand0, int mmvdCand1, + static_vector<double, N>& candCostList, static_vector<int, N>& geoSplitDirList, static_vector<int, N>& geoMergeCand0, static_vector<int, N>& geoMergeCand1, size_t uiFastCandNum) +{ + size_t i; + size_t shift = 0; + size_t currSize = std::min(uiFastCandNum, candCostList.size()); + + while (shift < uiFastCandNum && shift < currSize && uiCost < candCostList[currSize - 1 - shift]) + { + shift++; + } + + if (candCostList.size() >= uiFastCandNum && shift != 0) + { + for (i = 1; i < shift; i++) + { + geoSplitDirList[currSize - i] = geoSplitDirList[currSize - 1 - i]; + geoMergeCand0[currSize - i] = geoMergeCand0[currSize - 1 - i]; + geoMergeCand1[currSize - i] = geoMergeCand1[currSize - 1 - i]; + candCostList[currSize - i] = candCostList[currSize - 1 - i]; + } + geoSplitDirList[currSize - shift] = splitDir; + geoMergeCand0[currSize - shift] = mergeCand0; + geoMergeCand1[currSize - shift] = mergeCand1; + candCostList[currSize - shift] = uiCost; + return 1; + } + else if (currSize < uiFastCandNum) + { + geoSplitDirList.insert(geoSplitDirList.end() - shift, splitDir); + geoMergeCand0.insert(geoMergeCand0.end() - shift, mergeCand0); + geoMergeCand1.insert(geoMergeCand1.end() - shift, mergeCand1); + candCostList.insert(candCostList.end() - shift, uiCost); + return 1; + } + return 0; +} + +template<size_t N> +void sortCandList(double uiCost, int mergeCand, static_vector<double, N>& candCostList, static_vector<int, N>& mergeCandList, int fastCandNum) +{ + size_t i; + size_t shift = 0; + size_t currSize = candCostList.size(); + CHECK(currSize > fastCandNum, "list overflow!"); + + while (shift < currSize && uiCost < candCostList[currSize - 1 - shift]) + { + shift++; + } + + if (currSize == fastCandNum && shift != 0) + { + for (i = 1; i < shift; i++) + { + mergeCandList[currSize - i] = mergeCandList[currSize - 1 - i]; + candCostList[currSize - i] = candCostList[currSize - 1 - i]; + } + mergeCandList[currSize - shift] = mergeCand; + candCostList[currSize - shift] = uiCost; + } + else if (currSize < fastCandNum) + { + mergeCandList.insert(mergeCandList.end() - shift, mergeCand); + candCostList.insert(candCostList.end() - shift, uiCost); + } +} +#endif + template<size_t N> void sortCandList(double uiCost, int mergeCand, int mmvdCand, static_vector<double, N>& candCostList, static_vector<int, N>& mergeCandList, static_vector<int, N>& mmvdCandList, int fastCandNum) { diff --git a/source/Lib/CommonLib/x86/IntraX86.h b/source/Lib/CommonLib/x86/IntraX86.h index faba4e217ceffe34c12dcc0d901b02246e6f2f79..a8950ba493e7c89fa8e8ce66b4518c4e73465f09 100644 --- a/source/Lib/CommonLib/x86/IntraX86.h +++ b/source/Lib/CommonLib/x86/IntraX86.h @@ -369,6 +369,74 @@ void timdBlendingSIMD( Pel *pDst, int strideDst, Pel *pSrc, int strideSrc, int w } #endif +#if JVET_AC0112_IBC_CIIP && INTRA_TRANS_ENC_OPT +template< X86_VEXT vext > +void ibcCiipBlendingSIMD( Pel *pDst, int strideDst, const Pel *pSrc0, int strideSrc0, Pel *pSrc1, int strideSrc1, int w0, int w1, int shift, int width, int height ) +{ +#if USE_AVX2 + if ((vext >= AVX2) && (width & 0x7) == 0) + { + const int offset = 1 << (shift - 1); + __m256i mw = _mm256_unpacklo_epi16(_mm256_set1_epi16(w0), _mm256_set1_epi16(w1)); + __m256i voffset = _mm256_set1_epi32(offset); + __m256i msrc0, msrc1, msum0, msum1; + + for (int row = 0; row < height; row++) + { + for (int col = 0; col < width; col += 8) + { + msrc0 = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i*)(&pSrc0[col]))); + msrc1 = _mm256_castsi128_si256(_mm_lddqu_si128((__m128i*)(&pSrc1[col]))); + msum0 = _mm256_unpacklo_epi16(msrc0, msrc1); + msum1 = _mm256_unpackhi_epi16(msrc0, msrc1); + msum0 = _mm256_madd_epi16(msum0, mw); + msum1 = _mm256_madd_epi16(msum1, mw); + msum0 = _mm256_add_epi32(msum0, voffset); + msum1 = _mm256_add_epi32(msum1, voffset); + msum0 = _mm256_srai_epi32(msum0, shift); + msum1 = _mm256_srai_epi32(msum1, shift); + msum0 = _mm256_packs_epi32(msum0, msum1); + _mm_storeu_si128((__m128i *)&pDst[col], _mm256_castsi256_si128(msum0)); + } + pSrc0 += strideSrc0; + pSrc1 += strideSrc1; + pDst += strideDst; + } + } + else + { +#endif + __m128i vw0 = _mm_set1_epi32( w0 ); + __m128i vw1 = _mm_set1_epi32( w1 ); + const int offset = 1 << (shift - 1); + __m128i voffset = _mm_set1_epi32( offset ); + + for( int i = 0; i < height; i++ ) + { + for( int j = 0; j < width; j += 4 ) + { + __m128i vdst = _mm_cvtepi16_epi32( _mm_loadl_epi64( (__m128i*)(pDst + j) ) ); + __m128i vsrc0 = _mm_cvtepi16_epi32( _mm_loadl_epi64( (__m128i*)(pSrc0 + j) ) ); + __m128i vsrc1 = _mm_cvtepi16_epi32( _mm_loadl_epi64( (__m128i*)(pSrc1 + j) ) ); + + vdst = _mm_mullo_epi32( vsrc0, vw0 ); + vdst = _mm_add_epi32( vdst, _mm_mullo_epi32( vsrc1, vw1 ) ); + + vdst = _mm_add_epi32( vdst, voffset ); + vdst = _mm_srai_epi32( vdst, shift ); + vdst = _mm_packs_epi32( vdst, vdst ); + _mm_storel_epi64( (__m128i*)(pDst + j), vdst ); + } + pDst += strideDst; + pSrc0 += strideSrc0; + pSrc1 += strideSrc1; + } +#if USE_AVX2 + } +#endif +} +#endif + template <X86_VEXT vext> void IntraPrediction::_initIntraX86() { @@ -381,6 +449,9 @@ void IntraPrediction::_initIntraX86() #if JVET_W0123_TIMD_FUSION && INTRA_TRANS_ENC_OPT m_timdBlending = timdBlendingSIMD<vext>; #endif +#if JVET_AC0112_IBC_CIIP && INTRA_TRANS_ENC_OPT + m_ibcCiipBlending = ibcCiipBlendingSIMD<vext>; +#endif } template void IntraPrediction::_initIntraX86<SIMDX86>(); diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 097e405266432c6a48fba951322c2c2c8f940654..df750f2b1b61636319ffeba9a548bc661d66f87a 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -3217,6 +3217,9 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx ) #if JVET_AA0070_RRIBC rribcData(*pu.cu); #endif +#if JVET_AC0112_IBC_LIC + cuIbcLicFlag(*pu.cu); +#endif if( pu.mergeFlag ) { @@ -3231,6 +3234,13 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx ) } else if (CU::isIBC(*pu.cu)) { +#if JVET_AC0112_IBC_CIIP + ibcCiipFlag(pu); + if (pu.ibcCiipFlag) + { + ibcCiipIntraIdx(pu); + } +#endif pu.interDir = 1; pu.cu->affine = false; pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF; @@ -3816,6 +3826,204 @@ void CABACReader::tm_merge_flag(PredictionUnit& pu) } #endif +#if JVET_AC0112_IBC_CIIP +void CABACReader::ibcCiipFlag(PredictionUnit& pu) +{ + if (!pu.cs->sps->getUseIbcCiip() || ( pu.lx() == 0 && pu.ly() == 0)) + { + pu.ibcCiipFlag = false; + return; + } + if (pu.lwidth() * pu.lheight() < 32 || pu.lwidth() > 32 || pu.lheight() > 32) + { + pu.ibcCiipFlag = false; + return; + } + if (pu.mergeFlag) + { + if (pu.cu->skip) + { + pu.ibcCiipFlag = false; + return; + } + pu.ibcCiipFlag = m_BinDecoder.decodeBin(Ctx::IbcCiipFlag(0)); + } + else + { +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType) + { + pu.ibcCiipFlag = false; + return; + } +#endif +#if JVET_AC0112_IBC_LIC + if (pu.cu->ibcLicFlag) + { + pu.ibcCiipFlag = false; + return; + } +#endif + if (pu.cs->slice->getSliceType() != I_SLICE) + { + pu.ibcCiipFlag = false; + return; + } + pu.ibcCiipFlag = m_BinDecoder.decodeBin(Ctx::IbcCiipFlag(1)); + } +} + +void CABACReader::ibcCiipIntraIdx(PredictionUnit& pu) +{ + pu.ibcCiipIntraIdx = m_BinDecoder.decodeBin( Ctx::IbcCiipIntraIdx() ); +} +#endif + +#if JVET_AC0112_IBC_GPM +void CABACReader::ibcGpmFlag(PredictionUnit& pu) +{ + if (!pu.cs->sps->getUseIbcGpm() || (pu.lx() == 0 && pu.ly() == 0)) + { + pu.ibcGpmFlag = false; + return; + } + if (pu.lwidth() < 8 || pu.lheight() < 8 || pu.lwidth() > 32 || pu.lheight() > 32) + { + pu.ibcGpmFlag = false; + return; + } + pu.ibcGpmFlag = (m_BinDecoder.decodeBin(Ctx::IbcGpmFlag())); +} + +void CABACReader::ibcGpmMergeIdx(PredictionUnit& pu) +{ + uint32_t splitDir = 0; + bool splitDirFirstSet = m_BinDecoder.decodeBin( Ctx::IbcGpmSplitDirSetFlag() ); + if (splitDirFirstSet) + { + int splitDirIdx = m_BinDecoder.decodeBinsEP(3); + splitDir = g_ibcGpmFirstSetSplitDir[splitDirIdx]; + } + else + { + xReadTruncBinCode(splitDir, IBC_GPM_MAX_SPLIT_DIR_SECOND_SET_NUM); + uint8_t prefix = splitDir; + splitDir++; + for (uint8_t i = 0; i < GEO_NUM_PARTITION_MODE && splitDir != 0; i++) + { + if (!g_ibcGpmSecondSetSplitDir[i]) + { + prefix++; + } + else + { + splitDir--; + } + } + splitDir = prefix; + } + pu.ibcGpmSplitDir = splitDir; + + bool isIntra0 = m_BinDecoder.decodeBin( Ctx::IbcGpmIntraFlag() ) ? true : false; + bool isIntra1 = isIntra0 ? false : true; + + const int maxNumIbcGpmCand = pu.cs->sps->getMaxNumIBCMergeCand(); + int numCandminus2 = maxNumIbcGpmCand - 2; + int mergeCand0 = 0; + int mergeCand1 = 0; + if (isIntra0) + { + mergeCand0 = IBC_GPM_MAX_NUM_UNI_CANDS + unary_max_eqprob(IBC_GPM_MAX_NUM_INTRA_CANDS-1); + } + else if (numCandminus2 >= 0) + { + if (m_BinDecoder.decodeBin(Ctx::MergeIdx())) + { + mergeCand0 += unary_max_eqprob(numCandminus2) + 1; + } + } + if (isIntra1) + { + mergeCand1 = IBC_GPM_MAX_NUM_UNI_CANDS + unary_max_eqprob(IBC_GPM_MAX_NUM_INTRA_CANDS-1); + } + else if (numCandminus2 >= 0) + { + if (m_BinDecoder.decodeBin(Ctx::MergeIdx())) + { + mergeCand1 += unary_max_eqprob(numCandminus2) + 1; + } + } + pu.ibcGpmMergeIdx0 = mergeCand0; + pu.ibcGpmMergeIdx1 = mergeCand1; +} + +void CABACReader::ibcGpmAdaptBlendIdx(PredictionUnit& pu) +{ + if (IBC_GPM_NUM_BLENDING == 1) + { + pu.ibcGpmBldIdx = 0; + return; + } + int bin0 = m_BinDecoder.decodeBin(Ctx::IbcGpmBldIdx(0)); + if (bin0 == 1) + { + pu.ibcGpmBldIdx = 0; + } + else + { + int bin1 = m_BinDecoder.decodeBin(Ctx::IbcGpmBldIdx(1)); + if (bin1 == 0) + { + int bin2 = m_BinDecoder.decodeBin(Ctx::IbcGpmBldIdx(3)); + if (bin2 == 0) + { + pu.ibcGpmBldIdx = 4; + } + else + { + pu.ibcGpmBldIdx = 3; + } + } + else + { + int bin2 = m_BinDecoder.decodeBin(Ctx::IbcGpmBldIdx(2)); + if (bin2 == 0) + { + pu.ibcGpmBldIdx = 1; + } + else + { + pu.ibcGpmBldIdx = 2; + } + } + } +} +#endif + +#if JVET_AC0112_IBC_LIC +void CABACReader::cuIbcLicFlag( CodingUnit& cu ) +{ + if (!cu.cs->sps->getUseIbcLic() || !CU::isIBC(cu) || cu.firstPU->mergeFlag) + { + cu.ibcLicFlag = false; + return; + } +#if JVET_AA0070_RRIBC + if (cu.rribcFlipType > 0) + { + cu.ibcLicFlag = false; + return; + } +#endif + if (cu.lwidth() * cu.lheight() < 32 || cu.lwidth() * cu.lheight() > 256) + { + cu.ibcLicFlag = false; + return; + } + cu.ibcLicFlag = m_BinDecoder.decodeBin( Ctx::IbcLicFlag() ); +} +#endif + #if JVET_X0049_ADAPT_DMVR void CABACReader::bm_merge_flag(PredictionUnit& pu) { @@ -3870,6 +4078,34 @@ void CABACReader::merge_data( PredictionUnit& pu ) #if JVET_AA0061_IBC_MBVD } #endif +#endif +#if JVET_AC0112_IBC_CIIP + ibcCiipFlag(pu); + if (pu.ibcCiipFlag) + { + ibcCiipIntraIdx(pu); + } +#endif +#if JVET_AC0112_IBC_GPM +#if JVET_AC0112_IBC_CIIP && JVET_AA0061_IBC_MBVD + if (!pu.ibcMbvdMergeFlag && !pu.ibcCiipFlag) +#else +#if JVET_AA0061_IBC_MBVD + if (!pu.ibcMbvdMergeFlag) +#else +#if JVET_AC0112_IBC_CIIP + if (!pu.ibcCiipFlag) +#endif +#endif +#endif + { + ibcGpmFlag(pu); + if (pu.ibcGpmFlag) + { + ibcGpmMergeIdx(pu); + ibcGpmAdaptBlendIdx(pu); + } + } #endif merge_idx(pu); return; @@ -4238,6 +4474,13 @@ void CABACReader::merge_idx( PredictionUnit& pu ) { return; } +#endif +#if JVET_AC0112_IBC_GPM + if (pu.ibcGpmFlag) + { + pu.mergeIdx = pu.ibcGpmMergeIdx0 < IBC_GPM_MAX_NUM_UNI_CANDS ? pu.ibcGpmMergeIdx0 : pu.ibcGpmMergeIdx1; + return; + } #endif numCandminus1 = int(pu.cs->sps->getMaxNumIBCMergeCand()) - 1; } diff --git a/source/Lib/DecoderLib/CABACReader.h b/source/Lib/DecoderLib/CABACReader.h index 50ca36be866ada5c4349cbe409ece8afbed4ab7d..70d4fb4463637f57dd6020df0326a7b2f93196b6 100644 --- a/source/Lib/DecoderLib/CABACReader.h +++ b/source/Lib/DecoderLib/CABACReader.h @@ -164,6 +164,18 @@ public: #if JVET_AA0061_IBC_MBVD void ibcMbvdData ( PredictionUnit& pu ); #endif +#if JVET_AC0112_IBC_CIIP + void ibcCiipFlag ( PredictionUnit& pu ); + void ibcCiipIntraIdx ( PredictionUnit& pu ); +#endif +#if JVET_AC0112_IBC_GPM + void ibcGpmFlag ( PredictionUnit& pu ); + void ibcGpmMergeIdx ( PredictionUnit& pu ); + void ibcGpmAdaptBlendIdx ( PredictionUnit& pu ); +#endif +#if JVET_AC0112_IBC_LIC + void cuIbcLicFlag ( CodingUnit& cu ); +#endif #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) void tm_merge_flag ( PredictionUnit& pu ); #endif diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index 2c182ea136329c35543eec873c2d2dd56fe78dc6..b0680ffa154ac45c2c8e2c30c386d7e0435db74c 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -1288,6 +1288,12 @@ void DecCu::xReconInter(CodingUnit &cu) #endif #endif } +#if JVET_AC0112_IBC_GPM + else if (cu.firstPU->ibcGpmFlag) + { + m_pcInterPred->motionCompensationIbcGpm(cu, m_ibcMrgCtx, m_pcIntraPred); + } +#endif else { #if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION @@ -1309,7 +1315,41 @@ void DecCu::xReconInter(CodingUnit &cu) } } #endif + +#if JVET_AC0112_IBC_CIIP + uint8_t savedIntraDir[2] = {cu.firstPU->intraDir[0], cu.firstPU->intraDir[1]}; + if (CU::isIBC(cu) && cu.firstPU->ibcCiipFlag) + { + uint8_t ibcCiipIntraList[IBC_CIIP_MAX_NUM_INTRA_CANDS] = {PLANAR_IDX, HOR_IDX}; + m_pcIntraPred->deriveDimdMode(cu.cs->picture->getRecoBuf(cu.Y()), cu.Y(), cu); + cu.timdMode = m_pcIntraPred->deriveTimdMode(cu.cs->picture->getRecoBuf(cu.Y()), cu.Y(), cu); + ibcCiipIntraList[0] = MAP131TO67(cu.timdMode); + ibcCiipIntraList[1] = ibcCiipIntraList[0] == HOR_IDX ? PLANAR_IDX : HOR_IDX; + if (cu.firstPU->mergeFlag && cu.firstPU->ibcCiipIntraIdx > 0) + { + const PredictionUnit *puBv = cu.cs->getPURestricted(cu.lumaPos().offset(cu.firstPU->bv.getHor(), cu.firstPU->bv.getVer()), *cu.firstPU, cu.chType); + uint8_t intraDir = puBv ? puBv->getIpmInfo(cu.lumaPos().offset(cu.firstPU->bv.getHor(), cu.firstPU->bv.getVer())) : PLANAR_IDX; + if (intraDir != ibcCiipIntraList[0]) + { + ibcCiipIntraList[1] = intraDir; + } + else + { + ibcCiipIntraList[1] = ibcCiipIntraList[0] == PLANAR_IDX ? HOR_IDX : PLANAR_IDX; + } + } + cu.firstPU->intraDir[0] = ibcCiipIntraList[cu.firstPU->ibcCiipIntraIdx]; + cu.firstPU->intraDir[1] = cu.firstPU->intraDir[0]; + } +#endif m_pcIntraPred->geneIntrainterPred(cu, m_ciipBuffer); +#if JVET_AC0112_IBC_CIIP + if (CU::isIBC(cu) && cu.firstPU->ibcCiipFlag) + { + cu.firstPU->intraDir[0] = savedIntraDir[0]; + cu.firstPU->intraDir[1] = savedIntraDir[1]; + } +#endif // inter prediction CHECK(CU::isIBC(cu) && cu.firstPU->ciipFlag, "IBC and Ciip cannot be used together"); @@ -1336,6 +1376,22 @@ void DecCu::xReconInter(CodingUnit &cu) } if (cu.Y().valid()) { +#if JVET_AC0112_IBC_CIIP + if (CU::isIBC(cu) && cu.firstPU->ibcCiipFlag) + { + const UnitArea localUnitArea( cu.cs->area.chromaFormat, Area( 0, 0, cu.Y().width, cu.Y().height ) ); + m_pcIntraPred->geneWeightedPred( COMPONENT_Y, cu.cs->getPredBuf( *cu.firstPU ).Y(), *cu.firstPU, cu.cs->getPredBuf( *cu.firstPU ).Y(), m_ciipBuffer.getBuf( localUnitArea.Y() ) ); +#if INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS + if( isChromaEnabled( cu.chromaFormat ) && cu.Cb().valid()) +#else + if( isChromaEnabled( cu.chromaFormat ) && cu.Cb().valid() && cu.chromaSize().width > 2 ) +#endif + { + m_pcIntraPred->geneWeightedPred( COMPONENT_Cb, cu.cs->getPredBuf( *cu.firstPU ).Cb(), *cu.firstPU, cu.cs->getPredBuf( *cu.firstPU ).Cb(), m_ciipBuffer.getBuf( localUnitArea.Cb() ) ); + m_pcIntraPred->geneWeightedPred( COMPONENT_Cr, cu.cs->getPredBuf( *cu.firstPU ).Cr(), *cu.firstPU, cu.cs->getPredBuf( *cu.firstPU ).Cr(), m_ciipBuffer.getBuf( localUnitArea.Cr() ) ); + } + } +#endif bool isIbcSmallBlk = CU::isIBC(cu) && (cu.lwidth() * cu.lheight() <= 16); CU::saveMotionInHMVP( cu, isIbcSmallBlk ); } @@ -2086,7 +2142,13 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) { #if JVET_Z0075_IBC_HMVP_ENLARGE PU::getIBCMergeCandidates(pu, mrgCtx); +#if JVET_AC0112_IBC_LIC && !JVET_AA0070_RRIBC + pu.ibcMbvdMergeFlag = false; +#endif m_pcInterPred->adjustIBCMergeCandidates(pu, mrgCtx, 0, IBC_MRG_MAX_NUM_CANDS_MEM); +#if JVET_AC0112_IBC_LIC && !JVET_AA0070_RRIBC + pu.ibcMbvdMergeFlag = true; +#endif #else PU::getIBCMergeCandidates(pu, mrgCtx, (((fPosIBCBaseIdx / ADAPTIVE_IBC_SUB_GROUP_SIZE + 1) * ADAPTIVE_IBC_SUB_GROUP_SIZE < pu.cs->sps->getMaxNumIBCMergeCand()) || (fPosIBCBaseIdx / ADAPTIVE_IBC_SUB_GROUP_SIZE) == 0) ? fPosIBCBaseIdx / ADAPTIVE_IBC_SUB_GROUP_SIZE * ADAPTIVE_IBC_SUB_GROUP_SIZE + ADAPTIVE_IBC_SUB_GROUP_SIZE - 1 : fPosIBCBaseIdx); m_pcInterPred->adjustIBCMergeCandidates(pu, mrgCtx, fPosIBCBaseIdx); @@ -2123,6 +2185,12 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) #endif PU::getIBCMergeCandidates(pu, mrgCtx); m_pcInterPred->adjustIBCMergeCandidates(pu, mrgCtx, 0, IBC_MRG_MAX_NUM_CANDS_MEM); +#if JVET_AC0112_IBC_GPM && JVET_AA0070_RRIBC + if (pu.ibcGpmFlag) + { + m_pcInterPred->adjustIbcMergeRribcCand(pu, mrgCtx, 0, IBC_MRG_MAX_NUM_CANDS_MEM); + } +#endif pu.mergeIdx = mrgCandIdx; #else PU::getIBCMergeCandidates(pu, mrgCtx, (((pu.mergeIdx / ADAPTIVE_IBC_SUB_GROUP_SIZE + 1) * ADAPTIVE_IBC_SUB_GROUP_SIZE < pu.cs->sps->getMaxNumIBCMergeCand()) || (pu.mergeIdx / ADAPTIVE_IBC_SUB_GROUP_SIZE) == 0) ? pu.mergeIdx / ADAPTIVE_IBC_SUB_GROUP_SIZE * ADAPTIVE_IBC_SUB_GROUP_SIZE + ADAPTIVE_IBC_SUB_GROUP_SIZE - 1 : pu.mergeIdx); @@ -2132,6 +2200,9 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) else #endif PU::getIBCMergeCandidates(pu, mrgCtx, pu.mergeIdx); +#if JVET_AC0112_IBC_GPM + m_ibcMrgCtx = mrgCtx; +#endif #if JVET_AA0061_IBC_MBVD } #endif diff --git a/source/Lib/DecoderLib/DecCu.h b/source/Lib/DecoderLib/DecCu.h index 25ddddfe96f2fa0cc076ef405fc35576efa47642..3b13c88f53e47d753a83cde4c4196afea2a5a5e8 100644 --- a/source/Lib/DecoderLib/DecCu.h +++ b/source/Lib/DecoderLib/DecCu.h @@ -122,6 +122,9 @@ private: MergeCtx m_geoTmMrgCtx0, m_geoTmMrgCtx1; #endif #endif +#if JVET_AC0112_IBC_GPM + MergeCtx m_ibcMrgCtx; +#endif }; //! \} diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index dab338c57276a8f52434fb4ac98eee630a2de582..68bcbc4160e713d746593ab00778df27b87aca8e 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -2560,6 +2560,15 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) pcSPS->setMaxNumIBCMergeCand(IBC_MRG_MAX_NUM_CANDS - uiCode); #if JVET_AA0061_IBC_MBVD READ_FLAG( uiCode, "sps_ibc_mbvd_enabled_flag" ); pcSPS->setUseIbcMbvd ( uiCode != 0 ); +#endif +#if JVET_AC0112_IBC_CIIP + READ_FLAG( uiCode, "sps_ibc_ciip_enabled_flag" ); pcSPS->setUseIbcCiip ( uiCode != 0 ); +#endif +#if JVET_AC0112_IBC_GPM + READ_FLAG( uiCode, "sps_ibc_gpm_enabled_flag" ); pcSPS->setUseIbcGpm ( uiCode != 0 ); +#endif +#if JVET_AC0112_IBC_LIC + READ_FLAG( uiCode, "sps_ibc_lic_enabled_flag" ); pcSPS->setUseIbcLic ( uiCode != 0 ); #endif } else diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index bf3e32091980b0e324d849c803baff64eff2887e..a99b0b40487963bfcd8f15833b678ed15e2245ef 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -2854,6 +2854,9 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu ) } #if JVET_AA0070_RRIBC rribcData(*pu.cu); +#endif +#if JVET_AC0112_IBC_LIC + cuIbcLicFlag(*pu.cu); #endif if( pu.mergeFlag ) { @@ -2872,6 +2875,13 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu ) } else if (CU::isIBC(*pu.cu)) { +#if JVET_AC0112_IBC_CIIP + ibcCiipFlag(pu); + if (pu.ibcCiipFlag) + { + ibcCiipIntraIdx(pu); + } +#endif ref_idx(pu, REF_PIC_LIST_0); Mv mvd = pu.mvd[REF_PIC_LIST_0]; mvd.changeIbcPrecInternal2Amvr(pu.cu->imv); @@ -3439,6 +3449,175 @@ void CABACWriter::tm_merge_flag(const PredictionUnit& pu) } #endif +#if JVET_AC0112_IBC_CIIP +void CABACWriter::ibcCiipFlag(const PredictionUnit& pu) +{ + if (!pu.cs->sps->getUseIbcCiip() || (pu.lx() == 0 && pu.ly() == 0)) + { + return; + } + if (pu.lwidth() * pu.lheight() < 32 || pu.lwidth() > 32 || pu.lheight() > 32) + { + return; + } + if (pu.mergeFlag) + { + if (pu.cu->skip) + { + return; + } + m_BinEncoder.encodeBin(pu.ibcCiipFlag, Ctx::IbcCiipFlag(0)); + } + else + { + #if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType) + { + return; + } + #endif + #if JVET_AC0112_IBC_LIC + if (pu.cu->ibcLicFlag) + { + return; + } + #endif + if (pu.cs->slice->getSliceType() != I_SLICE) + { + return; + } + m_BinEncoder.encodeBin(pu.ibcCiipFlag, Ctx::IbcCiipFlag(1)); + } +} + +void CABACWriter::ibcCiipIntraIdx(const PredictionUnit& pu) +{ + m_BinEncoder.encodeBin( pu.ibcCiipIntraIdx > 0, Ctx::IbcCiipIntraIdx() ); +} +#endif + +#if JVET_AC0112_IBC_GPM +void CABACWriter::ibcGpmFlag(const PredictionUnit& pu) +{ + if (!pu.cs->sps->getUseIbcGpm() || (pu.lx() == 0 && pu.ly() == 0)) + { + return; + } + if (pu.lwidth() < 8 || pu.lheight() < 8 || pu.lwidth() > 32 || pu.lheight() > 32) + { + return; + } + m_BinEncoder.encodeBin(pu.ibcGpmFlag, Ctx::IbcGpmFlag()); +} + +void CABACWriter::ibcGpmMergeIdx(const PredictionUnit& pu) +{ + uint8_t splitDir = pu.ibcGpmSplitDir; + uint8_t candIdx0 = pu.ibcGpmMergeIdx0; + uint8_t candIdx1 = pu.ibcGpmMergeIdx1; + + uint8_t splitDirIdx = 0; + if (g_GeoParams[splitDir][0] % 8 == 0) + { + m_BinEncoder.encodeBin( 1, Ctx::IbcGpmSplitDirSetFlag() ); + splitDirIdx = g_ibcGpmFirstSetSplitDirToIdx[splitDir]; + m_BinEncoder.encodeBinsEP(splitDirIdx, 3); + } + else + { + m_BinEncoder.encodeBin( 0, Ctx::IbcGpmSplitDirSetFlag() ); + uint8_t prefix = 0; + for (uint8_t i = 0; i < splitDir; i++) + { + if (!g_ibcGpmSecondSetSplitDir[i]) + { + prefix++; + } + } + splitDirIdx = splitDir - prefix; + xWriteTruncBinCode(splitDirIdx, IBC_GPM_MAX_SPLIT_DIR_SECOND_SET_NUM); + } + + bool isIntra0 = (pu.ibcGpmMergeIdx0 >= IBC_GPM_MAX_NUM_UNI_CANDS); + bool isIntra1 = (pu.ibcGpmMergeIdx1 >= IBC_GPM_MAX_NUM_UNI_CANDS); + m_BinEncoder.encodeBin( isIntra0 ? 1 : 0, Ctx::IbcGpmIntraFlag() ); + + const int maxNumIbcGpmCand = pu.cs->sps->getMaxNumIBCMergeCand(); + int numCandminus2 = maxNumIbcGpmCand - 2; + if (isIntra0) + { + unary_max_eqprob(candIdx0 - IBC_GPM_MAX_NUM_UNI_CANDS, IBC_GPM_MAX_NUM_INTRA_CANDS-1); + } + else if (numCandminus2 >= 0) + { + m_BinEncoder.encodeBin(candIdx0 == 0 ? 0 : 1, Ctx::MergeIdx()); + if (candIdx0 > 0) + { + unary_max_eqprob(candIdx0 - 1, numCandminus2); + } + } + if (isIntra1) + { + unary_max_eqprob(candIdx1 - IBC_GPM_MAX_NUM_UNI_CANDS, IBC_GPM_MAX_NUM_INTRA_CANDS-1); + } + else if (numCandminus2 >= 0) + { + m_BinEncoder.encodeBin(candIdx1 == 0 ? 0 : 1, Ctx::MergeIdx()); + if (candIdx1 > 0) + { + unary_max_eqprob(candIdx1 - 1, numCandminus2); + } + } +} + +void CABACWriter::ibcGpmAdaptBlendIdx(const int flag) +{ + if (IBC_GPM_NUM_BLENDING == 1) + { + return; + } + if (flag == 0) + { + m_BinEncoder.encodeBin(1, Ctx::IbcGpmBldIdx(0)); + } + else + { + m_BinEncoder.encodeBin(0, Ctx::IbcGpmBldIdx(0)); + if (flag == 2 || flag == 1) + { + m_BinEncoder.encodeBin(1, Ctx::IbcGpmBldIdx(1)); + m_BinEncoder.encodeBin(flag == 2, Ctx::IbcGpmBldIdx(2)); + } + else + { + m_BinEncoder.encodeBin(0, Ctx::IbcGpmBldIdx(1)); + m_BinEncoder.encodeBin(flag == 3, Ctx::IbcGpmBldIdx(3)); + } + } +} +#endif + +#if JVET_AC0112_IBC_LIC +void CABACWriter::cuIbcLicFlag(const CodingUnit& cu) +{ + if (!cu.cs->sps->getUseIbcLic() || !CU::isIBC(cu) || cu.firstPU->mergeFlag) + { + return; + } +#if JVET_AA0070_RRIBC + if (cu.rribcFlipType > 0) + { + return; + } +#endif + if (cu.lwidth() * cu.lheight() < 32 || cu.lwidth() * cu.lheight() > 256) + { + return; + } + m_BinEncoder.encodeBin(cu.ibcLicFlag ? 1 : 0, Ctx::IbcLicFlag()); +} +#endif + #if JVET_X0049_ADAPT_DMVR void CABACWriter::bm_merge_flag(const PredictionUnit& pu) { @@ -3483,6 +3662,34 @@ void CABACWriter::merge_data(const PredictionUnit& pu) #if JVET_AA0061_IBC_MBVD } #endif +#endif +#if JVET_AC0112_IBC_CIIP + ibcCiipFlag(pu); + if (pu.ibcCiipFlag) + { + ibcCiipIntraIdx(pu); + } +#endif +#if JVET_AC0112_IBC_GPM +#if JVET_AC0112_IBC_CIIP && JVET_AA0061_IBC_MBVD + if (!pu.ibcMbvdMergeFlag && !pu.ibcCiipFlag) +#else +#if JVET_AA0061_IBC_MBVD + if (!pu.ibcMbvdMergeFlag) +#else +#if JVET_AC0112_IBC_CIIP + if (!pu.ibcCiipFlag) +#endif +#endif +#endif + { + ibcGpmFlag(pu); + if (pu.ibcGpmFlag) + { + ibcGpmMergeIdx(pu); + ibcGpmAdaptBlendIdx(pu.ibcGpmBldIdx); + } + } #endif merge_idx(pu); return; @@ -3877,17 +4084,21 @@ void CABACWriter::merge_idx( const PredictionUnit& pu ) #endif #endif if (pu.cu->predMode == MODE_IBC) -#if JVET_AA0061_IBC_MBVD { +#if JVET_AA0061_IBC_MBVD if (pu.ibcMbvdMergeFlag) { return; } +#endif +#if JVET_AC0112_IBC_GPM + if (pu.ibcGpmFlag) + { + return; + } #endif numCandminus1 = int(pu.cs->sps->getMaxNumIBCMergeCand()) - 1; -#if JVET_AA0061_IBC_MBVD } -#endif #if TM_MRG else if (pu.tmMergeFlag) #if JVET_X0141_CIIP_TIMD_TM diff --git a/source/Lib/EncoderLib/CABACWriter.h b/source/Lib/EncoderLib/CABACWriter.h index d6e0959c3498092642ebd10d59686385cbcf8e17..b059d4f8d8a80ec9fe7a726c152f58c98ee6cfee 100644 --- a/source/Lib/EncoderLib/CABACWriter.h +++ b/source/Lib/EncoderLib/CABACWriter.h @@ -175,6 +175,18 @@ public: #if JVET_AA0061_IBC_MBVD void ibcMbvdData ( const PredictionUnit& pu ); #endif +#if JVET_AC0112_IBC_CIIP + void ibcCiipFlag ( const PredictionUnit& pu ); + void ibcCiipIntraIdx ( const PredictionUnit& pu ); +#endif +#if JVET_AC0112_IBC_GPM + void ibcGpmFlag ( const PredictionUnit& pu ); + void ibcGpmMergeIdx ( const PredictionUnit& pu ); + void ibcGpmAdaptBlendIdx ( const int idx ); +#endif +#if JVET_AC0112_IBC_LIC + void cuIbcLicFlag (const CodingUnit& cu ); +#endif #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) void tm_merge_flag ( const PredictionUnit& pu); #endif diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index f0847b15450be388fd6d90fe3ab917513ab38281..d91eb363dc2ac24f6df20fd1947e7eba1b650c84 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -506,6 +506,15 @@ protected: #if JVET_AA0061_IBC_MBVD bool m_ibcMbvd; #endif +#if JVET_AC0112_IBC_CIIP + bool m_ibcCiip; +#endif +#if JVET_AC0112_IBC_GPM + bool m_ibcGpm; +#endif +#if JVET_AC0112_IBC_LIC + bool m_ibcLic; +#endif bool m_wrapAround; unsigned m_wrapAroundOffset; @@ -1382,6 +1391,18 @@ public: void setIbcMbvd ( bool b ) { m_ibcMbvd = b; } bool getIbcMbvd () const { return m_ibcMbvd; } #endif +#if JVET_AC0112_IBC_CIIP + void setIbcCiip ( bool b ) { m_ibcCiip = b; } + bool getIbcCiip () const { return m_ibcCiip; } +#endif +#if JVET_AC0112_IBC_GPM + void setIbcGpm ( bool b ) { m_ibcGpm = b; } + bool getIbcGpm () const { return m_ibcGpm; } +#endif +#if JVET_AC0112_IBC_LIC + void setIbcLic ( bool b ) { m_ibcLic = b; } + bool getIbcLic () const { return m_ibcLic; } +#endif #if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM || MULTI_PASS_DMVR void setUseDMVDMode (bool b) { m_DMVDMode = b; } bool getUseDMVDMode () const { return m_DMVDMode; } diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 369e53634fa5b985cf70996795c9d15d6ae5ff68..7e2326a898e11091bdec5efc7082548eb2662791 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -10838,6 +10838,32 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct uint32_t ibcMbvdValidNum[IBC_MBVD_BASE_NUM] = { 0 }; #endif +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM + const UnitArea localUnitArea(tempCS->area.chromaFormat, Area(0, 0, tempCS->area.Y().width, tempCS->area.Y().height)); + PelUnitBuf intraPredBuf[NUM_LUMA_MODE]; + bool intraPredBufSet[NUM_LUMA_MODE] = {false, }; +#endif +#if JVET_AC0112_IBC_CIIP + bool testIbcCiip = tempCS->sps->getUseIbcCiip() && (tempCS->area.lwidth() * tempCS->area.lheight() >= 32) && tempCS->area.lwidth() <= 32 && tempCS->area.lheight() <= 32 && (tempCS->area.lx() > 0 || tempCS->area.ly() > 0); + int wIbc = 13, wIntra = 3, shift = 4; + PelBuf ibcCiipBuf = m_ciipBuffer[1].getBuf(localUnitArea.Y()); + int ibcCiipIntraList[IBC_CIIP_MAX_NUM_INTRA_CANDS]; + double ibcCiipBestSatdCost = MAX_DOUBLE; + int ibcCiipBestMergeCand = 0; + int ibcCiipBestIntraCand = 0; +#endif +#if JVET_AC0112_IBC_GPM + MergeCtx mergeCtxIbcGeo; + int skipCandNum[IBC_MRG_MAX_NUM_CANDS] = {0, }; +#if JVET_Z0084_IBC_TM && IBC_TM_MRG + MergeCtx mergeCtxTmIbcGeo; + int skipCandNumTm[IBC_MRG_MAX_NUM_CANDS<<1] = {0, }; +#endif + DistParam distParamSad; + Distortion sadIntraWholeBlk[NUM_LUMA_MODE]; + uint8_t ibcGpmIntraCandList[GEO_NUM_PARTITION_MODE][2][IBC_GPM_MAX_NUM_INTRA_CANDS]; +#endif + if (sps.getSbTMVPEnabledFlag()) { Size bufSize = g_miScaling.scale(tempCS->area.lumaSize()); @@ -10861,6 +10887,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct cu.LICFlag = false; #endif cu.geoFlag = false; +#if JVET_AC0112_IBC_LIC + cu.ibcLicFlag = false; +#endif #if JVET_AA0070_RRIBC cu.rribcFlipType = 0; pu.mergeFlag = true; @@ -10938,25 +10967,71 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct numMrgSATDCand += 2; } numMrgSATDCand = std::min(numMrgSATDCand, (const int)(mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand)); +#if JVET_AC0112_IBC_CIIP + static_vector<ModeIbcInfo, ((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM)> rdModeList((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM); + for (unsigned i = 0; i < ((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM); i++) + { + rdModeList[i].mergeCand = i; + rdModeList[i].isCIIP = false; +#if JVET_AC0112_IBC_GPM + rdModeList[i].isIbcGpm = false; +#endif + } +#else +#if JVET_AC0112_IBC_GPM + static_vector<ModeIbcInfo, ((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM)> rdModeList((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM); + for (unsigned i = 0; i < ((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM); i++) + { + rdModeList[i].mergeCand = i; + rdModeList[i].isIbcGpm = false; + } +#else static_vector<unsigned, ((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM)> rdModeList((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM); for (unsigned i = 0; i < ((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM); i++) { rdModeList[i] = i; } +#endif +#endif static_vector<double, ((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM)> candCostList(((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM), MAX_DOUBLE); #else int candHasNoResidual[IBC_MRG_MAX_NUM_CANDS<<1] = {0,}; bool bestIsSkip = false; unsigned numMrgSATDCand = mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand; +#if JVET_AC0112_IBC_CIIP + static_vector<ModeIbcInfo, ((IBC_MRG_MAX_NUM_CANDS<<1)+2)> rdModeList((IBC_MRG_MAX_NUM_CANDS<<1)+2); + for (unsigned i = 0; i < (IBC_MRG_MAX_NUM_CANDS<<1)+2; i++) + { + rdModeList[i].mergeCand = i; + rdModeList[i].isCIIP = false; +#if JVET_AC0112_IBC_GPM + rdModeList[i].isIbcGpm = false; +#endif + } +#else +#if JVET_AC0112_IBC_GPM + static_vector<ModeIbcInfo, ((IBC_MRG_MAX_NUM_CANDS<<1)+2)> rdModeList((IBC_MRG_MAX_NUM_CANDS<<1)+2); + for (unsigned i = 0; i < (IBC_MRG_MAX_NUM_CANDS<<1)+2; i++) + { + rdModeList[i].mergeCand = i; + rdModeList[i].isIbcGpm = false; + } +#else static_vector<unsigned, (IBC_MRG_MAX_NUM_CANDS<<1)> rdModeList(IBC_MRG_MAX_NUM_CANDS<<1); for (unsigned i = 0; i < IBC_MRG_MAX_NUM_CANDS<<1; i++) { rdModeList[i] = i; } +#endif +#endif +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM + static_vector<double, ((IBC_MRG_MAX_NUM_CANDS<<1)+2)> candCostList((IBC_MRG_MAX_NUM_CANDS<<1)+2, MAX_DOUBLE); +#else static_vector<double, (IBC_MRG_MAX_NUM_CANDS<<1)> candCostList(IBC_MRG_MAX_NUM_CANDS<<1, MAX_DOUBLE); #endif +#endif #else #if JVET_AA0061_IBC_MBVD int candHasNoResidual[MRG_MAX_NUM_CANDS + IBC_MBVD_NUM] = {0,}; @@ -10985,6 +11060,24 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct static_vector<double, MRG_MAX_NUM_CANDS> candCostList(MRG_MAX_NUM_CANDS, MAX_DOUBLE); #endif #endif + +#if JVET_AC0112_IBC_GPM + Distortion sadWholeBlk[IBC_MRG_MAX_NUM_CANDS<<1]; + bool isSkipThisCand[IBC_GPM_MAX_NUM_UNI_CANDS<<1] = {false, }; + PelUnitBuf ibcPredBuf[IBC_MRG_MAX_NUM_CANDS<<1]; + static_vector<int, IBC_MRG_MAX_NUM_CANDS<<1> mergeCandList0[GEO_NUM_PARTITION_MODE]; + static_vector<int, IBC_MRG_MAX_NUM_CANDS<<1> mergeCandList1[GEO_NUM_PARTITION_MODE]; + static_vector<double, IBC_MRG_MAX_NUM_CANDS<<1> sadCostList0[GEO_NUM_PARTITION_MODE]; + static_vector<double, IBC_MRG_MAX_NUM_CANDS<<1> sadCostList1[GEO_NUM_PARTITION_MODE]; + int ibcGpmCandNumValid = 0; + PelUnitBuf geoCombinations[IBC_GPM_MAX_TRY_WEIGHTED_SAD*IBC_GPM_NUM_BLENDING+1]; + static_vector<int, IBC_GPM_MAX_NUM_INTRA_CANDS> intraCandList0[GEO_NUM_PARTITION_MODE]; + static_vector<int, IBC_GPM_MAX_NUM_INTRA_CANDS> intraCandList1[GEO_NUM_PARTITION_MODE]; + static_vector<double, IBC_GPM_MAX_NUM_INTRA_CANDS> intraSadCostList0[GEO_NUM_PARTITION_MODE]; + static_vector<double, IBC_GPM_MAX_NUM_INTRA_CANDS> intraSadCostList1[GEO_NUM_PARTITION_MODE]; + bool testIbcGpm = tempCS->sps->getUseIbcGpm() && (tempCS->area.lx() > 0 || tempCS->area.ly() > 0); +#endif + // 1. Pass: get SATD-cost for selected candidates and reduce their count { const double sqrtLambdaForFirstPass = m_pcRdCost->getMotionLambda( ); @@ -11001,6 +11094,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct cu.mmvdSkip = false; #if INTER_LIC cu.LICFlag = false; +#endif +#if JVET_AC0112_IBC_LIC + cu.ibcLicFlag = false; #endif cu.geoFlag = false; @@ -11013,6 +11109,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct Picture* refPic = pu.cu->slice->getPic(); const CPelBuf refBuf = refPic->getRecoBuf(pu.blocks[COMPONENT_Y]); const Pel* piRefSrch = refBuf.buf; +#if JVET_AC0112_IBC_LIC + PelBuf predBuf = tempCS->getPredBuf(pu.Y()); +#endif #if JVET_AA0070_RRIBC pu.cu->rribcFlipType = 0; const CompArea &area = cu.blocks[COMPONENT_Y]; @@ -11047,6 +11146,97 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); #endif +#if JVET_AC0112_IBC_GPM + int dimdMode = -1; + int timdMode = -1; +#endif +#if JVET_AC0112_IBC_CIIP + if (testIbcCiip) + { + IntraPrediction::deriveDimdMode(tempCS->picture->getRecoBuf(tempCS->area.Y()), tempCS->area.Y(), cu); + cu.timdMode = m_pcIntraSearch->deriveTimdMode(tempCS->picture->getRecoBuf(cu.Y()), cu.Y(), cu); + ibcCiipIntraList[0] = MAP131TO67(cu.timdMode); +#if JVET_AC0112_IBC_GPM + dimdMode = cu.dimdMode; + timdMode = cu.timdMode; +#endif + pu.ibcCiipFlag = true; + ibcCiipIntraList[1] = HOR_IDX; + pu.intraDir[0] = ibcCiipIntraList[0]; + m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Y(), true); + m_pcIntraSearch->initPredIntraParams(pu, pu.Y(), *pu.cs->sps, 0); + intraPredBuf[pu.intraDir[0]] = m_acMergeBuffer[pu.intraDir[0] + IBC_GPM_MAX_NUM_UNI_CANDS].getBuf(localUnitArea); + m_pcIntraSearch->predIntraAng(COMPONENT_Y, intraPredBuf[pu.intraDir[0]].Y(), pu); + intraPredBufSet[pu.intraDir[0]] = true; + pu.ibcCiipFlag = false; + } +#endif +#if JVET_AC0112_IBC_GPM + if (pu.lwidth() < 8 || pu.lheight() < 8 || pu.lwidth() > 32 || pu.lheight() > 32) + { + testIbcGpm &= false; + } + if (testIbcGpm) + { +#if JVET_AA0070_RRIBC + m_pcRdCost->setDistParam(distParamSad, tmpOrgLuma, m_acMergeBuffer[0].Y().buf, m_acMergeBuffer[0].Y().stride, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y); +#else + if (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()) + { + const CompArea &area = cu.blocks[COMPONENT_Y]; + CompArea tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size()); + PelBuf tmpLuma = m_tmpStorageLCU->getBuf(tmpArea); + tmpLuma.rspSignal( tempCS->getOrgBuf().Y(), m_pcReshape->getFwdLUT() ); + m_pcRdCost->setDistParam(distParamSad, tmpLuma, m_acMergeBuffer[0].Y().buf, m_acMergeBuffer[0].Y().stride, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y); + } + else + { + m_pcRdCost->setDistParam(distParamSad, tempCS->getOrgBuf().Y(), m_acMergeBuffer[0].Y().buf, m_acMergeBuffer[0].Y().stride, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y); + } +#endif + if (dimdMode == -1 || timdMode == -1) + { + IntraPrediction::deriveDimdMode(tempCS->picture->getRecoBuf(cu.Y()), cu.Y(), cu); + dimdMode = cu.dimdMode; + cu.timdMode = m_pcIntraSearch->deriveTimdMode(tempCS->picture->getRecoBuf(cu.Y()), cu.Y(), cu); + timdMode = cu.timdMode; + } + pu.ibcGpmFlag = true; + m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Y(), true); + for (int splitDir = 0; splitDir < GEO_NUM_PARTITION_MODE; splitDir++) + { + if (!g_ibcGpmSecondSetSplitDir[splitDir] && g_GeoParams[splitDir][0] % 8 != 0) + { + continue; + } + for (int partIdx = 0; partIdx < 2; partIdx++) + { + PU::getGeoIntraMPMs(pu, ibcGpmIntraCandList[splitDir][partIdx], splitDir, g_geoTmShape[partIdx][g_GeoParams[splitDir][0]] +#if JVET_Z0056_GPM_SPLIT_MODE_REORDERING + , (splitDir == 0 && partIdx == 0) +#endif + ); + for (int intraIdx = 0; intraIdx < IBC_GPM_MAX_NUM_INTRA_CANDS; intraIdx++) + { + uint8_t intraCand = ibcGpmIntraCandList[splitDir][partIdx][intraIdx]; + if (!intraPredBufSet[intraCand]) + { + intraPredBufSet[intraCand] = true; + pu.intraDir[0] = intraCand; + intraPredBuf[intraCand] = m_acMergeBuffer[intraCand + IBC_GPM_MAX_NUM_UNI_CANDS].getBuf(localUnitArea); + m_pcIntraSearch->initPredIntraParams(pu, pu.Y(), *pu.cs->sps, 0); + m_pcIntraSearch->predIntraAng(COMPONENT_Y, intraPredBuf[intraCand].Y(), pu); + } + distParamSad.cur.buf = intraPredBuf[intraCand].Y().buf; + distParamSad.cur.stride = intraPredBuf[intraCand].Y().stride; + sadIntraWholeBlk[intraCand] = distParamSad.distFunc(distParamSad); + } + } + } + pu.ibcGpmFlag = false; + } +#endif + int refStride = refBuf.stride; #if !JVET_Y0058_IBC_LIST_MODIFY const UnitArea localUnitArea(tempCS->area.chromaFormat, Area(0, 0, tempCS->area.Y().width, tempCS->area.Y().height)); @@ -11070,6 +11260,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct for (unsigned int mergeCand = 0; mergeCand < mergeCtx.numValidMergeCand; mergeCand++) { mergeCtx.setMergeInfo(pu, mergeCand); // set bv info in merge mode +#if JVET_AC0112_IBC_GPM + int mergeCandIbcGpm = mergeCand - skipCandNum[mergeCand > 0 ? mergeCand - 1 : 0]; +#endif int xPred = pu.bv.getHor(); int yPred = pu.bv.getVer(); @@ -11086,10 +11279,29 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct numValidBv--; #if JVET_AA0061_IBC_MBVD && !JVET_AA0070_RRIBC numValidBvIBC--; +#endif +#if JVET_AC0112_IBC_GPM + isSkipThisCand[mergeCandIbcGpm] = true; #endif continue; } +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM +#if JVET_AC0112_IBC_GPM +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType > 0) + { + isSkipThisCand[mergeCandIbcGpm] = true; + skipCandNum[mergeCand] = mergeCand > 0 ? skipCandNum[mergeCand - 1] + 1 : 1; + } + else +#endif + { + skipCandNum[mergeCand] = mergeCand > 0 ? skipCandNum[mergeCand - 1] : 0; + } +#endif +#else PU::spanMotionInfo(pu, mergeCtx); +#endif #if JVET_AA0070_RRIBC if (pu.cu->rribcFlipType == 0) @@ -11106,6 +11318,23 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct } #endif +#if JVET_AC0112_IBC_LIC + if (pu.cu->ibcLicFlag) + { + Pel* piPred = predBuf.buf; + int predStride = predBuf.stride; + int height = predBuf.height; + int width = predBuf.width; + for (int h = 0; h < height; h++) + { + memcpy(piPred, piRefSrch + h * refStride + refStride * yPred + xPred, width * sizeof(Pel)); + piPred += predStride; + } + m_pcInterSearch->xLocalIlluComp(pu, COMPONENT_Y, pu.bv, predBuf); + distParam.cur = predBuf; + } + else +#endif distParam.cur.buf = piRefSrch + refStride * yPred + xPred; Distortion sad = distParam.distFunc(distParam); @@ -11123,15 +11352,128 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct #endif double cost = (double)sad + (double)bitsCand * sqrtLambdaForFirstPass; +#if JVET_AC0112_IBC_CIIP + if (testIbcCiip) + { + const PredictionUnit *puBv = pu.cs->getPURestricted(pu.lumaPos().offset(xPred, yPred), pu, pu.chType); + int intraDir = puBv ? puBv->getIpmInfo(pu.lumaPos().offset(xPred, yPred)) : PLANAR_IDX; + if (intraDir != ibcCiipIntraList[0]) + { + ibcCiipIntraList[1] = intraDir; + } + else + { + ibcCiipIntraList[1] = ibcCiipIntraList[0] == PLANAR_IDX ? HOR_IDX : PLANAR_IDX; + } + intraDir = ibcCiipIntraList[1]; + if (!intraPredBufSet[intraDir]) + { + pu.ibcCiipFlag = true; + pu.intraDir[0] = intraDir; + intraPredBufSet[intraDir] = true; + intraPredBuf[intraDir] = m_acMergeBuffer[intraDir + IBC_GPM_MAX_NUM_UNI_CANDS].getBuf(localUnitArea); + m_pcIntraSearch->initPredIntraParams(pu, pu.Y(), *pu.cs->sps, 0); + m_pcIntraSearch->predIntraAng(COMPONENT_Y, intraPredBuf[intraDir].Y(), pu); + pu.ibcCiipFlag = false; + } + for (int dirIdx = 0; dirIdx < IBC_CIIP_MAX_NUM_INTRA_CANDS; dirIdx++) + { + int height = pu.lheight(); + int width = pu.lwidth(); + const Pel *pPredIbc = piRefSrch + refStride * yPred + xPred; + Pel *pPredDst = ibcCiipBuf.buf; + int dstStride = ibcCiipBuf.stride; + Pel *pPredIntra = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().buf; + int intraStride = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().stride; + m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, pPredIbc, refStride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height); + + distParam.cur.buf = ibcCiipBuf.buf; + distParam.cur.stride = ibcCiipBuf.stride; + + Distortion sad2 = distParam.distFunc(distParam); + unsigned int bitsCand2 = mergeCand + 1; +#if JVET_Z0084_IBC_TM + if (mergeCand == tempCS->sps->getMaxNumIBCMergeCand() - 1) +#else + if (mergeCand == tempCS->sps->getMaxNumMergeCand() - 1) +#endif + { + bitsCand2--; + } + bitsCand2 += dirIdx + 1; + if (dirIdx == IBC_CIIP_MAX_NUM_INTRA_CANDS - 1) + { + bitsCand2--; + } + bitsCand2++; // for ibc_mbvd_flag + double cost2 = (double)sad2 + (double)bitsCand2 * sqrtLambdaForFirstPass; + if (cost2 < ibcCiipBestSatdCost) + { + ibcCiipBestMergeCand = mergeCand; + ibcCiipBestIntraCand = dirIdx; + ibcCiipBestSatdCost = cost2; + } + } + } +#endif + +#if JVET_AC0112_IBC_GPM +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 0 && testIbcGpm) +#else + if (testIbcGpm) +#endif + { + ibcGpmCandNumValid++; + distParamSad.cur.buf = piRefSrch + refStride * yPred + xPred; + distParamSad.cur.stride = refBuf.stride; + ibcPredBuf[mergeCandIbcGpm] = m_acMergeBuffer[mergeCandIbcGpm].getBuf(localUnitArea); + ibcPredBuf[mergeCandIbcGpm].bufs[COMPONENT_Y].copyFrom(distParamSad.cur); + sadWholeBlk[mergeCandIbcGpm] = distParamSad.distFunc(distParamSad); + } +#endif + +#if JVET_AC0112_IBC_CIIP +#if JVET_AC0112_IBC_GPM + updateCandList(ModeIbcInfo(mergeCand, false, 0, false, 0, 0, 0, 0, 0), cost, rdModeList, candCostList + , numMrgSATDCand); +#else + updateCandList(ModeIbcInfo(mergeCand, false, 0), cost, rdModeList, candCostList + , numMrgSATDCand); +#endif +#else +#if JVET_AC0112_IBC_GPM + updateCandList(ModeIbcInfo(mergeCand, false, 0, 0, 0, 0, 0), cost, rdModeList, candCostList + , numMrgSATDCand); +#else updateCandList(mergeCand, cost, rdModeList, candCostList , numMrgSATDCand); +#endif +#endif } +#if JVET_AC0112_IBC_GPM + if (testIbcGpm && mergeCtx.numValidMergeCand > 0) + { + mergeCtxIbcGeo = mergeCtx; +#if JVET_AA0070_RRIBC + m_pcInterSearch->adjustIbcMergeRribcCand(pu, mergeCtxIbcGeo, 0, IBC_MRG_MAX_NUM_CANDS_MEM); +#endif + for (int i = 0; i < skipCandNum[mergeCtx.numValidMergeCand - 1]; i++) + { + isSkipThisCand[mergeCtx.numValidMergeCand - 1 - i] = true; + } + } +#endif + #if JVET_Z0084_IBC_TM && IBC_TM_MRG // Add TM refined candidates for (unsigned int mergeCand = 0; mergeCand < mergeCtxTm.numValidMergeCand; mergeCand++) { mergeCtxTm.setMergeInfo(pu, mergeCand); // set bv info in merge mode +#if JVET_AC0112_IBC_GPM + int mergeCandIbcGpm = mergeCand - skipCandNumTm[mergeCtx.numValidMergeCand + (mergeCand > 0 ? mergeCand - 1 : 0)]; +#endif Mv tempBv = pu.bv; pu.tmMergeFlag = true; @@ -11144,6 +11486,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct if (pu.bv == tempBv) { numValidBv--; +#if JVET_AC0112_IBC_GPM + isSkipThisCand[mergeCtx.numValidMergeCand + mergeCandIbcGpm] = true; +#endif continue; } @@ -11159,9 +11504,28 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct #endif { numValidBv--; +#if JVET_AC0112_IBC_GPM + isSkipThisCand[mergeCtx.numValidMergeCand + mergeCandIbcGpm] = true; +#endif continue; } +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_GPM +#if JVET_AC0112_IBC_GPM +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType > 0) + { + isSkipThisCand[mergeCtx.numValidMergeCand + mergeCandIbcGpm] = true; + skipCandNumTm[mergeCtx.numValidMergeCand + mergeCand] = mergeCand > 0 ? skipCandNumTm[mergeCtx.numValidMergeCand + mergeCand - 1] + 1 : 1; + } + else +#endif + { + skipCandNumTm[mergeCtx.numValidMergeCand + mergeCand] = mergeCand > 0 ? skipCandNumTm[mergeCtx.numValidMergeCand + mergeCand - 1] : 0; + } +#endif +#else PU::spanMotionInfo(pu, mergeCtxTm); +#endif #if JVET_AA0070_RRIBC if (pu.cu->rribcFlipType == 0) @@ -11176,6 +11540,23 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct { m_pcRdCost->setDistParam(distParam, tmpOrgLumaFlipV, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); } +#endif +#if JVET_AC0112_IBC_LIC + if (pu.cu->ibcLicFlag) + { + Pel* piPred = predBuf.buf; + int predStride = predBuf.stride; + int height = predBuf.height; + int width = predBuf.width; + for (int h = 0; h < height; h++) + { + memcpy(piPred, piRefSrch + h * refStride + refStride * yPred + xPred, width * sizeof(Pel)); + piPred += predStride; + } + m_pcInterSearch->xLocalIlluComp(pu, COMPONENT_Y, pu.bv, predBuf); + distParam.cur = predBuf; + } + else #endif distParam.cur.buf = piRefSrch + refStride * yPred + xPred; @@ -11190,9 +11571,116 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct #endif double cost = (double)sad + (double)bitsCand * sqrtLambdaForFirstPass; +#if JVET_AC0112_IBC_CIIP + if (testIbcCiip) + { + const PredictionUnit *puBv = pu.cs->getPURestricted(pu.lumaPos().offset(xPred, yPred), pu, pu.chType); + int intraDir = puBv ? puBv->getIpmInfo(pu.lumaPos().offset(xPred, yPred)) : PLANAR_IDX; + if (intraDir != ibcCiipIntraList[0]) + { + ibcCiipIntraList[1] = intraDir; + } + else + { + ibcCiipIntraList[1] = ibcCiipIntraList[0] == PLANAR_IDX ? HOR_IDX : PLANAR_IDX; + } + intraDir = ibcCiipIntraList[1]; + if (!intraPredBufSet[intraDir]) + { + pu.ibcCiipFlag = true; + pu.intraDir[0] = intraDir; + intraPredBufSet[intraDir] = true; + intraPredBuf[intraDir] = m_acMergeBuffer[intraDir + IBC_GPM_MAX_NUM_UNI_CANDS].getBuf(localUnitArea); + m_pcIntraSearch->initPredIntraParams(pu, pu.Y(), *pu.cs->sps, 0); + m_pcIntraSearch->predIntraAng(COMPONENT_Y, intraPredBuf[intraDir].Y(), pu); + pu.ibcCiipFlag = false; + } + for (int dirIdx = 0; dirIdx < IBC_CIIP_MAX_NUM_INTRA_CANDS; dirIdx++) + { + int height = pu.lheight(); + int width = pu.lwidth(); + const Pel *pPredIbc = piRefSrch + refStride * yPred + xPred; + Pel *pPredDst = ibcCiipBuf.buf; + int dstStride = ibcCiipBuf.stride; + Pel *pPredIntra = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().buf; + int intraStride = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().stride; + m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, pPredIbc, refStride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height); + + distParam.cur.buf = ibcCiipBuf.buf; + distParam.cur.stride = ibcCiipBuf.stride; + + Distortion sad2 = distParam.distFunc(distParam); + unsigned int bitsCand2 = mergeCand + 1; +#if JVET_Z0084_IBC_TM + if (mergeCand == tempCS->sps->getMaxNumIBCMergeCand() - 1) +#else + if (mergeCand == tempCS->sps->getMaxNumMergeCand() - 1) +#endif + { + bitsCand2--; + } + bitsCand2 += dirIdx + 1; + if (dirIdx == IBC_CIIP_MAX_NUM_INTRA_CANDS - 1) + { + bitsCand2--; + } + bitsCand2++; // for ibc_mbvd_flag + double cost2 = (double)sad2 + (double)bitsCand2 * sqrtLambdaForFirstPass; + if (cost2 < ibcCiipBestSatdCost) + { + ibcCiipBestMergeCand = mergeCand+mergeCtx.numValidMergeCand; + ibcCiipBestIntraCand = dirIdx; + ibcCiipBestSatdCost = cost2; + } + } + } +#endif + +#if JVET_AC0112_IBC_GPM +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 0 && testIbcGpm) +#else + if (testIbcGpm) +#endif + { + ibcGpmCandNumValid++; + distParamSad.cur.buf = piRefSrch + refStride * yPred + xPred; + distParamSad.cur.stride = refBuf.stride; + ibcPredBuf[mergeCtx.numValidMergeCand + mergeCandIbcGpm] = m_acMergeBuffer[mergeCtx.numValidMergeCand + mergeCandIbcGpm].getBuf(localUnitArea); + ibcPredBuf[mergeCtx.numValidMergeCand + mergeCandIbcGpm].bufs[COMPONENT_Y].copyFrom(distParamSad.cur); + sadWholeBlk[mergeCtx.numValidMergeCand + mergeCandIbcGpm] = distParamSad.distFunc(distParamSad); + } +#endif + +#if JVET_AC0112_IBC_CIIP +#if JVET_AC0112_IBC_GPM + updateCandList(ModeIbcInfo(mergeCand+mergeCtx.numValidMergeCand, false, 0, false, 0, 0, 0, 0, 0), cost, rdModeList, candCostList, numMrgSATDCand); +#else + updateCandList(ModeIbcInfo(mergeCand+mergeCtx.numValidMergeCand, false, 0), cost, rdModeList, candCostList, numMrgSATDCand); +#endif +#else +#if JVET_AC0112_IBC_GPM + updateCandList(ModeIbcInfo(mergeCand+mergeCtx.numValidMergeCand, false, 0, 0, 0, 0, 0), cost, rdModeList, candCostList, numMrgSATDCand); +#else updateCandList(mergeCand+mergeCtx.numValidMergeCand, cost, rdModeList, candCostList, numMrgSATDCand); +#endif +#endif } #endif +#if JVET_AC0112_IBC_GPM + if (testIbcGpm && mergeCtxTm.numValidMergeCand > 0) + { + mergeCtxTmIbcGeo = mergeCtxTm; +#if JVET_AA0070_RRIBC + m_pcInterSearch->adjustIbcMergeRribcCand(pu, mergeCtxTmIbcGeo, 0, IBC_MRG_MAX_NUM_CANDS_MEM); +#endif + for (int i = 0; i < skipCandNumTm[mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand - 1]; i++) + { + isSkipThisCand[mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand - 1 - i] = true; + } + } +#endif + #if JVET_AA0061_IBC_MBVD #if JVET_AA0070_RRIBC int numValidBvIBC = mergeCtxTmp.numValidMergeCand; @@ -11268,16 +11756,109 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct { m_pcRdCost->setDistParam(distParam, tmpOrgLumaFlipV, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); } +#endif +#if JVET_AC0112_IBC_LIC + if (pu.cu->ibcLicFlag) + { + Pel* piPred = predBuf.buf; + int predStride = predBuf.stride; + int height = predBuf.height; + int width = predBuf.width; + for (int h = 0; h < height; h++) + { + memcpy(piPred, piRefSrch + h * refStride + refStride * yPred + xPred, width * sizeof(Pel)); + piPred += predStride; + } + m_pcInterSearch->xLocalIlluComp(pu, COMPONENT_Y, pu.bv, predBuf); + distParam.cur = predBuf; + } + else #endif distParam.cur.buf = piRefSrch + refStride * yPred + xPred; Distortion sad = distParam.distFunc(distParam); uint32_t bitsCand = PU::getIbcMbvdEstBits(pu, mmvdMergeCandtemp); +#if JVET_AC0112_IBC_CIIP + uint32_t ibcMbvdBits = bitsCand; +#endif bitsCand++; // for ibc_mbvd_flag double cost = (double)sad + (double)bitsCand * sqrtLambdaForFirstPass; + +#if JVET_AC0112_IBC_CIIP + if (testIbcCiip) + { + const PredictionUnit *puBv = pu.cs->getPURestricted(pu.lumaPos().offset(xPred, yPred), pu, pu.chType); + int intraDir = puBv ? puBv->getIpmInfo(pu.lumaPos().offset(xPred, yPred)) : PLANAR_IDX; + if (intraDir != ibcCiipIntraList[0]) + { + ibcCiipIntraList[1] = intraDir; + } + else + { + ibcCiipIntraList[1] = ibcCiipIntraList[0] == PLANAR_IDX ? HOR_IDX : PLANAR_IDX; + } + intraDir = ibcCiipIntraList[1]; + if (!intraPredBufSet[intraDir]) + { + pu.ibcCiipFlag = true; + pu.intraDir[0] = intraDir; + intraPredBufSet[intraDir] = true; + intraPredBuf[intraDir] = m_acMergeBuffer[intraDir + IBC_GPM_MAX_NUM_UNI_CANDS].getBuf(localUnitArea); + m_pcIntraSearch->initPredIntraParams(pu, pu.Y(), *pu.cs->sps, 0); + m_pcIntraSearch->predIntraAng(COMPONENT_Y, intraPredBuf[intraDir].Y(), pu); + pu.ibcCiipFlag = false; + } + for (int dirIdx = 0; dirIdx < IBC_CIIP_MAX_NUM_INTRA_CANDS; dirIdx++) + { + int height = pu.lheight(); + int width = pu.lwidth(); + const Pel *pPredIbc = piRefSrch + refStride * yPred + xPred; + Pel *pPredDst = ibcCiipBuf.buf; + int dstStride = ibcCiipBuf.stride; + Pel *pPredIntra = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().buf; + int intraStride = intraPredBuf[ibcCiipIntraList[dirIdx]].Y().stride; + m_pcIntraSearch->m_ibcCiipBlending(pPredDst, dstStride, pPredIbc, refStride, pPredIntra, intraStride, wIbc, wIntra, shift, width, height); + + distParam.cur.buf = ibcCiipBuf.buf; + distParam.cur.stride = ibcCiipBuf.stride; + + Distortion sad2 = distParam.distFunc(distParam); + uint32_t bitsCand2 = ibcMbvdBits; + bitsCand2++; // for ibc_mbvd_flag + bitsCand2 += dirIdx + 1; + if (dirIdx == IBC_CIIP_MAX_NUM_INTRA_CANDS - 1) + { + bitsCand2--; + } + double cost2 = (double)sad2 + (double)bitsCand2 * sqrtLambdaForFirstPass; + if (cost2 < ibcCiipBestSatdCost) + { + ibcCiipBestMergeCand = mmvdMergeCandtemp + mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand; + ibcCiipBestIntraCand = dirIdx; + ibcCiipBestSatdCost = cost2; + } + } + } +#endif + #if JVET_Z0084_IBC_TM +#if JVET_AC0112_IBC_CIIP +#if JVET_AC0112_IBC_GPM + updateCandList(ModeIbcInfo(mmvdMergeCandtemp + mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand, false, 0, false, 0, 0, 0, 0, 0), cost, rdModeList, candCostList + , numMrgSATDCand); +#else + updateCandList(ModeIbcInfo(mmvdMergeCandtemp + mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand, false, 0), cost, rdModeList, candCostList + , numMrgSATDCand); +#endif +#else +#if JVET_AC0112_IBC_GPM + updateCandList(ModeIbcInfo(mmvdMergeCandtemp + mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand, false, 0, 0, 0, 0, 0), cost, rdModeList, candCostList + , numMrgSATDCand); +#else updateCandList(mmvdMergeCandtemp + mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand, cost, rdModeList, candCostList , numMrgSATDCand); +#endif +#endif #else updateCandList(mmvdMergeCandtemp + mergeCtx.numValidMergeCand, cost, rdModeList, candCostList , numMrgSATDCand); @@ -11291,30 +11872,310 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct m_tmpStorageCUflipV.destroy(); #endif - // Try to limit number of candidates using SATD-costs - if (numValidBv) +#if JVET_AC0112_IBC_GPM + static_vector<int, IBC_GPM_MAX_TRY_WEIGHTED_SATD> geoSplitDirList; + static_vector<int, IBC_GPM_MAX_TRY_WEIGHTED_SATD> geoMergeCand0; + static_vector<int, IBC_GPM_MAX_TRY_WEIGHTED_SATD> geoMergeCand1; + static_vector<uint8_t, IBC_GPM_MAX_TRY_WEIGHTED_SATD> geoBldIdxList; + static_vector<double, IBC_GPM_MAX_TRY_WEIGHTED_SATD> geoSADCostList; + int numSATDCands = IBC_GPM_MAX_TRY_WEIGHTED_SATD; + double ibcGpmBestSatdCost = MAX_DOUBLE; + int bestCandidateIdx = 0; + int m_numIbcCandPerPar = 6; + if (testIbcGpm && ibcGpmCandNumValid > 0) { -#if JVET_AA0061_IBC_MBVD - numMrgSATDCand = std::min(numMrgSATDCand,numValidBv); - for (int i = 1; i < numMrgSATDCand; i++) -#else - numMrgSATDCand = numValidBv; - for (unsigned int i = 1; i < numValidBv; i++) -#endif + int bitsCandSplit = floorLog2(IBC_GPM_MAX_SPLIT_DIR_SECOND_SET_NUM) + 1; + + int wIdx = floorLog2(cu.lwidth()) - GEO_MIN_CU_LOG2; + int hIdx = floorLog2(cu.lheight()) - GEO_MIN_CU_LOG2; + for (int splitDir = 0; splitDir < GEO_NUM_PARTITION_MODE; splitDir++) { - if (candCostList[i] > MRG_FAST_RATIO*candCostList[0]) + if (!g_ibcGpmSecondSetSplitDir[splitDir] && g_GeoParams[splitDir][0] % 8 != 0) { - numMrgSATDCand = i; - break; + continue; } - } - } - else - { - tempCS->dist = 0; - tempCS->fracBits = 0; - tempCS->cost = MAX_DOUBLE; - tempCS->costDbOffset = 0; + int maskStride = 0, maskStride2 = 0; + int stepX = 1; + Pel* SADmask; + int16_t angle = g_GeoParams[splitDir][0]; + if (g_angle2mirror[angle] == 2) + { + maskStride = -GEO_WEIGHT_MASK_SIZE; + maskStride2 = -(int)cu.lwidth(); + SADmask = &g_globalGeoEncSADmask[g_angle2mask[g_GeoParams[splitDir][0]]][(GEO_WEIGHT_MASK_SIZE - 1 - g_weightOffset[splitDir][hIdx][wIdx][1]) * GEO_WEIGHT_MASK_SIZE + g_weightOffset[splitDir][hIdx][wIdx][0]]; + } + else if (g_angle2mirror[angle] == 1) + { + stepX = -1; + maskStride2 = cu.lwidth(); + maskStride = GEO_WEIGHT_MASK_SIZE; + SADmask = &g_globalGeoEncSADmask[g_angle2mask[g_GeoParams[splitDir][0]]][g_weightOffset[splitDir][hIdx][wIdx][1] * GEO_WEIGHT_MASK_SIZE + (GEO_WEIGHT_MASK_SIZE - 1 - g_weightOffset[splitDir][hIdx][wIdx][0])]; + } + else + { + maskStride = GEO_WEIGHT_MASK_SIZE; + maskStride2 = -(int)cu.lwidth(); + SADmask = &g_globalGeoEncSADmask[g_angle2mask[g_GeoParams[splitDir][0]]][g_weightOffset[splitDir][hIdx][wIdx][1] * GEO_WEIGHT_MASK_SIZE + g_weightOffset[splitDir][hIdx][wIdx][0]]; + } + Distortion sadSmall = 0, sadLarge = 0; + double tempCost = 0; +#if JVET_AA0070_RRIBC + m_pcRdCost->setDistParam(distParam, tmpOrgLuma, refBuf.buf, refBuf.stride, SADmask, maskStride, stepX, maskStride2, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y); +#else + if (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()) + { + const CompArea &area = cu.blocks[COMPONENT_Y]; + CompArea tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size()); + PelBuf tmpLuma = m_tmpStorageLCU->getBuf(tmpArea); + tmpLuma.rspSignal( tempCS->getOrgBuf().Y(), m_pcReshape->getFwdLUT() ); + m_pcRdCost->setDistParam(distParam, tmpLuma, refBuf.buf, refBuf.stride, SADmask, maskStride, stepX, maskStride2, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y); + } + else + { + m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), refBuf.buf, refBuf.stride, SADmask, maskStride, stepX, maskStride2, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y); + } +#endif + for (unsigned int mergeCand = 0; mergeCand < mergeCtx.numValidMergeCand; mergeCand++) + { + if (isSkipThisCand[mergeCand]) + { + continue; + } + distParam.cur = ibcPredBuf[mergeCand].Y(); + sadLarge = distParam.distFunc(distParam); + tempCost = (double)sadLarge; + m_geoMMVDCostList.insert(splitDir, 0, mergeCand, 0, tempCost); + sortCandList(tempCost, mergeCand, sadCostList0[splitDir], mergeCandList0[splitDir], m_numIbcCandPerPar); + sadSmall = sadWholeBlk[mergeCand] - sadLarge; + tempCost = (double)sadSmall; + m_geoMMVDCostList.insert(splitDir, 1, mergeCand, 0, tempCost); + sortCandList(tempCost, mergeCand, sadCostList1[splitDir], mergeCandList1[splitDir], m_numIbcCandPerPar); + } +#if JVET_Z0084_IBC_TM && IBC_TM_MRG + for (unsigned int mergeCand = 0; mergeCand < mergeCtxTm.numValidMergeCand; mergeCand++) + { + if (isSkipThisCand[mergeCtx.numValidMergeCand + mergeCand]) + { + continue; + } + distParam.cur = ibcPredBuf[mergeCtx.numValidMergeCand + mergeCand].Y(); + sadLarge = distParam.distFunc(distParam); + tempCost = (double)sadLarge; + m_geoMMVDCostList.insert(splitDir, 0, mergeCtx.numValidMergeCand + mergeCand, 0, tempCost); + sortCandList(tempCost, mergeCtx.numValidMergeCand + mergeCand, sadCostList0[splitDir], mergeCandList0[splitDir], m_numIbcCandPerPar); + sadSmall = sadWholeBlk[mergeCtx.numValidMergeCand + mergeCand] - sadLarge; + tempCost = (double)sadSmall; + m_geoMMVDCostList.insert(splitDir, 1, mergeCtx.numValidMergeCand + mergeCand, 0, tempCost); + sortCandList(tempCost, mergeCtx.numValidMergeCand + mergeCand, sadCostList1[splitDir], mergeCandList1[splitDir], m_numIbcCandPerPar); + } +#endif + for (unsigned int mergeCand = IBC_GPM_MAX_NUM_UNI_CANDS; mergeCand < IBC_GPM_MAX_NUM_UNI_CANDS + IBC_GPM_MAX_NUM_INTRA_CANDS; mergeCand++) + { + int intraIdx = mergeCand - IBC_GPM_MAX_NUM_UNI_CANDS; + int rdobuffer = ibcGpmIntraCandList[splitDir][0][intraIdx]; + distParam.cur = intraPredBuf[rdobuffer].Y(); + sadLarge = distParam.distFunc(distParam); + tempCost = (double)sadLarge; + m_geoMMVDCostList.insert(splitDir, 0, mergeCand, 0, tempCost); + sortIntraCandList(tempCost, mergeCand, intraSadCostList0[splitDir], intraCandList0[splitDir]); + + if (ibcGpmIntraCandList[splitDir][0][intraIdx] != ibcGpmIntraCandList[splitDir][1][intraIdx]) + { + rdobuffer = ibcGpmIntraCandList[splitDir][1][intraIdx]; + distParam.cur = intraPredBuf[rdobuffer].Y(); + sadLarge = distParam.distFunc(distParam); + } + sadSmall = sadIntraWholeBlk[rdobuffer] - sadLarge; + tempCost = (double)sadSmall; + m_geoMMVDCostList.insert(splitDir, 1, mergeCand, 0, tempCost); + sortIntraCandList(tempCost, mergeCand, intraSadCostList1[splitDir], intraCandList1[splitDir]); + } + } + for (int splitDir = 0; splitDir < GEO_NUM_PARTITION_MODE; splitDir++) + { + if (!g_ibcGpmSecondSetSplitDir[splitDir] && g_GeoParams[splitDir][0] % 8 != 0) + { + continue; + } + int numCandMerge0 = min(m_numIbcCandPerPar, (int)mergeCandList0[splitDir].size()); + int numCandIntra0 = (int)intraCandList0[splitDir].size(); + int numCandPart0 = numCandMerge0 + numCandIntra0; + for (int candIdx0 = 0; candIdx0 < numCandPart0; candIdx0++) + { + int mergeCand0 = candIdx0 < numCandMerge0 ? mergeCandList0[splitDir][candIdx0] : intraCandList0[splitDir][candIdx0-numCandMerge0]; + int numCandMerge1 = min(m_numIbcCandPerPar, (int)mergeCandList1[splitDir].size()); + int numCandIntra1 = candIdx0 < numCandMerge0 ? (int)intraCandList1[splitDir].size() : 0; + int numCandPart1 = numCandMerge1 + numCandIntra1; + int candStart1 = 0; + for (int candIdx1 = candStart1; candIdx1 < numCandPart1; candIdx1++) + { + int mergeCand1 = candIdx1 < numCandMerge1 ? mergeCandList1[splitDir][candIdx1] : intraCandList1[splitDir][candIdx1-numCandMerge1]; + if (mergeCand0 == mergeCand1) + { + continue; + } + if ((candIdx0 < numCandMerge0 && candIdx1 < numCandMerge1) || (candIdx0 >= numCandMerge0 && candIdx1 >= numCandMerge1)) + { + continue; + } + if (isSkipThisCand[mergeCand0] || isSkipThisCand[mergeCand1]) + { + continue; + } + double tempCost = m_geoMMVDCostList.singleDistList[0][splitDir][mergeCand0][0].cost + m_geoMMVDCostList.singleDistList[1][splitDir][mergeCand1][0].cost; + updateGeoIbcCandList(tempCost, splitDir, mergeCand0, mergeCand1, 0, 0, geoSADCostList, geoSplitDirList, geoMergeCand0, geoMergeCand1, numSATDCands); + } + } + } + +#if JVET_AA0070_RRIBC + m_pcRdCost->setDistParam(distParam, tmpOrgLuma, m_acMergeBuffer[0].Y(), sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); +#else + if (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()) + { + const CompArea &area = cu.blocks[COMPONENT_Y]; + CompArea tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size()); + PelBuf tmpLuma = m_tmpStorageLCU->getBuf(tmpArea); + tmpLuma.rspSignal( tempCS->getOrgBuf().Y(), m_pcReshape->getFwdLUT() ); + m_pcRdCost->setDistParam(distParam, tmpLuma, m_acMergeBuffer[0].Y(), sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } + else + { + m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), m_acMergeBuffer[0].Y(), sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } +#endif + int numberGeoCandChecked = (int)geoSADCostList.size(); + for (uint8_t bldIdx = 0; bldIdx < IBC_GPM_NUM_BLENDING; bldIdx++) + { + for (uint8_t candidateIdx = 0; candidateIdx < numberGeoCandChecked; candidateIdx++) + { + int splitDir = geoSplitDirList[candidateIdx]; + int mergeCand0 = geoMergeCand0[candidateIdx]; + int mergeCand1 = geoMergeCand1[candidateIdx]; + geoCombinations[candidateIdx * IBC_GPM_NUM_BLENDING + bldIdx] = m_acGeoWeightedBuffer[candidateIdx * IBC_GPM_NUM_BLENDING + bldIdx].getBuf(localUnitArea); + int isIntra0 = (mergeCand0 >= IBC_GPM_MAX_NUM_UNI_CANDS) ? 1 : 0; + int isIntra1 = (mergeCand1 >= IBC_GPM_MAX_NUM_UNI_CANDS) ? 1 : 0; + int bitsCand = 1 + (g_GeoParams[splitDir][0] % 8 == 0 ? 4 : bitsCandSplit); + if (IBC_GPM_NUM_BLENDING > 1) + { + bitsCand++; + if (bldIdx > 0) + { + bitsCand += 2; + } + } + { + PelUnitBuf predSrc0, predSrc1; + if (isIntra0) + { + int intraIdx0 = mergeCand0 - IBC_GPM_MAX_NUM_UNI_CANDS; + int rdoBuffer = ibcGpmIntraCandList[splitDir][0][intraIdx0]; + predSrc0 = intraPredBuf[rdoBuffer]; + bitsCand += intraIdx0 + 1; + if (intraIdx0 == IBC_GPM_MAX_NUM_INTRA_CANDS - 1) + { + bitsCand--; + } + } + else + { + predSrc0 = ibcPredBuf[mergeCand0]; + int tempMergeCand0 = mergeCand0 > mergeCtx.numValidMergeCand ? mergeCand0 - mergeCtx.numValidMergeCand : mergeCand0; + bitsCand += tempMergeCand0 + 1; + if (tempMergeCand0 == tempCS->sps->getMaxNumIBCMergeCand() - 1) + { + bitsCand--; + } + } + if (isIntra1) + { + int intraIdx1 = mergeCand1 - IBC_GPM_MAX_NUM_UNI_CANDS; + int rdoBuffer = ibcGpmIntraCandList[splitDir][1][intraIdx1]; + predSrc1 = intraPredBuf[rdoBuffer]; + bitsCand += intraIdx1 + 1; + if (intraIdx1 == IBC_GPM_MAX_NUM_INTRA_CANDS - 1) + { + bitsCand--; + } + } + else + { + predSrc1 = ibcPredBuf[mergeCand1]; + int tempMergeCand1 = mergeCand1 > mergeCtx.numValidMergeCand ? mergeCand1 - mergeCtx.numValidMergeCand : mergeCand1; + bitsCand += tempMergeCand1 + 1; + if (tempMergeCand1 == tempCS->sps->getMaxNumIBCMergeCand() - 1) + { + bitsCand--; + } + } + m_pcInterSearch->weightedGeoBlkRounded(pu, splitDir, bldIdx, CHANNEL_TYPE_LUMA, geoCombinations[candidateIdx*IBC_GPM_NUM_BLENDING+bldIdx], predSrc0, predSrc1); + } + distParam.cur = geoCombinations[candidateIdx * IBC_GPM_NUM_BLENDING + bldIdx].Y(); + Distortion sad = distParam.distFunc(distParam); + double updateCost = (double)sad; + updateCost += bitsCand * sqrtLambdaForFirstPass; + if (updateCost < ibcGpmBestSatdCost) + { + bestCandidateIdx = candidateIdx * IBC_GPM_NUM_BLENDING + bldIdx; + ibcGpmBestSatdCost = updateCost; + } + } + } + } +#endif + + // Try to limit number of candidates using SATD-costs + if (numValidBv) + { +#if JVET_AA0061_IBC_MBVD + numMrgSATDCand = std::min(numMrgSATDCand,numValidBv); + for (int i = 1; i < numMrgSATDCand; i++) +#else + numMrgSATDCand = numValidBv; + for (unsigned int i = 1; i < numValidBv; i++) +#endif + { + if (candCostList[i] > MRG_FAST_RATIO*candCostList[0]) + { + numMrgSATDCand = i; + break; + } + } + +#if JVET_AC0112_IBC_CIIP + if (testIbcCiip && ibcCiipBestSatdCost != MAX_DOUBLE) + { + if (ibcCiipBestSatdCost < candCostList[candCostList.size() - 1]) + { + rdModeList[numMrgSATDCand].mergeCand = ibcCiipBestMergeCand; + rdModeList[numMrgSATDCand].isCIIP = true; + rdModeList[numMrgSATDCand].dirIdx = ibcCiipBestIntraCand; + numMrgSATDCand++; + } + } +#endif +#if JVET_AC0112_IBC_GPM + if (testIbcGpm && ibcGpmBestSatdCost != MAX_DOUBLE && ibcGpmBestSatdCost < candCostList[candCostList.size() - 1]) + { + uint8_t candidateIdx = bestCandidateIdx; + int splitDir = geoSplitDirList[candidateIdx/IBC_GPM_NUM_BLENDING]; + int mergeCand0 = geoMergeCand0[candidateIdx/IBC_GPM_NUM_BLENDING]; + int mergeCand1 = geoMergeCand1[candidateIdx/IBC_GPM_NUM_BLENDING]; + int bldIdx = candidateIdx%IBC_GPM_NUM_BLENDING; +#if JVET_AC0112_IBC_CIIP + rdModeList.at(numMrgSATDCand++) = ModeIbcInfo(0, false, 0, true, mergeCand0, mergeCand1, splitDir, bldIdx, candidateIdx); +#else + rdModeList.at(numMrgSATDCand++) = ModeIbcInfo(0, true, mergeCand0, mergeCand1, splitDir, bldIdx, candidateIdx); +#endif + } +#endif + } + else + { + tempCS->dist = 0; + tempCS->fracBits = 0; + tempCS->cost = MAX_DOUBLE; + tempCS->costDbOffset = 0; tempCS->initStructData(encTestMode.qp); return; } @@ -11331,7 +12192,29 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct { for (unsigned int mrgHADIdx = 0; mrgHADIdx < numMrgSATDCand; mrgHADIdx++) { +#if JVET_AC0112_IBC_CIIP + unsigned int mergeCand = rdModeList[mrgHADIdx].mergeCand; + if (numResidualPass == 1 && rdModeList[mrgHADIdx].isCIIP) + { + continue; + } +#if JVET_AC0112_IBC_GPM + if (rdModeList[mrgHADIdx].isIbcGpm) + { + mergeCand = rdModeList[mrgHADIdx].mergeIdx0 < IBC_GPM_MAX_NUM_UNI_CANDS ? rdModeList[mrgHADIdx].mergeIdx0 : rdModeList[mrgHADIdx].mergeIdx1; + } +#endif +#else +#if JVET_AC0112_IBC_GPM + unsigned int mergeCand = rdModeList[mrgHADIdx].mergeCand; + if (rdModeList[mrgHADIdx].isIbcGpm) + { + mergeCand = rdModeList[mrgHADIdx].mergeIdx0 < IBC_GPM_MAX_NUM_UNI_CANDS ? rdModeList[mrgHADIdx].mergeIdx0 : rdModeList[mrgHADIdx].mergeIdx1; + } +#else unsigned int mergeCand = rdModeList[mrgHADIdx]; +#endif +#endif if (!(numResidualPass == 1 && candHasNoResidual[mergeCand] == 1)) { if (!(bestIsSkip && (numResidualPass == 0))) @@ -11352,6 +12235,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct #if INTER_LIC cu.LICFlag = false; #endif +#if JVET_AC0112_IBC_LIC + cu.ibcLicFlag = false; +#endif #if JVET_AA0070_RRIBC cu.rribcFlipType = 0; @@ -11359,10 +12245,17 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct PredictionUnit &pu = tempCS->addPU(cu, partitioner.chType);// tempCS->addPU(cu); pu.intraDir[0] = DC_IDX; // set intra pred for ibc block pu.intraDir[1] = PLANAR_IDX; // set intra pred for ibc block +#if JVET_AC0112_IBC_CIIP + pu.ibcCiipFlag = rdModeList[mrgHADIdx].isCIIP; + pu.ibcCiipIntraIdx = rdModeList[mrgHADIdx].dirIdx; +#endif cu.mmvdSkip = false; pu.mmvdMergeFlag = false; pu.regularMergeFlag = false; cu.geoFlag = false; +#if JVET_AC0112_IBC_GPM + pu.ibcGpmFlag = rdModeList[mrgHADIdx].isIbcGpm; +#endif #if JVET_AA0061_IBC_MBVD #if JVET_Z0084_IBC_TM && IBC_TM_MRG int numPreviousBv = mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand; @@ -11384,14 +12277,38 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct { pu.tmMergeFlag = true; mergeCand -= mergeCtx.numValidMergeCand; +#if JVET_AC0112_IBC_GPM + if (pu.ibcGpmFlag) + { + mergeCtxTmIbcGeo.setMergeInfo(pu, mergeCand); + PU::spanMotionInfo(pu, mergeCtxTmIbcGeo); + } + else + { +#endif mergeCtxTm.setMergeInfo(pu, mergeCand); PU::spanMotionInfo(pu, mergeCtxTm); +#if JVET_AC0112_IBC_GPM + } +#endif } else #endif { +#if JVET_AC0112_IBC_GPM + if (pu.ibcGpmFlag) + { + mergeCtxIbcGeo.setMergeInfo(pu, mergeCand); + PU::spanMotionInfo(pu, mergeCtxIbcGeo); + } + else + { +#endif mergeCtx.setMergeInfo(pu, mergeCand); PU::spanMotionInfo(pu, mergeCtx); +#if JVET_AC0112_IBC_GPM + } +#endif } #if JVET_AA0061_IBC_MBVD } @@ -11402,7 +12319,101 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct const bool chroma = !pu.cu->isSepTree(); #endif // MC +#if JVET_AC0112_IBC_GPM + if (pu.ibcGpmFlag) + { + int candidateIdx = rdModeList[mrgHADIdx].combIdx; + pu.ibcGpmMergeIdx0 = rdModeList[mrgHADIdx].mergeIdx0; + pu.ibcGpmMergeIdx1 = rdModeList[mrgHADIdx].mergeIdx1; + if (rdModeList[mrgHADIdx].mergeIdx0 < IBC_GPM_MAX_NUM_UNI_CANDS && rdModeList[mrgHADIdx].mergeIdx0 >= mergeCtx.numValidMergeCand) + { + pu.ibcGpmMergeIdx0 = pu.ibcGpmMergeIdx0 - mergeCtx.numValidMergeCand; + } + if (rdModeList[mrgHADIdx].mergeIdx1 < IBC_GPM_MAX_NUM_UNI_CANDS && rdModeList[mrgHADIdx].mergeIdx1 >= mergeCtx.numValidMergeCand) + { + pu.ibcGpmMergeIdx1 = pu.ibcGpmMergeIdx1 - mergeCtx.numValidMergeCand; + } + pu.ibcGpmSplitDir = rdModeList[mrgHADIdx].splitDir; + pu.ibcGpmBldIdx = rdModeList[mrgHADIdx].bldIdx; + if (chroma) + { + m_pcInterSearch->motionCompensation(pu, REF_PIC_LIST_0, false, chroma); + if (pu.ibcGpmMergeIdx0 >= IBC_GPM_MAX_NUM_UNI_CANDS) + { + pu.intraDir[1] = ibcGpmIntraCandList[pu.ibcGpmSplitDir][0][pu.ibcGpmMergeIdx0 - IBC_GPM_MAX_NUM_UNI_CANDS]; + } + else + { + pu.intraDir[1] = ibcGpmIntraCandList[pu.ibcGpmSplitDir][1][pu.ibcGpmMergeIdx1 - IBC_GPM_MAX_NUM_UNI_CANDS]; + } + if (!intraPredBufSet[0]) + { + intraPredBuf[0] = m_acMergeBuffer[0 + IBC_GPM_MAX_NUM_UNI_CANDS].getBuf(localUnitArea); + intraPredBufSet[0] = true; + } + m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Cb()); + m_pcIntraSearch->predIntraAng(COMPONENT_Cb, intraPredBuf[0].Cb(), pu); + m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Cr()); + m_pcIntraSearch->predIntraAng(COMPONENT_Cr, intraPredBuf[0].Cr(), pu); + pu.intraDir[1] = PLANAR_IDX; + PelUnitBuf predBuf = cu.cs->getPredBuf(pu); + if (pu.ibcGpmMergeIdx0 < IBC_GPM_MAX_NUM_UNI_CANDS) + { + m_pcInterSearch->weightedGeoBlkRounded(pu, pu.ibcGpmSplitDir, pu.ibcGpmBldIdx, CHANNEL_TYPE_CHROMA, geoCombinations[candidateIdx], predBuf, intraPredBuf[0]); + } + else + { + m_pcInterSearch->weightedGeoBlkRounded(pu, pu.ibcGpmSplitDir, pu.ibcGpmBldIdx, CHANNEL_TYPE_CHROMA, geoCombinations[candidateIdx], intraPredBuf[0], predBuf); + } + } + tempCS->getPredBuf().copyFrom(geoCombinations[candidateIdx]); + } + else +#endif m_pcInterSearch->motionCompensation(pu,REF_PIC_LIST_0, true, chroma); +#if JVET_AC0112_IBC_CIIP + if (pu.ibcCiipFlag) + { + if (pu.ibcCiipIntraIdx > 0) + { + int xPred = pu.bv.getHor(); + int yPred = pu.bv.getVer(); + const PredictionUnit *puBv = pu.cs->getPURestricted(pu.lumaPos().offset(xPred, yPred), pu, pu.chType); + int intraDir = puBv ? puBv->getIpmInfo(pu.lumaPos().offset(xPred, yPred)) : PLANAR_IDX; + if (intraDir != ibcCiipIntraList[0]) + { + ibcCiipIntraList[1] = intraDir; + } + else + { + ibcCiipIntraList[1] = ibcCiipIntraList[0] == PLANAR_IDX ? HOR_IDX : PLANAR_IDX; + } + intraDir = ibcCiipIntraList[1]; + if (!intraPredBufSet[intraDir]) + { + pu.intraDir[0] = intraDir; + intraPredBufSet[intraDir] = true; + intraPredBuf[intraDir] = m_acMergeBuffer[intraDir + IBC_GPM_MAX_NUM_UNI_CANDS].getBuf(localUnitArea); + m_pcIntraSearch->initPredIntraParams(pu, pu.Y(), *pu.cs->sps, 0); + m_pcIntraSearch->predIntraAng(COMPONENT_Y, intraPredBuf[intraDir].Y(), pu); + } + } + m_pcIntraSearch->geneWeightedPred( COMPONENT_Y, tempCS->getPredBuf(pu).Y(), pu, tempCS->getPredBuf(pu).Y(), intraPredBuf[ibcCiipIntraList[pu.ibcCiipIntraIdx]].Y() ); + + if (chroma) + { + pu.intraDir[1] = ibcCiipIntraList[pu.ibcCiipIntraIdx]; + m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Cb()); + m_pcIntraSearch->predIntraAng(COMPONENT_Cb, intraPredBuf[pu.intraDir[1]].Cb(), pu); + m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Cr()); + m_pcIntraSearch->predIntraAng(COMPONENT_Cr, intraPredBuf[pu.intraDir[1]].Cr(), pu); + m_pcIntraSearch->geneWeightedPred( COMPONENT_Cb, tempCS->getPredBuf(pu).Cb(), pu, tempCS->getPredBuf(pu).Cb(), intraPredBuf[pu.intraDir[1]].Cb() ); + m_pcIntraSearch->geneWeightedPred( COMPONENT_Cr, tempCS->getPredBuf(pu).Cr(), pu, tempCS->getPredBuf(pu).Cr(), intraPredBuf[pu.intraDir[1]].Cr() ); + } + pu.intraDir[0] = DC_IDX; + pu.intraDir[1] = PLANAR_IDX; + } +#endif m_CABACEstimator->getCtx() = m_CurrCtx->start; m_pcInterSearch->encodeResAndCalcRdInterCU(*tempCS, partitioner, (numResidualPass != 0), true, chroma); @@ -11425,6 +12436,13 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct xCheckChromaQPOffset( *tempCS, partitioner ); +#if JVET_AC0112_IBC_CIIP + if((tempCS->getCU(partitioner.chType))->skip && (tempCS->getCU(partitioner.chType))->firstPU->ibcCiipFlag) + { + tempCS->cost = MAX_DOUBLE; + tempCS->costDbOffset = 0; + } +#endif DTRACE_MODE_COST(*tempCS, m_pcRdCost->getLambda()); xCheckBestMode(tempCS, bestCS, partitioner, encTestMode); @@ -11463,9 +12481,75 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best return; } - tempCS->initStructData(encTestMode.qp); + m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false; - m_bestModeUpdated = tempCS->useDbCost = bestCS->useDbCost = false; +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC + double curBestCost = bestCS->cost; + bool searchedByHash[1] = {false}; + Distortion tempCost[1] = {0}; + Distortion searchCost[2] = {0, 0}; +#endif +#if JVET_AC0112_IBC_CIIP + const UnitArea localUnitArea(tempCS->area.chromaFormat, Area(0, 0, tempCS->area.Y().width, tempCS->area.Y().height)); + PelBuf ibcCiipIntraBuf[3]; + bool skipSecondIbcCiipPass = false; + Distortion intraCandCost[2] = {0, 0}; +#endif + +#if JVET_AC0112_IBC_LIC + bool skipSecondLicPass = false; + int licIdxMax = tempCS->slice->getSPS()->getUseIbcLic() && (tempCS->area.lx() > 0 || tempCS->area.ly() > 0) ? 2 : 1; + if (tempCS->area.lwidth() * tempCS->area.lheight() < 32 || tempCS->area.lwidth() * tempCS->area.lheight() > 256) + { + licIdxMax = 1; + } +#endif +#if JVET_AC0112_IBC_CIIP + int ibcCiipLoopNum = (tempCS->sps->getUseIbcCiip() && tempCS->slice->getSliceType() == I_SLICE && (tempCS->area.lwidth() * tempCS->area.lheight() >= 32) && tempCS->area.lwidth() <= 32 && tempCS->area.lheight() <= 32 && (tempCS->area.lx() > 0 || tempCS->area.ly() > 0)) ? 2 : 1; +#if JVET_AA0070_RRIBC + if (isSecondPass && ibcCiipLoopNum > 1) + { + CodedCUInfo& relatedCU = ((EncModeCtrlMTnoRQT *)m_modeCtrl)->getBlkInfo(partitioner.currArea()); + if (relatedCU.isRribcCoded) + { + ibcCiipLoopNum = 1; + } + } +#endif + for (int ibcCiipIdx = 0; ibcCiipIdx < ibcCiipLoopNum; ibcCiipIdx++) + { +#if JVET_AC0112_IBC_LIC + if (ibcCiipIdx > 0) + { + CodingUnit* preBestCu = bestCS->getCU(partitioner.chType); + if (preBestCu && preBestCu->ibcLicFlag) + { + continue; + } + licIdxMax = 1; + } + for (int licIdx = 0; licIdx < licIdxMax; licIdx++) + { + if (licIdx == 1 && skipSecondLicPass) + { + continue; + } +#endif + if (ibcCiipIdx == 1 && skipSecondIbcCiipPass) + { + continue; + } +#else +#if JVET_AC0112_IBC_LIC + for (int licIdx = 0; licIdx < licIdxMax; licIdx++) + { + if (licIdx == 1 && skipSecondLicPass) + { + continue; + } +#endif +#endif + tempCS->initStructData(encTestMode.qp); CodingUnit &cu = tempCS->addCU(CS::getArea(*tempCS, tempCS->area, partitioner.chType), partitioner.chType); @@ -11478,6 +12562,9 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best cu.qp = encTestMode.qp; cu.imv = 0; cu.sbtInfo = 0; +#if JVET_AC0112_IBC_LIC + cu.ibcLicFlag = licIdx; +#endif CU::addPUs(cu); @@ -11486,11 +12573,61 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best PredictionUnit& pu = *cu.firstPU; cu.mmvdSkip = false; pu.mmvdMergeFlag = false; +#if JVET_AC0112_IBC_CIIP + pu.ibcCiipFlag = ibcCiipIdx; +#endif pu.regularMergeFlag = false; #if INTER_LIC cu.LICFlag = false; #endif +#if JVET_AC0112_IBC_CIIP + if (ibcCiipIdx > 0) + { + int ibcCiipIntraList[IBC_CIIP_MAX_NUM_INTRA_CANDS] = {PLANAR_IDX, HOR_IDX}; + IntraPrediction::deriveDimdMode(tempCS->picture->getRecoBuf(tempCS->area.Y()), tempCS->area.Y(), cu); + cu.timdMode = m_pcIntraSearch->deriveTimdMode(tempCS->picture->getRecoBuf(cu.Y()), cu.Y(), cu); + ibcCiipIntraList[0] = MAP131TO67(cu.timdMode); + ibcCiipIntraList[1] = ibcCiipIntraList[0] == HOR_IDX ? PLANAR_IDX : HOR_IDX; + m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Y(), true); + for (int i = 0; i < IBC_CIIP_MAX_NUM_INTRA_CANDS; i++) + { + pu.ibcCiipIntraIdx = i; + ibcCiipIntraBuf[0] = m_ciipBuffer[i].getBuf(localUnitArea.Y()); + pu.intraDir[0] = ibcCiipIntraList[i]; + m_pcIntraSearch->initPredIntraParams(pu, pu.Y(), *pu.cs->sps, 0); + m_pcIntraSearch->predIntraAng(COMPONENT_Y, ibcCiipIntraBuf[0], pu); + pu.interDir = 1; + pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF; +#if JVET_AA0070_RRIBC + pu.cu->rribcFlipType = 0; + m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap, tempCost, &ibcCiipIntraBuf[0], isSecondPass); +#else + m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap, tempCost, &ibcCiipIntraBuf[0]); +#endif + intraCandCost[i] = tempCost[0]; + } + pu.ibcCiipIntraIdx = intraCandCost[0] <= intraCandCost[1] ? 0 : 1; + tempCost[0] = intraCandCost[0] <= intraCandCost[1] ? intraCandCost[0] : intraCandCost[1]; + ibcCiipIntraBuf[0] = m_ciipBuffer[pu.ibcCiipIntraIdx].getBuf(localUnitArea.Y()); +#if INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS + const bool chroma = !(CS::isDualITree(*tempCS)); +#else + const bool chroma = !pu.cu->isSepTree(); +#endif + if (chroma) + { + ibcCiipIntraBuf[1] = m_ciipBuffer[0].getBuf(localUnitArea.Cb()); + ibcCiipIntraBuf[2] = m_ciipBuffer[0].getBuf(localUnitArea.Cr()); + pu.intraDir[1] = ibcCiipIntraList[pu.ibcCiipIntraIdx]; + m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Cb()); + m_pcIntraSearch->predIntraAng(COMPONENT_Cb, ibcCiipIntraBuf[1], pu); + m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Cr()); + m_pcIntraSearch->predIntraAng(COMPONENT_Cr, ibcCiipIntraBuf[2], pu); + } + } +#endif + pu.intraDir[0] = DC_IDX; // set intra pred for ibc block pu.intraDir[1] = PLANAR_IDX; // set intra pred for ibc block @@ -11498,13 +12635,69 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF; // last idx in the list #if JVET_AA0070_RRIBC pu.cu->rribcFlipType = 0; +#if JVET_AC0112_IBC_CIIP + bool bValid = m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap, tempCost, pu.ibcCiipFlag ? &ibcCiipIntraBuf[0] : NULL, isSecondPass, pu.ibcCiipFlag ? NULL : searchedByHash); +#else +#if JVET_AC0112_IBC_LIC + bool bValid = m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap, tempCost, isSecondPass, searchedByHash); +#else bool bValid = m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap, isSecondPass); +#endif +#endif +#else +#if JVET_AC0112_IBC_CIIP + bool bValid = m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap, tempCost, pu.ibcCiipFlag ? &ibcCiipIntraBuf[0] : NULL, pu.ibcCiipFlag ? NULL : searchedByHash); +#else +#if JVET_AC0112_IBC_LIC + bool bValid = m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap, tempCost, searchedByHash); #else bool bValid = m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap); #endif +#endif +#endif +#if JVET_AC0112_IBC_LIC + if (licIdx == 0 && searchedByHash[0]) + { + skipSecondLicPass = true; + } +#endif +#if JVET_AC0112_IBC_CIIP + if (ibcCiipIdx == 0 && searchedByHash[0]) + { + skipSecondIbcCiipPass = true; + } +#endif if (bValid) { +#if JVET_AC0112_IBC_LIC +#if JVET_AC0112_IBC_CIIP + if (ibcCiipIdx == 0) + { + searchCost[licIdx] = tempCost[0]; + } +#else + searchCost[licIdx] = tempCost[0]; +#endif + if (licIdx > 0 && searchCost[0] > 0 && searchCost[1] > 1.05 * searchCost[0]) + { + continue; + } +#endif +#if JVET_AC0112_IBC_CIIP +#if JVET_AC0112_IBC_LIC + if (licIdx == 0) + { + searchCost[ibcCiipIdx] = tempCost[0]; + } +#else + searchCost[ibcCiipIdx] = tempCost[0]; +#endif + if (ibcCiipIdx > 0 && searchCost[0] > 0 && searchCost[1] > 1.2 * searchCost[0]) + { + continue; + } +#endif PU::spanMotionInfo(pu); #if INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS const bool chroma = !(CS::isDualITree(*tempCS)); @@ -11513,6 +12706,22 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best #endif // MC m_pcInterSearch->motionCompensation(pu, REF_PIC_LIST_0, true, chroma); +#if JVET_AC0112_IBC_CIIP + if (pu.ibcCiipFlag) + { + m_pcIntraSearch->geneWeightedPred( COMPONENT_Y, cu.cs->getPredBuf(pu).Y(), pu, cu.cs->getPredBuf(pu).Y(), ibcCiipIntraBuf[0] ); +#if INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS + const bool chroma = !(CS::isDualITree(*tempCS)); +#else + const bool chroma = !pu.cu->isSepTree(); +#endif + if (chroma) + { + m_pcIntraSearch->geneWeightedPred( COMPONENT_Cb, cu.cs->getPredBuf(pu).Cb(), pu, cu.cs->getPredBuf(pu).Cb(), ibcCiipIntraBuf[1] ); + m_pcIntraSearch->geneWeightedPred( COMPONENT_Cr, cu.cs->getPredBuf(pu).Cr(), pu, cu.cs->getPredBuf(pu).Cr(), ibcCiipIntraBuf[2] ); + } + } +#endif { @@ -11541,6 +12750,18 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best { xCalDebCost( *tempCS, partitioner ); } +#if JVET_AC0112_IBC_CIIP + if (ibcCiipIdx == 0 && tempCS->cost > curBestCost * 1.1) + { + skipSecondIbcCiipPass = true; + } +#endif +#if JVET_AC0112_IBC_LIC + if (licIdx == 0 && tempCS->cost > curBestCost * 1.4) + { + skipSecondLicPass = true; + } +#endif DTRACE_MODE_COST(*tempCS, m_pcRdCost->getLambda()); xCheckBestMode(tempCS, bestCS, partitioner, encTestMode); @@ -11554,7 +12775,19 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best tempCS->fracBits = 0; tempCS->cost = MAX_DOUBLE; tempCS->costDbOffset = 0; +#if JVET_AC0112_IBC_CIIP + if (ibcCiipIdx == 0) + { + break; + } +#endif } +#if JVET_AC0112_IBC_LIC + } +#endif +#if JVET_AC0112_IBC_CIIP + } +#endif } // check ibc mode in encoder RD ////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index b96b0f42ad1fd7678e5346de773be1f7953656ce..a74ba15aa19e4de3607a5a59756fbf7760f12590 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1664,6 +1664,15 @@ void EncLib::xInitSPS( SPS& sps ) sps.setIBCFlag ( m_IBCMode); #if JVET_AA0061_IBC_MBVD sps.setUseIbcMbvd ( m_ibcMbvd ); +#endif +#if JVET_AC0112_IBC_CIIP + sps.setUseIbcCiip ( m_ibcCiip ); +#endif +#if JVET_AC0112_IBC_GPM + sps.setUseIbcGpm ( m_ibcGpm ); +#endif +#if JVET_AC0112_IBC_LIC + sps.setUseIbcLic ( m_ibcLic ); #endif sps.setWrapAroundEnabledFlag ( m_wrapAround ); #if MULTI_HYP_PRED diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index 9a542c4d6674c719a409d7a4438cbd675b3c6f57..127109a313a617db0342c96eec6905ca1ced0d3e 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -221,6 +221,9 @@ void InterSearch::destroy() } m_tmpStorageLCU.destroy(); m_tmpAffiStorage.destroy(); +#if JVET_AC0112_IBC_CIIP + m_ibcCiipBuffer.destroy(); +#endif if ( m_tmpAffiError != NULL ) { @@ -375,6 +378,9 @@ void InterSearch::init( EncCfg* pcEncCfg, #else m_tmpAffiDeri[0] = new int[MAX_CU_SIZE * MAX_CU_SIZE]; m_tmpAffiDeri[1] = new int[MAX_CU_SIZE * MAX_CU_SIZE]; +#endif +#if JVET_AC0112_IBC_CIIP + m_ibcCiipBuffer.create(UnitArea(cform, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE))); #endif m_pTempPel = new Pel[maxCUWidth*maxCUHeight]; m_affMVListMaxSize = (pcEncCfg->getIntraPeriod() == (uint32_t)-1) ? AFFINE_ME_LIST_SIZE_LD : AFFINE_ME_LIST_SIZE; @@ -1606,10 +1612,18 @@ end: // based on xMotionEstimation #if JVET_AA0070_RRIBC +#if JVET_AC0112_IBC_CIIP +void InterSearch::xIBCEstimation(PredictionUnit &pu, PelUnitBuf &origBuf, PelBuf &ibcCiipIntraBuf, Mv pcMvPred[3][2], Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY, int numRribcType) +#else void InterSearch::xIBCEstimation(PredictionUnit &pu, PelUnitBuf &origBuf, Mv pcMvPred[3][2], Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY, int numRribcType) +#endif +#else +#if JVET_AC0112_IBC_CIIP +void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, PelBuf &ibcCiipIntraBuf, Mv *pcMvPred, Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY) #else void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pcMvPred, Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY) #endif +#endif { const int iPicWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples(); const int iPicHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples(); @@ -1676,6 +1690,26 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc } #endif +#if JVET_AC0112_IBC_CIIP + if (pu.ibcCiipFlag) + { + const Pel *pelOrig = pcPatternKey->buf; + Pel *pelIntra = ibcCiipIntraBuf.buf; + int height = ibcCiipIntraBuf.height; + int width = ibcCiipIntraBuf.width; + for( int y = 0; y < height; y++ ) + { + for( int x = 0; x < width; x++ ) + { + pelIntra[x] = (pelOrig[x] << 1) - pelIntra[x]; + } + pelIntra += ibcCiipIntraBuf.stride; + pelOrig += pcPatternKey->stride; + } + pcPatternKey = (CPelBuf*)&ibcCiipIntraBuf; + } +#endif + m_lumaClpRng = pu.cs->slice->clpRng(COMPONENT_Y); Picture* refPic = pu.cu->slice->getPic(); const CPelBuf refBuf = refPic->getRecoBuf(pu.blocks[COMPONENT_Y]); @@ -1698,6 +1732,9 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pc m_pcRdCost->setCostScale(0); m_cDistParam.useMR = false; +#if JVET_AC0112_IBC_LIC + m_cDistParam.useMR = pu.cu->ibcLicFlag; +#endif #if !JVET_AA0070_RRIBC m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode); #endif @@ -2090,10 +2127,26 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR } #if JVET_AA0070_RRIBC +#if JVET_AC0112_IBC_CIIP +bool InterSearch::predIBCSearch( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, Distortion* bvSearchCost, PelBuf* ibcCiipIntraBuf, bool isSecondPass, bool* searchedByHash) +#else +#if JVET_AC0112_IBC_LIC +bool InterSearch::predIBCSearch( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, Distortion* bvSearchCost, bool isSecondPass, bool* searchedByHash) +#else bool InterSearch::predIBCSearch( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, bool isSecondPass) +#endif +#endif +#else +#if JVET_AC0112_IBC_CIIP +bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, Distortion* bvSearchCost, PelBuf* ibcCiipIntraBuf, bool* searchedByHash) +#else +#if JVET_AC0112_IBC_LIC +bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, Distortion* bvSearchCost, bool* searchedByHash) #else bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap) #endif +#endif +#endif { Mv cMvSrchRngLT; Mv cMvSrchRngRB; @@ -2106,6 +2159,12 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const #endif #if JVET_AA0070_RRIBC CodedCUInfo& relatedCU = ((EncModeCtrlMTnoRQT *)m_modeCtrl)->getBlkInfo(partitioner.currArea()); +#if JVET_AC0112_IBC_LIC + if (isSecondPass && relatedCU.isRribcCoded && cu.ibcLicFlag) + { + return false; + } +#endif #endif for (auto &pu : CU::traversePUs(cu)) @@ -2122,6 +2181,18 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const numRribcType = 1; } } +#if JVET_AC0112_IBC_CIIP + if (pu.ibcCiipFlag) + { + numRribcType = 1; + } +#endif +#if JVET_AC0112_IBC_LIC + if (pu.cu->ibcLicFlag) + { + numRribcType = 1; + } +#endif Mv cMv; cMv.setZero(); int iBvpNum = 2; @@ -2137,19 +2208,63 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const // prepare imv = 2 accuracy predictor info pu.cu->imv = 2; +#if JVET_AC0112_IBC_CIIP +#if JVET_AC0112_IBC_LIC + if (!pu.ibcCiipFlag && !pu.cu->ibcLicFlag) + { +#else + if (!pu.ibcCiipFlag) + { +#endif +#else +#if JVET_AC0112_IBC_LIC + if (!pu.cu->ibcLicFlag) + { +#endif +#endif #if JVET_Z0084_IBC_TM && IBC_TM_AMVP PU::fillIBCMvpCand(pu, amvpInfo4Pel[i], this); #else PU::fillIBCMvpCand(pu, amvpInfo4Pel[i]); #endif +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC + m_amvpInfo4Pel[i] = amvpInfo4Pel[i]; + } + else + { + amvpInfo4Pel[i] = m_amvpInfo4Pel[i]; + } +#endif // prepare imv = 0 accuracy predictor info pu.cu->imv = 0; +#if JVET_AC0112_IBC_CIIP +#if JVET_AC0112_IBC_LIC + if (!pu.ibcCiipFlag && !pu.cu->ibcLicFlag) + { +#else + if (!pu.ibcCiipFlag) + { +#endif +#else +#if JVET_AC0112_IBC_LIC + if (!pu.cu->ibcLicFlag) + { +#endif +#endif #if JVET_Z0084_IBC_TM && IBC_TM_AMVP PU::fillIBCMvpCand(pu, amvpInfo[i], this); #else PU::fillIBCMvpCand(pu, amvpInfo[i]); #endif +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC + m_amvpInfo[i] = amvpInfo[i]; + } + else + { + amvpInfo[i] = m_amvpInfo[i]; + } +#endif // store in full pel accuracy, shift before use in search cMvPred[i][0] = amvpInfo[i].mvCand[0]; @@ -2168,20 +2283,64 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const /// ibc search pu.cu->imv = 2; AMVPInfo amvpInfo4Pel; +#if JVET_AC0112_IBC_CIIP +#if JVET_AC0112_IBC_LIC + if (!pu.ibcCiipFlag && !pu.cu->ibcLicFlag) + { +#else + if (!pu.ibcCiipFlag) + { +#endif +#else +#if JVET_AC0112_IBC_LIC + if (!pu.cu->ibcLicFlag) + { +#endif +#endif #if JVET_Z0084_IBC_TM && IBC_TM_AMVP PU::fillIBCMvpCand(pu, amvpInfo4Pel, this); #else PU::fillIBCMvpCand(pu, amvpInfo4Pel); #endif +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC + m_amvpInfo4Pel = amvpInfo4Pel; + } + else + { + amvpInfo4Pel = m_amvpInfo4Pel; + } +#endif pu.cu->imv = 0;// (Int)cu.cs->sps->getUseIMV(); // set as IMV=0 initially Mv cMv, cMvPred[2]; AMVPInfo amvpInfo; +#if JVET_AC0112_IBC_CIIP +#if JVET_AC0112_IBC_LIC + if (!pu.ibcCiipFlag && !pu.cu->ibcLicFlag) + { +#else + if (!pu.ibcCiipFlag) + { +#endif +#else +#if JVET_AC0112_IBC_LIC + if (!pu.cu->ibcLicFlag) + { +#endif +#endif #if JVET_Z0084_IBC_TM && IBC_TM_AMVP PU::fillIBCMvpCand(pu, amvpInfo, this); #else PU::fillIBCMvpCand(pu, amvpInfo); #endif +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC + m_amvpInfo = amvpInfo; + } + else + { + amvpInfo = m_amvpInfo; + } +#endif // store in full pel accuracy, shift before use in search cMvPred[0] = amvpInfo.mvCand[0]; @@ -2200,23 +2359,57 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const } #endif +#if JVET_AC0112_IBC_CIIP + const CompArea &area = pu.blocks[COMPONENT_Y]; + const UnitArea localUnitArea(area.chromaFormat, Area(0, 0, area.width, area.height)); + PelBuf ibcCiipIntraBuff = m_ibcCiipBuffer.getBuf(localUnitArea.Y()); + if (pu.ibcCiipFlag) + { + ibcCiipIntraBuff.copyFrom(*ibcCiipIntraBuf); + } +#endif + +#if JVET_AC0112_IBC_CIIP + if (m_pcEncCfg->getIBCHashSearch() && !pu.ibcCiipFlag) +#else if (m_pcEncCfg->getIBCHashSearch()) +#endif { #if JVET_AA0070_RRIBC xxIBCHashSearch(pu, cMvPred, iBvpNum, cMv, bvpIdxBest, ibcHashMap, amvpInfo4Pel, numRribcType); #else xxIBCHashSearch(pu, cMvPred, iBvpNum, cMv, bvpIdxBest, ibcHashMap); +#endif +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC + if (searchedByHash) + { + *searchedByHash = true; + } #endif } if (cMv.getHor() == 0 && cMv.getVer() == 0) { +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC + if (searchedByHash) + { + *searchedByHash = false; + } +#endif // if hash search does not work or is not enabled PelUnitBuf origBuf = pu.cs->getOrgBuf(pu); #if JVET_AA0070_RRIBC +#if JVET_AC0112_IBC_CIIP + xIBCEstimation(pu, origBuf, ibcCiipIntraBuff, cMvPred, cMv, cost, localSearchRangeX, localSearchRangeY, numRribcType); +#else xIBCEstimation(pu, origBuf, cMvPred, cMv, cost, localSearchRangeX, localSearchRangeY, numRribcType); +#endif +#else +#if JVET_AC0112_IBC_CIIP + xIBCEstimation(pu, origBuf, ibcCiipIntraBuff, cMvPred, cMv, cost, localSearchRangeX, localSearchRangeY); #else xIBCEstimation(pu, origBuf, cMvPred, cMv, cost, localSearchRangeX, localSearchRangeY); +#endif #endif } @@ -2226,6 +2419,12 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const } /// ibc search ///////////////////////////////////////////////////////// +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC + if (bvSearchCost) + { + *bvSearchCost = cost; + } +#endif #if JVET_Z0131_IBC_BVD_BINARIZATION m_pcRdCost->setPredictors(cMvPred); m_pcRdCost->setCostScale(0); diff --git a/source/Lib/EncoderLib/InterSearch.h b/source/Lib/EncoderLib/InterSearch.h index 59e5d4f7cbb32300f5ddbdfe2ea6fd3cf28b53ce..bcb590c276cd1c0524c3e0aea0b0eb4c049f63ad 100644 --- a/source/Lib/EncoderLib/InterSearch.h +++ b/source/Lib/EncoderLib/InterSearch.h @@ -248,6 +248,84 @@ struct ModeInfo }; #endif +#if JVET_AC0112_IBC_CIIP +struct ModeIbcInfo +{ +#if JVET_AC0112_IBC_GPM + uint32_t mergeCand; + bool isCIIP; + int dirIdx; + bool isIbcGpm; + int mergeIdx0; + int mergeIdx1; + int splitDir; + int bldIdx; + int combIdx; + ModeIbcInfo() : mergeCand(0), isCIIP(false), dirIdx(0), isIbcGpm(false), mergeIdx0(0), mergeIdx1(0), splitDir(0), bldIdx(0), combIdx(0) + {} + ModeIbcInfo(const uint32_t mergeCand, const bool isCIIP, const int dirIdx, const bool isIbcGpm, const int mergeIdx0, const int mergeIdx1, const int splitDir, const int bldIdx, const int combIdx + ) : + mergeCand(mergeCand), isCIIP(isCIIP), dirIdx(dirIdx), isIbcGpm(isIbcGpm), mergeIdx0(mergeIdx0), mergeIdx1(mergeIdx1), splitDir(splitDir), bldIdx(bldIdx), combIdx(combIdx) + {} + ModeIbcInfo(const CodingUnit cu, const PredictionUnit pu) + { + mergeCand = pu.mergeIdx; + isCIIP = pu.ibcCiipFlag; + dirIdx = pu.ibcCiipIntraIdx; + isIbcGpm = pu.ibcGpmFlag; + mergeIdx0 = pu.ibcGpmMergeIdx0; + mergeIdx1 = pu.ibcGpmMergeIdx1; + splitDir = pu.ibcGpmSplitDir; + bldIdx = pu.ibcGpmBldIdx; + } +#else + uint32_t mergeCand; + bool isCIIP; + int dirIdx; + ModeIbcInfo() : mergeCand(0), isCIIP(false), dirIdx(0) + {} + ModeIbcInfo(const uint32_t mergeCand, const bool isCIIP, const int dirIdx + ) : + mergeCand(mergeCand), isCIIP(isCIIP), dirIdx(dirIdx) + {} + ModeIbcInfo(const CodingUnit cu, const PredictionUnit pu) + { + mergeCand = pu.mergeIdx; + isCIIP = pu.ibcCiipFlag; + dirIdx = pu.ibcCiipIntraIdx; + } +#endif +}; +#endif + +#if JVET_AC0112_IBC_GPM && !JVET_AC0112_IBC_CIIP +struct ModeIbcInfo +{ + uint32_t mergeCand; + bool isIbcGpm; + int mergeIdx0; + int mergeIdx1; + int splitDir; + int bldIdx; + int combIdx; + ModeIbcInfo() : mergeCand(0), isIbcGpm(false), mergeIdx0(0), mergeIdx1(0), splitDir(0), bldIdx(0), combIdx(0) + {} + ModeIbcInfo(const uint32_t mergeCand, const bool isIbcGpm, const int mergeIdx0, const int mergeIdx1, const int splitDir, const int bldIdx, const int combIdx + ) : + mergeCand(mergeCand), isIbcGpm(isIbcGpm), mergeIdx0(mergeIdx0), mergeIdx1(mergeIdx1), splitDir(splitDir), bldIdx(bldIdx), combIdx(combIdx) + {} + ModeIbcInfo(const CodingUnit cu, const PredictionUnit pu) + { + mergeCand = pu.mergeIdx; + isIbcGpm = pu.ibcGpmFlag; + mergeIdx0 = pu.ibcGpmMergeIdx0; + mergeIdx1 = pu.ibcGpmMergeIdx1; + splitDir = pu.ibcGpmSplitDir; + bldIdx = pu.ibcGpmBldIdx; + } +}; +#endif + #if INTER_LIC class EncFastLICCtrl { @@ -307,6 +385,18 @@ private: #else int* m_tmpAffiDeri[2]; #endif +#if JVET_AC0112_IBC_CIIP + PelStorage m_ibcCiipBuffer; +#endif +#if JVET_AC0112_IBC_CIIP || JVET_AC0112_IBC_LIC +#if JVET_AA0070_RRIBC + AMVPInfo m_amvpInfo[3]; + AMVPInfo m_amvpInfo4Pel[3]; +#else + AMVPInfo m_amvpInfo; + AMVPInfo m_amvpInfo4Pel; +#endif +#endif #if MULTI_HYP_PRED MergeCtx m_geoMrgCtx; @@ -674,10 +764,26 @@ public: /// set ME search range void setAdaptiveSearchRange ( int iDir, int iRefIdx, int iSearchRange) { CHECK(iDir >= MAX_NUM_REF_LIST_ADAPT_SR || iRefIdx>=int(MAX_IDX_ADAPT_SR), "Invalid index"); m_aaiAdaptSR[iDir][iRefIdx] = iSearchRange; } #if JVET_AA0070_RRIBC +#if JVET_AC0112_IBC_CIIP + bool predIBCSearch ( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, Distortion* bvSearchCost = NULL, PelBuf* ciipIbcBuff = NULL, bool isSecondPass = false, bool* searchedByHash = NULL ); +#else +#if JVET_AC0112_IBC_LIC + bool predIBCSearch ( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, Distortion* bvSearchCost = NULL, bool isSecondPass = false, bool* searchedByHash = NULL ); +#else bool predIBCSearch ( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, bool isSecondPass = false ); +#endif +#endif void xIntraPatternSearch ( PredictionUnit& pu, IntTZSearchStruct& cStruct, Mv& rcMv, Distortion& ruiCost, Mv* cMvSrchRngLT, Mv* cMvSrchRngRB, Mv* pcMvPred, int rribcFlipType ); +#else +#if JVET_AC0112_IBC_CIIP + bool predIBCSearch ( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, Distortion* bvSearchCost = NULL, PelBuf* ciipIbcBuff = NULL, bool* searchedByHash = NULL); +#else +#if JVET_AC0112_IBC_LIC + bool predIBCSearch ( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, Distortion* bvSearchCost = NULL, bool* searchedByHash = NULL); #else bool predIBCSearch ( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap); +#endif +#endif void xIntraPatternSearch ( PredictionUnit& pu, IntTZSearchStruct& cStruct, Mv& rcMv, Distortion& ruiCost, Mv* cMvSrchRngLT, Mv* cMvSrchRngRB, Mv* pcMvPred ); #endif void xSetIntraSearchRange ( PredictionUnit& pu, int iRoiWidth, int iRoiHeight, const int localSearchRangeX, const int localSearchRangeY, Mv& rcMvSrchRngLT, Mv& rcMvSrchRngRB); @@ -690,11 +796,19 @@ public: m_defaultCachedBvs.currCnt = 0; } #if JVET_AA0070_RRIBC +#if JVET_AC0112_IBC_CIIP + void xIBCEstimation(PredictionUnit &pu, PelUnitBuf &origBuf, PelBuf &ciipIbcIntraBuff, Mv pcMvPred[3][2], Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY, int numRribcType); +#else void xIBCEstimation(PredictionUnit &pu, PelUnitBuf &origBuf, Mv pcMvPred[3][2], Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY, int numRribcType); +#endif void xIBCSearchMVCandUpdate( Distortion uiSad, int x, int y, Distortion *uiSadBestCand, Mv *cMVCand); int xIBCSearchMVChromaRefine( PredictionUnit &pu, int iRoiWidth, int iRoiHeight, int cuPelX, int cuPelY, Distortion *uiSadBestCand, Mv *cMVCand, int rribcFlipType ); +#else +#if JVET_AC0112_IBC_CIIP + void xIBCEstimation ( PredictionUnit& pu, PelUnitBuf& origBuf, PelBuf &ciipIbcIntraBuff, Mv *pcMvPred, Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY); #else void xIBCEstimation ( PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pcMvPred, Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY); +#endif void xIBCSearchMVCandUpdate ( Distortion uiSad, int x, int y, Distortion* uiSadBestCand, Mv* cMVCand); int xIBCSearchMVChromaRefine( PredictionUnit& pu, int iRoiWidth, int iRoiHeight, int cuPelX, int cuPelY, Distortion* uiSadBestCand, Mv* cMVCand ); #endif diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 4d97426276d5b2841b370f6183a23c242739e029..f382e297355dfcac6e58bf4554282c8e7f0852ac 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -1621,6 +1621,15 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) WRITE_UVLC(IBC_MRG_MAX_NUM_CANDS - pcSPS->getMaxNumIBCMergeCand(), "six_minus_max_num_ibc_merge_cand"); #if JVET_AA0061_IBC_MBVD WRITE_FLAG( pcSPS->getUseIbcMbvd() ? 1 : 0, "sps_ibc_mbvd_enabled_flag" ); +#endif +#if JVET_AC0112_IBC_CIIP + WRITE_FLAG( pcSPS->getUseIbcCiip() ? 1 : 0, "sps_ibc_ciip_enabled_flag" ); +#endif +#if JVET_AC0112_IBC_GPM + WRITE_FLAG( pcSPS->getUseIbcGpm() ? 1 : 0, "sps_ibc_gpm_enabled_flag" ); +#endif +#if JVET_AC0112_IBC_LIC + WRITE_FLAG( pcSPS->getUseIbcLic() ? 1 : 0, "sps_ibc_lic_enabled_flag" ); #endif } #if !JVET_S0074_SPS_REORDER