From f3beea87986aa7db4a121d000036575ec1e58908 Mon Sep 17 00:00:00 2001 From: Frank Bossen <fbossen@gmail.com> Date: Sat, 3 Sep 2022 11:03:45 -0400 Subject: [PATCH] Clean up MMVD related code --- source/Lib/CommonLib/CommonDef.h | 27 +++- source/Lib/CommonLib/ContextModelling.cpp | 33 ++-- source/Lib/CommonLib/ContextModelling.h | 10 +- source/Lib/CommonLib/Rom.cpp | 3 + source/Lib/CommonLib/Unit.cpp | 2 +- source/Lib/CommonLib/Unit.h | 26 ++-- source/Lib/CommonLib/UnitTools.cpp | 6 +- source/Lib/CommonLib/UnitTools.h | 2 +- .../Lib/CommonLib/dtrace_blockstatistics.cpp | 6 +- source/Lib/DecoderLib/CABACReader.cpp | 29 +--- source/Lib/DecoderLib/DecCu.cpp | 5 +- source/Lib/EncoderLib/CABACWriter.cpp | 19 ++- source/Lib/EncoderLib/EncCu.cpp | 145 +++++++++--------- 13 files changed, 158 insertions(+), 155 deletions(-) diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index 238f9fb4d6..fbe683a8dc 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -351,13 +351,32 @@ static constexpr int LAST_SIGNIFICANT_GROUPS = 14; static constexpr int AFFINE_SUBBLOCK_SIZE = 4; // Minimum affine MC block size -static constexpr int MMVD_REFINE_STEP = 8; ///< max number of distance step -static constexpr int MMVD_MAX_REFINE_NUM = (MMVD_REFINE_STEP * 4); ///< max number of candidate from a base candidate -static constexpr int MMVD_BASE_MV_NUM = 2; ///< max number of base candidate -static constexpr int MMVD_ADD_NUM = (MMVD_MAX_REFINE_NUM * MMVD_BASE_MV_NUM);///< total number of mmvd candidate static constexpr int MMVD_MRG_MAX_RD_NUM = MRG_MAX_NUM_CANDS; static constexpr int MMVD_MRG_MAX_RD_BUF_NUM = (MMVD_MRG_MAX_RD_NUM + 1);///< increase buffer size by 1 +union MmvdIdx +{ + using T = uint8_t; + + static constexpr int LOG_REFINE_STEP = 3; + static constexpr int REFINE_STEP = 1 << LOG_REFINE_STEP; + static constexpr int LOG_BASE_MV_NUM = 1; + static constexpr int BASE_MV_NUM = 1 << LOG_BASE_MV_NUM; + static constexpr int MAX_REFINE_NUM = 4 * REFINE_STEP; + static constexpr int ADD_NUM = MAX_REFINE_NUM * BASE_MV_NUM; + static constexpr int INVALID = std::numeric_limits<T>::max(); + + struct + { + T baseIdx : LOG_BASE_MV_NUM; + T step : LOG_REFINE_STEP; + T position : 2; + } pos; + T val; +}; + +static_assert(sizeof(MmvdIdx::val) == sizeof(MmvdIdx::pos), "MmvdIdx::val is not wide enough"); + static constexpr int MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA = 28; static constexpr int MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA = 28; diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp index 317ad46982..6b533676bc 100644 --- a/source/Lib/CommonLib/ContextModelling.cpp +++ b/source/Lib/CommonLib/ContextModelling.cpp @@ -411,16 +411,9 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx ) pu.mmvdEncOptMode = 0; } -void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx) +void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit &pu, const MmvdIdx candIdx) { const Slice &slice = *pu.cs->slice; - const int mvShift = MV_FRACTIONAL_BITS_DIFF; - const int refMvdCands[8] = { 1 << mvShift , 2 << mvShift , 4 << mvShift , 8 << mvShift , 16 << mvShift , 32 << mvShift, 64 << mvShift , 128 << mvShift }; - int fPosGroup = 0; - int fPosBaseIdx = 0; - int fPosStep = 0; - int tempIdx = 0; - int fPosPosition = 0; Mv tempMv[2]; #if GDR_ENABLED @@ -428,14 +421,11 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx) const bool isEncodeGdrClean = cs.sps->getGDREnabledFlag() && cs.pcv->isEncoder && ((cs.picHeader->getInGdrInterval() && cs.isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs.picHeader->getNumVerVirtualBoundaries() == 0)); #endif - tempIdx = candIdx; - fPosGroup = tempIdx / (MMVD_BASE_MV_NUM * MMVD_MAX_REFINE_NUM); - tempIdx = tempIdx - fPosGroup * (MMVD_BASE_MV_NUM * MMVD_MAX_REFINE_NUM); - fPosBaseIdx = tempIdx / MMVD_MAX_REFINE_NUM; - tempIdx = tempIdx - fPosBaseIdx * (MMVD_MAX_REFINE_NUM); - fPosStep = tempIdx / 4; - fPosPosition = tempIdx - fPosStep * (4); - int offset = refMvdCands[fPosStep]; + const int fPosBaseIdx = candIdx.pos.baseIdx; + const int fPosStep = candIdx.pos.step; + const int fPosPosition = candIdx.pos.position; + + int offset = 1 << (fPosStep + MV_FRACTIONAL_BITS_DIFF); if ( pu.cu->slice->getPicHeader()->getDisFracMMVD() ) { offset <<= 2; @@ -625,12 +615,13 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx) #endif } - pu.mmvdMergeFlag = true; - pu.mmvdMergeIdx = candIdx; - pu.mergeFlag = true; + pu.mmvdMergeFlag = true; + pu.mmvdMergeIdx = candIdx; + pu.mergeFlag = true; pu.regularMergeFlag = true; - pu.mergeIdx = candIdx; - pu.mergeType = MRG_TYPE_DEFAULT_N; + pu.mergeIdx = candIdx.val; + pu.mergeType = MRG_TYPE_DEFAULT_N; + pu.mvd[REF_PIC_LIST_0] = Mv(); pu.mvd[REF_PIC_LIST_1] = Mv(); pu.mvpIdx[REF_PIC_LIST_0] = NOT_VALID; diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h index e56515b81b..1891741e68 100644 --- a/source/Lib/CommonLib/ContextModelling.h +++ b/source/Lib/CommonLib/ContextModelling.h @@ -619,13 +619,13 @@ public: MotionBuf subPuMvpMiBuf; MotionBuf subPuMvpExtMiBuf; - MvField mmvdBaseMv[MMVD_BASE_MV_NUM][2]; + MvField mmvdBaseMv[MmvdIdx::BASE_MV_NUM][2]; #if GDR_ENABLED - bool mmvdSolid[MMVD_BASE_MV_NUM][2]; - bool mmvdValid[MMVD_BASE_MV_NUM][2]; + bool mmvdSolid[MmvdIdx::BASE_MV_NUM][2]; + bool mmvdValid[MmvdIdx::BASE_MV_NUM][2]; #endif - void setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx); - bool mmvdUseAltHpelIf [ MMVD_BASE_MV_NUM ]; + void setMmvdMergeCandiInfo(PredictionUnit &pu, MmvdIdx candIdx); + bool mmvdUseAltHpelIf[MmvdIdx::BASE_MV_NUM]; bool useAltHpelIf [ MRG_MAX_NUM_CANDS ]; void setMergeInfo( PredictionUnit& pu, int candIdx ); }; diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp index b88e90ae46..ecb5702f41 100644 --- a/source/Lib/CommonLib/Rom.cpp +++ b/source/Lib/CommonLib/Rom.cpp @@ -44,6 +44,9 @@ #include <math.h> #include <iomanip> +constexpr int MmvdIdx::ADD_NUM; +constexpr int MmvdIdx::BASE_MV_NUM; + // ==================================================================================================================== // Initialize / destroy functions // ==================================================================================================================== diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index cab7cd4aae..2b113f8380 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -542,7 +542,7 @@ void PredictionUnit::initData() geoMergeIdx0 = MAX_UCHAR; geoMergeIdx1 = MAX_UCHAR; mmvdMergeFlag = false; - mmvdMergeIdx = MAX_UINT; + mmvdMergeIdx.val = MmvdIdx::INVALID; interDir = MAX_UCHAR; mergeType = MRG_TYPE_DEFAULT_N; bv.setZero(); diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index 5f7e1b8d79..b86e9089ab 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -383,19 +383,19 @@ struct IntraPredictionData struct InterPredictionData { - bool mergeFlag; - bool regularMergeFlag; - uint8_t mergeIdx; - uint8_t geoSplitDir; - uint8_t geoMergeIdx0; - uint8_t geoMergeIdx1; - bool mmvdMergeFlag; - uint32_t mmvdMergeIdx; - uint8_t interDir; - uint8_t mvpIdx [NUM_REF_PIC_LIST_01]; - uint8_t mvpNum [NUM_REF_PIC_LIST_01]; - Mv mvd [NUM_REF_PIC_LIST_01]; - Mv mv [NUM_REF_PIC_LIST_01]; + bool mergeFlag; + bool regularMergeFlag; + uint8_t mergeIdx; + uint8_t geoSplitDir; + uint8_t geoMergeIdx0; + uint8_t geoMergeIdx1; + bool mmvdMergeFlag; + MmvdIdx mmvdMergeIdx; + uint8_t interDir; + uint8_t mvpIdx[NUM_REF_PIC_LIST_01]; + uint8_t mvpNum[NUM_REF_PIC_LIST_01]; + Mv mvd[NUM_REF_PIC_LIST_01]; + Mv mv[NUM_REF_PIC_LIST_01]; #if GDR_ENABLED bool mvSolid[NUM_REF_PIC_LIST_01]; bool mvValid[NUM_REF_PIC_LIST_01]; diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 5f8e1adce6..74c0473a33 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -1752,7 +1752,7 @@ int PU::getDistScaleFactor(const int &currPOC, const int &currRefPOC, const int return xGetDistScaleFactor(currPOC, currRefPOC, colPOC, colRefPOC); } -void PU::getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx) +void PU::getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx &mrgCtx) { int refIdxList0, refIdxList1; int k; @@ -1765,7 +1765,7 @@ void PU::getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, #endif #if GDR_ENABLED - for (int k = 0; k < MMVD_BASE_MV_NUM; k++) + for (int k = 0; k < MmvdIdx::BASE_MV_NUM; k++) { mrgCtx.mmvdSolid[k][0] = true; mrgCtx.mmvdSolid[k][1] = true; @@ -1818,7 +1818,7 @@ void PU::getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, currBaseNum++; - if (currBaseNum == MMVD_BASE_MV_NUM) + if (currBaseNum == MmvdIdx::BASE_MV_NUM) { break; } diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 20f9c5128c..199f2286c6 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -151,7 +151,7 @@ namespace PU void getInterMergeCandidates(const PredictionUnit &pu, MergeCtx &mrgCtx, int mmvdList, const int &mrgCandIdx = -1); void getIBCMergeCandidates (const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx = -1); - void getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const int& mrgCandIdx = -1); + void getInterMMVDMergeCandidates(const PredictionUnit &pu, MergeCtx &mrgCtx); int getDistScaleFactor(const int &currPOC, const int &currRefPOC, const int &colPOC, const int &colRefPOC); bool isDiffMER (const Position &pos1, const Position &pos2, const unsigned plevel); bool getColocatedMVP (const PredictionUnit &pu, const RefPicList &eRefPicList, const Position &pos, Mv& rcMv, const int &refIdx, bool sbFlag); diff --git a/source/Lib/CommonLib/dtrace_blockstatistics.cpp b/source/Lib/CommonLib/dtrace_blockstatistics.cpp index 0e9da1860b..a747b941e2 100644 --- a/source/Lib/CommonLib/dtrace_blockstatistics.cpp +++ b/source/Lib/CommonLib/dtrace_blockstatistics.cpp @@ -598,7 +598,8 @@ void writeAllData(const CodingStructure& cs, const UnitArea& ctuArea) DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MMVDMergeFlag), pu.mmvdMergeFlag); if (cu.mmvdSkip || pu.mmvdMergeFlag) { - DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::MMVDMergeIdx), pu.mmvdMergeIdx); + DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, + GetBlockStatisticName(BlockStatistic::MMVDMergeIdx), pu.mmvdMergeIdx.val); } DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_ALL, pu, GetBlockStatisticName(BlockStatistic::CiipFlag), pu.ciipFlag); if (pu.ciipFlag) @@ -1039,7 +1040,8 @@ void writeAllCodedData(const CodingStructure & cs, const UnitArea & ctuArea) DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, pu, GetBlockStatisticName(BlockStatistic::MMVDMergeFlag), pu.mmvdMergeFlag); if (pu.mmvdMergeFlag) { - DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, pu, GetBlockStatisticName(BlockStatistic::MMVDMergeIdx), pu.mmvdMergeIdx); + DTRACE_BLOCK_SCALAR(g_trace_ctx, D_BLOCK_STATISTICS_CODED, pu, + GetBlockStatisticName(BlockStatistic::MMVDMergeIdx), pu.mmvdMergeIdx.val); } if (!cu.cs->slice->isIntra() && cu.cs->sps->getUseAffine() && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 && !pu.mmvdMergeFlag && !cu.mmvdSkip diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index f45dbe642e..b4e58e8bc0 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -2440,16 +2440,16 @@ void CABACReader::mmvd_merge_idx(PredictionUnit& pu) int var0 = 0; if (pu.cs->sps->getMaxNumMergeCand() > 1) { - static_assert(MMVD_BASE_MV_NUM == 2, ""); + static_assert(MmvdIdx::BASE_MV_NUM == 2, ""); var0 = m_binDecoder.decodeBin(Ctx::MmvdMergeIdx()); } DTRACE(g_trace_ctx, D_SYNTAX, "base_mvp_idx() base_mvp_idx=%d\n", var0); - int numCandminus1_step = MMVD_REFINE_STEP - 1; + int numStepCandMinus1 = MmvdIdx::REFINE_STEP - 1; int var1 = 0; if (m_binDecoder.decodeBin(Ctx::MmvdStepMvpIdx())) { var1++; - for (; var1 < numCandminus1_step; var1++) + for (; var1 < numStepCandMinus1; var1++) { if (!m_binDecoder.decodeBinEP()) { @@ -2458,26 +2458,11 @@ void CABACReader::mmvd_merge_idx(PredictionUnit& pu) } } DTRACE(g_trace_ctx, D_SYNTAX, "MmvdStepMvpIdx() MmvdStepMvpIdx=%d\n", var1); - int var2 = 0; - if (m_binDecoder.decodeBinEP()) - { - var2 += 2; - if (m_binDecoder.decodeBinEP()) - { - var2 += 1; - } - } - else - { - var2 += 0; - if (m_binDecoder.decodeBinEP()) - { - var2 += 1; - } - } + const int var2 = m_binDecoder.decodeBinsEP(2); DTRACE(g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", var2); - int mvpIdx = (var0 * MMVD_MAX_REFINE_NUM + var1 * 4 + var2); - pu.mmvdMergeIdx = mvpIdx; + pu.mmvdMergeIdx.pos.position = var2; + pu.mmvdMergeIdx.pos.step = var1; + pu.mmvdMergeIdx.pos.baseIdx = var0; DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", pu.mmvdMergeIdx); } diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index d93c0a3fec..8b04e45482 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -850,9 +850,8 @@ void DecCu::xDeriveCuMvs(CodingUnit &cu) mrgCtx.subPuMvpMiBuf = MotionBuf(m_SubPuMiBuf, bufSize); } - int fPosBaseIdx = pu.mmvdMergeIdx / MMVD_MAX_REFINE_NUM; - PU::getInterMergeCandidates(pu, mrgCtx, 1, fPosBaseIdx + 1); - PU::getInterMMVDMergeCandidates(pu, mrgCtx, pu.mmvdMergeIdx); + PU::getInterMergeCandidates(pu, mrgCtx, 1, pu.mmvdMergeIdx.pos.baseIdx + 1); + PU::getInterMMVDMergeCandidates(pu, mrgCtx); mrgCtx.setMmvdMergeCandiInfo(pu, pu.mmvdMergeIdx); PU::spanMotionInfo(pu, mrgCtx); diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index ecb4cf092f..032cec744d 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -2114,21 +2114,20 @@ void CABACWriter::merge_idx( const PredictionUnit& pu ) } void CABACWriter::mmvd_merge_idx(const PredictionUnit& pu) { - int var0, var1, var2; - int mvpIdx = pu.mmvdMergeIdx; - var0 = mvpIdx / MMVD_MAX_REFINE_NUM; - var1 = (mvpIdx - (var0 * MMVD_MAX_REFINE_NUM)) / 4; - var2 = mvpIdx - (var0 * MMVD_MAX_REFINE_NUM) - var1 * 4; + const int var0 = pu.mmvdMergeIdx.pos.baseIdx; + const int var1 = pu.mmvdMergeIdx.pos.step; + const int var2 = pu.mmvdMergeIdx.pos.position; + if (pu.cs->sps->getMaxNumMergeCand() > 1) { - static_assert(MMVD_BASE_MV_NUM == 2, ""); + static_assert(MmvdIdx::BASE_MV_NUM == 2, ""); assert(var0 < 2); m_binEncoder.encodeBin(var0, Ctx::MmvdMergeIdx()); } DTRACE(g_trace_ctx, D_SYNTAX, "base_mvp_idx() base_mvp_idx=%d\n", var0); - int numCandminus1_step = MMVD_REFINE_STEP - 1; - if (numCandminus1_step > 0) + int numStepCandMinus1 = MmvdIdx::REFINE_STEP - 1; + if (numStepCandMinus1 > 0) { if (var1 == 0) { @@ -2137,7 +2136,7 @@ void CABACWriter::mmvd_merge_idx(const PredictionUnit& pu) else { m_binEncoder.encodeBin(1, Ctx::MmvdStepMvpIdx()); - for (unsigned idx = 1; idx < numCandminus1_step; idx++) + for (unsigned idx = 1; idx < numStepCandMinus1; idx++) { m_binEncoder.encodeBinEP(var1 == idx ? 0 : 1); if (var1 == idx) @@ -2152,7 +2151,7 @@ void CABACWriter::mmvd_merge_idx(const PredictionUnit& pu) m_binEncoder.encodeBinsEP(var2, 2); DTRACE(g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", var2); - DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", pu.mmvdMergeIdx); + DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", pu.mmvdMergeIdx.val); } void CABACWriter::inter_pred_idc( const PredictionUnit& pu ) diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 50b44b70da..f70ab559c4 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -2242,8 +2242,8 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& isEncodeGdrClean = cs->sps->getGDREnabledFlag() && cs->pcv->isEncoder && ((cs->picHeader->getInGdrInterval() && cs->isClean(pu.Y().topRight(), CHANNEL_TYPE_LUMA)) || (cs->picHeader->getNumVerVirtualBoundaries() == 0)); #endif } - bool candHasNoResidual[MRG_MAX_NUM_CANDS + MMVD_ADD_NUM]; - for (uint32_t ui = 0; ui < MRG_MAX_NUM_CANDS + MMVD_ADD_NUM; ui++) + bool candHasNoResidual[MRG_MAX_NUM_CANDS + MmvdIdx::ADD_NUM]; + for (uint32_t ui = 0; ui < MRG_MAX_NUM_CANDS + MmvdIdx::ADD_NUM; ui++) { candHasNoResidual[ui] = false; } @@ -2256,7 +2256,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& PelUnitBuf *acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM]; PelUnitBuf *singleMergeTempBuffer; int insertPos; - unsigned uiNumMrgSATDCand = mergeCtx.numValidMergeCand + MMVD_ADD_NUM; + unsigned numMergeSatdCand = mergeCtx.numValidMergeCand + MmvdIdx::ADD_NUM; struct ModeInfo { @@ -2269,26 +2269,24 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& mergeCand(mergeCand), isRegularMerge(isRegularMerge), isMMVD(isMMVD), isCIIP(isCIIP) {} }; - static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> RdModeList; + static_vector<ModeInfo, MRG_MAX_NUM_CANDS + MmvdIdx::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); + for (int i = 0; i < mergeCtx.numValidMergeCand; i++) + { + rdModeList.push_back(ModeInfo(i, true, false, false)); + } - for (int i = 0; i < candNum; i++) + if (tempCS->sps->getUseMMVD()) { - if (i < mergeCtx.numValidMergeCand) - { - RdModeList.push_back(ModeInfo(i, true, false, false)); - } - else + const int numMmvdCand = std::min<int>(MmvdIdx::BASE_MV_NUM, mergeCtx.numValidMergeCand) * MmvdIdx::MAX_REFINE_NUM; + for (int i = 0; i < numMmvdCand; i++) { - RdModeList.push_back(ModeInfo(std::min(MMVD_ADD_NUM, i - mergeCtx.numValidMergeCand), false, true, false)); + rdModeList.push_back(ModeInfo(i, false, true, false)); } } + bool mrgTempBufSet = false; + const UnitArea localUnitArea(tempCS->area.chromaFormat, Area(0, 0, tempCS->area.Y().width, tempCS->area.Y().height)); for (unsigned i = 0; i < MMVD_MRG_MAX_RD_BUF_NUM; i++) { @@ -2315,10 +2313,10 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } if( m_pcEncCfg->getUseFastMerge() || isIntrainterEnabled) { - uiNumMrgSATDCand = NUM_MRG_SATD_CAND; + numMergeSatdCand = NUM_MRG_SATD_CAND; if (isIntrainterEnabled) { - uiNumMrgSATDCand += 1; + numMergeSatdCand += 1; } bestIsSkip = false; @@ -2339,12 +2337,12 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& bestIsSkip = false; } - static_vector<double, MRG_MAX_NUM_CANDS + MMVD_ADD_NUM> candCostList; + static_vector<double, MRG_MAX_NUM_CANDS + MmvdIdx::ADD_NUM> candCostList; // 1. Pass: get SATD-cost for selected candidates and reduce their count if( !bestIsSkip ) { - RdModeList.clear(); + rdModeList.clear(); mrgTempBufSet = true; const TempCtx ctxStart(m_ctxPool, m_CABACEstimator->getCtx()); @@ -2444,16 +2442,17 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } } #endif - updateCandList(ModeInfo(uiMergeCand, true, false, false), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(uiMergeCand, true, false, false), cost, rdModeList, candCostList, numMergeSatdCand, + &insertPos); 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]); } @@ -2461,7 +2460,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } } #if !GDR_ENABLED - CHECK(std::min(uiMergeCand + 1, uiNumMrgSATDCand) != RdModeList.size(), ""); + CHECK(std::min(uiMergeCand + 1, numMergeSatdCand) != rdModeList.size(), ""); #endif } @@ -2474,7 +2473,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; } for (uint32_t mergeCnt = 0; mergeCnt < std::min(std::min(NUM_MRG_SATD_CAND, (const int)mergeCtx.numValidMergeCand), 4); mergeCnt++) { @@ -2554,10 +2553,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& #endif insertPos = -1; - updateCandList(ModeInfo(mergeCand, false, false, true), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(mergeCand, false, false, true), cost, rdModeList, candCostList, numMergeSatdCand, + &insertPos); 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]); } @@ -2570,12 +2570,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& { cu.mmvdSkip = true; pu.regularMergeFlag = true; - const int tempNum = (mergeCtx.numValidMergeCand > 1) ? MMVD_ADD_NUM : MMVD_ADD_NUM >> 1; + const int tempNum = (mergeCtx.numValidMergeCand > 1) ? MmvdIdx::ADD_NUM : MmvdIdx::ADD_NUM >> 1; for (int mmvdMergeCand = 0; mmvdMergeCand < tempNum; mmvdMergeCand++) { - int baseIdx = mmvdMergeCand / MMVD_MAX_REFINE_NUM; - int refineStep = (mmvdMergeCand - (baseIdx * MMVD_MAX_REFINE_NUM)) / 4; - if (refineStep >= m_pcEncCfg->getMmvdDisNum()) + MmvdIdx mmvdIdx; + mmvdIdx.val = mmvdMergeCand; + + if (mmvdIdx.pos.step >= m_pcEncCfg->getMmvdDisNum()) { continue; } @@ -2589,12 +2590,12 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& pu.mvValid[REF_PIC_LIST_1] = true; } #endif - mergeCtx.setMmvdMergeCandiInfo(pu, mmvdMergeCand); + mergeCtx.setMmvdMergeCandiInfo(pu, mmvdIdx); PU::spanMotionInfo(pu, mergeCtx); pu.mvRefine = true; distParam.cur = singleMergeTempBuffer->Y(); - pu.mmvdEncOptMode = (refineStep > 2 ? 2 : 1); + pu.mmvdEncOptMode = (mmvdIdx.pos.step > 2 ? 2 : 1); CHECK(!pu.mmvdMergeFlag, "MMVD merge should be set"); // Don't do chroma MC here m_pcInterSearch->motionCompensation(pu, *singleMergeTempBuffer, REF_PIC_LIST_X, true, false, nullptr); @@ -2631,10 +2632,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } } #endif - updateCandList(ModeInfo(mmvdMergeCand, false, true, false), cost, RdModeList, candCostList, uiNumMrgSATDCand, &insertPos); + updateCandList(ModeInfo(mmvdMergeCand, false, true, false), cost, rdModeList, candCostList, numMergeSatdCand, + &insertPos); 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]); } @@ -2643,11 +2645,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } } // Try to limit number of candidates using SATD-costs - for( uint32_t i = 1; i < uiNumMrgSATDCand; i++ ) + for (uint32_t i = 1; i < numMergeSatdCand; i++) { if( candCostList[i] > MRG_FAST_RATIO * candCostList[0] ) { - uiNumMrgSATDCand = i; + numMergeSatdCand = i; break; } } @@ -2657,9 +2659,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& if (isIntrainterEnabled && isChromaEnabled(pu.cs->pcv->chrFormat)) { pu.ciipFlag = true; - for (uint32_t mergeCnt = 0; mergeCnt < uiNumMrgSATDCand; mergeCnt++) + for (uint32_t mergeCnt = 0; mergeCnt < numMergeSatdCand; mergeCnt++) { - if (RdModeList[mergeCnt].isCIIP) + if (rdModeList[mergeCnt].isCIIP) { pu.intraDir[0] = PLANAR_IDX; pu.intraDir[1] = DM_CHROMA_IDX; @@ -2687,11 +2689,12 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& { if (bestIsMMVDSkip) { - uiNumMrgSATDCand = mergeCtx.numValidMergeCand + ((mergeCtx.numValidMergeCand > 1) ? MMVD_ADD_NUM : MMVD_ADD_NUM >> 1); + numMergeSatdCand = + mergeCtx.numValidMergeCand + ((mergeCtx.numValidMergeCand > 1) ? MmvdIdx::ADD_NUM : MmvdIdx::ADD_NUM >> 1); } else { - uiNumMrgSATDCand = mergeCtx.numValidMergeCand; + numMergeSatdCand = mergeCtx.numValidMergeCand; } } } @@ -2701,11 +2704,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& iteration = 2; for (uint32_t uiNoResidualPass = iterationBegin; uiNoResidualPass < iteration; ++uiNoResidualPass) { - for( uint32_t uiMrgHADIdx = 0; uiMrgHADIdx < uiNumMrgSATDCand; uiMrgHADIdx++ ) + for (uint32_t uiMrgHADIdx = 0; uiMrgHADIdx < numMergeSatdCand; 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]) { @@ -2734,7 +2737,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& cu.qp = encTestMode.qp; PredictionUnit &pu = tempCS->addPU( cu, partitioner.chType ); - if (uiNoResidualPass == 0 && RdModeList[uiMrgHADIdx].isCIIP) + if (uiNoResidualPass == 0 && rdModeList[uiMrgHADIdx].isCIIP) { cu.mmvdSkip = false; mergeCtx.setMergeInfo(pu, uiMergeCand); @@ -2744,11 +2747,13 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& 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; - mergeCtx.setMmvdMergeCandiInfo(pu, uiMergeCand); + MmvdIdx mmvdIdx; + mmvdIdx.val = uiMergeCand; + mergeCtx.setMmvdMergeCandiInfo(pu, mmvdIdx); } else { @@ -2818,12 +2823,12 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& } else { - if (RdModeList[uiMrgHADIdx].isMMVD) + if (rdModeList[uiMrgHADIdx].isMMVD) { pu.mmvdEncOptMode = 0; m_pcInterSearch->motionCompensatePu(pu, REF_PIC_LIST_X, true, true); } - else if (uiNoResidualPass != 0 && RdModeList[uiMrgHADIdx].isCIIP) + else if (uiNoResidualPass != 0 && rdModeList[uiMrgHADIdx].isCIIP) { tempCS->getPredBuf().copyFrom(acMergeBuffer[uiMergeCand]); } @@ -3249,7 +3254,7 @@ void EncCu::xCheckRDCostMergeGeo2Nx2N(CodingStructure *&tempCS, CodingStructure pu.geoMergeIdx0 = (uint8_t) comboList.list[candidateIdx].mergeIdx0; pu.geoMergeIdx1 = (uint8_t) comboList.list[candidateIdx].mergeIdx1; pu.mmvdMergeFlag = false; - pu.mmvdMergeIdx = MAX_UINT; + pu.mmvdMergeIdx.val = MmvdIdx::INVALID; PU::spanGeoMotionInfo(pu, mergeCtx, pu.geoSplitDir, pu.geoMergeIdx0, pu.geoMergeIdx1); PelUnitBuf geoBuf = m_geoWeightedBuffers[candidateIdx].getBuf(localUnitArea); @@ -3341,20 +3346,21 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct candHasNoResidual[ui] = false; } - 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; - bool mrgTempBufSet = false; + bool bestIsSkip = false; + bool mrgTempBufSet = false; + uint32_t numMergeSatdCand = affineMergeCtx.numValidMergeCand; + PelUnitBuf acMergeBuffer[AFFINE_MRG_MAX_NUM_CANDS]; + + static_vector<uint32_t, AFFINE_MRG_MAX_NUM_CANDS> rdModeList; for ( uint32_t i = 0; i < AFFINE_MRG_MAX_NUM_CANDS; i++ ) { - RdModeList.push_back( i ); + rdModeList.push_back(i); } if ( m_pcEncCfg->getUseFastMerge() ) { - uiNumMrgSATDCand = std::min( NUM_AFF_MRG_SATD_CAND, affineMergeCtx.numValidMergeCand ); + numMergeSatdCand = std::min(NUM_AFF_MRG_SATD_CAND, affineMergeCtx.numValidMergeCand); bestIsSkip = false; if ( auto blkCache = dynamic_cast<CacheBlkInfoCtrl*>(m_modeCtrl) ) @@ -3367,7 +3373,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; const double sqrtLambdaForFirstPass = m_pcRdCost->getMotionLambda( ); @@ -3458,18 +3464,17 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct } } #endif - updateCandList( uiMergeCand, cost, RdModeList, candCostList - , uiNumMrgSATDCand ); + updateCandList(uiMergeCand, cost, rdModeList, candCostList, numMergeSatdCand); - CHECK( std::min( uiMergeCand + 1, uiNumMrgSATDCand ) != RdModeList.size(), "" ); + CHECK(std::min(uiMergeCand + 1, numMergeSatdCand) != rdModeList.size(), ""); } // Try to limit number of candidates using SATD-costs - for ( uint32_t i = 1; i < uiNumMrgSATDCand; i++ ) + for (uint32_t i = 1; i < numMergeSatdCand; i++) { if ( candCostList[i] > MRG_FAST_RATIO * candCostList[0] ) { - uiNumMrgSATDCand = i; + numMergeSatdCand = i; break; } } @@ -3480,7 +3485,7 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct } else { - uiNumMrgSATDCand = affineMergeCtx.numValidMergeCand; + numMergeSatdCand = affineMergeCtx.numValidMergeCand; } } @@ -3489,9 +3494,9 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct iteration = 2; for (uint32_t uiNoResidualPass = iterationBegin; uiNoResidualPass < iteration; ++uiNoResidualPass) { - for ( uint32_t uiMrgHADIdx = 0; uiMrgHADIdx < uiNumMrgSATDCand; uiMrgHADIdx++ ) + for (uint32_t uiMrgHADIdx = 0; uiMrgHADIdx < numMergeSatdCand; uiMrgHADIdx++) { - uint32_t uiMergeCand = RdModeList[uiMrgHADIdx]; + uint32_t uiMergeCand = rdModeList[uiMrgHADIdx]; if ( ((uiNoResidualPass != 0) && candHasNoResidual[uiMergeCand]) || ((uiNoResidualPass == 0) && bestIsSkip) ) @@ -3718,10 +3723,10 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct 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); @@ -3832,7 +3837,7 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct } } #endif - updateCandList(mergeCand, cost, RdModeList, candCostList, numMrgSATDCand); + updateCandList(mergeCand, cost, rdModeList, candCostList, numMrgSATDCand); } // Try to limit number of candidates using SATD-costs @@ -3868,7 +3873,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))) -- GitLab