diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 76fd1f61365192974d7c829703e6f738073e58d8..b33cb34a48fdfb8583a87e36694dd9b91f11c96e 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -854,6 +854,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setIBCHashSearchMaxCand ( m_IBCHashSearchMaxCand ); m_cEncLib.setIBCHashSearchRange4SmallBlk ( m_IBCHashSearchRange4SmallBlk ); m_cEncLib.setIBCFastMethod ( m_IBCFastMethod ); +#if JVET_AA0061_IBC_MBVD + m_cEncLib.setIbcMbvd ( m_ibcMbvd ); +#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 869e21c862f3b690ebb022404568776c3060b761..dd451e192fe718649e56cc3bc197728338d9277c 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1101,6 +1101,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ( "IBCHashSearchMaxCand", m_IBCHashSearchMaxCand, 256u, "Max candidates for hash based IBC search") ( "IBCHashSearchRange4SmallBlk", m_IBCHashSearchRange4SmallBlk, 256u, "Small block search range in based IBC search") ( "IBCFastMethod", m_IBCFastMethod, 6u, "Fast methods for IBC") +#if JVET_AA0061_IBC_MBVD + ("IBCMBVD", m_ibcMbvd, true, "IBC MMVD 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") @@ -4944,6 +4947,9 @@ void EncAppCfg::xPrintParameter() msg(VERBOSE, "ACT:%d ", m_useColorTrans); msg(VERBOSE, "PLT:%d ", m_PLTMode); msg(VERBOSE, "IBC:%d ", m_IBCMode); +#if JVET_AA0061_IBC_MBVD + msg( VERBOSE, "IBCMBVD:%d ", m_ibcMbvd ); +#endif msg( VERBOSE, "HashME:%d ", m_HashME ); msg( VERBOSE, "WrapAround:%d ", m_wrapAround); if( m_wrapAround ) diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 4170416e34b9a67ab0e1cda53f45e7f7a351fe0a..06b451d8dcdc193347bee0a8eae64e3b6094bf6d 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -464,6 +464,9 @@ protected: unsigned m_IBCHashSearchMaxCand; unsigned m_IBCHashSearchRange4SmallBlk; unsigned m_IBCFastMethod; +#if JVET_AA0061_IBC_MBVD + bool m_ibcMbvd; +#endif bool m_wrapAround; unsigned m_wrapAroundOffset; diff --git a/source/Lib/CommonLib/Buffer.cpp b/source/Lib/CommonLib/Buffer.cpp index 2f73ff97c8d6730293a9aebee430ac701632c6c8..41850a46415a38c40580d12e8576449732331b2b 100644 --- a/source/Lib/CommonLib/Buffer.cpp +++ b/source/Lib/CommonLib/Buffer.cpp @@ -1216,6 +1216,46 @@ void AreaBuf<Pel>::rspSignal( const AreaBuf<Pel> &toReshape, std::vector<Pel>& p } } +#if JVET_AA0070_RRIBC +template<> +void AreaBuf<Pel>::flipSignal(bool isFlipHor) +{ + Pel *tempPel; + Size tSize(width, height); + tempPel = new Pel[tSize.area()]; + PelBuf tmpBuf = PelBuf(tempPel, tSize); + copyBufferCore(buf, stride, tmpBuf.buf, tmpBuf.stride, tmpBuf.width, tmpBuf.height); + + Pel *dstbuf = buf; + Pel *srcbuf = tmpBuf.buf; + if (isFlipHor) + { + for (unsigned y = 0; y < height; y++) + { + for (unsigned x = 0; x < width; x++) + { + dstbuf[x] = srcbuf[width - 1 - x]; + } + dstbuf += stride; + srcbuf += tmpBuf.stride; + } + } + else + { + for (unsigned y = 0; y < height; y++) + { + for (unsigned x = 0; x < width; x++) + { + dstbuf[x] = srcbuf[(height - 1 - y) * tmpBuf.stride + x]; + } + dstbuf += stride; + } + } + + delete[] tempPel; +} +#endif + template<> void AreaBuf<Pel>::rspSignalAllAndSubtract( const AreaBuf<Pel> &buffer1, const AreaBuf<Pel> &buffer2, std::vector<Pel>& pLUT ) { diff --git a/source/Lib/CommonLib/Buffer.h b/source/Lib/CommonLib/Buffer.h index 5a67cf41dabac313632da090d30b6ff6b7ff265a..701f1f6af8a5478a617eaa6dc6ac03bfcca5cddd 100644 --- a/source/Lib/CommonLib/Buffer.h +++ b/source/Lib/CommonLib/Buffer.h @@ -206,6 +206,10 @@ struct AreaBuf : public Size void toLast ( const ClpRng& clpRng ); +#if JVET_AA0070_RRIBC + void flipSignal(bool isFlipHor); +#endif + void rspSignal ( std::vector<Pel>& pLUT ); void rspSignal ( const AreaBuf<const Pel>& other, std::vector<Pel>& pLUT ); void rspSignal ( const AreaBuf<Pel> &toReshape, std::vector<Pel>& pLUT ); diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index af2b778f3014f7c6969ce02b90e2086e583a83f7..5c17fe4b1b18966d083e988200eec812d0c07723 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -654,7 +654,7 @@ static const int MMVD_MRG_MAX_RD_NUM = 20; static const int MMVD_MRG_MAX_RD_NUM = MRG_MAX_NUM_CANDS; #endif static const int MMVD_MRG_MAX_RD_BUF_NUM = (MMVD_MRG_MAX_RD_NUM + 1);///< increase buffer size by 1 -#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED +#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED || JVET_AA0061_IBC_MBVD static const int LAST_MERGE_MMVD_IDX_CABAC = 5; #endif #if JVET_W0097_GPM_MMVD_TM @@ -748,6 +748,9 @@ static const int THRES_AFFINE = 4; #if !MERGE_ENC_OPT static const int NUM_MRG_SATD_CAND = 4; #endif +#if JVET_AA0061_IBC_MBVD +static const int NUM_IBC_MRG_SATD_CAND = 3; +#endif static const double MRG_FAST_RATIO = 1.25; static const int NUM_AFF_MRG_SATD_CAND = 2; #if AFFINE_MMVD @@ -1021,6 +1024,15 @@ static const int CHROMA_REFINEMENT_CANDIDATES = 8; /// 8 candidates BV to choose static const int IBC_FAST_METHOD_NOINTRA_IBCCBF0 = 0x01; static const int IBC_FAST_METHOD_BUFFERBV = 0X02; static const int IBC_FAST_METHOD_ADAPTIVE_SEARCHRANGE = 0X04; +#if JVET_AA0061_IBC_MBVD +static const int IBC_MBVD_BASE_NUM = 5; +static const int IBC_MBVD_STEP_NUM = 20; // number of distance offset +static const int IBC_MBVD_OFFSET_DIR = 4; // (+, 0); (-, 0); (0, +); (0, -); +static const int IBC_MBVD_MAX_REFINE_NUM = IBC_MBVD_STEP_NUM * IBC_MBVD_OFFSET_DIR; ///< max number of candidate from a base candidate +static const int IBC_MBVD_NUM = IBC_MBVD_BASE_NUM * IBC_MBVD_MAX_REFINE_NUM; ///< total number of IBC mmvd candidate +static const int IBC_MBVD_SIZE_ENC = 8; +static const int ADAPTIVE_SUB_GROUP_SIZE_IBC_MBVD = IBC_MBVD_MAX_REFINE_NUM; +#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 4258d75e88064aae67af583182063ec4247d0f8a..f7b2a4dfa2b2280b73f26bce7c8bde7ea300bb57 100644 --- a/source/Lib/CommonLib/ContextModelling.cpp +++ b/source/Lib/CommonLib/ContextModelling.cpp @@ -324,6 +324,23 @@ unsigned DeriveCtx::CtxBMMrgFlag(const CodingUnit& cu) return ctxId; } #endif + +#if JVET_AA0070_RRIBC +unsigned DeriveCtx::CtxRribcFlipType(const CodingUnit& cu) +{ + const CodingStructure *cs = cu.cs; + unsigned ctxId = 0; + + const CodingUnit *cuLeft = cs->getCURestricted(cu.lumaPos().offset(-1, 0), cu, CH_L); + ctxId = (cuLeft && cuLeft->predMode == MODE_IBC && !cuLeft->firstPU->mergeFlag && cuLeft->rribcFlipType) ? 1 : 0; + + const CodingUnit *cuAbove = cs->getCURestricted(cu.lumaPos().offset(0, -1), cu, CH_L); + ctxId += (cuAbove && cuAbove->predMode == MODE_IBC && !cuAbove->firstPU->mergeFlag && cuAbove->rribcFlipType) ? 1 : 0; + + return ctxId; +} +#endif + unsigned DeriveCtx::CtxAffineFlag( const CodingUnit& cu ) { const CodingStructure *cs = cu.cs; @@ -498,6 +515,13 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx ) #if MULTI_HYP_PRED pu.addHypData.clear(); pu.numMergedAddHyps = 0; +#endif +#if JVET_AA0070_RRIBC + pu.cu->rribcFlipType = rribcFlipTypes[candIdx]; + } + else + { + pu.cu->rribcFlipType = 0; #endif } pu.cu->BcwIdx = ( interDirNeighbours[candIdx] == 3 ) ? BcwIdx[candIdx] : BCW_DEFAULT; @@ -1164,6 +1188,93 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx) PU::restrictBiPredMergeCandsOne(pu); } +#if JVET_AA0061_IBC_MBVD +bool MergeCtx::setIbcMbvdMergeCandiInfo(PredictionUnit& pu, int candIdx, int candIdxMaped) +{ + const int mvShift = MV_FRACTIONAL_BITS_DIFF + 2; + const int refMvdCands[IBC_MBVD_STEP_NUM] = { 1 << mvShift , 2 << mvShift , 4 << mvShift , 8 << mvShift , 12 << mvShift , 16 << mvShift , 24 << mvShift , 32 << mvShift , 40 << mvShift , 48 << mvShift , 56 << mvShift , + 64 << mvShift , 72 << mvShift , 80 << mvShift , 88 << mvShift , 96 << mvShift , 104 << mvShift , 112 << mvShift , 120 << mvShift , 128 << mvShift }; + int fPosGroup = 0; + int fPosBaseIdx = 0; + int fPosStep = 0; + int tempIdx = 0; + int fPosPosition = 0; + Mv tempMv; + + if(candIdxMaped == -1) + { + candIdxMaped = candIdx; + } + tempIdx = candIdxMaped; + + fPosGroup = tempIdx / (IBC_MBVD_BASE_NUM * IBC_MBVD_MAX_REFINE_NUM); + tempIdx = tempIdx - fPosGroup * (IBC_MBVD_BASE_NUM * IBC_MBVD_MAX_REFINE_NUM); + fPosBaseIdx = tempIdx / IBC_MBVD_MAX_REFINE_NUM; + tempIdx = tempIdx - fPosBaseIdx * (IBC_MBVD_MAX_REFINE_NUM); + fPosStep = tempIdx / IBC_MBVD_OFFSET_DIR; + fPosPosition = tempIdx - fPosStep * (IBC_MBVD_OFFSET_DIR); + int offset = refMvdCands[fPosStep]; + + const int refList0 = ibcMbvdBaseBv[fPosBaseIdx][0].refIdx; + const int xDir[] = {1, -1, 0, 0, 1, -1, 1, -1, 2, -2, 2, -2, 1, 1, -1, -1}; + const int yDir[] = {0, 0, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 2, -2, 2, -2}; + + if (refList0 != -1) + { + tempMv = Mv(xDir[fPosPosition] * offset, yDir[fPosPosition] * offset); +#if JVET_AA0070_RRIBC + //check the BVD direction and base BV flip direction + if ((rribcFlipTypes[fPosBaseIdx] == 1) && (yDir[fPosPosition] != 0)) + { + return true; + } + if ((rribcFlipTypes[fPosBaseIdx] == 2) && (xDir[fPosPosition] != 0)) + { + return true; + } +#endif + pu.interDir = 1; + pu.mv[REF_PIC_LIST_0] = ibcMbvdBaseBv[fPosBaseIdx][0].mv + tempMv; + pu.refIdx[REF_PIC_LIST_0] = refList0; + pu.mv[REF_PIC_LIST_1] = Mv(0, 0); + pu.refIdx[REF_PIC_LIST_1] = -1; + } + + pu.ibcMbvdMergeFlag = true; + pu.ibcMbvdMergeIdx = candIdx; + pu.mergeFlag = true; + pu.mergeType = MRG_TYPE_IBC; + + pu.mvd[REF_PIC_LIST_0] = Mv(); + pu.mvd[REF_PIC_LIST_1] = Mv(); + pu.mvpIdx[REF_PIC_LIST_0] = NOT_VALID; + pu.mvpIdx[REF_PIC_LIST_1] = NOT_VALID; + pu.mvpNum[REF_PIC_LIST_0] = NOT_VALID; + pu.mvpNum[REF_PIC_LIST_1] = NOT_VALID; + + pu.cu->BcwIdx = (interDirNeighbours[fPosBaseIdx] == 3) ? BcwIdx[fPosBaseIdx] : BCW_DEFAULT; + + for (int refList = 0; refList < 2; refList++) + { + if (pu.refIdx[refList] >= 0) + { + pu.mv[refList].clipToStorageBitDepth(); + } + } + 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_AA0070_RRIBC + pu.cu->rribcFlipType = rribcFlipTypes[fPosBaseIdx]; +#endif +#if MULTI_HYP_PRED + pu.addHypData.clear(); + pu.numMergedAddHyps = 0; +#endif + return false; +} +#endif + #if JVET_V0130_INTRA_TMP unsigned DeriveCtx::CtxTmpFlag(const CodingUnit& cu) { diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h index 446f3ad05a1a3f6eff54a2789c968d84640ec599..2bc404197eb1586b3aaf337065564aa0e3ef2876 100644 --- a/source/Lib/CommonLib/ContextModelling.h +++ b/source/Lib/CommonLib/ContextModelling.h @@ -560,6 +560,9 @@ public: uint8_t BcwIdx[NUM_MERGE_CANDS]; #if INTER_LIC bool LICFlags[NUM_MERGE_CANDS]; +#endif +#if JVET_AA0070_RRIBC + int rribcFlipTypes[NUM_MERGE_CANDS]; #endif unsigned char interDirNeighbours[NUM_MERGE_CANDS]; #if MULTI_HYP_PRED @@ -574,6 +577,9 @@ public: uint8_t BcwIdx [ MRG_MAX_NUM_CANDS ]; #if INTER_LIC bool LICFlags [ MRG_MAX_NUM_CANDS ]; +#endif +#if JVET_AA0070_RRIBC + int rribcFlipTypes[MRG_MAX_NUM_CANDS]; #endif unsigned char interDirNeighbours[ MRG_MAX_NUM_CANDS ]; #if MULTI_HYP_PRED @@ -593,6 +599,10 @@ public: void setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx, int candIdxMaped = -1); #else void setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx); +#endif +#if JVET_AA0061_IBC_MBVD + MvField ibcMbvdBaseBv[IBC_MBVD_BASE_NUM][2]; + bool setIbcMbvdMergeCandiInfo(PredictionUnit& pu, int candIdx, int candIdxMaped = -1); #endif bool mmvdUseAltHpelIf [ MMVD_BASE_MV_NUM ]; #if (JVET_Y0134_TMVP_NAMVP_CAND_REORDERING && JVET_W0090_ARMC_TM) || JVET_Z0075_IBC_HMVP_ENLARGE @@ -685,6 +695,9 @@ unsigned CtxAffineFlag( const CodingUnit& cu ); #if JVET_X0049_ADAPT_DMVR unsigned CtxBMMrgFlag(const CodingUnit& cu); #endif +#if JVET_AA0070_RRIBC +unsigned CtxRribcFlipType(const CodingUnit& cu); +#endif unsigned CtxPredModeFlag( const CodingUnit& cu ); unsigned CtxIBCFlag(const CodingUnit& cu); unsigned CtxMipFlag ( const CodingUnit& cu ); diff --git a/source/Lib/CommonLib/Contexts.cpp b/source/Lib/CommonLib/Contexts.cpp index 24568d429a95caf310338b9a7979eff8897edc71..a5164509bd83c1c9b69125ca7863bb883d5c5820 100644 --- a/source/Lib/CommonLib/Contexts.cpp +++ b/source/Lib/CommonLib/Contexts.cpp @@ -1152,6 +1152,53 @@ const CtxSet ContextSetCfg::AfMmvdOffsetStep = ContextSetCfg::addCtxSet }); #endif +#if JVET_AA0061_IBC_MBVD +const CtxSet ContextSetCfg::IbcMbvdFlag = ContextSetCfg::addCtxSet +({ + { 18, }, + { 18, }, + { CNU, }, + { 6, }, + { 5, }, + { DWS, }, + { 18, }, + { 18, }, + { DWE, }, + { 117, }, + { 117, }, + }); + +const CtxSet ContextSetCfg::IbcMbvdMergeIdx = ContextSetCfg::addCtxSet +({ + { 58, }, + { 43, }, + { CNU, }, + { 9, }, + { 10, }, + { DWS, }, + { 18, }, + { 11, }, + { DWE, }, + { 116, }, + { 118, }, + }); + +const CtxSet ContextSetCfg::IbcMbvdStepMvpIdx = ContextSetCfg::addCtxSet +({ + { 43, 36, 36, 28, 35, }, + { 28, 21, 36, 28, 43, }, + { CNU, CNU, CNU, CNU, CNU, }, + { 5, 4, 4, 4, 4, }, + { 5, 5, 5, 5, 4, }, + { DWS, DWS, DWS, DWS, DWS, }, + { 18, 11, 11, 11, 11, }, + { 18, 18, 18, 18, 11, }, + { DWE, DWE, DWE, DWE, DWE, }, + { 142, 157, 157, 142, 155, }, + { 116, 103, 104, 108, 117, }, + }); +#endif + #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) const CtxSet ContextSetCfg::TMMergeFlag = ContextSetCfg::addCtxSet ({ @@ -1572,6 +1619,23 @@ const CtxSet ContextSetCfg::BMMergeFlag = ContextSetCfg::addCtxSet }); #endif +#if JVET_AA0070_RRIBC +const CtxSet ContextSetCfg::rribcFlipType = ContextSetCfg::addCtxSet +({ + { 48, 50, 50, 50, }, + { 56, 50, 43, 28, }, + { CNU, CNU, CNU, CNU, }, + { 5, 5, 9, 5, }, + { 5, 5, 5, 5, }, + { DWS, DWS, DWS, DWS, }, + { 18, 18, 25, 18, }, + { 18, 18, 11, 18, }, + { DWE, DWE, DWE, DWE, }, + { 126, 126, 181, 126, }, + { 117, 117, 110, 116, }, + }); +#endif + const CtxSet ContextSetCfg::AffineFlag = ContextSetCfg::addCtxSet ({ { 19, 6, 7, }, @@ -3198,6 +3262,38 @@ const CtxSet ContextSetCfg::AfMmvdOffsetStep = ContextSetCfg::addCtxSet }); #endif +#if JVET_AA0061_IBC_MBVD +const CtxSet ContextSetCfg::IbcMbvdFlag = ContextSetCfg::addCtxSet +({ + { 25 }, + { 33 }, + { 35 }, + { 5 }, + { 4 }, + { 4 } + }); + +const CtxSet ContextSetCfg::IbcMbvdMergeIdx = ContextSetCfg::addCtxSet +({ + { 58 }, + { 43 }, + { 35 }, + { 9 }, + { 10 }, + { 10 } + }); + +const CtxSet ContextSetCfg::IbcMbvdStepMvpIdx = ContextSetCfg::addCtxSet +({ + { 35, 35, 35, 35, 35}, + { 35, 35, 35, 35, 35}, + { 35, 35, 35, 35, 35}, + { 4, 4, 4, 4, 4 }, + { 4, 4, 4, 4, 4 }, + { 4, 4, 4, 4, 4 } + }); +#endif + #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) const CtxSet ContextSetCfg::TMMergeFlag = ContextSetCfg::addCtxSet ({ @@ -3484,6 +3580,18 @@ const CtxSet ContextSetCfg::BMMergeFlag = ContextSetCfg::addCtxSet }); #endif +#if JVET_AA0070_RRIBC +const CtxSet ContextSetCfg::rribcFlipType = ContextSetCfg::addCtxSet +({ + { 25, CNU, CNU, CNU }, + { 26, CNU, CNU, CNU }, + { 35, CNU, CNU, CNU }, + { 4, 4, 4, 4 }, + { 4, 4, 4, 4 }, + { 4, 4, 4, 4 } + }); +#endif + const CtxSet ContextSetCfg::AffineFlag = ContextSetCfg::addCtxSet ({ { 34, 27, 6 }, @@ -4641,6 +4749,32 @@ const CtxSet ContextSetCfg::AfMmvdOffsetStep = ContextSetCfg::addCtxSet }); #endif +#if JVET_AA0061_IBC_MBVD +const CtxSet ContextSetCfg::IbcMbvdFlag = ContextSetCfg::addCtxSet +({ + { 25, }, + { 26, }, + { CNU, }, + { 4, }, + }); + +const CtxSet ContextSetCfg::IbcMbvdMergeIdx = ContextSetCfg::addCtxSet +({ + { 43, }, + { 43, }, + { CNU, }, + { 10, }, + }); + +const CtxSet ContextSetCfg::IbcMbvdStepMvpIdx = ContextSetCfg::addCtxSet +({ + { 59, }, + { 60, }, + { CNU, }, + { 0, }, + }); +#endif + #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) const CtxSet ContextSetCfg::TMMergeFlag = ContextSetCfg::addCtxSet ({ @@ -4843,6 +4977,17 @@ const CtxSet ContextSetCfg::BMMergeFlag = ContextSetCfg::addCtxSet { 4, 4, 4, 4 }, }); #endif + +#if JVET_AA0070_RRIBC +const CtxSet ContextSetCfg::rribcFlipType = ContextSetCfg::addCtxSet +({ + { 25, CNU, CNU, CNU }, + { 26, CNU, CNU, CNU }, + { CNU, CNU, CNU, CNU }, + { 4, 4, 4, 4 }, + }); +#endif + const CtxSet ContextSetCfg::AffineFlag = ContextSetCfg::addCtxSet ({ { 19, 13, 6, }, diff --git a/source/Lib/CommonLib/Contexts.h b/source/Lib/CommonLib/Contexts.h index 9b051f6e040db202ca019b82d4ced09d6f9f10b2..491ea1c3e3471f5ad9b48b98ad2339fa5dddfbfe 100644 --- a/source/Lib/CommonLib/Contexts.h +++ b/source/Lib/CommonLib/Contexts.h @@ -342,6 +342,9 @@ public: #if JVET_X0049_ADAPT_DMVR static const CtxSet BMMergeFlag; #endif +#if JVET_AA0070_RRIBC + static const CtxSet rribcFlipType; +#endif #if JVET_Y0065_GPM_INTRA static const CtxSet GPMIntraFlag; #endif @@ -399,6 +402,12 @@ public: static const CtxSet AfMmvdIdx; static const CtxSet AfMmvdOffsetStep; #endif + #if JVET_AA0061_IBC_MBVD + static const CtxSet IbcMbvdFlag; + static const CtxSet IbcMbvdMergeIdx; + static const CtxSet IbcMbvdStepMvpIdx; +#endif + #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) static const CtxSet TMMergeFlag; #endif diff --git a/source/Lib/CommonLib/IbcHashMap.cpp b/source/Lib/CommonLib/IbcHashMap.cpp index 1d1d6cf46036ccb2604f151dec6911154564dcfb..e8ef1e9aef3f015f877da722c10d0077e111a638 100644 --- a/source/Lib/CommonLib/IbcHashMap.cpp +++ b/source/Lib/CommonLib/IbcHashMap.cpp @@ -243,7 +243,11 @@ void IbcHashMap::xxBuildPicHashMap(const PelUnitBuf& pic) } } +#if JVET_AA0070_RRIBC +void IbcHashMap::rebuildPicHashMap(const PelUnitBuf &pic, bool isDualTree) +#else void IbcHashMap::rebuildPicHashMap(const PelUnitBuf& pic) +#endif { m_hash2Pos.clear(); @@ -252,9 +256,13 @@ void IbcHashMap::rebuildPicHashMap(const PelUnitBuf& pic) case CHROMA_400: xxBuildPicHashMap<CHROMA_400>(pic); break; +#if JVET_AA0070_RRIBC + case CHROMA_420: isDualTree ? xxBuildPicHashMap<CHROMA_400>(pic) : xxBuildPicHashMap<CHROMA_420>(pic); break; +#else case CHROMA_420: xxBuildPicHashMap<CHROMA_420>(pic); break; +#endif case CHROMA_422: xxBuildPicHashMap<CHROMA_422>(pic); break; @@ -267,8 +275,90 @@ void IbcHashMap::rebuildPicHashMap(const PelUnitBuf& pic) } } +#if JVET_AA0070_RRIBC +void IbcHashMap::buildFlipHashTable(PredictionUnit &pu, unsigned int pos2HashCurPU[MAX_CU_SIZE][MAX_CU_SIZE], const int rribcFlipType) +{ + if (rribcFlipType == 0) + { + return; + } + for (int i = 0; i < MAX_CU_SIZE; i++) + { + std::fill_n(pos2HashCurPU[i], MAX_CU_SIZE, 0x1FF); + } + PelStorage m_tmpStorageCU; + m_tmpStorageCU.create(UnitArea(pu.chromaFormat, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE))); + const UnitArea tmpArea(pu.chromaFormat, Area(0, 0, pu.cs->getOrgBuf(pu).Y().width, pu.cs->getOrgBuf(pu).Y().height)); + PelUnitBuf flipCU = m_tmpStorageCU.getBuf(tmpArea); + if (CS::isDualITree(*pu.cs)) + { + flipCU.Y().copyFrom(pu.cs->getOrgBuf(pu).Y()); + } + else + { + flipCU.copyFrom(pu.cs->getOrgBuf(pu)); + } + flipCU.Y().flipSignal(rribcFlipType == 1); + if (pu.chromaFormat != CHROMA_400 && !(CS::isDualITree(*pu.cs))) + { + flipCU.Cb().flipSignal(rribcFlipType == 1); + flipCU.Cr().flipSignal(rribcFlipType == 1); + } + + const int chromaScalingX = getChannelTypeScaleX(CHANNEL_TYPE_CHROMA, pu.chromaFormat); + const int chromaScalingY = getChannelTypeScaleY(CHANNEL_TYPE_CHROMA, pu.chromaFormat); + const int chromaMinBlkWidth = MIN_PU_SIZE >> chromaScalingX; + const int chromaMinBlkHeight = MIN_PU_SIZE >> chromaScalingY; + const Pel *pelY = NULL; + const Pel *pelCb = NULL; + const Pel *pelCr = NULL; + + Position pos; + for (pos.y = 0; pos.y < flipCU.Y().height; pos.y += MIN_PU_SIZE) + { + // row pointer + pelY = flipCU.Y().bufAt(0, pos.y); + if (pu.chromaFormat != CHROMA_400 && !(CS::isDualITree(*pu.cs))) + { + int chromaY = pos.y >> chromaScalingY; + pelCb = flipCU.Cb().bufAt(0, chromaY); + pelCr = flipCU.Cr().bufAt(0, chromaY); + } + + for (pos.x = 0; pos.x < flipCU.Y().width; pos.x += MIN_PU_SIZE) + { + // 0x1FF is just an initial value + unsigned int hashValue = 0x1FF; + + // luma part + hashValue = xxCalcBlockHash(&pelY[pos.x], flipCU.Y().stride, MIN_PU_SIZE, MIN_PU_SIZE, hashValue); + + // chroma part + if (pu.chromaFormat != CHROMA_400 && !(CS::isDualITree(*pu.cs))) + { + int chromaX = pos.x >> chromaScalingX; + hashValue = xxCalcBlockHash(&pelCb[chromaX], flipCU.Cb().stride, chromaMinBlkWidth, chromaMinBlkHeight, hashValue); + hashValue = xxCalcBlockHash(&pelCr[chromaX], flipCU.Cr().stride, chromaMinBlkWidth, chromaMinBlkHeight, hashValue); + } + + pos2HashCurPU[pos.y][pos.x] = hashValue; + } + } + + m_tmpStorageCU.destroy(); +} + +bool IbcHashMap::ibcHashMatch(PredictionUnit &pu, const Area &lumaArea, std::vector<Position> &cand, + const CodingStructure &cs, const int maxCand, const int searchRange4SmallBlk, + const int rribcFlipType) +{ + unsigned int pos2HashCurPU[MAX_CU_SIZE][MAX_CU_SIZE]; + + buildFlipHashTable(pu, pos2HashCurPU, rribcFlipType); +#else bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand, const CodingStructure& cs, const int maxCand, const int searchRange4SmallBlk) { +#endif cand.clear(); // find the block with least candidates @@ -280,6 +370,12 @@ bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand, for (SizeType x = 0; x < lumaArea.width && minSize > 1; x += MIN_PU_SIZE) { unsigned int hash = m_pos2Hash[lumaArea.pos().y + y][lumaArea.pos().x + x]; +#if JVET_AA0070_RRIBC + if (rribcFlipType) + { + hash = pos2HashCurPU[y][x]; + } +#endif if (m_hash2Pos[hash].size() < minSize) { minSize = m_hash2Pos[hash].size(); @@ -291,7 +387,7 @@ bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand, if (m_hash2Pos[targetHashOneBlock].size() > 1) { - std::vector<Position>& candOneBlock = m_hash2Pos[targetHashOneBlock]; + std::vector<Position> &candOneBlock = m_hash2Pos[targetHashOneBlock]; // check whether whole block match for (std::vector<Position>::iterator refBlockPos = candOneBlock.begin(); refBlockPos != candOneBlock.end(); refBlockPos++) @@ -310,6 +406,13 @@ bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand, for (SizeType x = 0; x < lumaArea.width && wholeBlockMatch; x += MIN_PU_SIZE) { // whether the reference block and current block has the same hash +#if JVET_AA0070_RRIBC + if (rribcFlipType) + { + wholeBlockMatch &= (pos2HashCurPU[y][x] == m_pos2Hash[topLeft.y + y][topLeft.x + x]); + } + else +#endif wholeBlockMatch &= (m_pos2Hash[lumaArea.pos().y + y][lumaArea.pos().x + x] == m_pos2Hash[topLeft.y + y][topLeft.x + x]); } } diff --git a/source/Lib/CommonLib/IbcHashMap.h b/source/Lib/CommonLib/IbcHashMap.h index 84d575418685dd63d1f90c3b458a11e1bcf3b211..3639b7ea18786cfeaa3798917a458039ed57b8ca 100644 --- a/source/Lib/CommonLib/IbcHashMap.h +++ b/source/Lib/CommonLib/IbcHashMap.h @@ -78,8 +78,14 @@ public: void init(const int picWidth, const int picHeight); void destroy(); +#if JVET_AA0070_RRIBC + void rebuildPicHashMap(const PelUnitBuf &pic, bool isDualTree); + void buildFlipHashTable(PredictionUnit &pu, unsigned int pos2HashCurPU[MAX_CU_SIZE][MAX_CU_SIZE], const int rribcFlipType); + bool ibcHashMatch(PredictionUnit &pu, const Area &lumaArea, std::vector<Position> &cand, const CodingStructure &cs, const int maxCand, const int searchRange4SmallBlk, const int rribcFlipType); +#else void rebuildPicHashMap(const PelUnitBuf& pic); bool ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand, const CodingStructure& cs, const int maxCand, const int searchRange4SmallBlk); +#endif int getHashHitRatio(const Area& lumaArea); int calHashBlkMatchPerc(const Area& lumaArea); diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index 01b504a9e7110e47c78de340ed29771aeae06188..8b609952ba9e866dfe6c31658d86b6d171fc6923 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -5903,6 +5903,109 @@ void InterPrediction::xProcessDMVR(PredictionUnit& pu, PelUnitBuf &pcYuvDst, con #endif } +#if JVET_AA0061_IBC_MBVD +void InterPrediction::sortIbcMergeMbvdCandidates(PredictionUnit &pu, MergeCtx& mrgCtx, uint32_t * ibcMbvdLUT,uint32_t * ibcMbvdValidNum, int ibcMbvdIdx) +{ + + const int tempNum = (const int) (std::min<int>(IBC_MBVD_BASE_NUM, mrgCtx.numValidMergeCand) * IBC_MBVD_MAX_REFINE_NUM); + const int groupSize = std::min<int>(tempNum, ADAPTIVE_SUB_GROUP_SIZE_IBC_MBVD); + + Distortion candCostList[IBC_MBVD_BASE_NUM* IBC_MBVD_MAX_REFINE_NUM]; + + for (uint32_t i = 0; i < tempNum; i++) + { + ibcMbvdLUT[i] = i; + candCostList[i] = MAX_UINT; + } + Distortion uiCost; + DistParam cDistParam; + cDistParam.applyWeight = false; + int nWidth = pu.lumaSize().width; + int nHeight = pu.lumaSize().height; + if (!xAMLIBCGetCurBlkTemplate(pu, nWidth, nHeight)) + { + return; + } + + int startMMVDIdx = 0; + int endMMVDIdx = tempNum; + if(ibcMbvdIdx!= -1) + { + uint32_t gpId = ibcMbvdIdx/groupSize; + startMMVDIdx = gpId * groupSize; + endMMVDIdx = (gpId+1) * groupSize; + } + + int encGrpSize = IBC_MBVD_SIZE_ENC; + int baseIdx = 0; + const int cuPelX = pu.Y().x; + const int cuPelY = pu.Y().y; + int roiWidth = pu.lwidth(); + int roiHeight = pu.lheight(); + const int picWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples(); + const int picHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples(); + const unsigned int lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth(); + for (int mmvdMergeCand = startMMVDIdx; mmvdMergeCand < endMMVDIdx; mmvdMergeCand++) + { + bool mbvdCandMisAlign = mrgCtx.setIbcMbvdMergeCandiInfo(pu, mmvdMergeCand, mmvdMergeCand); + if (mbvdCandMisAlign) + { + continue; + } + int xPred = pu.bv.getHor(); + int yPred = pu.bv.getVer(); + + if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived + { + continue; + } + baseIdx = mmvdMergeCand / IBC_MBVD_MAX_REFINE_NUM; + ibcMbvdValidNum[baseIdx]++; + uiCost = 0; + + PelUnitBuf pcBufPredRefTop = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvRefAMLTemplate[0][0], nWidth, AML_MERGE_TEMPLATE_SIZE))); + PelUnitBuf pcBufPredCurTop = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvCurAMLTemplate[0][0], nWidth, AML_MERGE_TEMPLATE_SIZE))); + PelUnitBuf pcBufPredRefLeft = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvRefAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight))); + PelUnitBuf pcBufPredCurLeft = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvCurAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight))); + + getIBCAMLRefTemplate(pu, nWidth, nHeight); + + if (m_bAMLTemplateAvailabe[0]) + { + m_pcRdCost->setDistParam(cDistParam, pcBufPredCurTop.Y(), pcBufPredRefTop.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, false); + + uiCost += cDistParam.distFunc(cDistParam); + } + + if (m_bAMLTemplateAvailabe[1]) + { + m_pcRdCost->setDistParam(cDistParam, pcBufPredCurLeft.Y(), pcBufPredRefLeft.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, false); + + uiCost += cDistParam.distFunc(cDistParam); + } + // update part + uint32_t i; + uint32_t shift = 0; + uint32_t gpIdx = mmvdMergeCand/groupSize; + uint32_t endIdx = gpIdx * groupSize + encGrpSize; + while (shift < encGrpSize && uiCost < candCostList[endIdx - 1 - shift]) + { + shift++; + } + if (shift != 0) + { + for (i = 1; i < shift; i++) + { + ibcMbvdLUT[endIdx - i] = ibcMbvdLUT[endIdx - 1 - i]; + candCostList[endIdx - i] = candCostList[endIdx - 1 - i]; + } + ibcMbvdLUT[endIdx - shift] = mmvdMergeCand; + candCostList[endIdx - shift] = uiCost; + } + } +} +#endif + #if JVET_J0090_MEMORY_BANDWITH_MEASURE void InterPrediction::cacheAssign( CacheModel *cache ) { @@ -8686,6 +8789,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u mrgCtxTmp.useAltHpelIf[ui] = false; #if INTER_LIC mrgCtxTmp.LICFlags[ui] = false; +#endif +#if JVET_AA0070_RRIBC + mrgCtxTmp.rribcFlipTypes[ui] = 0; #endif } for (uint32_t uiMergeCand = ((mrgCandIdx < 0) ? 0 : (mrgCandIdx / ADAPTIVE_IBC_SUB_GROUP_SIZE)*ADAPTIVE_IBC_SUB_GROUP_SIZE); uiMergeCand < (((mrgCandIdx < 0) || ((mrgCandIdx / ADAPTIVE_IBC_SUB_GROUP_SIZE + 1)*ADAPTIVE_IBC_SUB_GROUP_SIZE > mrgCtx.numValidMergeCand)) ? mrgCtx.numValidMergeCand : ((mrgCandIdx / ADAPTIVE_IBC_SUB_GROUP_SIZE + 1)*ADAPTIVE_IBC_SUB_GROUP_SIZE)); ++uiMergeCand) @@ -8708,6 +8814,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u mrgCtxTmp.useAltHpelIf[uiMergeCand] = mrgCtx.useAltHpelIf[uiMergeCand]; #if INTER_LIC mrgCtxTmp.LICFlags[uiMergeCand] = mrgCtx.LICFlags[uiMergeCand]; +#endif +#if JVET_AA0070_RRIBC + mrgCtxTmp.rribcFlipTypes[uiMergeCand] = mrgCtx.rribcFlipTypes[uiMergeCand]; #endif } //update @@ -8731,6 +8840,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u mrgCtx.useAltHpelIf[uiMergeCand] = mrgCtxTmp.useAltHpelIf[RdCandList[uiMergeCand / ADAPTIVE_IBC_SUB_GROUP_SIZE][uiMergeCand%ADAPTIVE_IBC_SUB_GROUP_SIZE]]; #if INTER_LIC mrgCtx.LICFlags[uiMergeCand] = mrgCtxTmp.LICFlags[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 } } @@ -8758,12 +8870,6 @@ bool InterPrediction::xAMLIBCGetCurBlkTemplate(PredictionUnit& pu, int nCurBlkWi for (int l = 0; l < AML_MERGE_TEMPLATE_SIZE; l++) { int recVal = rec[k + l * recBuf.stride]; - - //if (m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag()) - //{ - // recVal = invLUT[recVal]; - //} - pcY[k + l * nCurBlkWidth] = recVal; } } @@ -8779,12 +8885,6 @@ bool InterPrediction::xAMLIBCGetCurBlkTemplate(PredictionUnit& pu, int nCurBlkWi for (int l = 0; l < AML_MERGE_TEMPLATE_SIZE; l++) { int recVal = rec[recBuf.stride * k + l]; - - //if (m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag()) - //{ - // recVal = invLUT[recVal]; - //} - pcY[AML_MERGE_TEMPLATE_SIZE * k + l] = recVal; } } @@ -8805,11 +8905,27 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, if (m_bAMLTemplateAvailabe[0]) { Mv mvTop(0, -AML_MERGE_TEMPLATE_SIZE); +#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; +#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)) { mvTop = mvCurr; @@ -8821,13 +8937,23 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, { 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]; - - //if (m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag()) - //{ - // recVal = invLUT[recVal]; - //} - +#endif pcY[k + l * nCurBlkWidth] = recVal; } } @@ -8836,11 +8962,27 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, if (m_bAMLTemplateAvailabe[1]) { Mv mvLeft(-AML_MERGE_TEMPLATE_SIZE, 0); +#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; +#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)) { mvLeft = mvCurr; @@ -8852,19 +8994,30 @@ void InterPrediction::getIBCAMLRefTemplate(PredictionUnit &pu, int nCurBlkWidth, { 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]; - - //if (m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag()) - //{ - // recVal = invLUT[recVal]; - //} - +#endif pcY[AML_MERGE_TEMPLATE_SIZE * k + l] = recVal; } } } } #endif + #if JVET_Z0075_IBC_HMVP_ENLARGE void InterPrediction::adjustIBCMergeCandidates(PredictionUnit &pu, MergeCtx& mrgCtx,uint32_t startPos,uint32_t endPos) { @@ -8948,6 +9101,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u mrgCtxTmp.useAltHpelIf[ui] = false; #if INTER_LIC mrgCtxTmp.LICFlags[ui] = false; +#endif +#if JVET_AA0070_RRIBC + mrgCtxTmp.rribcFlipTypes[ui] = 0; #endif } for (uint32_t uiMergeCand = startPos; uiMergeCand < endPos; ++uiMergeCand) @@ -8964,6 +9120,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u mrgCtxTmp.useAltHpelIf[uiMergeCand] = mrgCtx.useAltHpelIf[uiMergeCand]; #if INTER_LIC mrgCtxTmp.LICFlags[uiMergeCand] = mrgCtx.LICFlags[uiMergeCand]; +#endif +#if JVET_AA0070_RRIBC + mrgCtxTmp.rribcFlipTypes[uiMergeCand] = mrgCtx.rribcFlipTypes[uiMergeCand]; #endif } //update @@ -8981,6 +9140,9 @@ void InterPrediction::updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, u mrgCtx.useAltHpelIf[uiMergeCand] = mrgCtxTmp.useAltHpelIf[RdCandList[uiMergeCand -startPos]]; #if INTER_LIC mrgCtx.LICFlags[uiMergeCand] = mrgCtxTmp.LICFlags[RdCandList[uiMergeCand -startPos]]; +#endif +#if JVET_AA0070_RRIBC + mrgCtx.rribcFlipTypes[uiMergeCand] = mrgCtxTmp.rribcFlipTypes[RdCandList[uiMergeCand -startPos]]; #endif } } diff --git a/source/Lib/CommonLib/InterPrediction.h b/source/Lib/CommonLib/InterPrediction.h index aa0b7f12a8d08f2ffce4ca0989ef99712ba45e23..5a2cb82be53edfc2aab433ac48cacb21717583be 100644 --- a/source/Lib/CommonLib/InterPrediction.h +++ b/source/Lib/CommonLib/InterPrediction.h @@ -509,6 +509,9 @@ public: uint64_t xDMVRCost(int bitDepth, Pel* pRef, uint32_t refStride, const Pel* pOrg, uint32_t orgStride, int width, int height); void xinitMC(PredictionUnit& pu, const ClpRngs &clpRngs); void xProcessDMVR(PredictionUnit& pu, PelUnitBuf &pcYuvDst, const ClpRngs &clpRngs, const bool bioApplied ); +#if JVET_AA0061_IBC_MBVD + void sortIbcMergeMbvdCandidates(PredictionUnit &pu, MergeCtx& mrgCtx, uint32_t * ibcMbvdLUT, uint32_t * ibcMbvdValidNum, int ibcMbvdIdx= -1); +#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); diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index 181f18601588648479fd25005766efc33e23e45a..b276406c64e62ed303edd0fb681daa27957d5d1e 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -276,7 +276,6 @@ void IntraPrediction::init(ChromaFormat chromaFormatIDC, const unsigned bitDepth #endif #if JVET_V0130_INTRA_TMP unsigned int blkSize; - if( m_pppTarPatch == NULL ) { m_pppTarPatch = new Pel * *[USE_MORE_BLOCKSIZE_DEPTH_MAX]; @@ -6785,6 +6784,7 @@ void IntraPrediction::candidateSearchIntra( CodingUnit* pcCU, unsigned int uiBlk unsigned int uiPatchWidth = uiBlkWidth + TMP_TEMPLATE_SIZE; unsigned int uiPatchHeight = uiBlkHeight + TMP_TEMPLATE_SIZE; unsigned int uiTarDepth = floorLog2( std::max( uiBlkWidth, uiBlkHeight ) ) - 2; + Pel** tarPatch = getTargetPatch( uiTarDepth ); //Initialize the library for saving the best candidates m_tempLibFast.initTemplateDiff( uiPatchWidth, uiPatchHeight, uiBlkWidth, uiBlkHeight, channelBitDepth ); diff --git a/source/Lib/CommonLib/MotionInfo.h b/source/Lib/CommonLib/MotionInfo.h index 2c753477ce012922760d911ac8dba74cb8fa2844..ab4595ae0de29bc8c4ea714c03f2cc856c055753 100644 --- a/source/Lib/CommonLib/MotionInfo.h +++ b/source/Lib/CommonLib/MotionInfo.h @@ -176,6 +176,10 @@ struct MotionInfo #if INTER_LIC bool usesLIC; #endif +#if JVET_AA0070_RRIBC + int rribcFlipType; + Position centerPos; +#endif #if MULTI_HYP_PRED MultiHypVec addHypData; #endif diff --git a/source/Lib/CommonLib/RdCost.cpp b/source/Lib/CommonLib/RdCost.cpp index c1187bbbc6aab180997a880de72470e697e7ba05..5f23a3ff629272d58e599a061fe27037895bb9c5 100644 --- a/source/Lib/CommonLib/RdCost.cpp +++ b/source/Lib/CommonLib/RdCost.cpp @@ -58,6 +58,26 @@ RdCost::RdCost() RdCost::~RdCost() { } +#if JVET_AA0070_RRIBC +void RdCost::setPredictors(Mv pcMv[3][2]) + { + for (int j = 0; j < 3; j++) + { + for (int i = 0; i < 2; i++) + { + m_bvPredictors[j][i] = pcMv[j][i]; + } + } + } +#else +void RdCost::setPredictors(Mv* pcMv) + { + for (int i = 0; i < 2; i++) + { + m_bvPredictors[i] = pcMv[i]; + } + } +#endif #if WCG_EXT double RdCost::calcRdCost( uint64_t fracBits, Distortion distortion, bool useUnadjustedLambda ) diff --git a/source/Lib/CommonLib/RdCost.h b/source/Lib/CommonLib/RdCost.h index 7d19adc09664d3847eb4bd0c4e64666131090b17..d70e715b22ba82dcb61fe8c884de2b60e8dfaa79 100644 --- a/source/Lib/CommonLib/RdCost.h +++ b/source/Lib/CommonLib/RdCost.h @@ -155,14 +155,18 @@ private: // for motion cost Mv m_mvPredictor; +#if JVET_AA0070_RRIBC + Mv m_bvPredictors[3][2]; +#else Mv m_bvPredictors[2]; +#endif double m_motionLambda; int m_iCostScale; - double m_dCost; // for ibc #if JVET_Z0131_IBC_BVD_BINARIZATION EstBvdBitsStruct m_cBvdBitCosts; #endif + public: RdCost(); virtual ~RdCost(); @@ -221,17 +225,234 @@ public: // for ibc void getMotionCost(int add) { m_dCost = m_dLambdaMotionSAD + add; } - void setPredictors(Mv* pcMv) + +#if JVET_AA0070_RRIBC + void setPredictors(Mv pcMv[3][2]); +#if JVET_Z0131_IBC_BVD_BINARIZATION + EstBvdBitsStruct *getBvdBitCosts() { return &m_cBvdBitCosts; } +#if JVET_Z0084_IBC_TM && IBC_TM_AMVP + inline Distortion getBvCostMultiplePreds(int x, int y, bool useIMV, int rribcFlipType, uint8_t *bvImvResBest = NULL, int *bvpIdxBest = NULL, bool flag = false, AMVPInfo *amvpInfo4Pel = NULL) +#else + inline Distortion getBvCostMultiplePreds(int x, int y, bool useIMV, int rribcFlipType, uint8_t *bvImvResBest = NULL, int *bvpIdxBest = NULL) +#endif { - for (int i = 0; i<2; i++) + uint32_t b0 = (rribcFlipType == 1) ? 0 : xGetExpGolombNumberOfBitsIBCV(y - m_bvPredictors[rribcFlipType][0].getVer()); + b0 += (rribcFlipType == 2) ? 0 : xGetExpGolombNumberOfBitsIBCH(x - m_bvPredictors[rribcFlipType][0].getHor()); + b0 += m_cBvdBitCosts.bitsIdx[0]; + + uint32_t b1 = (rribcFlipType == 1) ? 0 : xGetExpGolombNumberOfBitsIBCV(y - m_bvPredictors[rribcFlipType][1].getVer()); + b1 += (rribcFlipType == 2) ? 0 : xGetExpGolombNumberOfBitsIBCH(x - m_bvPredictors[rribcFlipType][1].getHor()); + b1 += m_cBvdBitCosts.bitsIdx[1]; + + if (useIMV) + { + if (rribcFlipType == 0) + { + b0 += (x != m_bvPredictors[rribcFlipType][0].getHor() || y != m_bvPredictors[rribcFlipType][0].getVer()) ? m_cBvdBitCosts.bitsImv[0] : 0; + b1 += (x != m_bvPredictors[rribcFlipType][1].getHor() || y != m_bvPredictors[rribcFlipType][1].getVer()) ? m_cBvdBitCosts.bitsImv[0] : 0; + } + else if (rribcFlipType == 1) + { + b0 += (x != m_bvPredictors[rribcFlipType][0].getHor()) ? m_cBvdBitCosts.bitsImv[0] : 0; + b1 += (x != m_bvPredictors[rribcFlipType][1].getHor()) ? m_cBvdBitCosts.bitsImv[0] : 0; + } + else + { + b0 += (y != m_bvPredictors[rribcFlipType][0].getVer()) ? m_cBvdBitCosts.bitsImv[0] : 0; + b1 += (y != m_bvPredictors[rribcFlipType][1].getVer()) ? m_cBvdBitCosts.bitsImv[0] : 0; + } + } + uint32_t bBest = (b1 < b0) ? b1 : b0; + int bBestIdx = (b1 < b0) ? 1 : 0; + uint8_t bestRes; + if (rribcFlipType == 0) { - m_bvPredictors[i] = pcMv[i]; + bestRes = (useIMV && (x != m_bvPredictors[rribcFlipType][bBestIdx].getHor() || y != m_bvPredictors[rribcFlipType][bBestIdx].getVer())) ? 1 : 0; + } + else if (rribcFlipType == 1) + { + bestRes = (useIMV && (x != m_bvPredictors[rribcFlipType][bBestIdx].getHor())) ? 1 : 0; + } + else + { + bestRes = (useIMV && (y != m_bvPredictors[rribcFlipType][bBestIdx].getVer())) ? 1 : 0; + } + + if (bvImvResBest) + { + *bvImvResBest = bestRes; + *bvpIdxBest = bBestIdx; + } + + if (bestRes && x % 4 == 0 && y % 4 == 0) + { + Mv cMv(x >> 2, y >> 2); + +#if JVET_Z0084_IBC_TM && IBC_TM_AMVP + Mv tmpBv0; + Mv tmpBv1; + if (flag) + { + tmpBv0 = amvpInfo4Pel->mvCand[0]; + tmpBv1 = amvpInfo4Pel->mvCand[1]; + tmpBv0.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_4PEL); + tmpBv1.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_4PEL); + } + else + { + tmpBv0 = m_bvPredictors[rribcFlipType][0]; + tmpBv1 = m_bvPredictors[rribcFlipType][1]; + tmpBv0.changePrecision(MV_PRECISION_INT, MV_PRECISION_4PEL); + tmpBv1.changePrecision(MV_PRECISION_INT, MV_PRECISION_4PEL); + } +#else + Mv tmpBv0 = m_bvPredictors[rribcFlipType][0]; + Mv tmpBv1 = m_bvPredictors[rribcFlipType][1]; + tmpBv0.changePrecision(MV_PRECISION_INT, MV_PRECISION_4PEL); + tmpBv1.changePrecision(MV_PRECISION_INT, MV_PRECISION_4PEL); +#endif + + uint32_t bQ0, bQ1; + if (rribcFlipType == 0) + { + bQ0 = (cMv == tmpBv0) ? std::numeric_limits<uint32_t>::max() : (xGetExpGolombNumberOfBitsIBCH(cMv.getHor() - tmpBv0.getHor()) + xGetExpGolombNumberOfBitsIBCV(cMv.getVer() - tmpBv0.getVer()) + m_cBvdBitCosts.bitsIdx[0]); + bQ1 = (cMv == tmpBv1) ? std::numeric_limits<uint32_t>::max() : (xGetExpGolombNumberOfBitsIBCH(cMv.getHor() - tmpBv1.getHor()) + xGetExpGolombNumberOfBitsIBCV(cMv.getVer() - tmpBv1.getVer()) + m_cBvdBitCosts.bitsIdx[1]); + } + else if (rribcFlipType == 1) + { + bQ0 = (cMv.getHor() == tmpBv0.getHor()) ? std::numeric_limits<uint32_t>::max() : (xGetExpGolombNumberOfBitsIBCH(cMv.getHor() - tmpBv0.getHor()) + m_cBvdBitCosts.bitsIdx[0]); + bQ1 = (cMv.getHor() == tmpBv1.getHor()) ? std::numeric_limits<uint32_t>::max() : (xGetExpGolombNumberOfBitsIBCH(cMv.getHor() - tmpBv1.getHor()) + m_cBvdBitCosts.bitsIdx[1]); + } + else + { + bQ0 = (cMv.getVer() == tmpBv0.getVer()) ? std::numeric_limits<uint32_t>::max() : (xGetExpGolombNumberOfBitsIBCV(cMv.getVer() - tmpBv0.getVer()) + m_cBvdBitCosts.bitsIdx[0]); + bQ1 = (cMv.getVer() == tmpBv1.getVer()) ? std::numeric_limits<uint32_t>::max() : (xGetExpGolombNumberOfBitsIBCV(cMv.getVer() - tmpBv1.getVer()) + m_cBvdBitCosts.bitsIdx[1]); + } + + uint32_t bQBest = (bQ1 < bQ0) ? bQ1 : bQ0; + bQBest += (bQBest < std::numeric_limits<uint32_t>::max()) ? m_cBvdBitCosts.bitsImv[1] : 0; + + if (bQBest < bBest) + { + if (bvImvResBest) + { + *bvImvResBest = 2; + *bvpIdxBest = (bQ1 < bQ0) ? 1 : 0; + } + bBest = bQBest; + } } + return Distortion(m_dCost * bBest) >> SCALE_BITS; + } +#else + inline Distortion getBvCostMultiplePreds(int x, int y, bool useIMV, int rribcFlipType) + { + return Distortion(m_dCost * getBitsMultiplePreds(x, y, useIMV, rribcFlipType)); } + unsigned int getBitsMultiplePreds(int x, int y, bool useIMV, int rribcFlipType) + { + int rmvH[2]; + int rmvV[2]; + rmvH[0] = x - m_bvPredictors[rribcFlipType][0].getHor(); + rmvH[1] = x - m_bvPredictors[rribcFlipType][1].getHor(); + + rmvV[0] = y - m_bvPredictors[rribcFlipType][0].getVer(); + rmvV[1] = y - m_bvPredictors[rribcFlipType][1].getVer(); + + int absCand[2]; + absCand[0] = abs(rmvH[0]) + abs(rmvV[0]); + absCand[1] = abs(rmvH[1]) + abs(rmvV[1]); + + int rmvHQP[2]; + int rmvVQP[2]; + if (x % 4 == 0 && y % 4 == 0 && useIMV) + { + int imvShift = 2; + int offset = 1 << (imvShift - 1); + + rmvHQP[0] = (x >> 2) - ((m_bvPredictors[rribcFlipType][0].getHor() + offset) >> 2); + rmvHQP[1] = (x >> 2) - ((m_bvPredictors[rribcFlipType][1].getHor() + offset) >> 2); + rmvVQP[0] = (y >> 2) - ((m_bvPredictors[rribcFlipType][0].getVer() + offset) >> 2); + rmvVQP[1] = (y >> 2) - ((m_bvPredictors[rribcFlipType][1].getVer() + offset) >> 2); + + int absCandQP[2]; + absCandQP[0] = abs(rmvHQP[0]) + abs(rmvVQP[0]); + absCandQP[1] = abs(rmvHQP[1]) + abs(rmvVQP[1]); + unsigned int candBits0QP, candBits1QP; + if (absCand[0] < absCand[1]) + { + unsigned int candBits0 = (rribcFlipType == 1) ? 0 : getIComponentBits(rmvV[0]); + candBits0 += (rribcFlipType == 2) ? 0 : getIComponentBits(rmvH[0]); + if (absCandQP[0] < absCandQP[1]) + { + candBits0QP = (rribcFlipType == 1) ? 0 : getIComponentBits(rmvVQP[0]); + candBits0QP += (rribcFlipType == 2) ? 0 : getIComponentBits(rmvHQP[0]); + return candBits0QP < candBits0 ? candBits0QP : candBits0; + } + else + { + candBits1QP = (rribcFlipType == 1) ? 0 : getIComponentBits(rmvVQP[1]); + candBits1QP = (rribcFlipType == 2) ? 0 : getIComponentBits(rmvHQP[1]); + return candBits1QP < candBits0 ? candBits1QP : candBits0; + } + } + else + { + unsigned int candBits1 = (rribcFlipType == 1) ? 0 : getIComponentBits(rmvV[1]); + candBits1 += (rribcFlipType == 2) ? 0 : getIComponentBits(rmvH[1]); + if (absCandQP[0] < absCandQP[1]) + { + candBits0QP = (rribcFlipType == 1) ? 0 : getIComponentBits(rmvVQP[0]); + candBits0QP += (rribcFlipType == 2) ? 0 : getIComponentBits(rmvHQP[0]); + return candBits0QP < candBits1 ? candBits0QP : candBits1; + } + else + { + candBits1QP = (rribcFlipType == 1) ? 0 : getIComponentBits(rmvVQP[1]); + candBits1QP = (rribcFlipType == 2) ? 0 : getIComponentBits(rmvHQP[1]); + return candBits1QP < candBits1 ? candBits1QP : candBits1; + } + } + } + else + { + if (absCand[0] < absCand[1]) + { + return ((rribcFlipType == 1) ? (getIComponentBits(rmvH[0])) : ((rribcFlipType == 2) ? (getIComponentBits(rmvV[0])) : (getIComponentBits(rmvH[0]) + getIComponentBits(rmvV[0])))); + } + else + { + return ((rribcFlipType == 1) ? (getIComponentBits(rmvH[1])) : ((rribcFlipType == 2) ? (getIComponentBits(rmvV[1])) : (getIComponentBits(rmvH[1]) + getIComponentBits(rmvV[1])))); + } + } + } + + unsigned int getIComponentBits(int val) + { + if (!val) + { + return 1; + } + + unsigned int length = 1; + unsigned int temp = (val <= 0) ? (-val << 1) + 1 : (val << 1); + + while (1 != temp) + { + temp >>= 1; + length += 2; + } + + return length; + } +#endif +#else + void setPredictors(Mv *pcMv); + #if JVET_Z0131_IBC_BVD_BINARIZATION - EstBvdBitsStruct* getBvdBitCosts() - { - return &m_cBvdBitCosts; + EstBvdBitsStruct* getBvdBitCosts() + { + return &m_cBvdBitCosts; } #if JVET_Z0084_IBC_TM && IBC_TM_AMVP inline Distortion getBvCostMultiplePreds(int x, int y, bool useIMV, uint8_t *bvImvResBest = NULL, int *bvpIdxBest = NULL, bool flag = false, AMVPInfo* amvpInfo4Pel = NULL) @@ -262,7 +483,7 @@ public: #if JVET_Z0084_IBC_TM && IBC_TM_AMVP Mv tmpBv0; Mv tmpBv1; - if (flag) + if (flag) { tmpBv0 = amvpInfo4Pel->mvCand[0]; tmpBv1 = amvpInfo4Pel->mvCand[1]; @@ -381,7 +602,10 @@ public: unsigned int getIComponentBits(int val) { - if (!val) return 1; + if (!val) + { + return 1; + } unsigned int length = 1; unsigned int temp = (val <= 0) ? (-val << 1) + 1 : (val << 1); @@ -395,6 +619,7 @@ public: return length; } #endif +#endif #if ENABLE_SPLIT_PARALLELISM void copyState( const RdCost& other ); @@ -414,8 +639,19 @@ public: return uiLength2 + ( floorLog2(uiTemp2) << 1 ); } + Distortion getCostOfVectorWithPredictor( const int x, const int y, const unsigned imvShift ) { return Distortion( m_motionLambda * getBitsOfVectorWithPredictor(x, y, imvShift )); } - uint32_t getBitsOfVectorWithPredictor( const int x, const int y, const unsigned imvShift ) { return xGetExpGolombNumberOfBits(((x << m_iCostScale) - m_mvPredictor.getHor())>>imvShift) + xGetExpGolombNumberOfBits(((y << m_iCostScale) - m_mvPredictor.getVer())>>imvShift); } +#if JVET_AA0070_RRIBC && !JVET_Z0131_IBC_BVD_BINARIZATION + uint32_t getBitsOfVectorWithPredictor( const int x, const int y, const unsigned imvShift, const int &rribcFlipType = 0) + { + return ((rribcFlipType == 1) ? (xGetExpGolombNumberOfBits(((x << m_iCostScale) - m_mvPredictor.getHor()) >> imvShift)) : ((rribcFlipType == 2) ? xGetExpGolombNumberOfBits(((y << m_iCostScale) - m_mvPredictor.getVer()) >> imvShift) + : (xGetExpGolombNumberOfBits(((x << m_iCostScale) - m_mvPredictor.getHor()) >> imvShift) + xGetExpGolombNumberOfBits(((y << m_iCostScale) - m_mvPredictor.getVer()) >> imvShift)))); + } +#else + uint32_t getBitsOfVectorWithPredictor( const int x, const int y, const unsigned imvShift ) { return xGetExpGolombNumberOfBits(((x << m_iCostScale) - m_mvPredictor.getHor())>>imvShift) + xGetExpGolombNumberOfBits(((y << m_iCostScale) - m_mvPredictor.getVer())>>imvShift); } +#endif + + #if JVET_Z0131_IBC_BVD_BINARIZATION // for block vector cost uint32_t xGetExpGolombNumberOfBitsIBCH( int iVal ) @@ -472,6 +708,7 @@ public: } } +#if !JVET_AA0070_RRIBC Distortion getCostOfVectorWithPredictorIBC( const int x, const int y, const unsigned imvShift ) { return Distortion( m_motionLambda * getBitsOfVectorWithPredictorIBC(x, y, imvShift )) >> SCALE_BITS; @@ -481,6 +718,7 @@ public: return xGetExpGolombNumberOfBitsIBCH(((x << m_iCostScale) - m_mvPredictor.getHor())>>imvShift) + xGetExpGolombNumberOfBitsIBCV(((y << m_iCostScale) - m_mvPredictor.getVer())>>imvShift); } #endif +#endif #if WCG_EXT void saveUnadjustedLambda (); void initLumaLevelToWeightTable (); diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index bf2331c9e8f5832fcae8431d01af6cb167c6ee55..f6698ee24376111a4fa79a63e61d6a1ba626c66a 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -3485,6 +3485,9 @@ SPS::SPS() #if AFFINE_MMVD , m_AffineMmvdMode ( false ) #endif +#if JVET_AA0061_IBC_MBVD + , m_ibcMbvd ( 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 1ca1eeebbc16eba3af3dea0c4ecce3e5c2bd663a..6214c6bc13a1ad8341c686526a66071712dbe7f2 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1520,6 +1520,9 @@ private: #if AFFINE_MMVD bool m_AffineMmvdMode; #endif +#if JVET_AA0061_IBC_MBVD + bool m_ibcMbvd; +#endif #if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM || MULTI_PASS_DMVR bool m_DMVDMode; #endif @@ -2018,6 +2021,10 @@ void setCCALFEnabledFlag( bool b ) void setUseAffineMmvdMode(bool b) { m_AffineMmvdMode = b; } bool getUseAffineMmvdMode() const { return m_AffineMmvdMode; } #endif +#if JVET_AA0061_IBC_MBVD + void setUseIbcMbvd(bool b) { m_ibcMbvd = b; } + bool getUseIbcMbvd() const { return m_ibcMbvd; } +#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 af3c1cf8233158638dafa7ce639421b5f71e804d..e83c5cb8641a3884884d812b3bbe9cb20d5a0514 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -150,6 +150,8 @@ #define JVET_Z0153_IBC_EXT_REF 1 // JVET-Z0153: Extend reference area for IBC #define JVET_Z0160_IBC_ZERO_PADDING 1 // JVET-Z0160: Replacement of zero-padding candidates #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 // 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 81e67cd6e40f2287255dc0cdbed3caf33c1cd3cb..cb7507a43d697c4a729cf97aff2b3a58a7418832 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -320,6 +320,9 @@ CodingUnit& CodingUnit::operator=( const CodingUnit& other ) #if INTER_LIC LICFlag = other.LICFlag; #endif +#if JVET_AA0070_RRIBC + rribcFlipType = other.rribcFlipType; +#endif for (int idx = 0; idx < MAX_NUM_CHANNEL_TYPE; idx++) { @@ -415,6 +418,9 @@ void CodingUnit::initData() #if INTER_LIC LICFlag = false; #endif +#if JVET_AA0070_RRIBC + rribcFlipType = 0; +#endif for (int idx = 0; idx < MAX_NUM_CHANNEL_TYPE; idx++) { @@ -682,6 +688,10 @@ void PredictionUnit::initData() #endif mmvdMergeFlag = false; mmvdMergeIdx = MAX_UCHAR; +#if JVET_AA0061_IBC_MBVD + ibcMbvdMergeFlag = false; + ibcMbvdMergeIdx = MAX_INT; +#endif #if AFFINE_MMVD afMmvdFlag = false; afMmvdBaseIdx = UINT8_MAX; @@ -813,6 +823,10 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData) #endif mmvdMergeFlag = predData.mmvdMergeFlag; mmvdMergeIdx = predData.mmvdMergeIdx; +#if JVET_AA0061_IBC_MBVD + ibcMbvdMergeFlag = predData.ibcMbvdMergeFlag; + ibcMbvdMergeIdx = predData.ibcMbvdMergeIdx; +#endif #if AFFINE_MMVD afMmvdFlag = predData.afMmvdFlag; afMmvdBaseIdx = predData.afMmvdBaseIdx; @@ -940,6 +954,10 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other ) #endif mmvdMergeFlag = other.mmvdMergeFlag; mmvdMergeIdx = other.mmvdMergeIdx; +#if JVET_AA0061_IBC_MBVD + ibcMbvdMergeFlag = other.ibcMbvdMergeFlag; + ibcMbvdMergeIdx = other.ibcMbvdMergeIdx; +#endif #if AFFINE_MMVD afMmvdFlag = other.afMmvdFlag; afMmvdBaseIdx = other.afMmvdBaseIdx; diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index f0c868563e6da4f3666c936f08f45d4da82e83ea..66f9521870f16c614e31a4d5a66d11962168cd0b 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -350,6 +350,9 @@ struct CodingUnit : public UnitArea #if INTER_LIC bool LICFlag; #endif +#if JVET_AA0070_RRIBC + int rribcFlipType; +#endif // needed for fast imv mode decisions int8_t imvNumCand; @@ -476,6 +479,10 @@ struct InterPredictionData #else uint8_t mmvdMergeIdx; #endif +#if JVET_AA0061_IBC_MBVD + bool ibcMbvdMergeFlag; + int ibcMbvdMergeIdx; +#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 eaca0c884545156cb54d149e812a1b2b28396b93..e627446672db1a76e1f669d8d4654c52efd5d8f3 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -445,6 +445,13 @@ void CU::saveMotionInHMVP( const CodingUnit& cu, const bool isToBeDone ) #if MULTI_HYP_PRED mi.addHypData = pu.addHypData; #endif +#if JVET_AA0070_RRIBC + if(CU::isIBC(cu)) + { + mi.centerPos.x = cu.lx() + (cu.lwidth() >> 1); + mi.centerPos.y = cu.ly() + (cu.lheight() >> 1); + } +#endif mi.BcwIdx = (mi.interDir == 3) ? cu.BcwIdx : BCW_DEFAULT; @@ -1870,10 +1877,28 @@ bool PU::addMergeHMVPCand(const CodingStructure &cs, MergeCtx &mrgCtx, const int int num_avai_candInLUT = (int)lut.size(); +#if JVET_AA0070_RRIBC && !JVET_Z0075_IBC_HMVP_ENLARGE + int cPosCurX = pu.lx() + (pu.lwidth() >> 1); + int cPosCurY = pu.ly() + (pu.lheight() >> 1); + int thW = (pu.lwidth() >> 1) * 3; + int thH = (pu.lheight() >> 1) * 3; +#endif + for (int mrgIdx = 1; mrgIdx <= num_avai_candInLUT; mrgIdx++) { miNeighbor = lut[num_avai_candInLUT - mrgIdx]; +#if JVET_AA0070_RRIBC && !JVET_Z0075_IBC_HMVP_ENLARGE + if (ibcFlag) + { + Position cPos(miNeighbor.centerPos.x, miNeighbor.centerPos.y); + if (pu.mergeFlag || ((abs(cPosCurX - (int) cPos.x) <= thW) && (abs(cPosCurY - (int) cPos.y) <= thH))) + { + rribcAdjustMotion(pu, &cPos, miNeighbor); + } + } +#endif + #if JVET_X0083_BM_AMVP_MERGE_MODE #if JVET_Y0128_NON_CTC bool isValidAmMode = checkIsValidMergeMvCand(pu, miNeighbor.refIdx); @@ -1910,9 +1935,15 @@ bool PU::addMergeHMVPCand(const CodingStructure &cs, MergeCtx &mrgCtx, const int mrgCtx.BcwIdx [cnt] = (miNeighbor.interDir == 3) ? miNeighbor.BcwIdx : BCW_DEFAULT; #if INTER_LIC mrgCtx.LICFlags [cnt] = miNeighbor.usesLIC; +#if JVET_AA0070_RRIBC + mrgCtx.rribcFlipTypes [cnt] = 0; +#endif #if !JVET_Z0075_IBC_HMVP_ENLARGE if (ibcFlag) { +#if JVET_AA0070_RRIBC + mrgCtx.rribcFlipTypes[cnt] = !pu.tmMergeFlag ? miNeighbor.rribcFlipType : 0; +#endif CHECK(mrgCtx.LICFlags[cnt], "addMergeHMVPCand: LIC is not used with IBC mode") } #endif @@ -2015,15 +2046,35 @@ bool PU::addIBCMergeHMVPCand(const CodingStructure &cs, MergeCtx &mrgCtx, const int num_avai_candInLUT = (int)lut.size(); int compareNum = cnt; +#if JVET_AA0070_RRIBC + int cPosCurX = pu.lx() + (pu.lwidth() >> 1); + int cPosCurY = pu.ly() + (pu.lheight() >> 1); + int thW = (pu.lwidth() >> 1) * 3; + int thH = (pu.lheight() >> 1) * 3; +#endif for (int mrgIdx = 1; mrgIdx <= num_avai_candInLUT; mrgIdx++) { miNeighbor = lut[num_avai_candInLUT - mrgIdx]; +#if JVET_AA0070_RRIBC + Position cPos(miNeighbor.centerPos.x, miNeighbor.centerPos.y); + if (pu.mergeFlag || ((abs(cPosCurX - (int) cPos.x) <= thW) && (abs(cPosCurY - (int) cPos.y) <= thH))) + { + rribcAdjustMotion(pu, &cPos, miNeighbor); + } +#endif #if JVET_Y0058_IBC_LIST_MODIFY && JVET_Z0084_IBC_TM if (checkIsIBCCandidateValid(pu, miNeighbor)) { #endif mrgCtx.interDirNeighbours[cnt] = miNeighbor.interDir; +#if JVET_AA0070_RRIBC +#if IBC_TM_MRG + mrgCtx.rribcFlipTypes[cnt] = !pu.tmMergeFlag ? miNeighbor.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = miNeighbor.rribcFlipType; +#endif +#endif #if !JVET_Z0084_IBC_TM mrgCtx.useAltHpelIf [cnt] = false; mrgCtx.BcwIdx [cnt] = (miNeighbor.interDir == 3) ? miNeighbor.BcwIdx : BCW_DEFAULT; @@ -2090,6 +2141,59 @@ bool PU::addIBCMergeHMVPCand(const CodingStructure &cs, MergeCtx &mrgCtx, const return false; } #endif + +#if JVET_AA0070_RRIBC +void PU::rribcAdjustMotion(const PredictionUnit &pu, const Position *cPos, MotionInfo &miNeighbor) +{ +#if IBC_TM_MRG + if (pu.tmMergeFlag) + { + return; + } +#endif + +#if JVET_AA0061_IBC_MBVD + if (pu.ibcMbvdMergeFlag) + { + return; + } +#endif + + int curCPosX = pu.lx() + (pu.lwidth() >> 1); + int curCPosY = pu.ly() + (pu.lheight() >> 1); + + if (miNeighbor.isIBCmot && miNeighbor.rribcFlipType && (pu.mergeFlag || (!pu.mergeFlag && (pu.cu->rribcFlipType == miNeighbor.rribcFlipType)))) + { + if (miNeighbor.rribcFlipType == 1) + { + int shift = (cPos->x - curCPosX) << 1; + if (shift) + { + int storeHor = miNeighbor.mv[0].getHor(); + miNeighbor.mv[0].setHor(storeHor + (shift << 4)); + if (!checkIsIBCCandidateValid(pu, miNeighbor)) + { + miNeighbor.mv[0].setHor(storeHor); + } + } + } + else if (miNeighbor.rribcFlipType == 2) + { + int shift = (cPos->y - curCPosY) << 1; + if (shift) + { + int storeVer = miNeighbor.mv[0].getVer(); + miNeighbor.mv[0].setVer(storeVer + (shift << 4)); + if (!checkIsIBCCandidateValid(pu, miNeighbor)) + { + miNeighbor.mv[0].setVer(storeVer); + } + } + } + } +} +#endif + void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx) { const CodingStructure &cs = *pu.cs; @@ -2100,7 +2204,11 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const #endif #if JVET_Z0084_IBC_TM #if IBC_TM_MRG +#if JVET_AA0070_RRIBC + const uint32_t mvdSimilarityThresh = ((pu.tmMergeFlag && pu.mergeFlag) || (!pu.mergeFlag && !pu.cu->rribcFlipType)) ? PU::getTMMvdThreshold(pu) : 1; +#else const uint32_t mvdSimilarityThresh = pu.tmMergeFlag ? PU::getTMMvdThreshold(pu) : 1; +#endif #else const uint32_t mvdSimilarityThresh = 1; #endif @@ -2115,6 +2223,9 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const mrgCtx.useAltHpelIf[ui] = false; #if INTER_LIC mrgCtx.LICFlags[ui] = false; +#endif +#if JVET_AA0070_RRIBC + mrgCtx.rribcFlipTypes[ui] = 0; #endif } @@ -2142,6 +2253,10 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const if (isGt4x4 && isAvailableA1) { miLeft = puLeft->getMotionInfo(posLB.offset(-1, 0)); +#if JVET_AA0070_RRIBC + Position cPos(puLeft->lx() + (puLeft->lwidth() >> 1), puLeft->ly() + (puLeft->lheight() >> 1)); + rribcAdjustMotion(pu, &cPos, miLeft); +#endif #if JVET_Y0058_IBC_LIST_MODIFY if (checkIsIBCCandidateValid(pu, miLeft)) @@ -2151,6 +2266,21 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const mrgCtx.interDirNeighbours[cnt] = miLeft.interDir; // get Mv from Left mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miLeft.mv[0], miLeft.refIdx[0]); +#if JVET_AA0070_RRIBC +#if IBC_TM_MRG +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miLeft.isIBCmot && !pu.tmMergeFlag && !pu.ibcMbvdMergeFlag) ? miLeft.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = (miLeft.isIBCmot && !pu.tmMergeFlag) ? miLeft.rribcFlipType : 0; +#endif +#else +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miLeft.isIBCmot && !pu.ibcMbvdMergeFlag) ? miLeft.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = miLeft.isIBCmot ? miLeft.rribcFlipType : 0; +#endif +#endif +#endif if (mrgCandIdx == cnt) { return; @@ -2173,6 +2303,10 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const if (isGt4x4 && isAvailableB1) { miAbove = puAbove->getMotionInfo(posRT.offset(0, -1)); +#if JVET_AA0070_RRIBC + Position cPos(puAbove->lx() + (puAbove->lwidth() >> 1), puAbove->ly() + (puAbove->lheight() >> 1)); + rribcAdjustMotion(pu, &cPos, miAbove); +#endif if (!isAvailableA1 || (miAbove != miLeft)) { @@ -2184,6 +2318,21 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const mrgCtx.interDirNeighbours[cnt] = miAbove.interDir; // get Mv from Above mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miAbove.mv[0], miAbove.refIdx[0]); +#if JVET_AA0070_RRIBC +#if IBC_TM_MRG +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miAbove.isIBCmot && !pu.tmMergeFlag && !pu.ibcMbvdMergeFlag) ? miAbove.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = (miAbove.isIBCmot && !pu.tmMergeFlag) ? miAbove.rribcFlipType : 0; +#endif +#else +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miAbove.isIBCmot && !pu.ibcMbvdMergeFlag) ? miAbove.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = miAbove.isIBCmot ? miAbove.rribcFlipType : 0; +#endif +#endif +#endif #if JVET_Z0084_IBC_TM if( !mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) ) @@ -2214,6 +2363,10 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const if (isGt4x4 && isAvailableB0) { miAboveRight = puAboveRight->getMotionInfo(posRT.offset(1, -1)); +#if JVET_AA0070_RRIBC + Position cPos(puAboveRight->lx() + (puAboveRight->lwidth() >> 1), puAboveRight->ly() + (puAboveRight->lheight() >> 1)); + rribcAdjustMotion(pu, &cPos, miAboveRight); +#endif if ((!isAvailableB1 || (miAbove != miAboveRight)) && (!isAvailableA1 || (miLeft != miAboveRight))) { @@ -2223,6 +2376,21 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const mrgCtx.interDirNeighbours[cnt] = miAboveRight.interDir; // get Mv from Above-right mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miAboveRight.mv[0], miAboveRight.refIdx[0]); +#if JVET_AA0070_RRIBC +#if IBC_TM_MRG +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miAboveRight.isIBCmot && !pu.tmMergeFlag && !pu.ibcMbvdMergeFlag) ? miAboveRight.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = (miAboveRight.isIBCmot && !pu.tmMergeFlag) ? miAboveRight.rribcFlipType : 0; +#endif +#else +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miAboveRight.isIBCmot && !pu.ibcMbvdMergeFlag) ? miAboveRight.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = miAboveRight.isIBCmot ? miAboveRight.rribcFlipType : 0; +#endif +#endif +#endif #if JVET_Z0084_IBC_TM if( !mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) ) @@ -2250,6 +2418,10 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const if (isGt4x4 && isAvailableA0) { miBelowLeft = puLeftBottom->getMotionInfo(posLB.offset(-1, 1)); +#if JVET_AA0070_RRIBC + Position cPos(puLeftBottom->lx() + (puLeftBottom->lwidth() >> 1), puLeftBottom->ly() + (puLeftBottom->lheight() >> 1)); + rribcAdjustMotion(pu, &cPos, miBelowLeft); +#endif if ((!isAvailableA1 || (miBelowLeft != miLeft)) && (!isAvailableB1 || (miBelowLeft != miAbove)) && (!isAvailableB0 || (miBelowLeft != miAboveRight))) { @@ -2258,6 +2430,21 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const // get Inter Dir mrgCtx.interDirNeighbours[cnt] = miBelowLeft.interDir; mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miBelowLeft.mv[0], miBelowLeft.refIdx[0]); +#if JVET_AA0070_RRIBC +#if IBC_TM_MRG +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miBelowLeft.isIBCmot && !pu.tmMergeFlag && !pu.ibcMbvdMergeFlag) ? miBelowLeft.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = (miBelowLeft.isIBCmot && !pu.tmMergeFlag) ? miBelowLeft.rribcFlipType : 0; +#endif +#else +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miBelowLeft.isIBCmot && !pu.ibcMbvdMergeFlag) ? miBelowLeft.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = miBelowLeft.isIBCmot ? miBelowLeft.rribcFlipType : 0; +#endif +#endif +#endif #if JVET_Z0084_IBC_TM if( !mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) ) @@ -2291,6 +2478,10 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const if (isGt4x4 && isAvailableB2) { miAboveLeft = puAboveLeft->getMotionInfo(posLT.offset(-1, -1)); +#if JVET_AA0070_RRIBC + Position cPos(puAboveLeft->lx() + (puAboveLeft->lwidth() >> 1), puAboveLeft->ly() + (puAboveLeft->lheight() >> 1)); + rribcAdjustMotion(pu, &cPos, miAboveLeft); +#endif if ((!isAvailableA1 || (miLeft != miAboveLeft)) && (!isAvailableB1 || (miAbove != miAboveLeft)) && (!isAvailableA0 || (miBelowLeft != miAboveLeft)) && (!isAvailableB0 || (miAboveRight != miAboveLeft))) { @@ -2299,6 +2490,21 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const // get Inter Dir mrgCtx.interDirNeighbours[cnt] = miAboveLeft.interDir; mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miAboveLeft.mv[0], miAboveLeft.refIdx[0]); +#if JVET_AA0070_RRIBC +#if IBC_TM_MRG +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miAboveLeft.isIBCmot && !pu.tmMergeFlag && !pu.ibcMbvdMergeFlag) ? miAboveLeft.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = (miAboveLeft.isIBCmot && !pu.tmMergeFlag) ? miAboveLeft.rribcFlipType : 0; +#endif +#else +#if JVET_AA0061_IBC_MBVD + mrgCtx.rribcFlipTypes[cnt] = (miAboveLeft.isIBCmot && !pu.ibcMbvdMergeFlag) ? miAboveLeft.rribcFlipType : 0; +#else + mrgCtx.rribcFlipTypes[cnt] = (miAboveLeft.isIBCmot) ? miAboveLeft.rribcFlipType : 0; +#endif +#endif +#endif #if JVET_Z0084_IBC_TM if( !mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) ) @@ -2493,6 +2699,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_AA0070_RRIBC + mrgCtx.rribcFlipTypes[cnt] = 0; +#endif #if JVET_Z0084_IBC_TM if (!mrgCtx.xCheckSimilarIBCMotion(cnt, mvdSimilarityThresh) && checkIsIBCCandidateValid(pu, miCand)) @@ -2514,6 +2723,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_AA0070_RRIBC + mrgCtx.rribcFlipTypes[cnt] = 0; +#endif if (mrgCandIdx == cnt) { return; @@ -2539,14 +2751,23 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const } #if JVET_Y0058_IBC_LIST_MODIFY +#if JVET_AA0070_RRIBC +bool PU::checkIsIBCCandidateValid(const PredictionUnit& pu, const MotionInfo miNeighbor, bool isRefTemplate, bool isRefAbove) +#else bool PU::checkIsIBCCandidateValid(const PredictionUnit& pu, const MotionInfo miNeighbor) +#endif { Mv bv = miNeighbor.mv[REF_PIC_LIST_0]; bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); // used for only integer resolution const int cuPelX = pu.Y().x; const int cuPelY = pu.Y().y; +#if JVET_AA0070_RRIBC + int roiWidth = (isRefTemplate && !isRefAbove) ? AML_MERGE_TEMPLATE_SIZE : pu.lwidth(); + int roiHeight = (isRefTemplate && isRefAbove) ? AML_MERGE_TEMPLATE_SIZE : pu.lheight(); +#else int roiWidth = pu.lwidth(); int roiHeight = pu.lheight(); +#endif const int picWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples(); const int picHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples(); const unsigned int lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth(); @@ -2747,6 +2968,45 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h } #endif +#if JVET_AA0061_IBC_MBVD +void PU::getIbcMbvdMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, int numValidBv) +{ + int refIdxList0; + int k; + int currBaseNum = 0; + + for( k = 0; k < numValidBv; k++ ) + { + refIdxList0 = mrgCtx.mvFieldNeighbours[( k << 1 )].refIdx; + + if( refIdxList0 >= 0 ) + { + mrgCtx.ibcMbvdBaseBv[currBaseNum][0] = mrgCtx.mvFieldNeighbours[( k << 1 )]; + mrgCtx.ibcMbvdBaseBv[currBaseNum][1] = MvField( Mv( 0, 0 ), -1 ); + } + + currBaseNum++; + + if( currBaseNum == IBC_MBVD_BASE_NUM ) + { + break; + } + } +} +int32_t PU::getIbcMbvdEstBits(const PredictionUnit &pu,unsigned int mmvdMergeCand) +{ + int baseIdx = mmvdMergeCand / IBC_MBVD_MAX_REFINE_NUM; + int baseBits = (IBC_MBVD_BASE_NUM == 1 ? 0 : baseIdx + (baseIdx == IBC_MBVD_BASE_NUM - 1 ? 0: 1)); + int ricePar = 1; + unsigned int mvpIdx = mmvdMergeCand; + mvpIdx -= baseIdx * IBC_MBVD_MAX_REFINE_NUM; + mvpIdx >>= ricePar; + int numCandStepMinus1 = (IBC_MBVD_SIZE_ENC >> ricePar) - 1; + int mmvdUnaryBits = mvpIdx + (mvpIdx == numCandStepMinus1 ? 0 : 1); + return baseBits + mmvdUnaryBits + ricePar; +} +#endif + #if MULTI_PASS_DMVR || JVET_W0097_GPM_MMVD_TM uint32_t PU::getBDMVRMvdThreshold(const PredictionUnit &pu) { @@ -2875,6 +3135,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, mrgCtx.BcwIdx[ui] = BCW_DEFAULT; #if INTER_LIC mrgCtx.LICFlags[ui] = false; +#endif +#if JVET_AA0070_RRIBC + mrgCtx.rribcFlipTypes[ui] = 0; #endif mrgCtx.interDirNeighbours[ui] = 0; mrgCtx.mvFieldNeighbours[(ui << 1) ].refIdx = NOT_VALID; @@ -6929,11 +7192,20 @@ void PU::fillIBCMvpCand(PredictionUnit &pu, AMVPInfo &amvpInfo) MergeCtx mergeCtx; #if JVET_Z0084_IBC_TM && IBC_TM_AMVP +#if JVET_AA0070_RRIBC + pInfo->maxSimilarityThreshold = (pu.cs->sps->getUseDMVDMode() && pcInter && !pu.cu->rribcFlipType) ? PU::getTMMvdThreshold(pu) : 1; +#if IBC_TM_MRG + if (!pu.cu->rribcFlipType) + { + pu.tmMergeFlag = true; + } +#endif +#else pInfo->maxSimilarityThreshold = (pu.cs->sps->getUseDMVDMode() && pcInter) ? PU::getTMMvdThreshold(pu) : 1; - #if IBC_TM_MRG pu.tmMergeFlag = true; #endif +#endif #if JVET_Z0075_IBC_HMVP_ENLARGE PU::getIBCMergeCandidates(pu, mergeCtx, pu.cs->sps->getMaxNumIBCMergeCand()); #else @@ -6955,7 +7227,11 @@ void PU::fillIBCMvpCand(PredictionUnit &pu, AMVPInfo &amvpInfo) candIdx++; } +#if JVET_AA0070_RRIBC + if (pu.cs->sps->getUseDMVDMode() && pcInter && pInfo->numCand > 0 && !pu.cu->rribcFlipType) +#else if (pu.cs->sps->getUseDMVDMode() && pcInter && pInfo->numCand > 0) +#endif { struct AMVPSort { @@ -11382,6 +11658,9 @@ void PU::spanMotionInfo( PredictionUnit &pu, const MergeCtx &mrgCtx ) #if INTER_LIC mi.usesLIC = pu.cu->LICFlag; #endif +#if JVET_AA0070_RRIBC + mi.rribcFlipType = mi.isIBCmot ? pu.cu->rribcFlipType : 0; +#endif if( mi.isInter ) { @@ -11845,6 +12124,16 @@ void PU::applyImv( PredictionUnit& pu, MergeCtx &mrgCtx, InterPrediction *interP #endif pu.mv [0] = amvpInfo.mvCand[mvpIdx] + pu.mvd[0]; pu.mv[0].mvCliptoStorageBitDepth(); +#if JVET_AA0070_RRIBC + if (CU::isIBC(*pu.cu) && pu.cu->rribcFlipType == 1) + { + pu.mv[0].setVer(0); + } + else if (CU::isIBC(*pu.cu) && pu.cu->rribcFlipType == 2) + { + pu.mv[0].setHor(0); + } +#endif #if JVET_Z0160_IBC_ZERO_PADDING pu.bv = pu.mv[0]; pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index f8908e63f0a8b028f5fded92cc4d9f453b587464..f8eb6f82499345763c8b7b2c9e0418e72ee4424a 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -192,11 +192,22 @@ namespace PU void getNonAdjacentMergeCand (const PredictionUnit &pu, MergeCtx& mvpMrgCtx); #endif void getIBCMergeCandidates (const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx = -1); +#if JVET_AA0070_RRIBC + void rribcAdjustMotion(const PredictionUnit &pu, const Position *cPos, MotionInfo &miNeighbor); +#if JVET_Y0058_IBC_LIST_MODIFY + bool checkIsIBCCandidateValid (const PredictionUnit &pu,const MotionInfo miNeighbor, bool isRefTemplate = false, bool isRefAbove = false ); +#endif +#else #if JVET_Y0058_IBC_LIST_MODIFY bool checkIsIBCCandidateValid (const PredictionUnit &pu,const MotionInfo miNeighbor); #endif -#if JVET_Y0058_IBC_LIST_MODIFY || JVET_Z0084_IBC_TM +#endif +#if JVET_Y0058_IBC_LIST_MODIFY || JVET_Z0084_IBC_TM || JVET_AA0061_IBC_MBVD bool searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize); +#endif +#if JVET_AA0061_IBC_MBVD + void getIbcMbvdMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, int numValidBv); + int32_t getIbcMbvdEstBits (const PredictionUnit &pu, unsigned int mmvdMergeCand); #endif void getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx = -1); int getDistScaleFactor(const int &currPOC, const int &currRefPOC, const int &colPOC, const int &colRefPOC); diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 544d56b07966f49f0abfec16b490195384f2525c..6ac643054e1f366e55f3ea03db268697d10ba1ff 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -3044,6 +3044,11 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx ) { merge_flag( pu ); } + +#if JVET_AA0070_RRIBC + rribcData(*pu.cu); +#endif + if( pu.mergeFlag ) { merge_data(pu); @@ -3061,10 +3066,18 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx ) pu.cu->affine = false; pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF; RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET_SIZE(STATS__CABAC_BITS__MVD, pu.lumaSize()); +#if JVET_AA0070_RRIBC +#if JVET_Z0131_IBC_BVD_BINARIZATION + bvdCoding(pu.mvd[REF_PIC_LIST_0], pu.cu->rribcFlipType); +#else + mvd_coding(pu.mvd[REF_PIC_LIST_0], true, pu.cu->rribcFlipType); +#endif +#else #if JVET_Z0131_IBC_BVD_BINARIZATION bvdCoding(pu.mvd[REF_PIC_LIST_0]); #else mvd_coding(pu.mvd[REF_PIC_LIST_0]); +#endif #endif if (pu.cs->sps->getMaxNumIBCMergeCand() == 1) { @@ -3476,6 +3489,62 @@ void CABACReader::affine_mmvd_data(PredictionUnit& pu) } #endif +#if JVET_AA0061_IBC_MBVD +void CABACReader::ibcMbvdData(PredictionUnit& pu) +{ + if (!pu.cs->sps->getUseIbcMbvd() || !pu.mergeFlag || !CU::isIBC(*pu.cu)) + { + return; + } + + pu.ibcMbvdMergeFlag = (m_BinDecoder.decodeBin(Ctx::IbcMbvdFlag())); + DTRACE(g_trace_ctx, D_SYNTAX, "IBC_mbvd_flag() IBC_mbvd_merge=%d pos=(%d,%d) size=%dx%d\n", pu.ibcMbvdMergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height); + + if (!pu.ibcMbvdMergeFlag) + { + return; + } + + // Base IBC merge candidate idx + uint8_t var0 = 0; + int numBaseCandMinus1 = IBC_MBVD_BASE_NUM - 1; + if (numBaseCandMinus1 > 0) + { + // to support more base candidates + if (m_BinDecoder.decodeBin(Ctx::IbcMbvdMergeIdx())) + { + var0++; + for (; var0 < numBaseCandMinus1; var0++) + { + if (!m_BinDecoder.decodeBinEP()) + { + break; + } + } + } + } + DTRACE(g_trace_ctx, D_SYNTAX, "ibcMbvdBaseIdx() ibcMbvdBaseIdx=%d\n", var0); + + unsigned int uiUnaryIdx = 0; + unsigned int ricePar = 1; + int numCandStepMinus1 = (IBC_MBVD_SIZE_ENC >> ricePar) - 1; + int temp = 0; + temp = m_BinDecoder.decodeBinsEP(ricePar); + + for (; uiUnaryIdx < numCandStepMinus1; ++uiUnaryIdx) + { + if (!m_BinDecoder.decodeBin(Ctx::IbcMbvdStepMvpIdx((uiUnaryIdx > LAST_MERGE_MMVD_IDX_CABAC - 1 ? LAST_MERGE_MMVD_IDX_CABAC - 1 : uiUnaryIdx)))) + { + break; + } + } + uiUnaryIdx <<= ricePar; + uiUnaryIdx += temp; + pu.ibcMbvdMergeIdx = var0 * IBC_MBVD_MAX_REFINE_NUM +uiUnaryIdx; + DTRACE(g_trace_ctx, D_SYNTAX, "IBC_mbvd_merge_idx() IBC_mbvd_merge_idx=%d\n", pu.ibcMbvdMergeIdx); +} +#endif + #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) void CABACReader::tm_merge_flag(PredictionUnit& pu) { @@ -3539,8 +3608,18 @@ void CABACReader::merge_data( PredictionUnit& pu ) { if (CU::isIBC(*pu.cu)) { +#if JVET_AA0061_IBC_MBVD + ibcMbvdData(pu); +#endif #if JVET_Z0084_IBC_TM && IBC_TM_MRG - tm_merge_flag(pu); +#if JVET_AA0061_IBC_MBVD + if (!pu.ibcMbvdMergeFlag) + { +#endif + tm_merge_flag(pu); +#if JVET_AA0061_IBC_MBVD + } +#endif #endif merge_idx(pu); return; @@ -3892,6 +3971,12 @@ void CABACReader::merge_idx( PredictionUnit& pu ) if (pu.cu->predMode == MODE_IBC) { +#if JVET_AA0061_IBC_MBVD + if (pu.ibcMbvdMergeFlag) + { + return; + } +#endif numCandminus1 = int(pu.cs->sps->getMaxNumIBCMergeCand()) - 1; } #if TM_MRG @@ -4851,8 +4936,26 @@ bool CABACReader::cbf_comp( CodingStructure& cs, const CompArea& area, unsigned //-------------------------------------------------------------------------------- // void mvd_coding( pu, refList ) //================================================================================ - -void CABACReader::mvd_coding( Mv &rMvd +#if JVET_AA0070_RRIBC +void CABACReader::mvd_coding( Mv &rMvd +#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED + , bool codeSign +#endif + , const int &rribcFlipType +) +{ + // abs_mvd_greater0_flag[ 0 | 1 ] + int horAbs = 0, verAbs = 0; + if (rribcFlipType != 2) + { + horAbs = (int) m_BinDecoder.decodeBin(Ctx::Mvd()); + } + if (rribcFlipType != 1) + { + verAbs = (int) m_BinDecoder.decodeBin(Ctx::Mvd()); + } +#else +void CABACReader::mvd_coding( Mv &rMvd #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , bool codeSign #endif @@ -4861,6 +4964,7 @@ void CABACReader::mvd_coding( Mv &rMvd // abs_mvd_greater0_flag[ 0 | 1 ] int horAbs = (int)m_BinDecoder.decodeBin(Ctx::Mvd()); int verAbs = (int)m_BinDecoder.decodeBin(Ctx::Mvd()); +#endif // abs_mvd_greater1_flag[ 0 | 1 ] if (horAbs) @@ -4934,10 +5038,24 @@ unsigned CABACReader::xReadBvdContext(unsigned ctxT, int offset, int param) #endif #if JVET_Z0131_IBC_BVD_BINARIZATION +#if JVET_AA0070_RRIBC +void CABACReader::bvdCoding(Mv &rMvd, const int &rribcFlipType) +{ + int horAbs = 0, verAbs = 0; + if (rribcFlipType != 2) + { + horAbs = (int) m_BinDecoder.decodeBin(Ctx::Bvd(HOR_BVD_CTX_OFFSET)); + } + if (rribcFlipType != 1) + { + verAbs = (int) m_BinDecoder.decodeBin(Ctx::Bvd(VER_BVD_CTX_OFFSET)); + } +#else void CABACReader::bvdCoding( Mv &rMvd ) { int horAbs = (int)m_BinDecoder.decodeBin(Ctx::Bvd(HOR_BVD_CTX_OFFSET)); int verAbs = (int)m_BinDecoder.decodeBin(Ctx::Bvd(VER_BVD_CTX_OFFSET)); +#endif if (horAbs) { @@ -6427,6 +6545,27 @@ void CABACReader::cu_lic_flag( CodingUnit& cu ) } #endif +#if JVET_AA0070_RRIBC +void CABACReader::rribcData(CodingUnit &cu) +{ + if (!CU::isIBC(cu) || cu.firstPU->mergeFlag) + { + return; + } + + cu.rribcFlipType = 0; + + unsigned ctxId = DeriveCtx::CtxRribcFlipType(cu); + cu.rribcFlipType = (m_BinDecoder.decodeBin(Ctx::rribcFlipType(ctxId))); + if (cu.rribcFlipType) + { + cu.rribcFlipType += m_BinDecoder.decodeBin(Ctx::rribcFlipType(3)); + } + DTRACE(g_trace_ctx, D_SYNTAX, "rribcData() rribcFlipType = %d\n", cu.rribcFlipType); +} +#endif + + #if SIGN_PREDICTION void CABACReader::parsePredictedSigns( TransformUnit &tu, ComponentID compID ) { diff --git a/source/Lib/DecoderLib/CABACReader.h b/source/Lib/DecoderLib/CABACReader.h index 3825af393018ae55d76c0d3b2ac144af430b7ade..1f5b452f32fac785920aa8f91ce02836a6c9ab3b 100644 --- a/source/Lib/DecoderLib/CABACReader.h +++ b/source/Lib/DecoderLib/CABACReader.h @@ -155,6 +155,9 @@ public: #if AFFINE_MMVD void affine_mmvd_data ( PredictionUnit& pu ); #endif +#if JVET_AA0061_IBC_MBVD + void ibcMbvdData ( PredictionUnit& pu ); +#endif #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) void tm_merge_flag ( PredictionUnit& pu ); #endif @@ -205,6 +208,17 @@ public: bool cbf_comp ( CodingStructure& cs, const CompArea& area, unsigned depth, const bool prevCbf = false, const bool useISP = false ); // mvd coding (clause 7.3.8.9) +#if JVET_AA0070_RRIBC +#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED + void mvd_coding ( Mv &rMvd, bool codeSign = true, const int &rribcFlipType = 0); +#else + void mvd_coding ( Mv &rMvd, const int &rribcFlipType = 0); +#endif +#if JVET_Z0131_IBC_BVD_BINARIZATION + void bvdCoding ( Mv &rMvd, const int &rribcFlipType = 0); + unsigned xReadBvdContext(unsigned ctxT, int offset, int param); +#endif +#else void mvd_coding ( Mv &rMvd #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , bool codeSign = true @@ -214,6 +228,7 @@ public: void bvdCoding ( Mv &rMvd ); unsigned xReadBvdContext(unsigned ctxT, int offset, int param); #endif +#endif #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED void mvsdIdxFunc(PredictionUnit &pu, RefPicList eRefList); void mvsdAffineIdxFunc(PredictionUnit &pu, RefPicList eRefList); @@ -268,6 +283,9 @@ public: void cu_lic_flag ( CodingUnit& cu ); #endif +#if JVET_AA0070_RRIBC + void rribcData ( CodingUnit &cu ); +#endif #if JVET_Z0135_TEMP_CABAC_WIN_WEIGHT CABACDataStore* m_CABACDataStore; #endif diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index f00b2d95a114868980d389d1d2e1eb63c9db7388..4a75ab93182938b52e11f817f9946d20a8acdf95 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -1376,6 +1376,17 @@ void DecCu::xReconInter(CodingUnit &cu) cs.getRecoBuf(cu).get(COMPONENT_Y).rspSignal(m_pcReshape->getFwdLUT()); } } +#if JVET_AA0070_RRIBC + if (CU::isIBC(cu) && cu.rribcFlipType) + { + cu.cs->getRecoBuf(cu).get(COMPONENT_Y).flipSignal(cu.rribcFlipType == 1); + if (isChromaEnabled(cu.chromaFormat) && cu.Cb().valid()) + { + cu.cs->getRecoBuf(cu).get(COMPONENT_Cb).flipSignal(cu.rribcFlipType == 1); + cu.cs->getRecoBuf(cu).get(COMPONENT_Cr).flipSignal(cu.rribcFlipType == 1); + } + } +#endif #endif DTRACE ( g_trace_ctx, D_TMP, "reco " ); @@ -1503,6 +1514,12 @@ void DecCu::xDecodeInterTU( TransformUnit & currTU, const ComponentID compID ) else { currTU.cs->getRecoBuf( currTU.blocks[currCompID] ).reconstruct( cs.getPredBuf( currTU.blocks[currCompID] ), compResiBuf, currTU.cu->cs->slice->clpRng( currCompID ) ); +#if JVET_AA0070_RRIBC + if (CU::isIBC(*currTU.cu) && currTU.cu->rribcFlipType) + { + currTU.cs->getRecoBuf(currTU.blocks[currCompID]).flipSignal(currTU.cu->rribcFlipType == 1); + } +#endif } } #endif @@ -1523,7 +1540,21 @@ void DecCu::xDecodeInterTexture(CodingUnit &cu) { cs.getRecoBuf(cu).get(COMPONENT_Y).rspSignal(m_pcReshape->getFwdLUT()); } + +#if JVET_AA0070_RRIBC + if (CU::isIBC(cu) && cu.rribcFlipType) + { + cu.cs->getRecoBuf(cu).get(COMPONENT_Y).flipSignal(cu.rribcFlipType == 1); + if (isChromaEnabled(cu.chromaFormat) && cu.Cb().valid()) + { + cu.cs->getRecoBuf(cu).get(COMPONENT_Cb).flipSignal(cu.rribcFlipType == 1); + cu.cs->getRecoBuf(cu).get(COMPONENT_Cr).flipSignal(cu.rribcFlipType == 1); + } + } +#endif #endif + + return; } @@ -1934,26 +1965,48 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) #endif if (CU::isIBC(*pu.cu)) { -#if JVET_Y0058_IBC_LIST_MODIFY && JVET_W0090_ARMC_TM - if (pu.cs->sps->getUseAML()) +#if JVET_AA0061_IBC_MBVD + if (pu.ibcMbvdMergeFlag) + { + int fPosIBCBaseIdx = pu.ibcMbvdMergeIdx / IBC_MBVD_MAX_REFINE_NUM; + PU::getIBCMergeCandidates(pu, mrgCtx); + m_pcInterPred->adjustIBCMergeCandidates(pu, mrgCtx, 0, IBC_MRG_MAX_NUM_CANDS_MEM); + + PU::getIbcMbvdMergeCandidates(pu, mrgCtx, fPosIBCBaseIdx + 1); + + uint32_t ibcMbvdLUT[IBC_MBVD_NUM]; + uint32_t ibcMbvdValidNum[IBC_MBVD_BASE_NUM] = { 0 }; + int ibcMbvdIdx= pu.ibcMbvdMergeIdx; + m_pcInterPred->sortIbcMergeMbvdCandidates(pu, mrgCtx, ibcMbvdLUT, ibcMbvdValidNum, ibcMbvdIdx); + bool mbvdCandMisAlign = mrgCtx.setIbcMbvdMergeCandiInfo(pu, ibcMbvdIdx, ibcMbvdLUT[ibcMbvdIdx]); + CHECK(mbvdCandMisAlign, "MBVD candidate is invalid"); + } + else { +#endif +#if JVET_Y0058_IBC_LIST_MODIFY && JVET_W0090_ARMC_TM + if (pu.cs->sps->getUseAML()) + { #if JVET_Z0075_IBC_HMVP_ENLARGE #if JVET_AA0093_ENHANCED_MMVD_EXTENSION uint16_t mrgCandIdx = pu.mergeIdx; #else uint8_t mrgCandIdx = pu.mergeIdx; #endif - PU::getIBCMergeCandidates(pu, mrgCtx); - m_pcInterPred->adjustIBCMergeCandidates(pu, mrgCtx, 0, IBC_MRG_MAX_NUM_CANDS_MEM); - pu.mergeIdx = mrgCandIdx; + PU::getIBCMergeCandidates(pu, mrgCtx); + m_pcInterPred->adjustIBCMergeCandidates(pu, mrgCtx, 0, IBC_MRG_MAX_NUM_CANDS_MEM); + 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); - m_pcInterPred->adjustIBCMergeCandidates(pu, mrgCtx, pu.mergeIdx); + 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); + m_pcInterPred->adjustIBCMergeCandidates(pu, mrgCtx, pu.mergeIdx); +#endif + } + else #endif + PU::getIBCMergeCandidates(pu, mrgCtx, pu.mergeIdx); +#if JVET_AA0061_IBC_MBVD } - else #endif - PU::getIBCMergeCandidates(pu, mrgCtx, pu.mergeIdx); } else #if JVET_X0049_ADAPT_DMVR @@ -2405,8 +2458,15 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) } #else PU::getInterMergeCandidates(pu, mrgCtx, 0, pu.mergeIdx); +#endif +#if JVET_AA0061_IBC_MBVD + if (!pu.ibcMbvdMergeFlag) + { #endif mrgCtx.setMergeInfo( pu, pu.mergeIdx ); +#if JVET_AA0061_IBC_MBVD + } +#endif #if JVET_AA0093_REFINED_MOTION_FOR_ARMC if (pu.tmMergeFlag && tmMergeRefinedMotion) { @@ -2716,6 +2776,16 @@ void DecCu::xDeriveCUMV( CodingUnit &cu ) } pu.mv[REF_PIC_LIST_0] = amvpInfo.mvCand[pu.mvpIdx[REF_PIC_LIST_0]] + mvd; pu.mv[REF_PIC_LIST_0].mvCliptoStorageBitDepth(); +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 1) + { + pu.mv[REF_PIC_LIST_0].setVer(0); + } + else if (pu.cu->rribcFlipType == 2) + { + pu.mv[REF_PIC_LIST_0].setHor(0); + } +#endif #if JVET_Z0160_IBC_ZERO_PADDING pu.bv = pu.mv[0]; pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index d3539facebf902f6ad8106aabc73babf93c81611..377df7775dfee0d1899b9b8cf9a60e6db6285c33 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -2464,6 +2464,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) READ_UVLC(uiCode, "six_minus_max_num_ibc_merge_cand"); CHECK(IBC_MRG_MAX_NUM_CANDS <= uiCode, "Incorrrect max number of IBC merge candidates!"); 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 } else pcSPS->setMaxNumIBCMergeCand(0); diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index e4730b65018b3554b82529efcc81f1e47c7aaef7..bfd0b401fc82d6e80f25e8f450be5cb46fb4efca 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -2670,6 +2670,9 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu ) { merge_flag( pu ); } +#if JVET_AA0070_RRIBC + rribcData(*pu.cu); +#endif if( pu.mergeFlag ) { merge_data(pu); @@ -2690,10 +2693,18 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu ) ref_idx(pu, REF_PIC_LIST_0); Mv mvd = pu.mvd[REF_PIC_LIST_0]; mvd.changeIbcPrecInternal2Amvr(pu.cu->imv); +#if JVET_AA0070_RRIBC +#if JVET_Z0131_IBC_BVD_BINARIZATION + bvdCoding(mvd, 0, pu.cu->rribcFlipType); // already changed to signaling precision +#else + mvd_coding(mvd, 0, true, pu.cu->rribcFlipType); // already changed to signaling precision +#endif +#else #if JVET_Z0131_IBC_BVD_BINARIZATION bvdCoding(mvd, 0); // already changed to signaling precision #else mvd_coding(mvd, 0); // already changed to signaling precision +#endif #endif if (pu.cs->sps->getMaxNumIBCMergeCand() == 1) { @@ -3083,6 +3094,68 @@ void CABACWriter::affine_mmvd_data(const PredictionUnit& pu) } #endif +#if JVET_AA0061_IBC_MBVD +void CABACWriter::ibcMbvdData(const PredictionUnit& pu) +{ + if (!pu.cs->sps->getUseIbcMbvd() || !pu.mergeFlag || !CU::isIBC(*pu.cu)) + { + return; + } + m_BinEncoder.encodeBin(pu.ibcMbvdMergeFlag, Ctx::IbcMbvdFlag()); + DTRACE(g_trace_ctx, D_SYNTAX, "IBC_mbvd_flag() IBC_mbvd_merge=%d pos=(%d,%d) size=%dx%d\n", pu.ibcMbvdMergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height); + + if (!pu.ibcMbvdMergeFlag) + { + return; + } + int mvpIdx = pu.ibcMbvdMergeIdx; + uint8_t var0; + var0 = mvpIdx / IBC_MBVD_MAX_REFINE_NUM; + mvpIdx -= var0 * IBC_MBVD_MAX_REFINE_NUM; + + // Base affine merge candidate idx + + int numBaseCandMinus1 = IBC_MBVD_BASE_NUM - 1; + if (numBaseCandMinus1 > 0) + { + // to support more base candidates + m_BinEncoder.encodeBin((var0 == 0 ? 0 : 1), Ctx::IbcMbvdMergeIdx()); + + if (var0 > 0) + { + for (unsigned idx = 1; idx < numBaseCandMinus1; idx++) + { + m_BinEncoder.encodeBinEP(var0 == idx ? 0 : 1); + if (var0 == idx) + { + break; + } + } + } + } + DTRACE(g_trace_ctx, D_SYNTAX, "ibcMbvdBaseIdx() ibcMbvdBaseIdx=%d\n", var0); + + unsigned int ricePar = 1; + int numCandStepMinus1 = (IBC_MBVD_SIZE_ENC >> ricePar) - 1; + if(ricePar > 0) + { + m_BinEncoder.encodeBinsEP( mvpIdx % (1 << ricePar), ricePar); + } + mvpIdx >>= ricePar; + for (unsigned int uiUnaryIdx = 0; uiUnaryIdx < numCandStepMinus1; ++uiUnaryIdx) + { + unsigned int uiSymbol = mvpIdx == uiUnaryIdx ? 0 : 1; + m_BinEncoder.encodeBin(uiSymbol, Ctx::IbcMbvdStepMvpIdx((uiUnaryIdx > LAST_MERGE_MMVD_IDX_CABAC - 1 ? LAST_MERGE_MMVD_IDX_CABAC - 1 : uiUnaryIdx))); + if (uiSymbol == 0) + { + break; + } + } + + DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", pu.ibcMbvdMergeIdx); +} +#endif + #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) void CABACWriter::tm_merge_flag(const PredictionUnit& pu) { @@ -3145,8 +3218,18 @@ void CABACWriter::merge_data(const PredictionUnit& pu) { if (CU::isIBC(*pu.cu)) { +#if JVET_AA0061_IBC_MBVD + ibcMbvdData(pu); +#endif #if JVET_Z0084_IBC_TM && IBC_TM_MRG - tm_merge_flag(pu); +#if JVET_AA0061_IBC_MBVD + if (!pu.ibcMbvdMergeFlag) + { +#endif + tm_merge_flag(pu); +#if JVET_AA0061_IBC_MBVD + } +#endif #endif merge_idx(pu); return; @@ -3525,7 +3608,17 @@ void CABACWriter::merge_idx( const PredictionUnit& pu ) #endif #endif if (pu.cu->predMode == MODE_IBC) +#if JVET_AA0061_IBC_MBVD + { + if (pu.ibcMbvdMergeFlag) + { + 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 @@ -4627,6 +4720,9 @@ void CABACWriter::mvd_coding( const Mv &rMvd, int8_t imv #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , bool codeSign #endif +#if JVET_AA0070_RRIBC + , const int &rribcFlipType +#endif ) { int horMvd = rMvd.getHor(); @@ -4654,8 +4750,19 @@ void CABACWriter::mvd_coding( const Mv &rMvd, int8_t imv // abs_mvd_greater0_flag[ 0 | 1 ] - m_BinEncoder.encodeBin( (horAbs > 0), Ctx::Mvd() ); - m_BinEncoder.encodeBin( (verAbs > 0), Ctx::Mvd() ); +#if JVET_AA0070_RRIBC + if (rribcFlipType != 2) + { + m_BinEncoder.encodeBin((horAbs > 0), Ctx::Mvd()); + } + if (rribcFlipType != 1) + { + m_BinEncoder.encodeBin((verAbs > 0), Ctx::Mvd()); + } +#else + m_BinEncoder.encodeBin((horAbs > 0), Ctx::Mvd()); + m_BinEncoder.encodeBin((verAbs > 0), Ctx::Mvd()); +#endif // abs_mvd_greater1_flag[ 0 | 1 ] if( horAbs > 0 ) @@ -4729,7 +4836,11 @@ void CABACWriter::xWriteBvdContext(unsigned uiSymbol, unsigned ctxT, int offset, #endif #if JVET_Z0131_IBC_BVD_BINARIZATION -void CABACWriter::bvdCoding( const Mv &rMvd, int8_t imv ) +#if JVET_AA0070_RRIBC +void CABACWriter::bvdCoding(const Mv &rMvd, int8_t imv, const int &rribcFlipType) +#else +void CABACWriter::bvdCoding( const Mv &rMvd, int8_t imv) +#endif { int horMvd = rMvd.getHor(); int verMvd = rMvd.getVer(); @@ -4737,8 +4848,19 @@ void CABACWriter::bvdCoding( const Mv &rMvd, int8_t imv ) unsigned horAbs = unsigned( horMvd < 0 ? -horMvd : horMvd ); unsigned verAbs = unsigned( verMvd < 0 ? -verMvd : verMvd ); +#if JVET_AA0070_RRIBC + if (rribcFlipType != 2) + { + m_BinEncoder.encodeBin((horAbs > 0), Ctx::Bvd(HOR_BVD_CTX_OFFSET)); + } + if (rribcFlipType != 1) + { + m_BinEncoder.encodeBin((verAbs > 0), Ctx::Bvd(VER_BVD_CTX_OFFSET)); + } +#else m_BinEncoder.encodeBin( (horAbs > 0), Ctx::Bvd(HOR_BVD_CTX_OFFSET) ); m_BinEncoder.encodeBin( (verAbs > 0), Ctx::Bvd(VER_BVD_CTX_OFFSET) ); +#endif if( horAbs > 0 ) { @@ -6377,6 +6499,25 @@ void CABACWriter::cu_lic_flag(const CodingUnit& cu) } #endif +#if JVET_AA0070_RRIBC +void CABACWriter::rribcData(const CodingUnit& cu) +{ + if (!CU::isIBC(cu) || cu.firstPU->mergeFlag) + { + return; + } + + unsigned ctxId = DeriveCtx::CtxRribcFlipType(cu); + m_BinEncoder.encodeBin(cu.rribcFlipType > 0, Ctx::rribcFlipType(ctxId)); + if (cu.rribcFlipType) + { + CHECK(cu.rribcFlipType != 1 && cu.rribcFlipType != 2, "cu.rribcFlipType != 1 && cu.rribcFlipType != 2"); + m_BinEncoder.encodeBin(cu.rribcFlipType >> 1, Ctx::rribcFlipType(3)); + } + DTRACE(g_trace_ctx, D_SYNTAX, "rribcData() rribcFlipType = %d\n", cu.rribcFlipType); +} +#endif + #if SIGN_PREDICTION #if JVET_Y0141_SIGN_PRED_IMPROVE struct signCombInfo diff --git a/source/Lib/EncoderLib/CABACWriter.h b/source/Lib/EncoderLib/CABACWriter.h index 05c2bf5d0c05c19e5e70dbf0bb09b08cd816a831..09e5b24573169b537d54923b396f3bcc9940ac69 100644 --- a/source/Lib/EncoderLib/CABACWriter.h +++ b/source/Lib/EncoderLib/CABACWriter.h @@ -166,6 +166,9 @@ public: #if AFFINE_MMVD void affine_mmvd_data ( const PredictionUnit& pu ); #endif +#if JVET_AA0061_IBC_MBVD + void ibcMbvdData ( const PredictionUnit& pu ); +#endif #if TM_MRG || (JVET_Z0084_IBC_TM && IBC_TM_MRG) void tm_merge_flag ( const PredictionUnit& pu); #endif @@ -231,15 +234,28 @@ public: void cbf_comp ( const CodingStructure& cs, bool cbf, const CompArea& area, unsigned depth, const bool prevCbf = false, const bool useISP = false ); // mvd coding (clause 7.3.8.9) +#if JVET_AA0070_RRIBC +#if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED + void mvd_coding ( const Mv &rMvd, int8_t imv, bool codeSign = true, const int &rribcFlipType = 0 ); +#else + void mvd_coding ( const Mv &rMvd, int8_t imv, const int &rribcFlipType = 0 ); +#endif +#if JVET_Z0131_IBC_BVD_BINARIZATION + void bvdCoding ( const Mv &rMvd, int8_t imv, const int &rribcFlipType = 0 ); + void xWriteBvdContext(unsigned uiSymbol, unsigned ctxT, int offset, int param); +#endif +#else void mvd_coding ( const Mv &rMvd, int8_t imv #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , bool codeSign = true #endif ); + #if JVET_Z0131_IBC_BVD_BINARIZATION void bvdCoding ( const Mv &rMvd, int8_t imv ); void xWriteBvdContext(unsigned uiSymbol, unsigned ctxT, int offset, int param); #endif +#endif #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED void mvsdIdxFunc(const PredictionUnit &pu, RefPicList eRefList); void mvsdAffineIdxFunc(const PredictionUnit &pu, RefPicList eRefList); @@ -288,6 +304,9 @@ public: void cu_lic_flag ( const CodingUnit& cu ); #endif +#if JVET_AA0070_RRIBC + void rribcData ( const CodingUnit &cu); +#endif #if JVET_Z0135_TEMP_CABAC_WIN_WEIGHT CABACDataStore* m_CABACDataStore; #endif diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 8a488b86cbd8aec3e0dc18db7a0c2c929535da0d..fd74572ac1f8c6dc35a31803937c487336be57e4 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -470,6 +470,9 @@ protected: unsigned m_IBCHashSearchMaxCand; unsigned m_IBCHashSearchRange4SmallBlk; unsigned m_IBCFastMethod; +#if JVET_AA0061_IBC_MBVD + bool m_ibcMbvd; +#endif bool m_wrapAround; unsigned m_wrapAroundOffset; @@ -1328,6 +1331,10 @@ public: void setAffineMmvdMode ( bool b ) { m_AffineMmvdMode = b; } bool getAffineMmvdMode () const { return m_AffineMmvdMode; } #endif +#if JVET_AA0061_IBC_MBVD + void setIbcMbvd ( bool b ) { m_ibcMbvd = b; } + bool getIbcMbvd () const { return m_ibcMbvd; } +#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 946892d1bbebe2d67a62008ad3ee4a7b71f03d35..01cd9327a692c857d93228e18d725f0be89505be 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -1337,6 +1337,22 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par } else if (currTestMode.type == ETM_IBC) { +#if JVET_AA0070_RRIBC + if (m_pcEncCfg->getIntraPeriod() <= 1) + { + CodedCUInfo &relatedCU = ((EncModeCtrlMTnoRQT *) m_modeCtrl)->getBlkInfo(partitioner.currArea()); + if (!relatedCU.isRribcTested) + { + xCheckRDCostIBCMode(tempCS, bestCS, partitioner, currTestMode); + relatedCU.isRribcTested = 1; + } + else + { + xCheckRDCostIBCMode(tempCS, bestCS, partitioner, currTestMode, true); + } + } + else +#endif xCheckRDCostIBCMode(tempCS, bestCS, partitioner, currTestMode); #if JVET_Y0152_TT_ENC_SPEEDUP splitRdCostBest[CTU_LEVEL] = bestCS->cost; @@ -3895,7 +3911,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #endif }; #endif - static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> RdModeList; + static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> rdModeList; bool mrgTempBufSet = false; const int candNum = mergeCtx.numValidMergeCand + (tempCS->sps->getUseMMVD() ? std::min<int>(MMVD_BASE_MV_NUM, mergeCtx.numValidMergeCand) * MMVD_MAX_REFINE_NUM : 0); @@ -3906,22 +3922,22 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #if CIIP_PDPC #if MERGE_ENC_OPT #if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION - RdModeList.push_back(ModeInfo(i, true, false, false, false, 0, false)); + rdModeList.push_back(ModeInfo(i, true, false, false, false, 0, false)); #else - RdModeList.push_back(ModeInfo(i, true, false, false, false, false)); + rdModeList.push_back(ModeInfo(i, true, false, false, false, false)); #endif #else - RdModeList.push_back(ModeInfo(i, true, false, false, false)); + rdModeList.push_back(ModeInfo(i, true, false, false, false)); #endif #else #if MERGE_ENC_OPT #if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION - RdModeList.push_back(ModeInfo(i, true, false, false, 0, false)); + rdModeList.push_back(ModeInfo(i, true, false, false, 0, false)); #else - RdModeList.push_back(ModeInfo(i, true, false, false, false)); + rdModeList.push_back(ModeInfo(i, true, false, false, false)); #endif #else - RdModeList.push_back(ModeInfo(i, true, false, false)); + rdModeList.push_back(ModeInfo(i, true, false, false)); #endif #endif } @@ -3930,22 +3946,22 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #if MERGE_ENC_OPT #if CIIP_PDPC #if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION - RdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, false, 0, false)); + rdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, false, 0, false)); #else - RdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, false, false)); + rdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, false, false)); #endif #else #if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION - RdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, 0, false)); + rdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, 0, false)); #else - RdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, false)); + rdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, false)); #endif #endif #else #if CIIP_PDPC - RdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, false)); + rdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false, false)); #else - RdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false)); + rdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false)); #endif #endif } @@ -4038,7 +4054,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& // 1. Pass: get SATD-cost for selected candidates and reduce their count if( !bestIsSkip ) { - RdModeList.clear(); + rdModeList.clear(); mrgTempBufSet = true; const TempCtx ctxStart(m_CtxCache, m_CABACEstimator->getCtx()); @@ -4093,7 +4109,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #if !MULTI_PASS_DMVR , refinedMvdL0 #endif - , uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart + , uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart #if MULTI_PASS_DMVR , applyBDMVR #endif @@ -4209,26 +4225,26 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #endif insertPos = -1; #if CIIP_PDPC - updateCandList(ModeInfo(uiMergeCand, true, false, false, false), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(uiMergeCand, true, false, false, false), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); #else - updateCandList(ModeInfo(uiMergeCand, true, false, false), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(uiMergeCand, true, false, false), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); #endif if (insertPos != -1) { - if (insertPos == RdModeList.size() - 1) + if (insertPos == rdModeList.size() - 1) { swap(singleMergeTempBuffer, acMergeTempBuffer[insertPos]); } else { - for (uint32_t i = uint32_t(RdModeList.size()) - 1; i > insertPos; i--) + for (uint32_t i = uint32_t(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } swap(singleMergeTempBuffer, acMergeTempBuffer[insertPos]); } } - CHECK(std::min(uiMergeCand + 1, uiNumMrgSATDCand) != RdModeList.size(), ""); + CHECK(std::min(uiMergeCand + 1, uiNumMrgSATDCand) != rdModeList.size(), ""); #if MULTI_PASS_DMVR pu.bdmvrRefine = false; #endif @@ -4237,11 +4253,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& if (isIntrainterEnabled) { #if MERGE_ENC_OPT - xCheckSATDCostCiipMerge(tempCS, cu, pu, mergeCtx, acMergeTempBuffer, singleMergeTempBuffer, acMergeTmpBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart); + xCheckSATDCostCiipMerge(tempCS, cu, pu, mergeCtx, acMergeTempBuffer, singleMergeTempBuffer, acMergeTmpBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart); #if JVET_X0141_CIIP_TIMD_TM && TM_MRG if (sps.getUseCiipTmMrg()) { - xCheckSATDCostCiipTmMerge(tempCS, cu, pu, ciipTmMrgCtx, acMergeTempBuffer, singleMergeTempBuffer, acTmMergeTmpBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart); + xCheckSATDCostCiipTmMerge(tempCS, cu, pu, ciipTmMrgCtx, acMergeTempBuffer, singleMergeTempBuffer, acTmMergeTmpBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart); } #endif #else @@ -4252,7 +4268,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& uint32_t CiipMergeCand[NUM_MRG_SATD_CAND]; for (uint32_t mergeCnt = 0; mergeCnt < std::min(NUM_MRG_SATD_CAND, (const int)mergeCtx.numValidMergeCand); mergeCnt++) { - CiipMergeCand[mergeCnt] = RdModeList[mergeCnt].mergeCand; + CiipMergeCand[mergeCnt] = rdModeList[mergeCnt].mergeCand; } #if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION int intraMode = PLANAR_IDX; @@ -4336,13 +4352,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& double cost = (double)sadValue + (double)fracBits * sqrtLambdaForFirstPassIntra; insertPos = -1; #if CIIP_PDPC - updateCandList(ModeInfo(mergeCand, false, false, true, pu.ciipPDPC), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(mergeCand, false, false, true, pu.ciipPDPC), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); #else - updateCandList(ModeInfo(mergeCand, false, false, true), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(mergeCand, false, false, true), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); #endif if (insertPos != -1) { - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } @@ -4362,13 +4378,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& { #if MERGE_ENC_OPT #if JVET_W0090_ARMC_TM - xCheckSATDCostMmvdMerge(tempCS, cu, pu, mergeCtxtmp, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart + xCheckSATDCostMmvdMerge(tempCS, cu, pu, mergeCtxtmp, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , mmvdLUT #endif ); #else - xCheckSATDCostMmvdMerge(tempCS, cu, pu, mergeCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart + xCheckSATDCostMmvdMerge(tempCS, cu, pu, mergeCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , mmvdLUT #endif @@ -4418,13 +4434,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #endif insertPos = -1; #if CIIP_PDPC - updateCandList(ModeInfo(mmvdMergeCand, false, true, false, false), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(mmvdMergeCand, false, true, false, false), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); #else - updateCandList(ModeInfo(mmvdMergeCand, false, true, false), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(mmvdMergeCand, false, true, false), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); #endif if (insertPos != -1) { - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } @@ -4437,7 +4453,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #if TM_MRG if (sps.getUseDMVDMode()) { - xCheckSATDCostTMMerge(tempCS, cu, pu, tmMrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart + xCheckSATDCostTMMerge(tempCS, cu, pu, tmMrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart #if MULTI_PASS_DMVR , applyBDMVR4TM #endif @@ -4446,13 +4462,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #endif if (affineMrgAvail) { - xCheckSATDCostAffineMerge(tempCS, cu, pu, affineMergeCtx, mrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart); + xCheckSATDCostAffineMerge(tempCS, cu, pu, affineMergeCtx, mrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart); } #if AFFINE_MMVD if (affineMmvdAvail) { #if JVET_W0090_ARMC_TM - xCheckSATDCostAffineMmvdMerge(tempCS, cu, pu, affineMergeCtxTmp, mrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart + xCheckSATDCostAffineMmvdMerge(tempCS, cu, pu, affineMergeCtxTmp, mrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , affMmvdLUT #if JVET_AA0093_ENHANCED_MMVD_EXTENSION @@ -4461,7 +4477,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #endif ); #else - xCheckSATDCostAffineMmvdMerge(tempCS, cu, pu, affineMergeCtx, mrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart + xCheckSATDCostAffineMmvdMerge(tempCS, cu, pu, affineMergeCtx, mrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , affMmvdLUT #endif @@ -4474,13 +4490,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& if (sps.getUseDMVDMode() && checkBmMrg) { #if JVET_AA0093_REFINED_MOTION_FOR_ARMC - xCheckSATDCostBMMerge(tempCS, cu, pu, bmMrgCtx, bmMrgCtxDir2, admvrRefinedMotion, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart + xCheckSATDCostBMMerge(tempCS, cu, pu, bmMrgCtx, bmMrgCtxDir2, admvrRefinedMotion, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart #if MULTI_PASS_DMVR , applyBDMVR4BM #endif ); #else - xCheckSATDCostBMMerge(tempCS, cu, pu, bmMrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, RdModeList, candCostList, distParam, ctxStart + xCheckSATDCostBMMerge(tempCS, cu, pu, bmMrgCtx, acMergeTempBuffer, singleMergeTempBuffer, uiNumMrgSATDCand, rdModeList, candCostList, distParam, ctxStart #if MULTI_PASS_DMVR , applyBDMVR4BM #endif @@ -4507,7 +4523,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& for (uint32_t mergeCnt = 0; mergeCnt < uiNumMrgSATDCand; mergeCnt++) { - if (RdModeList[mergeCnt].isCIIP) + if (rdModeList[mergeCnt].isCIIP) { pu.intraDir[0] = PLANAR_IDX; pu.intraDir[1] = DM_CHROMA_IDX; @@ -4516,13 +4532,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& continue; #endif #if CIIP_PDPC - pu.ciipPDPC = RdModeList[mergeCnt].isCiipPDPC; + pu.ciipPDPC = rdModeList[mergeCnt].isCiipPDPC; uint32_t bufIdx = pu.ciipPDPC ? 1 : 0; #else uint32_t bufIdx = 0; #endif #if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION - pu.intraDir[0] = RdModeList[mergeCnt].intraMode; + pu.intraDir[0] = rdModeList[mergeCnt].intraMode; #endif if (!tag[bufIdx]) { @@ -4571,9 +4587,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& { for( uint32_t uiMrgHADIdx = 0; uiMrgHADIdx < uiNumMrgSATDCand; uiMrgHADIdx++ ) { - uint32_t uiMergeCand = RdModeList[uiMrgHADIdx].mergeCand; + uint32_t uiMergeCand = rdModeList[uiMrgHADIdx].mergeCand; - if (uiNoResidualPass != 0 && RdModeList[uiMrgHADIdx].isCIIP) // intrainter does not support skip mode + if (uiNoResidualPass != 0 && rdModeList[uiMrgHADIdx].isCIIP) // intrainter does not support skip mode { if (isTestSkipMerge[uiMergeCand]) { @@ -4581,7 +4597,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } } #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED - if (RdModeList[uiMrgHADIdx].isMMVD && (uiMergeCand - (uiMergeCand / MMVD_MAX_REFINE_NUM)* MMVD_MAX_REFINE_NUM >= (MMVD_MAX_REFINE_NUM >> MMVD_SIZE_SHIFT))) + if (rdModeList[uiMrgHADIdx].isMMVD && (uiMergeCand - (uiMergeCand / MMVD_MAX_REFINE_NUM)* MMVD_MAX_REFINE_NUM >= (MMVD_MAX_REFINE_NUM >> MMVD_SIZE_SHIFT))) { continue; } @@ -4633,11 +4649,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #if JVET_X0141_CIIP_TIMD_TM pu.intraDir[0] = PLANAR_IDX; #endif - if (uiNoResidualPass == 0 && RdModeList[uiMrgHADIdx].isCIIP) + if (uiNoResidualPass == 0 && rdModeList[uiMrgHADIdx].isCIIP) { cu.mmvdSkip = false; #if JVET_X0141_CIIP_TIMD_TM && TM_MRG - pu.tmMergeFlag = RdModeList[uiMrgHADIdx].isTMMrg; + pu.tmMergeFlag = rdModeList[uiMrgHADIdx].isTMMrg; #endif #if MULTI_HYP_PRED pu.ciipFlag = true; @@ -4654,18 +4670,18 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& pu.ciipFlag = true; #endif #if CIIP_PDPC - pu.ciipPDPC = RdModeList[uiMrgHADIdx].isCiipPDPC; + pu.ciipPDPC = rdModeList[uiMrgHADIdx].isCiipPDPC; #endif pu.regularMergeFlag = false; #if JVET_X0141_CIIP_TIMD_TM && JVET_W0123_TIMD_FUSION - pu.intraDir[0] = RdModeList[uiMrgHADIdx].intraMode; + pu.intraDir[0] = rdModeList[uiMrgHADIdx].intraMode; #else pu.intraDir[0] = PLANAR_IDX; #endif CHECK(pu.intraDir[0]<0 || pu.intraDir[0]>(NUM_LUMA_MODE - 1), "out of intra mode"); pu.intraDir[1] = DM_CHROMA_IDX; } - else if (RdModeList[uiMrgHADIdx].isMMVD) + else if (rdModeList[uiMrgHADIdx].isMMVD) { cu.mmvdSkip = true; pu.regularMergeFlag = true; @@ -4685,7 +4701,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } #if MERGE_ENC_OPT #if AFFINE_MMVD - else if (RdModeList[uiMrgHADIdx].isAffineMmvd) + else if (rdModeList[uiMrgHADIdx].isAffineMmvd) { #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED int uiMergeCandTemp = affMmvdLUT[uiMergeCand]; @@ -4756,7 +4772,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& PU::spanMotionInfo(pu); } #endif - else if (RdModeList[uiMrgHADIdx].isAffine) + else if (rdModeList[uiMrgHADIdx].isAffine) { CHECK(uiMergeCand >= affineMergeCtx.numValidMergeCand, ""); cu.mmvdSkip = false; @@ -4802,9 +4818,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } #if TM_MRG && MERGE_ENC_OPT #if JVET_X0141_CIIP_TIMD_TM - else if (RdModeList[uiMrgHADIdx].isTMMrg && !RdModeList[uiMrgHADIdx].isCIIP) + else if (rdModeList[uiMrgHADIdx].isTMMrg && !rdModeList[uiMrgHADIdx].isCIIP) #else - else if (RdModeList[uiMrgHADIdx].isTMMrg) + else if (rdModeList[uiMrgHADIdx].isTMMrg) #endif { cu.mmvdSkip = false; @@ -4825,12 +4841,12 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } #endif #if JVET_X0049_ADAPT_DMVR - else if (RdModeList[uiMrgHADIdx].isBMMrg) + else if (rdModeList[uiMrgHADIdx].isBMMrg) { cu.mmvdSkip = false; pu.regularMergeFlag = true; pu.bmMergeFlag = true; - pu.bmDir = RdModeList[uiMrgHADIdx].bmDir; + pu.bmDir = rdModeList[uiMrgHADIdx].bmDir; #if JVET_AA0093_REFINED_MOTION_FOR_ARMC if (pu.bmDir == 1) { @@ -4871,7 +4887,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #endif } #if MERGE_ENC_OPT - if (!RdModeList[uiMrgHADIdx].isAffine && !RdModeList[uiMrgHADIdx].isGeo) + if (!rdModeList[uiMrgHADIdx].isAffine && !rdModeList[uiMrgHADIdx].isGeo) #endif #if MULTI_PASS_DMVR if( !pu.bdmvrRefine ) @@ -4995,9 +5011,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } else { - if (RdModeList[uiMrgHADIdx].isMMVD + if (rdModeList[uiMrgHADIdx].isMMVD #if AFFINE_MMVD && MERGE_ENC_OPT - || RdModeList[uiMrgHADIdx].isAffineMmvd + || rdModeList[uiMrgHADIdx].isAffineMmvd #endif ) { @@ -5005,18 +5021,18 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& m_pcInterSearch->motionCompensation(pu); } #if MERGE_ENC_OPT - else if (uiNoResidualPass != 0 && RdModeList[uiMrgHADIdx].isCIIP) + else if (uiNoResidualPass != 0 && rdModeList[uiMrgHADIdx].isCIIP) { // perform regular MC instead, i.e. test skip mode pu.mvRefine = true; m_pcInterSearch->motionCompensation(pu); pu.mvRefine = false; #if MULTI_PASS_DMVR - if (!RdModeList[uiMrgHADIdx].isAffine && !RdModeList[uiMrgHADIdx].isGeo && pu.bdmvrRefine) + if (!rdModeList[uiMrgHADIdx].isAffine && !rdModeList[uiMrgHADIdx].isGeo && pu.bdmvrRefine) { #if TM_MRG #if JVET_X0141_CIIP_TIMD_TM - if (pu.tmMergeFlag && !RdModeList[uiMrgHADIdx].isCIIP) + if (pu.tmMergeFlag && !rdModeList[uiMrgHADIdx].isCIIP) #else if ( pu.tmMergeFlag ) #endif @@ -5037,7 +5053,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #endif } #else - else if (uiNoResidualPass != 0 && RdModeList[uiMrgHADIdx].isCIIP) + else if (uiNoResidualPass != 0 && rdModeList[uiMrgHADIdx].isCIIP) { tempCS->getPredBuf().copyFrom(acMergeBuffer[uiMergeCand]); #if MULTI_PASS_DMVR @@ -5056,7 +5072,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } #endif #if MERGE_ENC_OPT - else if (RdModeList[uiMrgHADIdx].isAffine) + else if (rdModeList[uiMrgHADIdx].isAffine) { tempCS->getPredBuf().copyFrom(*acMergeTempBuffer[uiMrgHADIdx], true); #if JVET_Z0136_OOB @@ -5071,7 +5087,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& tempCS->getPredBuf().copyFrom(*acMergeTempBuffer[uiMrgHADIdx]); #if MULTI_PASS_DMVR #if MERGE_ENC_OPT - if (!RdModeList[uiMrgHADIdx].isAffine && !RdModeList[uiMrgHADIdx].isGeo && pu.bdmvrRefine) + if (!rdModeList[uiMrgHADIdx].isAffine && !rdModeList[uiMrgHADIdx].isGeo && pu.bdmvrRefine) #else if(pu.bdmvrRefine) #endif @@ -8228,7 +8244,7 @@ void EncCu::xCheckSATDCostRegularMerge(CodingStructure *&tempCS, CodingUnit &cu, #if !MULTI_PASS_DMVR , Mv refinedMvdL0[MAX_NUM_PARTS_IN_CTU][MRG_MAX_NUM_CANDS] #endif - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart #if MULTI_PASS_DMVR , bool* applyBDMVR #endif @@ -8359,23 +8375,23 @@ void EncCu::xCheckSATDCostRegularMerge(CodingStructure *&tempCS, CodingUnit &cu, } #endif insertPos = -1; - updateCandList(ModeInfo(cu, pu), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(cu, pu), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); if (insertPos != -1 && insertPos < MMVD_MRG_MAX_RD_NUM) { - if (insertPos == RdModeList.size() - 1) + if (insertPos == rdModeList.size() - 1) { swap(singleMergeTempBuffer, acMergeTempBuffer[insertPos]); } else { - for (uint32_t i = uint32_t(RdModeList.size()) - 1; i > insertPos; i--) + for (uint32_t i = uint32_t(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } swap(singleMergeTempBuffer, acMergeTempBuffer[insertPos]); } } - CHECK(std::min(uiMergeCand + 1, uiNumMrgSATDCand) != RdModeList.size(), ""); + CHECK(std::min(uiMergeCand + 1, uiNumMrgSATDCand) != rdModeList.size(), ""); } #if MULTI_PASS_DMVR pu.bdmvrRefine = false; @@ -8383,7 +8399,7 @@ void EncCu::xCheckSATDCostRegularMerge(CodingStructure *&tempCS, CodingUnit &cu, } void EncCu::xCheckSATDCostCiipMerge(CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx mergeCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer, PelUnitBuf acMergeTmpBuffer[MRG_MAX_NUM_CANDS] - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart) + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart) { #if INTER_LIC cu.LICFlag = false; @@ -8475,10 +8491,10 @@ void EncCu::xCheckSATDCostCiipMerge(CodingStructure *&tempCS, CodingUnit &cu, Pr uint64_t fracBits = m_pcInterSearch->xCalcPuMeBits(pu); double cost = (double)sadValue + (double)fracBits * sqrtLambdaForFirstPassIntra; // need to check the cost calculation again??? insertPos = -1; - updateCandList(ModeInfo(cu, pu), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(cu, pu), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); if (insertPos != -1 && insertPos < MMVD_MRG_MAX_RD_NUM) { - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } @@ -8496,7 +8512,7 @@ pu.ciipPDPC = false; #if JVET_X0141_CIIP_TIMD_TM && TM_MRG void EncCu::xCheckSATDCostCiipTmMerge(CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx mergeCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer, PelUnitBuf acTmMergeTmpBuffer[MRG_MAX_NUM_CANDS] - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart) + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart) { #if INTER_LIC cu.LICFlag = false; @@ -8593,10 +8609,10 @@ void EncCu::xCheckSATDCostCiipTmMerge(CodingStructure *&tempCS, CodingUnit &cu, uint64_t fracBits = m_pcInterSearch->xCalcPuMeBits(pu); double cost = (double)sadValue + (double)fracBits * sqrtLambdaForFirstPassIntra; // need to check the cost calculation again??? insertPos = -1; - updateCandList(ModeInfo(cu, pu), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(cu, pu), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); if (insertPos != -1 && insertPos < MMVD_MRG_MAX_RD_NUM) { - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } @@ -8615,7 +8631,7 @@ pu.tmMergeFlag = false; #endif void EncCu::xCheckSATDCostMmvdMerge(CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx mergeCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , uint32_t * mmvdLUT #endif @@ -8714,10 +8730,10 @@ void EncCu::xCheckSATDCostMmvdMerge(CodingStructure *&tempCS, CodingUnit &cu, Pr } #endif insertPos = -1; - updateCandList(ModeInfo(cu, pu), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(cu, pu), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); if (insertPos != -1 && insertPos < MMVD_MRG_MAX_RD_NUM) { - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } @@ -8727,7 +8743,7 @@ void EncCu::xCheckSATDCostMmvdMerge(CodingStructure *&tempCS, CodingUnit &cu, Pr } void EncCu::xCheckSATDCostAffineMerge(CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, AffineMergeCtx affineMergeCtx, MergeCtx& mrgCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart) + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart) { cu.mmvdSkip = false; cu.geoFlag = false; @@ -8807,14 +8823,14 @@ void EncCu::xCheckSATDCostAffineMerge(CodingStructure *&tempCS, CodingUnit &cu, } #endif insertPos = -1; - updateCandList(ModeInfo(cu, pu), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(cu, pu), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); #if MERGE_ENC_OPT if (insertPos != -1 && insertPos < MMVD_MRG_MAX_RD_NUM) #else if (insertPos != -1) #endif { - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } @@ -8833,7 +8849,7 @@ void EncCu::xCheckSATDCostTMMerge( CodingStructure*& tempCS, PelUnitBuf* acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf*& singleMergeTempBuffer, unsigned& uiNumMrgSATDCand, - static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, + static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx& ctxStart @@ -8897,11 +8913,11 @@ void EncCu::xCheckSATDCostTMMerge( CodingStructure*& tempCS, uint64_t fracBits = m_pcInterSearch->xCalcPuMeBits(pu); double cost = (double)uiSad + (double)fracBits * sqrtLambdaForFirstPassIntra; insertPos = -1; - updateCandList(ModeInfo(cu, pu), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(cu, pu), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); if (insertPos != -1 && insertPos < MMVD_MRG_MAX_RD_NUM) { - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } @@ -8929,7 +8945,7 @@ void EncCu::xCheckSATDCostAffineMmvdMerge( CodingStructure*& tempCS, PelUnitBuf* acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf*& singleMergeTempBuffer, unsigned& uiNumMrgSATDCand, - static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, + static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx& ctxStart @@ -9052,11 +9068,11 @@ void EncCu::xCheckSATDCostAffineMmvdMerge( CodingStructure*& tempCS, } #endif insertPos = -1; - updateCandList(ModeInfo(cu, pu), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(cu, pu), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); if (insertPos != -1 && insertPos < MMVD_MRG_MAX_RD_NUM) { - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } @@ -9070,7 +9086,7 @@ void EncCu::xCheckSATDCostAffineMmvdMerge( CodingStructure*& tempCS, #endif #if !JVET_W0097_GPM_MMVD_TM && !JVET_Z0056_GPM_SPLIT_MODE_REORDERING void EncCu::xCheckSATDCostGeoMerge(CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx geoMergeCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart) + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart) { const SPS &sps = *tempCS->sps; int numGeoChecked = 0; @@ -9247,7 +9263,7 @@ void EncCu::xCheckSATDCostGeoMerge(CodingStructure *&tempCS, CodingUnit &cu, Pre } numGeoChecked++; insertPos = -1; - updateCandList(ModeInfo(cu, pu), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(cu, pu), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); #if MERGE_ENC_OPT if (insertPos != -1 && insertPos < MMVD_MRG_MAX_RD_NUM) #else @@ -9255,7 +9271,7 @@ void EncCu::xCheckSATDCostGeoMerge(CodingStructure *&tempCS, CodingUnit &cu, Pre #endif { m_pcInterSearch->weightedGeoBlk(pu, splitDir, CHANNEL_TYPE_CHROMA, *singleMergeTempBuffer, geoBuffer[pu.geoMergeIdx0], geoBuffer[pu.geoMergeIdx1]); //have to use pu.geoMergeIdx1 since mergeCand1 maybe changed - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } @@ -9271,9 +9287,9 @@ void EncCu::xCheckSATDCostGeoMerge(CodingStructure *&tempCS, CodingUnit &cu, Pre uiNumMrgSATDCand = uiNumMrgSATDCand - GEO_MAX_TRY_WEIGHTED_SATD + numGeoChecked; } - if (uiNumMrgSATDCand > RdModeList.size()) //to make sure we have engough candidates in the list + if (uiNumMrgSATDCand > rdModeList.size()) //to make sure we have engough candidates in the list { - uiNumMrgSATDCand = (unsigned int)RdModeList.size(); + uiNumMrgSATDCand = (unsigned int)rdModeList.size(); } } #endif @@ -9356,12 +9372,12 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct bool bestIsSkip = false; uint32_t uiNumMrgSATDCand = affineMergeCtx.numValidMergeCand; PelUnitBuf acMergeBuffer[AFFINE_MRG_MAX_NUM_CANDS]; - static_vector<uint32_t, AFFINE_MRG_MAX_NUM_CANDS> RdModeList; + static_vector<uint32_t, AFFINE_MRG_MAX_NUM_CANDS> rdModeList; bool mrgTempBufSet = false; for ( uint32_t i = 0; i < AFFINE_MRG_MAX_NUM_CANDS; i++ ) { - RdModeList.push_back( i ); + rdModeList.push_back( i ); } if ( m_pcEncCfg->getUseFastMerge() ) @@ -9379,7 +9395,7 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct // 1. Pass: get SATD-cost for selected candidates and reduce their count if ( !bestIsSkip ) { - RdModeList.clear(); + rdModeList.clear(); mrgTempBufSet = true; #if JVET_W0097_GPM_MMVD_TM const double sqrtLambdaForFirstPassIntra = m_pcRdCost->getMotionLambda() * FRAC_BITS_SCALE; @@ -9477,10 +9493,10 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct m_baseResultsForMH.push_back(mergeResult); } #endif - updateCandList( uiMergeCand, cost, RdModeList, candCostList + updateCandList( uiMergeCand, cost, rdModeList, candCostList , uiNumMrgSATDCand ); - CHECK( std::min( uiMergeCand + 1, uiNumMrgSATDCand ) != RdModeList.size(), "" ); + CHECK( std::min( uiMergeCand + 1, uiNumMrgSATDCand ) != rdModeList.size(), "" ); } // Try to limit number of candidates using SATD-costs @@ -9512,7 +9528,7 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct { for ( uint32_t uiMrgHADIdx = 0; uiMrgHADIdx < uiNumMrgSATDCand; uiMrgHADIdx++ ) { - uint32_t uiMergeCand = RdModeList[uiMrgHADIdx]; + uint32_t uiMergeCand = rdModeList[uiMrgHADIdx]; if ( ((uiNoResidualPass != 0) && candHasNoResidual[uiMergeCand]) || ((uiNoResidualPass == 0) && bestIsSkip) ) @@ -9696,11 +9712,11 @@ void EncCu::xCheckRDCostAffineMmvd2Nx2N(CodingStructure *&tempCS, CodingStructur bool bestIsSkip = false; int afMmvdCandCount = baseCount * AF_MMVD_MAX_REFINE_NUM; uint32_t uiNumMrgSATDCand = std::min( AF_MMVD_NUM, afMmvdCandCount ); - static_vector<uint32_t, AF_MMVD_NUM> RdModeList; + static_vector<uint32_t, AF_MMVD_NUM> rdModeList; for (uint32_t i = 0; i < AF_MMVD_NUM; i++) { - RdModeList.push_back(i); + rdModeList.push_back(i); } if (m_pcEncCfg->getUseFastMerge()) @@ -9717,7 +9733,7 @@ void EncCu::xCheckRDCostAffineMmvd2Nx2N(CodingStructure *&tempCS, CodingStructur // 1. Pass: get SATD-cost for selected candidates and reduce their count if (!bestIsSkip) { - RdModeList.clear(); + rdModeList.clear(); const double sqrtLambdaForFirstPass = m_pcRdCost->getMotionLambda(); CodingUnit &cu = tempCS->addCU(tempCS->area, partitioner.chType); @@ -9804,9 +9820,9 @@ void EncCu::xCheckRDCostAffineMmvd2Nx2N(CodingStructure *&tempCS, CodingStructur m_baseResultsForMH.push_back(mergeResult); } #endif - updateCandList(uiMergeCand, cost, RdModeList, candCostList, uiNumMrgSATDCand); + updateCandList(uiMergeCand, cost, rdModeList, candCostList, uiNumMrgSATDCand); - CHECK(std::min(uiMergeCand + 1, uiNumMrgSATDCand) != RdModeList.size(), ""); + CHECK(std::min(uiMergeCand + 1, uiNumMrgSATDCand) != rdModeList.size(), ""); } } @@ -9838,7 +9854,7 @@ void EncCu::xCheckRDCostAffineMmvd2Nx2N(CodingStructure *&tempCS, CodingStructur { for (uint32_t uiMrgHADIdx = 0; uiMrgHADIdx < uiNumMrgSATDCand; uiMrgHADIdx++) { - uint32_t uiMergeCand = RdModeList[uiMrgHADIdx]; + uint32_t uiMergeCand = rdModeList[uiMrgHADIdx]; if (((uiNoResidualPass != 0) && candHasNoResidual[uiMergeCand]) || ((uiNoResidualPass == 0) && bestIsSkip)) @@ -10046,10 +10062,10 @@ void EncCu::xCheckRDCostTMMerge2Nx2N(CodingStructure *&tempCS, CodingStructure * int32_t numMrgSATDCand = candNum; bool mrgTempBufSet = false; - static_vector<uint32_t, TM_MRG_MAX_NUM_CANDS> RdModeList; + static_vector<uint32_t, TM_MRG_MAX_NUM_CANDS> rdModeList; for (uint32_t i = 0; i < TM_MRG_MAX_NUM_CANDS; i++) { - RdModeList.push_back(i); + rdModeList.push_back(i); } const UnitArea localUnitArea(tempCS->area.chromaFormat, Area(0, 0, tempCS->area.Y().width, tempCS->area.Y().height)); @@ -10078,7 +10094,7 @@ void EncCu::xCheckRDCostTMMerge2Nx2N(CodingStructure *&tempCS, CodingStructure * // 1. Pass: get SATD-cost for selected candidates and reduce their count if( !bestIsSkip ) { - RdModeList.clear(); + rdModeList.clear(); mrgTempBufSet = true; const TempCtx ctxStart(m_CtxCache, m_CABACEstimator->getCtx()); @@ -10146,9 +10162,9 @@ void EncCu::xCheckRDCostTMMerge2Nx2N(CodingStructure *&tempCS, CodingStructure * uint64_t fracBits = m_pcInterSearch->xCalcPuMeBits(pu); double cost = (double)uiSad + (double)fracBits * sqrtLambdaForFirstPassIntra; - updateCandList(uiMergeCand, cost, RdModeList, candCostList, numMrgSATDCand); + updateCandList(uiMergeCand, cost, rdModeList, candCostList, numMrgSATDCand); - CHECK(std::min(uiMergeCand + 1, (uint32_t)numMrgSATDCand) != RdModeList.size(), ""); + CHECK(std::min(uiMergeCand + 1, (uint32_t)numMrgSATDCand) != rdModeList.size(), ""); } // Try to limit number of candidates using SATD-costs @@ -10177,7 +10193,7 @@ void EncCu::xCheckRDCostTMMerge2Nx2N(CodingStructure *&tempCS, CodingStructure * { for( uint32_t uiMrgHADIdx = 0; uiMrgHADIdx < numMrgSATDCand; uiMrgHADIdx++ ) { - uint32_t uiMergeCand = RdModeList[uiMrgHADIdx]; + uint32_t uiMergeCand = rdModeList[uiMrgHADIdx]; if (((uiNoResidualPass != 0) && candHasNoResidual[uiMrgHADIdx]) || ( (uiNoResidualPass == 0) && bestIsSkip ) ) @@ -10320,6 +10336,11 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct #if JVET_Z0084_IBC_TM && IBC_TM_MRG MergeCtx mergeCtxTm; #endif +#if JVET_AA0061_IBC_MBVD + MergeCtx mergeCtxTmp; + uint32_t ibcMbvdLUT[IBC_MBVD_NUM]; + uint32_t ibcMbvdValidNum[IBC_MBVD_BASE_NUM] = { 0 }; +#endif if (sps.getSbTMVPEnabledFlag()) { @@ -10343,9 +10364,15 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct #if INTER_LIC cu.LICFlag = false; #endif - cu.geoFlag = false; +#if JVET_AA0070_RRIBC + cu.rribcFlipType = 0; + pu.mergeFlag = true; PU::getIBCMergeCandidates(pu, mergeCtx); + pu.mergeFlag = false; +#else + PU::getIBCMergeCandidates(pu, mergeCtx); +#endif #if JVET_Y0058_IBC_LIST_MODIFY && JVET_W0090_ARMC_TM if(pu.cs->sps->getUseAML()) { @@ -10361,7 +10388,13 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct if (pu.cs->sps->getUseDMVDMode() == true) { pu.tmMergeFlag = true; +#if JVET_AA0070_RRIBC + pu.mergeFlag = true; PU::getIBCMergeCandidates(pu, mergeCtxTm); + pu.mergeFlag = false; +#else + PU::getIBCMergeCandidates(pu, mergeCtxTm); +#endif #if JVET_Y0058_IBC_LIST_MODIFY && JVET_W0090_ARMC_TM if (pu.cs->sps->getUseAML()) { @@ -10378,42 +10411,80 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct { mergeCtxTm.numValidMergeCand = 0; } +#endif +#if JVET_AA0070_RRIBC && JVET_AA0061_IBC_MBVD + pu.ibcMbvdMergeFlag = true; + pu.mergeFlag = true; + PU::getIBCMergeCandidates(pu, mergeCtxTmp); + pu.mergeFlag = false; + +#if JVET_Y0058_IBC_LIST_MODIFY && JVET_W0090_ARMC_TM +#if JVET_Z0075_IBC_HMVP_ENLARGE + m_pcInterSearch->adjustIBCMergeCandidates(pu, mergeCtxTmp, 0, IBC_MRG_MAX_NUM_CANDS_MEM); +#else + m_pcInterSearch->adjustIBCMergeCandidates(pu, mergeCtxTmp); +#endif +#endif + pu.ibcMbvdMergeFlag = false; #endif } #if JVET_Z0084_IBC_TM && IBC_TM_MRG - int candHasNoResidual[IBC_MRG_MAX_NUM_CANDS<<1]; - for (unsigned int ui = 0; ui < IBC_MRG_MAX_NUM_CANDS<<1; ui++) +#if JVET_AA0061_IBC_MBVD + int candHasNoResidual[((IBC_MRG_MAX_NUM_CANDS<<1)+IBC_MBVD_NUM)] = {0,}; + bool bestIsSkip = false; + int32_t numMrgSATDCand = NUM_IBC_MRG_SATD_CAND; + if (m_pcEncCfg->getIntraPeriod() != 1) { - candHasNoResidual[ui] = 0; + numMrgSATDCand += 2; + } + numMrgSATDCand = std::min(numMrgSATDCand, (const int)(mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand)); + 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; } + 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; - static_vector<unsigned, (IBC_MRG_MAX_NUM_CANDS<<1)> RdModeList(IBC_MRG_MAX_NUM_CANDS<<1); + 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; + rdModeList[i] = i; } static_vector<double, (IBC_MRG_MAX_NUM_CANDS<<1)> candCostList(IBC_MRG_MAX_NUM_CANDS<<1, MAX_DOUBLE); +#endif #else - int candHasNoResidual[MRG_MAX_NUM_CANDS]; - for (unsigned int ui = 0; ui < mergeCtx.numValidMergeCand; ui++) +#if JVET_AA0061_IBC_MBVD + int candHasNoResidual[MRG_MAX_NUM_CANDS + IBC_MBVD_NUM] = {0,}; + bool bestIsSkip = false; + int32_t numMrgSATDCand = NUM_IBC_MRG_SATD_CAND; + numMrgSATDCand = std::min(numMrgSATDCand, (const int)(mergeCtx.numValidMergeCand)); + static_vector<unsigned, MRG_MAX_NUM_CANDS + IBC_MBVD_NUM> rdModeList(MRG_MAX_NUM_CANDS + IBC_MBVD_NUM); + for (unsigned i = 0; i < MRG_MAX_NUM_CANDS + IBC_MBVD_NUM; i++) { - candHasNoResidual[ui] = 0; + rdModeList[i] = i; } + //{ + static_vector<double, MRG_MAX_NUM_CANDS + IBC_MBVD_NUM> candCostList(MRG_MAX_NUM_CANDS + IBC_MBVD_NUM, MAX_DOUBLE); +#else + int candHasNoResidual[MRG_MAX_NUM_CANDS] = {0,}; bool bestIsSkip = false; unsigned numMrgSATDCand = mergeCtx.numValidMergeCand; - static_vector<unsigned, MRG_MAX_NUM_CANDS> RdModeList(MRG_MAX_NUM_CANDS); + static_vector<unsigned, MRG_MAX_NUM_CANDS> rdModeList(MRG_MAX_NUM_CANDS); for (unsigned i = 0; i < MRG_MAX_NUM_CANDS; i++) { - RdModeList[i] = i; + rdModeList[i] = i; } //{ static_vector<double, MRG_MAX_NUM_CANDS> candCostList(MRG_MAX_NUM_CANDS, MAX_DOUBLE); +#endif #endif // 1. Pass: get SATD-cost for selected candidates and reduce their count { @@ -10443,6 +10514,28 @@ 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_AA0070_RRIBC + pu.cu->rribcFlipType = 0; + const CompArea &area = cu.blocks[COMPONENT_Y]; + CompArea tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size()); + PelBuf tmpOrgLuma = m_tmpStorageLCU->getBuf(tmpArea); + tmpOrgLuma.copyFrom(tempCS->getOrgBuf().Y()); + if (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()) + { + tmpOrgLuma.rspSignal(tempCS->getOrgBuf().Y(), m_pcReshape->getFwdLUT()); + } + PelStorage m_tmpStorageCUflipH; + m_tmpStorageCUflipH.create(UnitArea(pu.chromaFormat, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE))); + PelBuf tmpOrgLumaFlipH = m_tmpStorageCUflipH.getBuf(tmpArea); + tmpOrgLumaFlipH.copyFrom(tmpOrgLuma); + tmpOrgLumaFlipH.flipSignal(true); + + PelStorage m_tmpStorageCUflipV; + m_tmpStorageCUflipV.create(UnitArea(pu.chromaFormat, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE))); + PelBuf tmpOrgLumaFlipV = m_tmpStorageCUflipV.getBuf(tmpArea); + tmpOrgLumaFlipV.copyFrom(tmpOrgLuma); + tmpOrgLumaFlipV.flipSignal(false); +#else if (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()) { const CompArea &area = cu.blocks[COMPONENT_Y]; @@ -10453,6 +10546,7 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct } else m_pcRdCost->setDistParam(distParam, tempCS->getOrgBuf().Y(), refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); +#endif int refStride = refBuf.stride; #if !JVET_Y0058_IBC_LIST_MODIFY @@ -10470,6 +10564,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct int numValidBv = mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand; #else int numValidBv = mergeCtx.numValidMergeCand; +#endif +#if JVET_AA0061_IBC_MBVD && !JVET_AA0070_RRIBC + int numValidBvIBC = mergeCtx.numValidMergeCand; #endif for (unsigned int mergeCand = 0; mergeCand < mergeCtx.numValidMergeCand; mergeCand++) { @@ -10488,10 +10585,28 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct #endif { numValidBv--; +#if JVET_AA0061_IBC_MBVD && !JVET_AA0070_RRIBC + numValidBvIBC--; +#endif continue; } PU::spanMotionInfo(pu, mergeCtx); +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 0) + { + m_pcRdCost->setDistParam(distParam, tmpOrgLuma, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } + else if (pu.cu->rribcFlipType == 1) + { + m_pcRdCost->setDistParam(distParam, tmpOrgLumaFlipH, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } + else + { + m_pcRdCost->setDistParam(distParam, tmpOrgLumaFlipV, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } +#endif + distParam.cur.buf = piRefSrch + refStride * yPred + xPred; Distortion sad = distParam.distFunc(distParam); @@ -10504,9 +10619,12 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct { bitsCand--; } +#if JVET_AA0061_IBC_MBVD + bitsCand++; // for ibc_mbvd_flag +#endif double cost = (double)sad + (double)bitsCand * sqrtLambdaForFirstPass; - updateCandList(mergeCand, cost, RdModeList, candCostList + updateCandList(mergeCand, cost, rdModeList, candCostList , numMrgSATDCand); } @@ -10546,6 +10664,20 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct } PU::spanMotionInfo(pu, mergeCtxTm); +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 0) + { + m_pcRdCost->setDistParam(distParam, tmpOrgLuma, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } + else if (pu.cu->rribcFlipType == 1) + { + m_pcRdCost->setDistParam(distParam, tmpOrgLumaFlipH, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } + else + { + m_pcRdCost->setDistParam(distParam, tmpOrgLumaFlipV, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } +#endif distParam.cur.buf = piRefSrch + refStride * yPred + xPred; Distortion sad = distParam.distFunc(distParam); @@ -10554,17 +10686,122 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct { bitsCand--; } +#if JVET_AA0061_IBC_MBVD + bitsCand++; // for ibc_mbvd_flag +#endif double cost = (double)sad + (double)bitsCand * sqrtLambdaForFirstPass; - updateCandList(mergeCand+mergeCtx.numValidMergeCand, cost, RdModeList, candCostList, numMrgSATDCand); + updateCandList(mergeCand+mergeCtx.numValidMergeCand, cost, rdModeList, candCostList, numMrgSATDCand); + } +#endif +#if JVET_AA0061_IBC_MBVD +#if JVET_AA0070_RRIBC + int numValidBvIBC = mergeCtxTmp.numValidMergeCand; +#endif + if (numValidBvIBC) + { + if (pu.cs->sps->getUseIbcMbvd()) + { +#if JVET_AA0070_RRIBC + for (unsigned int mergeCand = 0; mergeCand < mergeCtxTmp.numValidMergeCand; mergeCand++) + { + mergeCtxTmp.setMergeInfo(pu, mergeCand); // set bv info in merge mode + +#if !JVET_Y0058_IBC_LIST_MODIFY //should have already been checked at merge list construction +#if JVET_Z0084_IBC_TM + if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived +#else + if (!m_pcInterSearch->searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, xPred, yPred, lcuWidth)) // not valid bv derived +#endif +#else + if (pu.bv == Mv(0, 0)) +#endif + { + numValidBvIBC--; + continue; + } + } +#endif + const int baseNum = std::min(numValidBvIBC, IBC_MBVD_BASE_NUM); +#if !JVET_AA0070_RRIBC + mergeCtxTmp = mergeCtx; +#endif + + PU::getIbcMbvdMergeCandidates(pu, mergeCtxTmp, baseNum); + + bool flag = pu.ibcMbvdMergeFlag; + pu.ibcMbvdMergeFlag = true; + m_pcInterSearch->sortIbcMergeMbvdCandidates(pu, mergeCtxTmp, ibcMbvdLUT, ibcMbvdValidNum); + pu.ibcMbvdMergeFlag = flag; + + const int tempNum = baseNum * IBC_MBVD_MAX_REFINE_NUM; + int baseIdx = 0; + for (unsigned int mmvdMergeCandtemp = 0; mmvdMergeCandtemp < tempNum; mmvdMergeCandtemp++) + { + baseIdx = mmvdMergeCandtemp / IBC_MBVD_MAX_REFINE_NUM; + if (mmvdMergeCandtemp - (mmvdMergeCandtemp / IBC_MBVD_MAX_REFINE_NUM) * IBC_MBVD_MAX_REFINE_NUM >= IBC_MBVD_SIZE_ENC) + { + continue; + } + if (mmvdMergeCandtemp - (mmvdMergeCandtemp / IBC_MBVD_MAX_REFINE_NUM) * IBC_MBVD_MAX_REFINE_NUM >= ibcMbvdValidNum[baseIdx]) + { + continue; + } + unsigned int mmvdMergeCand = ibcMbvdLUT[mmvdMergeCandtemp]; + bool mbvdCandMisAlign = mergeCtxTmp.setIbcMbvdMergeCandiInfo(pu, mmvdMergeCandtemp, mmvdMergeCand); + CHECK(mbvdCandMisAlign, "MBVD candidate is invalid"); + + int xPred = pu.bv.getHor(); + int yPred = pu.bv.getVer(); + + PU::spanMotionInfo(pu, mergeCtxTmp); + +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 0) + { + m_pcRdCost->setDistParam(distParam, tmpOrgLuma, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } + else if (pu.cu->rribcFlipType == 1) + { + m_pcRdCost->setDistParam(distParam, tmpOrgLumaFlipH, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } + else + { + m_pcRdCost->setDistParam(distParam, tmpOrgLumaFlipV, refBuf, sps.getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard); + } +#endif + distParam.cur.buf = piRefSrch + refStride * yPred + xPred; + + Distortion sad = distParam.distFunc(distParam); + uint32_t bitsCand = PU::getIbcMbvdEstBits(pu, mmvdMergeCandtemp); + bitsCand++; // for ibc_mbvd_flag + double cost = (double)sad + (double)bitsCand * sqrtLambdaForFirstPass; +#if JVET_Z0084_IBC_TM + updateCandList(mmvdMergeCandtemp + mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand, cost, rdModeList, candCostList + , numMrgSATDCand); +#else + updateCandList(mmvdMergeCandtemp + mergeCtx.numValidMergeCand, cost, rdModeList, candCostList + , numMrgSATDCand); +#endif + } + } } #endif +#if JVET_AA0070_RRIBC + m_tmpStorageCUflipH.destroy(); + m_tmpStorageCUflipV.destroy(); +#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]) { @@ -10595,7 +10832,7 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct { for (unsigned int mrgHADIdx = 0; mrgHADIdx < numMrgSATDCand; mrgHADIdx++) { - unsigned int mergeCand = RdModeList[mrgHADIdx]; + unsigned int mergeCand = rdModeList[mrgHADIdx]; if (!(numResidualPass == 1 && candHasNoResidual[mergeCand] == 1)) { if (!(bestIsSkip && (numResidualPass == 0))) @@ -10617,6 +10854,9 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct cu.LICFlag = false; #endif +#if JVET_AA0070_RRIBC + cu.rribcFlipType = 0; +#endif 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 @@ -10624,21 +10864,39 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct pu.mmvdMergeFlag = false; pu.regularMergeFlag = false; cu.geoFlag = false; +#if JVET_AA0061_IBC_MBVD #if JVET_Z0084_IBC_TM && IBC_TM_MRG - pu.tmMergeFlag = false; - if (mergeCand >= mergeCtx.numValidMergeCand) + int numPreviousBv = mergeCtx.numValidMergeCand + mergeCtxTm.numValidMergeCand; +#else + int numPreviousBv = mergeCtx.numValidMergeCand; +#endif + if (mergeCand >= numPreviousBv) { - pu.tmMergeFlag = true; - mergeCand -= mergeCtx.numValidMergeCand; - mergeCtxTm.setMergeInfo(pu, mergeCand); - PU::spanMotionInfo(pu, mergeCtxTm); + bool mbvdCandMisAlign = mergeCtxTmp.setIbcMbvdMergeCandiInfo(pu, mergeCand - numPreviousBv, ibcMbvdLUT[mergeCand - numPreviousBv]); + CHECK(mbvdCandMisAlign, "MBVD candidate is invalid"); + PU::spanMotionInfo(pu, mergeCtxTmp); } else -#endif { - mergeCtx.setMergeInfo(pu, mergeCand); - PU::spanMotionInfo(pu, mergeCtx); +#endif +#if JVET_Z0084_IBC_TM && IBC_TM_MRG + pu.tmMergeFlag = false; + if (mergeCand >= mergeCtx.numValidMergeCand) + { + pu.tmMergeFlag = true; + mergeCand -= mergeCtx.numValidMergeCand; + mergeCtxTm.setMergeInfo(pu, mergeCand); + PU::spanMotionInfo(pu, mergeCtxTm); + } + else +#endif + { + mergeCtx.setMergeInfo(pu, mergeCand); + PU::spanMotionInfo(pu, mergeCtx); + } +#if JVET_AA0061_IBC_MBVD } +#endif #if INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS const bool chroma = !(CS::isDualITree(*tempCS)); #else @@ -10691,7 +10949,11 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct } } +#if JVET_AA0070_RRIBC +void EncCu::xCheckRDCostIBCMode( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode, bool isSecondPass) +#else void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode) +#endif { #if CTU_256 if( tempCS->area.lwidth() >= 128 || tempCS->area.lheight() >= 128 ) // disable IBC mode larger than 64x64 @@ -10735,7 +10997,12 @@ void EncCu::xCheckRDCostIBCMode(CodingStructure *&tempCS, CodingStructure *&best pu.interDir = 1; // use list 0 for IBC mode pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF; // last idx in the list +#if JVET_AA0070_RRIBC + pu.cu->rribcFlipType = 0; + bool bValid = m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap, isSecondPass); +#else bool bValid = m_pcInterSearch->predIBCSearch(cu, partitioner, m_ctuIbcSearchRangeX, m_ctuIbcSearchRangeY, m_ibcHashMap); +#endif if (bValid) { @@ -12739,7 +13006,7 @@ void EncCu::xCheckSATDCostBMMerge(CodingStructure*& tempCS, PelUnitBuf* acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf*& singleMergeTempBuffer, unsigned& uiNumMrgSATDCand, - static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, + static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx& ctxStart @@ -12957,10 +13224,10 @@ void EncCu::xCheckSATDCostBMMerge(CodingStructure*& tempCS, uint64_t fracBits = m_pcInterSearch->xCalcPuMeBits(pu); double cost = (double)uiSad + (double)fracBits * sqrtLambdaForFirstPassIntra; insertPos = -1; - updateCandList(ModeInfo(cu, pu), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(cu, pu), cost, rdModeList, candCostList, uiNumMrgSATDCand, &insertPos); if (insertPos != -1 && insertPos < MMVD_MRG_MAX_RD_NUM) { - for (int i = int(RdModeList.size()) - 1; i > insertPos; i--) + for (int i = int(rdModeList.size()) - 1; i > insertPos; i--) { swap(acMergeTempBuffer[i - 1], acMergeTempBuffer[i]); } diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h index 22ba1bc679e91c7576696986a3f9a9e88e96daf7..98ed1f40ea4dee82fd33723d87089a1fd8eaf1f3 100644 --- a/source/Lib/EncoderLib/EncCu.h +++ b/source/Lib/EncoderLib/EncCu.h @@ -454,7 +454,7 @@ protected: #if !MULTI_PASS_DMVR , Mv refinedMvdL0[MAX_NUM_PARTS_IN_CTU][MRG_MAX_NUM_CANDS] #endif - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart #if MULTI_PASS_DMVR , bool* applyBDMVR #endif @@ -463,7 +463,7 @@ protected: #if JVET_AA0093_REFINED_MOTION_FOR_ARMC void xCheckSATDCostBMMerge ( CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx& mrgCtx, MergeCtx& mrgCtxDir2, bool armcRefinedMotion, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart #if MULTI_PASS_DMVR , bool* applyBDMVR #endif @@ -471,7 +471,7 @@ protected: #else void xCheckSATDCostBMMerge ( CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx& mrgCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart #if MULTI_PASS_DMVR , bool* applyBDMVR #endif @@ -480,26 +480,26 @@ protected: #endif void xCheckSATDCostCiipMerge ( CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx mergeCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer, PelUnitBuf acMergeTmpBuffer[MRG_MAX_NUM_CANDS] - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart); + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart); #if JVET_X0141_CIIP_TIMD_TM && TM_MRG void xCheckSATDCostCiipTmMerge (CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx mergeCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer, PelUnitBuf acTmMergeTmpBuffer[MRG_MAX_NUM_CANDS] - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart); + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart); #endif void xCheckSATDCostMmvdMerge ( CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx mergeCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , uint32_t * mmvdLUT = NULL #endif ); void xCheckSATDCostAffineMerge ( CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, AffineMergeCtx affineMergeCtx, MergeCtx& mrgCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart); + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart); #if AFFINE_MMVD void xCheckSATDCostAffineMmvdMerge ( CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, AffineMergeCtx affineMergeCtx, MergeCtx& mrgCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED , uint32_t * affMmvdLUT #if JVET_AA0093_ENHANCED_MMVD_EXTENSION @@ -511,7 +511,7 @@ protected: #if TM_MRG void xCheckSATDCostTMMerge ( CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx& mrgCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart #if MULTI_PASS_DMVR , bool* applyBDMVR #endif @@ -520,7 +520,7 @@ protected: #if !JVET_W0097_GPM_MMVD_TM && !JVET_Z0056_GPM_SPLIT_MODE_REORDERING void xCheckSATDCostGeoMerge ( CodingStructure *&tempCS, CodingUnit &cu, PredictionUnit &pu, MergeCtx geoMergeCtx, PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM], PelUnitBuf *&singleMergeTempBuffer - , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &RdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart); + , unsigned& uiNumMrgSATDCand, static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &rdModeList, static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> &candCostList, DistParam distParam, const TempCtx &ctxStart); #endif #else void xCheckRDCostAffineMerge2Nx2N @@ -577,8 +577,13 @@ protected: && (abs(cu.slice->getPOC() - cu.slice->getRefPOC(REF_PIC_LIST_0, cu.refIdxBi[0])) == 1 || abs(cu.slice->getPOC() - cu.slice->getRefPOC(REF_PIC_LIST_1, cu.refIdxBi[1])) == 1)))); } +#if JVET_AA0070_RRIBC + void xCheckRDCostIBCMode ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode, bool isSecondPass = false ); +#else void xCheckRDCostIBCMode ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode ); - void xCheckRDCostIBCModeMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode ); +#endif + void xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, \ + const EncTestMode &encTestMode); void xCheckPLT ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode ); }; diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 7f40f141b505d9ac8668051e1c9c10d8c8ebd4c8..cf39a5696ddf259adae2c4da6e8e17736d751031 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1654,6 +1654,9 @@ void EncLib::xInitSPS( SPS& sps ) sps.setUseColorTrans(m_useColorTrans); sps.setPLTMode ( m_PLTMode); sps.setIBCFlag ( m_IBCMode); +#if JVET_AA0061_IBC_MBVD + sps.setUseIbcMbvd ( m_ibcMbvd ); +#endif sps.setWrapAroundEnabledFlag ( m_wrapAround ); #if MULTI_HYP_PRED sps.setMaxNumAddHyps(m_maxNumAddHyps); diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp index 3b87cc63c606635a49078dd71a5eae2df7c81d84..462e57b11fb4670fa64c838285e2d79554a60dc8 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.cpp +++ b/source/Lib/EncoderLib/EncModeCtrl.cpp @@ -2259,6 +2259,9 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt } else if (CU::isIBC(*bestCU)) { +#if JVET_AA0070_RRIBC + relatedCU.isRribcCoded = bestCU->rribcFlipType > 0; +#endif relatedCU.isIBC = true; relatedCU.isSkip |= bestCU->skip; if (bestCU->slice->getSPS()->getUseColorTrans()) diff --git a/source/Lib/EncoderLib/EncModeCtrl.h b/source/Lib/EncoderLib/EncModeCtrl.h index e347c668e916fa3bfa61907d3d94506578123cc1..ee5734cbb7498c1081dd423c50d1cf0e0d857603 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.h +++ b/source/Lib/EncoderLib/EncModeCtrl.h @@ -966,6 +966,10 @@ struct CodedCUInfo int numGeoDirCand; int geoMrgIdx0List[GEO_MAX_TRY_WEIGHTED_SATD]; int geoMrgIdx1List[GEO_MAX_TRY_WEIGHTED_SATD]; +#endif +#if JVET_AA0070_RRIBC + bool isRribcCoded; + bool isRribcTested; #endif bool validMv[NUM_REF_PIC_LIST_01][MAX_STORED_CU_INFO_REFS]; Mv saveMv [NUM_REF_PIC_LIST_01][MAX_STORED_CU_INFO_REFS]; diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 5afacf2091433b0cb1e9013111ef39b46f6c5851..291a39d586aa6d6d8164bbc56c00e688466f5609 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1751,7 +1751,11 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons if( ( !pcSlice->isIntra() && pcSlice->getSPS()->getFpelMmvdEnabledFlag() ) || ( pcSlice->getSPS()->getIBCFlag() && m_pcCuEncoder->getEncCfg()->getIBCHashSearch() ) ) { +#if JVET_AA0070_RRIBC + m_pcCuEncoder->getIbcHashMap().rebuildPicHashMap(cs.picture->getTrueOrigBuf(), CS::isDualITree(cs)); +#else m_pcCuEncoder->getIbcHashMap().rebuildPicHashMap(cs.picture->getTrueOrigBuf()); +#endif if (m_pcCfg->getIntraPeriod() != -1) { int hashBlkHitPerc = m_pcCuEncoder->getIbcHashMap().calHashBlkMatchPerc(cs.area.Y()); diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index fa1f06e3e01439daf2f1de95b69adb2566efc236..890858ebdf442acb9743ce98bc47fa2bb28972c0 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -923,6 +923,9 @@ void InterSearch::xIBCSearchMVCandUpdate(Distortion sad, int x, int y, Distorti } } +#if JVET_AA0070_RRIBC +int InterSearch::xIBCSearchMVChromaRefine( PredictionUnit& pu, int roiWidth, int roiHeight, int cuPelX, int cuPelY, Distortion* sadBestCand, Mv* cMVCand, int rribcFlipType ) +#else int InterSearch::xIBCSearchMVChromaRefine(PredictionUnit& pu, int roiWidth, int roiHeight, @@ -930,8 +933,8 @@ int InterSearch::xIBCSearchMVChromaRefine(PredictionUnit& pu, int cuPelY, Distortion* sadBestCand, Mv* cMVCand - ) +#endif { if ( (!isChromaEnabled(pu.chromaFormat)) || (!pu.Cb().valid()) ) { @@ -957,6 +960,12 @@ int InterSearch::xIBCSearchMVChromaRefine(PredictionUnit& pu, { continue; } +#if JVET_AA0070_RRIBC + if ((rribcFlipType == 1 && cMVCand[cand].getVer() != 0) || (rribcFlipType == 2 && cMVCand[cand].getHor() != 0)) + { + continue; + } +#endif if ((!cMVCand[cand].getHor()) && (!cMVCand[cand].getVer())) continue; @@ -984,7 +993,22 @@ int InterSearch::xIBCSearchMVChromaRefine(PredictionUnit& pu, PelUnitBuf origBuf = pu.cs->getOrgBuf(allCompBlocks); PelUnitBuf* pBuf = &origBuf; +#if JVET_AA0070_RRIBC + PelBuf tmpPattern; + if (rribcFlipType) + { + CompArea tmpArea(ComponentID(ch), pu.chromaFormat, Position(0, 0), Size(pBuf->get(ComponentID(ch)).width, pBuf->get(ComponentID(ch)).height)); + tmpPattern = m_tmpStorageLCU.getBuf(tmpArea); + tmpPattern.copyFrom(pBuf->get(ComponentID(ch))); + tmpPattern.flipSignal(rribcFlipType == 1); + } + else + { + tmpPattern = pBuf->get(ComponentID(ch)); + } +#else CPelBuf tmpPattern = pBuf->get(ComponentID(ch)); +#endif pOrg = (Pel*)tmpPattern.buf; Picture* refPic = pu.cu->slice->getPic(); @@ -1050,7 +1074,11 @@ static unsigned int xMergeCandLists(Mv *dst, unsigned int dn, unsigned int dstTo return dn; } -void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cStruct, Mv& rcMv, Distortion& ruiCost, Mv* pcMvSrchRngLT, Mv* pcMvSrchRngRB, Mv* pcMvPred) +#if JVET_AA0070_RRIBC +void InterSearch::xIntraPatternSearch( PredictionUnit &pu, IntTZSearchStruct &cStruct, Mv &rcMv, Distortion &ruiCost, Mv *pcMvSrchRngLT, Mv *pcMvSrchRngRB, Mv *pcMvPred, int rribcFlipType ) +#else +void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cStruct, Mv &rcMv, Distortion &ruiCost, Mv *pcMvSrchRngLT, Mv *pcMvSrchRngRB, Mv *pcMvPred) +#endif { const int srchRngHorLeft = pcMvSrchRngLT->getHor(); const int srchRngHorRight = pcMvSrchRngRB->getHor(); @@ -1111,6 +1139,13 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS int xPred = m_acBVs[cand].getHor(); int yPred = m_acBVs[cand].getVer(); +#if JVET_AA0070_RRIBC + if ((rribcFlipType == 1 && yPred != 0) || (rribcFlipType == 2 && xPred != 0)) + { + continue; + } +#endif + if (!(xPred == 0 && yPred == 0) && !((yPred < srTop) || (yPred > srBottom)) && !((xPred < srLeft) || (xPred > srRight))) @@ -1123,7 +1158,11 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS if (validCand) { +#if JVET_AA0070_RRIBC + sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); +#else sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag()); +#endif m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * yPred + xPred; sad += m_cDistParam.distFunc(m_cDistParam); @@ -1140,6 +1179,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS const int boundY = (0 - roiHeight - puPelOffsetY); for (int y = std::max(srchRngVerTop, 0 - cuPelY); y <= boundY; ++y) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 1 && y != 0) + { + continue; + } +#endif #if JVET_Z0084_IBC_TM if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, 0, y, lcuWidth)) #else @@ -1149,7 +1194,11 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS continue; } +#if JVET_AA0070_RRIBC + sad = m_pcRdCost->getBvCostMultiplePreds(0, y, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); +#else sad = m_pcRdCost->getBvCostMultiplePreds(0, y, pu.cs->sps->getAMVREnabledFlag()); +#endif m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y; sad += m_cDistParam.distFunc(m_cDistParam); @@ -1169,6 +1218,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS const int boundX = std::max(srchRngHorLeft, -cuPelX); for (int x = 0 - roiWidth - puPelOffsetX; x >= boundX; --x) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 2 && x != 0) + { + continue; + } +#endif #if JVET_Z0084_IBC_TM if (!PU::searchBv(pu, cuPelX, cuPelY, roiWidth, roiHeight, picWidth, picHeight, x, 0, lcuWidth)) #else @@ -1178,7 +1233,11 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS continue; } +#if JVET_AA0070_RRIBC + sad = m_pcRdCost->getBvCostMultiplePreds(x, 0, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); +#else sad = m_pcRdCost->getBvCostMultiplePreds(x, 0, pu.cs->sps->getAMVREnabledFlag()); +#endif m_cDistParam.cur.buf = piRefSrch + x; sad += m_cDistParam.distFunc(m_cDistParam); @@ -1199,10 +1258,17 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS bestX = cMVCand[0].getHor(); bestY = cMVCand[0].getVer(); sadBest = sadBestCand[0]; +#if JVET_AA0070_RRIBC + if ((!bestX && !bestY) || (sadBest - m_pcRdCost->getBvCostMultiplePreds(bestX, bestY, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType) <= 32)) + { + //chroma refine + bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand, rribcFlipType); +#else if ((!bestX && !bestY) || (sadBest - m_pcRdCost->getBvCostMultiplePreds(bestX, bestY, pu.cs->sps->getAMVREnabledFlag()) <= 32)) { //chroma refine bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand); +#endif bestX = cMVCand[bestCandIdx].getHor(); bestY = cMVCand[bestCandIdx].getVer(); sadBest = sadBestCand[bestCandIdx]; @@ -1222,20 +1288,44 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS for (int y = std::max(verTop, -cuPelY); y <= verBottom; y += 2) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 1 && y != 0) + { + continue; + } +#endif if ((y == 0) || ((int)(cuPelY + y + roiHeight) >= picHeight)) { continue; } for (int x = std::max(horLeft, -cuPelX); x <= horRight; x++) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 2 && x != 0) + { + continue; + } +#endif #else for (int y = std::max(srchRngVerTop, -cuPelY); y <= srchRngVerBottom; y += 2) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 1 && y != 0) + { + continue; + } +#endif if ((y == 0) || ((int)(cuPelY + y + roiHeight) >= picHeight)) continue; for (int x = std::max(srchRngHorLeft, -cuPelX); x <= srchRngHorRight; x++) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 2 && x != 0) + { + continue; + } +#endif #endif if ((x == 0) || ((int)(cuPelX + x + roiWidth) >= picWidth)) continue; @@ -1249,7 +1339,11 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS continue; } +#if JVET_AA0070_RRIBC + sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); +#else sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag()); +#endif m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y + x; sad += m_cDistParam.distFunc(m_cDistParam); @@ -1260,11 +1354,16 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS bestX = cMVCand[0].getHor(); bestY = cMVCand[0].getVer(); sadBest = sadBestCand[0]; +#if JVET_AA0070_RRIBC + if (sadBest - m_pcRdCost->getBvCostMultiplePreds(bestX, bestY, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType) <= 16) + { + bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand, rribcFlipType); +#else if (sadBest - m_pcRdCost->getBvCostMultiplePreds(bestX, bestY, pu.cs->sps->getAMVREnabledFlag()) <= 16) { - //chroma refine + // chroma refine bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand); - +#endif bestX = cMVCand[bestCandIdx].getHor(); bestY = cMVCand[bestCandIdx].getVer(); sadBest = sadBestCand[bestCandIdx]; @@ -1276,6 +1375,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS #if JVET_Z0153_IBC_EXT_REF for (int y = (std::max(verTop, -cuPelY) + 1); y <= verBottom; y += 2) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 1 && y != 0) + { + continue; + } +#endif if ((y == 0) || ((int)(cuPelY + y + roiHeight) >= picHeight)) { continue; @@ -1285,12 +1390,24 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS #else for (int y = (std::max(srchRngVerTop, -cuPelY) + 1); y <= srchRngVerBottom; y += 2) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 1 && y != 0) + { + continue; + } +#endif if ((y == 0) || ((int)(cuPelY + y + roiHeight) >= picHeight)) continue; for (int x = std::max(srchRngHorLeft, -cuPelX); x <= srchRngHorRight; x += 2) #endif { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 2 && x != 0) + { + continue; + } +#endif if ((x == 0) || ((int)(cuPelX + x + roiWidth) >= picWidth)) continue; @@ -1303,7 +1420,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS continue; } +#if JVET_AA0070_RRIBC + sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); +#else sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag()); +#endif + m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y + x; sad += m_cDistParam.distFunc(m_cDistParam); @@ -1311,8 +1433,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS xIBCSearchMVCandUpdate(sad, x, y, sadBestCand, cMVCand); if (sadBestCand[0] <= 5) { - //chroma refine & return + // chroma refine & return +#if JVET_AA0070_RRIBC + bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand, rribcFlipType); +#else bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand); +#endif bestX = cMVCand[bestCandIdx].getHor(); bestY = cMVCand[bestCandIdx].getVer(); sadBest = sadBestCand[bestCandIdx]; @@ -1327,10 +1453,17 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS bestY = cMVCand[0].getVer(); sadBest = sadBestCand[0]; +#if JVET_AA0070_RRIBC + if ((sadBest >= tempSadBest) || ((sadBest - m_pcRdCost->getBvCostMultiplePreds(bestX, bestY, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType)) <= 32)) + { + // chroma refine + bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand, rribcFlipType); +#else if ((sadBest >= tempSadBest) || ((sadBest - m_pcRdCost->getBvCostMultiplePreds(bestX, bestY, pu.cs->sps->getAMVREnabledFlag())) <= 32)) { - //chroma refine + // chroma refine bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand); +#endif bestX = cMVCand[bestCandIdx].getHor(); bestY = cMVCand[bestCandIdx].getVer(); sadBest = sadBestCand[bestCandIdx]; @@ -1344,6 +1477,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS #if JVET_Z0153_IBC_EXT_REF for (int y = (std::max(verTop, -cuPelY) + 1); y <= verBottom; y += 2) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 1 && y != 0) + { + continue; + } +#endif if ((y == 0) || ((int)(cuPelY + y + roiHeight) >= picHeight)) { continue; @@ -1352,6 +1491,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS #else for (int y = (std::max(srchRngVerTop, -cuPelY) + 1); y <= srchRngVerBottom; y += 2) { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 1 && y != 0) + { + continue; + } +#endif if ((y == 0) || ((int)(cuPelY + y + roiHeight) >= picHeight)) continue; @@ -1359,6 +1504,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS #endif { +#if JVET_AA0070_RRIBC + if (rribcFlipType == 2 && x != 0) + { + continue; + } +#endif if ((x == 0) || ((int)(cuPelX + x + roiWidth) >= picWidth)) continue; @@ -1371,7 +1522,11 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS continue; } +#if JVET_AA0070_RRIBC + sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); +#else sad = m_pcRdCost->getBvCostMultiplePreds(x, y, pu.cs->sps->getAMVREnabledFlag()); +#endif m_cDistParam.cur.buf = piRefSrch + cStruct.iRefStride * y + x; sad += m_cDistParam.distFunc(m_cDistParam); @@ -1379,8 +1534,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS xIBCSearchMVCandUpdate(sad, x, y, sadBestCand, cMVCand); if (sadBestCand[0] <= 5) { - //chroma refine & return + // chroma refine & return +#if JVET_AA0070_RRIBC + bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand, rribcFlipType); +#else bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand); +#endif bestX = cMVCand[bestCandIdx].getHor(); bestY = cMVCand[bestCandIdx].getVer(); sadBest = sadBestCand[bestCandIdx]; @@ -1393,7 +1552,11 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS } } +#if JVET_AA0070_RRIBC + bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand, rribcFlipType); +#else bestCandIdx = xIBCSearchMVChromaRefine(pu, roiWidth, roiHeight, cuPelX, cuPelY, sadBestCand, cMVCand); +#endif bestX = cMVCand[bestCandIdx].getHor(); bestY = cMVCand[bestCandIdx].getVer(); @@ -1411,10 +1574,28 @@ end: for (unsigned int cand = 0; cand < CHROMA_REFINEMENT_CANDIDATES; cand++) { +#if JVET_AA0070_RRIBC + if ((rribcFlipType == 1 && cMVCand[cand].getVer() != 0) || (rribcFlipType == 2 && cMVCand[cand].getHor() != 0)) + { + continue; + } + if (m_pcEncCfg->getIntraPeriod() < 1 && m_pcEncCfg->getIBCFastMethod()) + { + if (sadBestCand[cand] >= minCostProj) + { + break; + } + else if (!cand && rribcFlipType) + { + minCostProj = 3 * sadBestCand[0]; + } + } +#endif if (cMVCand[cand].getHor() == 0 && cMVCand[cand].getVer() == 0) { continue; } + m_ctuRecord[pu.lumaPos()][pu.lumaSize()].bvRecord[cMVCand[cand]] = sadBestCand[cand]; } @@ -1424,11 +1605,11 @@ end: // based on xMotionEstimation -void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, - Mv *pcMvPred, - Mv &rcMv, - Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY -) +#if JVET_AA0070_RRIBC +void InterSearch::xIBCEstimation(PredictionUnit &pu, PelUnitBuf &origBuf, 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, Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY) +#endif { const int iPicWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples(); const int iPicHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples(); @@ -1444,7 +1625,47 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, CPelBuf tmpPattern = pBuf->Y(); CPelBuf* pcPatternKey = &tmpPattern; PelBuf tmpOrgLuma; +#if JVET_AA0070_RRIBC + const CompArea &area = pu.blocks[COMPONENT_Y]; + CompArea tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size()); + if ((pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())) + { + tmpOrgLuma = m_tmpStorageLCU.getBuf(tmpArea); + tmpOrgLuma.rspSignal(tmpPattern, m_pcReshape->getFwdLUT()); + pcPatternKey = (CPelBuf *) &tmpOrgLuma; + } + + CPelBuf *pcPatternKeyFlipH; + CPelBuf *pcPatternKeyFlipV; + PelStorage m_tmpStorageCUflipH; + PelStorage m_tmpStorageCUflipV; + PelBuf tmpOrgLumaFlipH, tmpOrgLumaFlipV; + if (numRribcType > 1) + { + m_tmpStorageCUflipH.create(UnitArea(pu.chromaFormat, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE))); + tmpOrgLumaFlipH = m_tmpStorageCUflipH.getBuf(tmpArea); + + m_tmpStorageCUflipV.create(UnitArea(pu.chromaFormat, Area(0, 0, MAX_CU_SIZE, MAX_CU_SIZE))); + tmpOrgLumaFlipV = m_tmpStorageCUflipV.getBuf(tmpArea); + + if ((pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())) + { + tmpOrgLumaFlipH.copyFrom(tmpOrgLuma); + tmpOrgLumaFlipV.copyFrom(tmpOrgLuma); + } + else + { + tmpOrgLumaFlipH.copyFrom(tmpPattern); + tmpOrgLumaFlipV.copyFrom(tmpPattern); + } + tmpOrgLumaFlipH.flipSignal(true); + pcPatternKeyFlipH = (CPelBuf *) &tmpOrgLumaFlipH; + + tmpOrgLumaFlipV.flipSignal(false); + pcPatternKeyFlipV = (CPelBuf *) &tmpOrgLumaFlipV; + } +#else if ((pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())) { const CompArea &area = pu.blocks[COMPONENT_Y]; @@ -1453,13 +1674,16 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, tmpOrgLuma.rspSignal( tmpPattern, m_pcReshape->getFwdLUT() ); pcPatternKey = (CPelBuf*)&tmpOrgLuma; } +#endif m_lumaClpRng = pu.cs->slice->clpRng(COMPONENT_Y); Picture* refPic = pu.cu->slice->getPic(); const CPelBuf refBuf = refPic->getRecoBuf(pu.blocks[COMPONENT_Y]); IntTZSearchStruct cStruct; +#if !JVET_AA0070_RRIBC cStruct.pcPatternKey = pcPatternKey; +#endif cStruct.iRefStride = refBuf.stride; cStruct.piRefY = refBuf.buf; CHECK(pu.cu->imv == IMV_HPEL, "IF_IBC"); @@ -1474,15 +1698,187 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, m_pcRdCost->setCostScale(0); m_cDistParam.useMR = false; +#if !JVET_AA0070_RRIBC m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode); +#endif bool buffered = false; +#if JVET_AA0070_RRIBC + minCostProj = MAX_INT; + if (m_pcEncCfg->getIntraPeriod() < 1 && m_pcEncCfg->getIBCFastMethod()) + { + ruiCost = MAX_UINT; + std::unordered_map<Mv, Distortion> &history = m_ctuRecord[pu.lumaPos()][pu.lumaSize()].bvRecord; + if (history.size()) + { + std::vector<std::pair<Mv, Distortion>> historyOrdered(history.size()); + int i = 0; + for (std::unordered_map<Mv, Distortion>::iterator p = history.begin(); p != history.end(); p++) + { + historyOrdered[i] = { p->first, p->second }; + i++; + } + std::stable_sort(historyOrdered.begin(), historyOrdered.end(),[](const std::pair<Mv, Distortion> &l, const std::pair<Mv, Distortion> &r) + { return (l.second < r.second) || (l.second == r.second && (l.first.getHor() < r.first.getHor() || (l.first.getHor() == r.first.getHor() && l.first.getVer() < r.first.getVer()))); }); + minCostProj = 3 * historyOrdered[0].second; + + Distortion cand0Cost[3] = { MAX_UINT, MAX_UINT, MAX_UINT }; + bool isCalc[3] = { false }, isSkip[3] = { false }, checkDone[3] = { false }; + int map[6] = { 1, 2, 0, 2, 0, 1 }; + for (int i = 0; i < history.size(); i++) + { + if (historyOrdered[i].second >= minCostProj) + { + break; + } + const Mv &bv = historyOrdered[i].first; + int xBv = bv.hor; + int yBv = bv.ver; + + for (int rribcFlipType = 0; rribcFlipType < numRribcType; rribcFlipType++) + { + if (isSkip[rribcFlipType]) + { + continue; + } + if (!checkDone[rribcFlipType] && isCalc[rribcFlipType] && (isCalc[map[rribcFlipType * 2]] || isCalc[map[rribcFlipType * 2 + 1]])) + { + if (isCalc[map[rribcFlipType * 2]] && cand0Cost[rribcFlipType] >= 1.1 * cand0Cost[map[rribcFlipType * 2]]) + { + isSkip[rribcFlipType] = true; + } + else if (isCalc[map[rribcFlipType * 2]] && cand0Cost[rribcFlipType] >= 1.1 * cand0Cost[map[rribcFlipType * 2 + 1]]) + { + isSkip[rribcFlipType] = true; + } + checkDone[rribcFlipType] = true; + } + if ((rribcFlipType == 1 && yBv != 0) || (rribcFlipType == 2 && xBv != 0)) + { + continue; + } +#if JVET_Z0084_IBC_TM + if (PU::searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth)) +#else + if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth)) +#endif + { + buffered = true; + Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xBv, yBv, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); + cStruct.pcPatternKey = (rribcFlipType == 0) ? pcPatternKey : ((rribcFlipType == 1) ? pcPatternKeyFlipH : pcPatternKeyFlipV); + m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode); + m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * yBv + xBv; + sad += m_cDistParam.distFunc(m_cDistParam); + if (!isCalc[rribcFlipType]) + { + cand0Cost[rribcFlipType] = sad; + isCalc[rribcFlipType] = true; + } + if (sad < ruiCost) + { + rcMv = bv; + ruiCost = sad; + pu.cu->rribcFlipType = rribcFlipType; + } + else if (sad == ruiCost) + { + // stabilise the search through the unordered list + if (abs(bv.hor) < abs(rcMv.getHor()) || (bv.hor == rcMv.getHor() && abs(bv.ver) < abs(rcMv.getVer()))) + { + // update the vector. + rcMv = bv; + pu.cu->rribcFlipType = rribcFlipType; + } + } + } + } + } + + if (buffered) + { + Mv cMvPredEncOnly[IBC_NUM_CANDIDATES]; + int nbPreds = 0; + PU::getIbcMVPsEncOnly(pu, cMvPredEncOnly, nbPreds); + + for (unsigned int cand = 0; cand < nbPreds; cand++) + { + int xPred = cMvPredEncOnly[cand].getHor(); + int yPred = cMvPredEncOnly[cand].getVer(); + + for (int rribcFlipType = 0; rribcFlipType < numRribcType; rribcFlipType++) + { + if (isSkip[rribcFlipType]) + { + continue; + } + if ((rribcFlipType == 1 && yPred != 0) || (rribcFlipType == 2 && xPred != 0)) + { + continue; + } +#if JVET_Z0084_IBC_TM + if (PU::searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth)) +#else + if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth)) +#endif + { + Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); + cStruct.pcPatternKey = (rribcFlipType == 0) ? pcPatternKey : ((rribcFlipType == 1) ? pcPatternKeyFlipH : pcPatternKeyFlipV); + m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode); + m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * yPred + xPred; + sad += m_cDistParam.distFunc(m_cDistParam); + if (sad >= minCostProj) + { + continue; + } + if (sad < ruiCost) + { + rcMv.set(xPred, yPred); + ruiCost = sad; + pu.cu->rribcFlipType = rribcFlipType; + } + else if (sad == ruiCost) + { + // stabilise the search through the unordered list + if (abs(xPred) < abs(rcMv.getHor()) || (xPred == rcMv.getHor() && abs(yPred) < abs(rcMv.getVer()))) + { + // update the vector. + rcMv.set(xPred, yPred); + pu.cu->rribcFlipType = rribcFlipType; + } + } + + m_ctuRecord[pu.lumaPos()][pu.lumaSize()].bvRecord[Mv(xPred, yPred)] = sad; + } + } + } + } + } + } + else if (m_pcEncCfg->getIBCFastMethod() & IBC_FAST_METHOD_BUFFERBV) +#else if (m_pcEncCfg->getIBCFastMethod() & IBC_FAST_METHOD_BUFFERBV) +#endif { ruiCost = MAX_UINT; std::unordered_map<Mv, Distortion>& history = m_ctuRecord[pu.lumaPos()][pu.lumaSize()].bvRecord; +#if JVET_AA0070_RRIBC + std::vector<std::pair<Mv, Distortion>> historyOrdered(history.size()); + int i = 0; + for (std::unordered_map<Mv, Distortion>::iterator p = history.begin(); p != history.end(); p++) + { + historyOrdered[i] = { p->first, p->second }; + i++; + } + std::stable_sort(historyOrdered.begin(), historyOrdered.end(),[](const std::pair<Mv, Distortion> &l, const std::pair<Mv, Distortion> &r) + { return (l.second < r.second) || (l.second == r.second && (l.first.getHor() < r.first.getHor() || (l.first.getHor() == r.first.getHor() && l.first.getVer() < r.first.getVer()))); }); + + for (int i = 0; i < history.size(); i++) + { + const Mv &bv = historyOrdered[i].first; +#else for (std::unordered_map<Mv, Distortion>::iterator p = history.begin(); p != history.end(); p++) { const Mv& bv = p->first; +#endif int xBv = bv.hor; int yBv = bv.ver; @@ -1492,26 +1888,53 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xBv, yBv, lcuWidth)) #endif { +#if JVET_AA0070_RRIBC + for (int rribcFlipType = 0; rribcFlipType < numRribcType; rribcFlipType++) + { + if ((rribcFlipType == 1 && yBv != 0) || (rribcFlipType == 2 && xBv != 0)) + { + continue; + } + buffered = true; + Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xBv, yBv, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); + cStruct.pcPatternKey = (rribcFlipType == 0) ? pcPatternKey : ((rribcFlipType == 1) ? pcPatternKeyFlipH : pcPatternKeyFlipV); + m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode); +#else buffered = true; Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xBv, yBv, pu.cs->sps->getAMVREnabledFlag()); +#endif m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * yBv + xBv; sad += m_cDistParam.distFunc(m_cDistParam); if (sad < ruiCost) { rcMv = bv; ruiCost = sad; +#if JVET_AA0070_RRIBC + pu.cu->rribcFlipType = rribcFlipType; +#endif } else if (sad == ruiCost) { // stabilise the search through the unordered list - if (bv.hor < rcMv.getHor() - || (bv.hor == rcMv.getHor() && bv.ver < rcMv.getVer())) +#if JVET_AA0070_RRIBC + if (abs(bv.hor) < abs(rcMv.getHor()) || (bv.hor == rcMv.getHor() && abs(bv.ver) < abs(rcMv.getVer()))) + { + // update the vector. + rcMv = bv; + pu.cu->rribcFlipType = rribcFlipType; + } + } + } + } +#else + if (bv.hor < rcMv.getHor() || (bv.hor == rcMv.getHor() && bv.ver < rcMv.getVer())) { // update the vector. rcMv = bv; } } } +#endif } if (buffered) @@ -1531,26 +1954,46 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, if (searchBv(pu, cuPelX, cuPelY, iRoiWidth, iRoiHeight, iPicWidth, iPicHeight, xPred, yPred, lcuWidth)) #endif { +#if JVET_AA0070_RRIBC + for (int rribcFlipType = 0; rribcFlipType < numRribcType; rribcFlipType++) + { + if ((rribcFlipType == 1 && yPred != 0) || (rribcFlipType == 2 && xPred != 0)) + { + continue; + } + Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag(), rribcFlipType); + cStruct.pcPatternKey = (rribcFlipType == 0) ? pcPatternKey : ((rribcFlipType == 1) ? pcPatternKeyFlipH : pcPatternKeyFlipV); + m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode); +#else Distortion sad = m_pcRdCost->getBvCostMultiplePreds(xPred, yPred, pu.cs->sps->getAMVREnabledFlag()); +#endif m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * yPred + xPred; sad += m_cDistParam.distFunc(m_cDistParam); if (sad < ruiCost) { rcMv.set(xPred, yPred); ruiCost = sad; +#if JVET_AA0070_RRIBC + pu.cu->rribcFlipType = rribcFlipType; +#endif } else if (sad == ruiCost) { // stabilise the search through the unordered list - if (xPred < rcMv.getHor() - || (xPred == rcMv.getHor() && yPred < rcMv.getVer())) + if (xPred < rcMv.getHor() || (xPred == rcMv.getHor() && yPred < rcMv.getVer())) { // update the vector. rcMv.set(xPred, yPred); +#if JVET_AA0070_RRIBC + pu.cu->rribcFlipType = rribcFlipType; +#endif } } m_ctuRecord[pu.lumaPos()][pu.lumaSize()].bvRecord[Mv(xPred, yPred)] = sad; +#if JVET_AA0070_RRIBC + } +#endif } } } @@ -1565,8 +2008,32 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, xSetIntraSearchRange(pu, pu.lwidth(), pu.lheight(), localSearchRangeX, localSearchRangeY, cMvSrchRngLT, cMvSrchRngRB); // Do integer search +#if JVET_AA0070_RRIBC + Distortion minCost = MAX_UINT; + Mv tempMv; + tempMv.setZero(); + for (int rribcFlipType = 0; rribcFlipType < numRribcType; rribcFlipType++) + { + cStruct.pcPatternKey = (rribcFlipType == 0) ? pcPatternKey : ((rribcFlipType == 1) ? pcPatternKeyFlipH : pcPatternKeyFlipV); + m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode); + xIntraPatternSearch(pu, cStruct, tempMv, ruiCost, &cMvSrchRngLT, &cMvSrchRngRB, pcMvPred[rribcFlipType], rribcFlipType); + if (ruiCost < minCost) + { + minCost = ruiCost; + rcMv.set(tempMv.getHor(), tempMv.getVer()); + pu.cu->rribcFlipType = rribcFlipType; + } + } + } + if (numRribcType > 1) + { + m_tmpStorageCUflipH.destroy(); + m_tmpStorageCUflipV.destroy(); + } +#else xIntraPatternSearch(pu, cStruct, rcMv, ruiCost, &cMvSrchRngLT, &cMvSrchRngRB, pcMvPred); } +#endif } // based on xSetSearchRange @@ -1622,7 +2089,11 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR rcMvSrchRngRB >>= 2; } +#if JVET_AA0070_RRIBC +bool InterSearch::predIBCSearch( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, bool isSecondPass) +#else bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap) +#endif { Mv cMvSrchRngLT; Mv cMvSrchRngRB; @@ -1633,12 +2104,66 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const #if JVET_Z0131_IBC_BVD_BINARIZATION xEstBvdBitCosts(m_pcRdCost->getBvdBitCosts()); #endif +#if JVET_AA0070_RRIBC + CodedCUInfo& relatedCU = ((EncModeCtrlMTnoRQT *)m_modeCtrl)->getBlkInfo(partitioner.currArea()); +#endif for (auto &pu : CU::traversePUs(cu)) { m_maxCompIDToPred = MAX_NUM_COMPONENT; CHECK(pu.cu != &cu, "PU is contained in another CU"); +#if JVET_AA0070_RRIBC + int numRribcType = 3; + if (isSecondPass) + { + if (!relatedCU.isRribcCoded) + { + numRribcType = 1; + } + } + Mv cMv; + cMv.setZero(); + int iBvpNum = 2; + int bvpIdxBest = 0; + Distortion cost = 0; + + AMVPInfo amvpInfo4Pel[3]; + AMVPInfo amvpInfo[3]; + Mv cMvPred[3][2]; + for (int i = 0; i < numRribcType; i++) + { + pu.cu->rribcFlipType = i; + + // prepare imv = 2 accuracy predictor info + pu.cu->imv = 2; +#if JVET_Z0084_IBC_TM && TM_AMVP + PU::fillIBCMvpCand(pu, amvpInfo4Pel[i], this); +#else + PU::fillIBCMvpCand(pu, amvpInfo4Pel[i]); +#endif + + // prepare imv = 0 accuracy predictor info + pu.cu->imv = 0; +#if JVET_Z0084_IBC_TM && TM_AMVP + PU::fillIBCMvpCand(pu, amvpInfo[i], this); +#else + PU::fillIBCMvpCand(pu, amvpInfo[i]); +#endif + + // store in full pel accuracy, shift before use in search + cMvPred[i][0] = amvpInfo[i].mvCand[0]; + cMvPred[i][0].changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); + cMvPred[i][1] = amvpInfo[i].mvCand[1]; + cMvPred[i][1].changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); + if (pu.cs->sps->getMaxNumIBCMergeCand() == 1) + { + iBvpNum = 1; + cMvPred[i][1] = cMvPred[i][0]; + } + } + pu.cu->rribcFlipType = 0; +#else ////////////////////////////////////////////////////////// /// ibc search pu.cu->imv = 2; @@ -1673,17 +2198,26 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const iBvpNum = 1; cMvPred[1] = cMvPred[0]; } +#endif if (m_pcEncCfg->getIBCHashSearch()) { +#if JVET_AA0070_RRIBC + xxIBCHashSearch(pu, cMvPred, iBvpNum, cMv, bvpIdxBest, ibcHashMap, amvpInfo4Pel, numRribcType); +#else xxIBCHashSearch(pu, cMvPred, iBvpNum, cMv, bvpIdxBest, ibcHashMap); +#endif } if (cMv.getHor() == 0 && cMv.getVer() == 0) { // if hash search does not work or is not enabled PelUnitBuf origBuf = pu.cs->getOrgBuf(pu); +#if JVET_AA0070_RRIBC + xIBCEstimation(pu, origBuf, cMvPred, cMv, cost, localSearchRangeX, localSearchRangeY, numRribcType); +#else xIBCEstimation(pu, origBuf, cMvPred, cMv, cost, localSearchRangeX, localSearchRangeY); +#endif } if (cMv.getHor() == 0 && cMv.getVer() == 0) @@ -1695,11 +2229,19 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const #if JVET_Z0131_IBC_BVD_BINARIZATION m_pcRdCost->setPredictors(cMvPred); m_pcRdCost->setCostScale(0); +#if JVET_AA0070_RRIBC +#if JVET_Z0084_IBC_TM && IBC_TM_AMVP + m_pcRdCost->getBvCostMultiplePreds(cMv.getHor(), cMv.getVer(), pu.cs->sps->getAMVREnabledFlag(), pu.cu->rribcFlipType, &pu.cu->imv, &bvpIdxBest, true, &amvpInfo4Pel[pu.cu->rribcFlipType]); +#else + m_pcRdCost->getBvCostMultiplePreds(cMv.getHor(), cMv.getVer(), pu.cs->sps->getAMVREnabledFlag(), pu.cu->rribcFlipType, &pu.cu->imv, &bvpIdxBest); +#endif +#else #if JVET_Z0084_IBC_TM && IBC_TM_AMVP m_pcRdCost->getBvCostMultiplePreds(cMv.getHor(), cMv.getVer(), pu.cs->sps->getAMVREnabledFlag(), &pu.cu->imv, &bvpIdxBest, true, &amvpInfo4Pel); #else m_pcRdCost->getBvCostMultiplePreds(cMv.getHor(), cMv.getVer(), pu.cs->sps->getAMVREnabledFlag(), &pu.cu->imv, &bvpIdxBest); #endif +#endif #else unsigned int bitsBVPBest, bitsBVPTemp; bitsBVPBest = MAX_INT; @@ -1707,16 +2249,31 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const for (int bvpIdxTemp = 0; bvpIdxTemp<iBvpNum; bvpIdxTemp++) { +#if JVET_AA0070_RRIBC + Mv ccMvPred = cMvPred[pu.cu->rribcFlipType][bvpIdxTemp]; + m_pcRdCost->setPredictor(ccMvPred); + bitsBVPTemp = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), 0, cu.rribcFlipType); +#else m_pcRdCost->setPredictor(cMvPred[bvpIdxTemp]); bitsBVPTemp = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), 0); +#endif if (bitsBVPTemp < bitsBVPBest) { bitsBVPBest = bitsBVPTemp; bvpIdxBest = bvpIdxTemp; +#if JVET_AA0070_RRIBC + bool diffMV = false; + if ((pu.cu->rribcFlipType == 1 && cMv.getHor() != ccMvPred.getHor()) || (pu.cu->rribcFlipType == 2 && cMv.getVer() != ccMvPred.getVer()) || (pu.cu->rribcFlipType == 0 && cMv != ccMvPred)) + { + diffMV = true; + } + if (cu.cs->sps->getAMVREnabledFlag() && diffMV) +#else if (cu.cs->sps->getAMVREnabledFlag() && cMv != cMvPred[bvpIdxTemp]) +#endif pu.cu->imv = 1; // set as full-pel else pu.cu->imv = 0; // set as fractional-pel @@ -1729,17 +2286,35 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const Mv mvPredQuadPel; if ((cMv.getHor() % 4 == 0) && (cMv.getVer() % 4 == 0) && (pu.cs->sps->getAMVREnabledFlag())) { +#if JVET_AA0070_RRIBC + mvPredQuadPel = amvpInfo4Pel[pu.cu->rribcFlipType].mvCand[bvpIdxTemp]; +#else mvPredQuadPel = amvpInfo4Pel.mvCand[bvpIdxTemp];// cMvPred[bvpIdxTemp]; +#endif + mvPredQuadPel.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_4PEL); m_pcRdCost->setPredictor(mvPredQuadPel); +#if JVET_AA0070_RRIBC + bitsBVPQP = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor() >> 2, cMv.getVer() >> 2, 0, cu.rribcFlipType); +#else bitsBVPQP = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor() >> 2, cMv.getVer() >> 2, 0); +#endif } mvPredQuadPel.changePrecision(MV_PRECISION_4PEL, MV_PRECISION_INT); +#if JVET_AA0070_RRIBC + bool diffMV = false; + if ((pu.cu->rribcFlipType == 1 && cMv.getHor() != mvPredQuadPel.getHor()) || (pu.cu->rribcFlipType == 2 && cMv.getVer() != mvPredQuadPel.getVer()) || (pu.cu->rribcFlipType == 0 && cMv != mvPredQuadPel)) + { + diffMV = true; + } + if ((bitsBVPQP < bitsBVPBest) && diffMV) +#else if (bitsBVPQP < bitsBVPBest && cMv != mvPredQuadPel) +#endif { bitsBVPBest = bitsBVPQP; bvpIdxBest = bvpIdxTemp; @@ -1751,16 +2326,36 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const } #endif + pu.bv = cMv; // bv is always at integer accuracy cMv.changePrecision(MV_PRECISION_INT, MV_PRECISION_INTERNAL); pu.mv[REF_PIC_LIST_0] = cMv; // store in fractional pel accuracy pu.mvpIdx[REF_PIC_LIST_0] = bvpIdxBest; - if(pu.cu->imv == 2 && cMv != amvpInfo4Pel.mvCand[bvpIdxBest]) +#if JVET_AA0070_RRIBC + if (pu.cu->imv == 2 && cMv != amvpInfo4Pel[pu.cu->rribcFlipType].mvCand[bvpIdxBest]) + { + pu.mvd[REF_PIC_LIST_0] = cMv - amvpInfo4Pel[pu.cu->rribcFlipType].mvCand[bvpIdxBest]; + } + else + { + pu.mvd[REF_PIC_LIST_0] = cMv - amvpInfo[pu.cu->rribcFlipType].mvCand[bvpIdxBest]; + } + if (pu.cu->rribcFlipType == 1) + { + pu.mvd[REF_PIC_LIST_0].setVer(0); + } + else if (pu.cu->rribcFlipType == 2) + { + pu.mvd[REF_PIC_LIST_0].setHor(0); + } +#else + if (pu.cu->imv == 2 && cMv != amvpInfo4Pel.mvCand[bvpIdxBest]) pu.mvd[REF_PIC_LIST_0] = cMv - amvpInfo4Pel.mvCand[bvpIdxBest]; else pu.mvd[REF_PIC_LIST_0] = cMv - amvpInfo.mvCand[bvpIdxBest]; +#endif if (pu.mvd[REF_PIC_LIST_0] == Mv(0, 0)) pu.cu->imv = 0; @@ -1776,11 +2371,61 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const return true; } -void InterSearch::xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred, Mv &mv, int& idxMvPred, IbcHashMap& ibcHashMap) +#if JVET_AA0070_RRIBC +void InterSearch::xxIBCHashSearch(PredictionUnit &pu, Mv mvPred[3][2], int numMvPred, Mv &mv, int &idxMvPred, IbcHashMap &ibcHashMap, AMVPInfo amvpInfo4Pel[3], int numRribcType) +#else +void InterSearch::xxIBCHashSearch(PredictionUnit &pu, Mv *mvPred, int numMvPred, Mv &mv, int &idxMvPred, IbcHashMap &ibcHashMap) +#endif { mv.setZero(); m_pcRdCost->setCostScale(0); +#if JVET_AA0070_RRIBC + const unsigned int lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth(); + const int cuPelX = pu.Y().x; + const int cuPelY = pu.Y().y; + const int picWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples(); + const int picHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples(); + int roiWidth = pu.lwidth(); + int roiHeight = pu.lheight(); +#if JVET_Z0131_IBC_BVD_BINARIZATION + Distortion minCost = MAX_UINT64; + m_pcRdCost->setPredictors(mvPred); +#else + unsigned int minCost = MAX_UINT; +#endif + + std::vector<Position> candPos[3]; + bool isHashMatch[3] = { false }; + for (int rribcFlipType = 0; rribcFlipType < numRribcType; rribcFlipType++) + { + if(rribcFlipType && m_pcEncCfg->getIntraPeriod() <= 1) + { + Distortion th = m_pcEncCfg->getIntraPeriod() == -1 ? 50 : 200; + if ((minCost < th) || (!isHashMatch[rribcFlipType - 1])) + { + continue; + } + } + else if (rribcFlipType) + { + if (minCost < 100 || (rribcFlipType == 1 && !isHashMatch[0]) || (rribcFlipType == 2 && !isHashMatch[0] && !isHashMatch[1])) + { + continue; + } + } + isHashMatch[rribcFlipType] = ibcHashMap.ibcHashMatch(pu, pu.Y(), candPos[rribcFlipType], *pu.cs, m_pcEncCfg->getIBCHashSearchMaxCand(), m_pcEncCfg->getIBCHashSearchRange4SmallBlk(), rribcFlipType); + if (!isHashMatch[rribcFlipType]) + { + continue; + } + for (std::vector<Position>::iterator pos = candPos[rribcFlipType].begin(); pos != candPos[rribcFlipType].end(); pos++) + { + if ((rribcFlipType == 1 && (*pos - pu.Y().pos()).y != 0) || (rribcFlipType == 2 && (*pos - pu.Y().pos()).x != 0)) + { + continue; + } +#else std::vector<Position> candPos; if (ibcHashMap.ibcHashMatch(pu.Y(), candPos, *pu.cs, m_pcEncCfg->getIBCHashSearchMaxCand(), m_pcEncCfg->getIBCHashSearchRange4SmallBlk())) { @@ -1801,6 +2446,7 @@ void InterSearch::xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred, for (std::vector<Position>::iterator pos = candPos.begin(); pos != candPos.end(); pos++) { +#endif Position bottomRight = pos->offset(pu.Y().width - 1, pu.Y().height - 1); if (pu.cs->isDecomp(*pos, CHANNEL_TYPE_LUMA) && pu.cs->isDecomp(bottomRight, CHANNEL_TYPE_LUMA)) { @@ -1817,25 +2463,44 @@ void InterSearch::xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred, continue; } + #if JVET_Z0131_IBC_BVD_BINARIZATION +#if JVET_AA0070_RRIBC +#if JVET_Z0084_IBC_TM && IBC_TM_AMVP + Distortion cost = m_pcRdCost->getBvCostMultiplePreds(candMv.getHor(), candMv.getVer(), pu.cs->sps->getAMVREnabledFlag(), rribcFlipType, &pu.cu->imv, &idxMvPred, true, &amvpInfo4Pel[rribcFlipType]); +#else + Distortion cost = m_pcRdCost->getBvCostMultiplePreds(candMv.getHor(), candMv.getVer(), pu.cs->sps->getAMVREnabledFlag(), rribcFlipType, &pu.cu->imv, &idxMvPred); +#endif +#else Distortion cost = m_pcRdCost->getBvCostMultiplePreds(candMv.getHor(), candMv.getVer(), pu.cs->sps->getAMVREnabledFlag()); +#endif if (cost < minCost) { mv = candMv; minCost = cost; +#if JVET_AA0070_RRIBC + pu.cu->rribcFlipType = rribcFlipType; +#endif } #else for (int n = 0; n < numMvPred; n++) { +#if JVET_AA0070_RRIBC + m_pcRdCost->setPredictor(mvPred[rribcFlipType][n]); + unsigned int cost = m_pcRdCost->getBitsOfVectorWithPredictor(candMv.getHor(), candMv.getVer(), 0, rribcFlipType); +#else m_pcRdCost->setPredictor(mvPred[n]); - unsigned int cost = m_pcRdCost->getBitsOfVectorWithPredictor(candMv.getHor(), candMv.getVer(), 0); +#endif if (cost < minCost) { mv = candMv; idxMvPred = n; minCost = cost; +#if JVET_AA0070_RRIBC + pu.cu->rribcFlipType = rribcFlipType; +#endif } int costQuadPel = MAX_UINT; @@ -1845,13 +2510,22 @@ void InterSearch::xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred, int imvShift = 2; int offset = 1 << (imvShift - 1); +#if JVET_AA0070_RRIBC + int x = (mvPred[rribcFlipType][n].hor + offset - (mvPred[rribcFlipType][n].hor >= 0)) >> 2; + int y = (mvPred[rribcFlipType][n].ver + offset - (mvPred[rribcFlipType][n].ver >= 0)) >> 2; +#else int x = (mvPred[n].hor + offset - (mvPred[n].hor >= 0)) >> 2; int y = (mvPred[n].ver + offset - (mvPred[n].ver >= 0)) >> 2; +#endif mvPredQuadPel.set(x, y); m_pcRdCost->setPredictor(mvPredQuadPel); +#if JVET_AA0070_RRIBC + costQuadPel = m_pcRdCost->getBitsOfVectorWithPredictor(candMv.getHor() >> 2, candMv.getVer() >> 2, 0, rribcFlipType); +#else costQuadPel = m_pcRdCost->getBitsOfVectorWithPredictor(candMv.getHor() >> 2, candMv.getVer() >> 2, 0); +#endif } if (costQuadPel < minCost) @@ -1859,6 +2533,9 @@ void InterSearch::xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred, mv = candMv; idxMvPred = n; minCost = costQuadPel; +#if JVET_AA0070_RRIBC + pu.cu->rribcFlipType = rribcFlipType; +#endif } } @@ -1866,7 +2543,6 @@ void InterSearch::xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred, } } } - } @@ -9897,6 +10573,14 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa else { cs.getRecoBuf().copyFrom( cs.getPredBuf() ); +#if JVET_AA0070_RRIBC + if (CU::isIBC(cu) && cu.rribcFlipType) + { + cs.getRecoBuf().Y().flipSignal(cu.rribcFlipType == 1); + cs.getRecoBuf().Cb().flipSignal(cu.rribcFlipType == 1); + cs.getRecoBuf().Cr().flipSignal(cu.rribcFlipType == 1); + } +#endif } // add empty TU(s) @@ -9968,19 +10652,65 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa } else { +#if JVET_AA0070_RRIBC + if (CU::isIBC(cu) && cu.rribcFlipType) + { + PelBuf tmpPattern; + CompArea tmpArea(COMPONENT_Y, cu.chromaFormat, Position(0, 0), Size(cs.getOrgBuf(COMPONENT_Y).width, cs.getOrgBuf(COMPONENT_Y).height)); + tmpPattern = m_tmpStorageLCU.getBuf(tmpArea); + tmpPattern.copyFrom(cs.getOrgBuf(COMPONENT_Y)); + tmpPattern.flipSignal(cu.rribcFlipType == 1); + cs.getResiBuf(COMPONENT_Y).rspSignalAndSubtract(tmpPattern, cs.getPredBuf(COMPONENT_Y), m_pcReshape->getFwdLUT()); + } + else +#endif cs.getResiBuf( COMPONENT_Y ).rspSignalAndSubtract( cs.getOrgBuf( COMPONENT_Y ), cs.getPredBuf( COMPONENT_Y ), m_pcReshape->getFwdLUT() ); } } else { +#if JVET_AA0070_RRIBC + if (CU::isIBC(cu) && cu.rribcFlipType) + { + PelBuf tmpPattern; + CompArea tmpArea(COMPONENT_Y, cu.chromaFormat, Position(0, 0), Size(cs.getOrgBuf(COMPONENT_Y).width, cs.getOrgBuf(COMPONENT_Y).height)); + tmpPattern = m_tmpStorageLCU.getBuf(tmpArea); + tmpPattern.copyFrom(cs.getOrgBuf(COMPONENT_Y)); + tmpPattern.flipSignal(cu.rribcFlipType == 1); + cs.getResiBuf(COMPONENT_Y).subtract(tmpPattern, cs.getPredBuf(COMPONENT_Y)); + } + else +#endif cs.getResiBuf( COMPONENT_Y ).subtract( cs.getOrgBuf( COMPONENT_Y ), cs.getPredBuf( COMPONENT_Y ) ); } } if( chroma && isChromaEnabled( cs.pcv->chrFormat ) ) { +#if JVET_AA0070_RRIBC + if (CU::isIBC(cu) && cu.rribcFlipType) + { + PelBuf tmpPattern; + CompArea tmpArea1(COMPONENT_Cb, cu.chromaFormat, Position(0, 0), Size(cs.getOrgBuf(COMPONENT_Cb).width, cs.getOrgBuf(COMPONENT_Cb).height)); + tmpPattern = m_tmpStorageLCU.getBuf(tmpArea1); + tmpPattern.copyFrom(cs.getOrgBuf(COMPONENT_Cb)); + tmpPattern.flipSignal(cu.rribcFlipType == 1); + cs.getResiBuf(COMPONENT_Cb).subtract(tmpPattern, cs.getPredBuf(COMPONENT_Cb)); + + CompArea tmpArea2(COMPONENT_Cr, cu.chromaFormat, Position(0, 0), Size(cs.getOrgBuf(COMPONENT_Cr).width, cs.getOrgBuf(COMPONENT_Cr).height)); + tmpPattern = m_tmpStorageLCU.getBuf(tmpArea2); + tmpPattern.copyFrom(cs.getOrgBuf(COMPONENT_Cr)); + tmpPattern.flipSignal(cu.rribcFlipType == 1); + cs.getResiBuf(COMPONENT_Cr).subtract(tmpPattern, cs.getPredBuf(COMPONENT_Cr)); + } + else + { +#endif cs.getResiBuf( COMPONENT_Cb ).subtract( cs.getOrgBuf( COMPONENT_Cb ), cs.getPredBuf( COMPONENT_Cb ) ); cs.getResiBuf( COMPONENT_Cr ).subtract( cs.getOrgBuf( COMPONENT_Cr ), cs.getPredBuf( COMPONENT_Cr ) ); +#if JVET_AA0070_RRIBC + } +#endif } const UnitArea curUnitArea = partitioner.currArea(); @@ -10259,7 +10989,14 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa } else { - cs.getRecoBuf( COMPONENT_Y ).reconstruct( cs.getPredBuf( COMPONENT_Y ), cs.getResiBuf( COMPONENT_Y ), cs.slice->clpRng( COMPONENT_Y ) ); + cs.getRecoBuf(COMPONENT_Y) + .reconstruct(cs.getPredBuf(COMPONENT_Y), cs.getResiBuf(COMPONENT_Y), cs.slice->clpRng(COMPONENT_Y)); +#if JVET_AA0070_RRIBC + if (CU::isIBC(cu) && cu.rribcFlipType) + { + cs.getRecoBuf(COMPONENT_Y).flipSignal(cu.rribcFlipType == 1); + } +#endif } } else @@ -10273,12 +11010,25 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa { cs.getRecoBuf().bufs[0].rspSignal(m_pcReshape->getFwdLUT()); } +#if JVET_AA0070_RRIBC + if (CU::isIBC(cu) && cu.rribcFlipType) + { + cs.getRecoBuf().bufs[0].flipSignal(cu.rribcFlipType == 1); + } +#endif } } if (chroma && isChromaEnabled(cs.pcv->chrFormat)) { cs.getRecoBuf().bufs[1].reconstruct(cs.getPredBuf().bufs[1], cs.getResiBuf().bufs[1], cs.slice->clpRngs().comp[1]); cs.getRecoBuf().bufs[2].reconstruct(cs.getPredBuf().bufs[2], cs.getResiBuf().bufs[2], cs.slice->clpRngs().comp[2]); +#if JVET_AA0070_RRIBC + if (CU::isIBC(cu) && cu.rribcFlipType) + { + cs.getRecoBuf().bufs[1].flipSignal(cu.rribcFlipType == 1); + cs.getRecoBuf().bufs[2].flipSignal(cu.rribcFlipType == 1); + } +#endif } // update with clipped distortion and cost (previously unclipped reconstruction values were used) diff --git a/source/Lib/EncoderLib/InterSearch.h b/source/Lib/EncoderLib/InterSearch.h index 7cd239f081b9905d7642d7973963ebfd8a15b18c..6340850c4b848acaf70331d70443ec58dca71abe 100644 --- a/source/Lib/EncoderLib/InterSearch.h +++ b/source/Lib/EncoderLib/InterSearch.h @@ -121,6 +121,9 @@ struct ModeInfo #if JVET_X0049_ADAPT_DMVR bool isBMMrg; uint8_t bmDir; +#endif +#if JVET_AA0070_RRIBC + int rribcFlipType; #endif bool isGeo; uint8_t geoSplitDir; @@ -147,6 +150,9 @@ struct ModeInfo #if JVET_X0049_ADAPT_DMVR , isBMMrg(false) , bmDir(0) +#endif +#if JVET_AA0070_RRIBC + , rribcFlipType(0) #endif , isGeo(false), geoSplitDir(0), geoMergeIdx0(0), geoMergeIdx1(0) #if ENABLE_OBMC @@ -224,6 +230,9 @@ struct ModeInfo #if JVET_X0049_ADAPT_DMVR isBMMrg = pu.bmMergeFlag; bmDir = pu.bmDir; +#endif +#if JVET_AA0070_RRIBC + rribcFlipType = cu.rribcFlipType; #endif isGeo = cu.geoFlag; geoSplitDir = pu.geoSplitDir; @@ -314,6 +323,9 @@ private: BcwMotionParam m_uniMotions; bool m_affineModeSelected; std::unordered_map< Position, std::unordered_map< Size, BlkRecord> > m_ctuRecord; +#if JVET_AA0070_RRIBC + Distortion minCostProj; +#endif AffineMVInfo *m_affMVList; int m_affMVListIdx; int m_affMVListSize; @@ -658,8 +670,13 @@ 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 + bool predIBCSearch ( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap, bool isSecondPass = false ); + void xIntraPatternSearch ( PredictionUnit& pu, IntTZSearchStruct& cStruct, Mv& rcMv, Distortion& ruiCost, Mv* cMvSrchRngLT, Mv* cMvSrchRngRB, Mv* pcMvPred, int rribcFlipType ); +#else bool predIBCSearch ( CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap); - void xIntraPatternSearch ( PredictionUnit& pu, IntTZSearchStruct& cStruct, Mv& rcMv, Distortion& ruiCost, Mv* cMvSrchRngLT, Mv* cMvSrchRngRB, Mv* pcMvPred); + 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); void resetIbcSearch() { @@ -669,9 +686,15 @@ public: } m_defaultCachedBvs.currCnt = 0; } +#if JVET_AA0070_RRIBC + void xIBCEstimation(PredictionUnit &pu, PelUnitBuf &origBuf, Mv pcMvPred[3][2], Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY, int numRribcType); + 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 void xIBCEstimation ( PredictionUnit& pu, PelUnitBuf& origBuf, Mv *pcMvPred, Mv &rcMv, Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY); 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 xIBCSearchMVChromaRefine( PredictionUnit& pu, int iRoiWidth, int iRoiHeight, int cuPelX, int cuPelY, Distortion* uiSadBestCand, Mv* cMVCand ); +#endif void addToSortList(std::list<BlockHash>& listBlockHash, std::list<int>& listCost, int cost, const BlockHash& blockHash); bool predInterHashSearch(CodingUnit& cu, Partitioner& partitioner, bool& isPerfectMatch); bool xHashInterEstimation(PredictionUnit& pu, RefPicList& bestRefPicList, int& bestRefIndex, Mv& bestMv, Mv& bestMvd, int& bestMVPIndex, bool& isPerfectMatch); @@ -989,7 +1012,11 @@ protected: void setWpScalingDistParam ( int iRefIdx, RefPicList eRefPicListCur, Slice *slice ); private: +#if JVET_AA0070_RRIBC + void xxIBCHashSearch(PredictionUnit &pu, Mv mvPred[3][2], int numMvPred, Mv &mv, int &idxMvPred, IbcHashMap &ibcHashMap, AMVPInfo amvpInfo4Pel[3], int numRribcType); +#else void xxIBCHashSearch(PredictionUnit& pu, Mv* mvPred, int numMvPred, Mv &mv, int& idxMvPred, IbcHashMap& ibcHashMap); +#endif public: #if JVET_AA0133_INTER_MTS_OPT bool encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &partitioner, const bool &skipResidual diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 0611d87735f235c2e1c738f353f454da6c270974..9da96f496113ef5f5d948d83f6d52226b6867947 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -1545,6 +1545,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) { CHECK(pcSPS->getMaxNumIBCMergeCand() > IBC_MRG_MAX_NUM_CANDS, "More IBC merge candidates signalled than supported"); 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_S0074_SPS_REORDER WRITE_FLAG(pcSPS->getUseLmcs() ? 1 : 0, "sps_lmcs_enable_flag");