[FFmpeg-devel] [PATCH 05/11] avcodec/vvcdec: implement update_hmvp for IBC

Nuo Mi nuomi2021 at gmail.com
Thu Feb 22 09:14:00 EET 2024


From: Wu Jianhua <toqsxw at outlook.com>

Signed-off-by: Wu Jianhua <toqsxw at outlook.com>
Signed-off-by: Nuo Mi <nuomi2021 at gmail.com>
---
 libavcodec/vvc/vvc_ctu.c |  9 +++++--
 libavcodec/vvc/vvc_ctu.h |  3 +++
 libavcodec/vvc/vvc_mvs.c | 53 ++++++++++++++++++++++++++--------------
 3 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/libavcodec/vvc/vvc_ctu.c b/libavcodec/vvc/vvc_ctu.c
index 2e48f7bed8..b78a1417c7 100644
--- a/libavcodec/vvc/vvc_ctu.c
+++ b/libavcodec/vvc/vvc_ctu.c
@@ -1717,10 +1717,15 @@ static int inter_data(VVCLocalContext *lc)
     } else {
         ret = mvp_data(lc);
     }
-    if (!pu->merge_gpm_flag && !pu->inter_affine_flag && !pu->merge_subblock_flag) {
+
+    if (cu->pred_mode == MODE_IBC)
+    {
+        ff_vvc_update_hmvp(lc, mi);
+    } else if (!pu->merge_gpm_flag && !pu->inter_affine_flag && !pu->merge_subblock_flag) {
         refine_regular_subblock(lc);
         ff_vvc_update_hmvp(lc, mi);
     }
+
     if (!pu->dmvr_flag)
         fill_dmvr_info(lc->fc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
     return ret;
@@ -2394,8 +2399,8 @@ int ff_vvc_coding_tree_unit(VVCLocalContext *lc,
     int ret;
 
     if (rx == pps->ctb_to_col_bd[rx]) {
-        //fix me for ibc
         ep->num_hmvp = 0;
+        ep->num_hmvp_ibc = 0;
         ep->is_first_qg = ry == pps->ctb_to_row_bd[ry] || !ctu_idx;
     }
 
diff --git a/libavcodec/vvc/vvc_ctu.h b/libavcodec/vvc/vvc_ctu.h
index ab3fac626d..5ed331a831 100644
--- a/libavcodec/vvc/vvc_ctu.h
+++ b/libavcodec/vvc/vvc_ctu.h
@@ -357,8 +357,11 @@ typedef struct EntryPoint {
     int ctu_end;
 
     uint8_t is_first_qg;                            // first quantization group
+
     MvField hmvp[MAX_NUM_HMVP_CANDS];               ///< HmvpCandList
     int     num_hmvp;                               ///< NumHmvpCand
+    MvField hmvp_ibc[MAX_NUM_HMVP_CANDS];           ///< HmvpIbcCandList
+    int     num_hmvp_ibc;                           ///< NumHmvpIbcCand
 } EntryPoint;
 
 typedef struct VVCLocalContext {
diff --git a/libavcodec/vvc/vvc_mvs.c b/libavcodec/vvc/vvc_mvs.c
index 2ed05ad2a4..8af57e8ed3 100644
--- a/libavcodec/vvc/vvc_mvs.c
+++ b/libavcodec/vvc/vvc_mvs.c
@@ -1758,34 +1758,49 @@ static av_always_inline int is_greater_mer(const VVCFrameContext *fc, const int
            y0_br >> plevel > y0 >> plevel;
 }
 
-//8.5.2.16 Updating process for the history-based motion vector predictor candidate list
-void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi)
+static void update_hmvp(MvField *hmvp, int *num_hmvp, const MvField *mvf,
+    int (*compare)(const MvField *n, const MvField *o))
 {
-    const VVCFrameContext *fc   = lc->fc;
-    const CodingUnit *cu        = lc->cu;
-    const int min_pu_width      = fc->ps.pps->min_pu_width;
-    const MvField* tab_mvf      = fc->tab.mvf;
-    EntryPoint* ep              = lc->ep;
-    const MvField *mvf;
     int i;
-
-    if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height))
-        return;
-    mvf = &TAB_MVF(cu->x0, cu->y0);
-
-    for (i = 0; i < ep->num_hmvp; i++) {
-        if (compare_mv_ref_idx(mvf, ep->hmvp + i)) {
-            ep->num_hmvp--;
+    for (i = 0; i < *num_hmvp; i++) {
+        if (compare(mvf, hmvp + i)) {
+            (*num_hmvp)--;
             break;
         }
     }
     if (i == MAX_NUM_HMVP_CANDS) {
-        ep->num_hmvp--;
+        (*num_hmvp)--;
         i = 0;
     }
 
-    memmove(ep->hmvp + i, ep->hmvp + i + 1, (ep->num_hmvp - i) * sizeof(MvField));
-    ep->hmvp[ep->num_hmvp++] = *mvf;
+    memmove(hmvp + i, hmvp + i + 1, (*num_hmvp - i) * sizeof(MvField));
+    hmvp[(*num_hmvp)++] = *mvf;
+}
+
+static int compare_l0_mv(const MvField *n, const MvField *o)
+{
+    return IS_SAME_MV(&n->mv[L0], &o->mv[L0]);
+}
+
+//8.6.2.4 Derivation process for IBC history-based block vector candidates
+//8.5.2.16 Updating process for the history-based motion vector predictor candidate list
+void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi)
+{
+    const VVCFrameContext *fc   = lc->fc;
+    const CodingUnit *cu        = lc->cu;
+    const int min_pu_width      = fc->ps.pps->min_pu_width;
+    const MvField *tab_mvf      = fc->tab.mvf;
+    EntryPoint *ep              = lc->ep;
+
+    if (cu->pred_mode == MODE_IBC) {
+        if (cu->cb_width * cu->cb_height <= 16)
+            return;
+        update_hmvp(ep->hmvp_ibc, &ep->num_hmvp_ibc, &TAB_MVF(cu->x0, cu->y0), compare_l0_mv);
+    } else {
+        if (!is_greater_mer(fc, cu->x0, cu->y0, cu->x0 + cu->cb_width, cu->y0 + cu->cb_height))
+            return;
+        update_hmvp(ep->hmvp, &ep->num_hmvp, &TAB_MVF(cu->x0, cu->y0), compare_mv_ref_idx);
+    }
 }
 
 MvField* ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0)
-- 
2.25.1



More information about the ffmpeg-devel mailing list