[FFmpeg-cvslog] lavc/vvc: Use a bitfield to store MIP information

Frank Plowman git at videolan.org
Sat Dec 7 11:40:24 EET 2024


ffmpeg | branch: master | Frank Plowman <post at frankplowman.com> | Tue Dec  3 20:47:25 2024 +0000| [34c6ad0a077aea97068fe63502e2edd761891d9d] | committer: Nuo Mi

lavc/vvc: Use a bitfield to store MIP information

Reduces memory consumption by ~4MB for 1080p video with a maximum delay
of 16 frames by packing various information related to MIP:
* intra_mip_flag, 1 bit
* intra_mip_transposed_flag, 1 bit
* intra_mip_mode, 4 bits
Into a single byte.

Co-authored-by: Nuo Mi <nuomi2021 at gmail.com>
Signed-off-by: Frank Plowman <post at frankplowman.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=34c6ad0a077aea97068fe63502e2edd761891d9d
---

 libavcodec/vvc/cabac.c          | 10 +++++++++-
 libavcodec/vvc/ctu.c            | 12 +++++++++---
 libavcodec/vvc/dec.c            |  2 --
 libavcodec/vvc/dec.h            |  4 +---
 libavcodec/vvc/dsp.c            |  9 +++++++++
 libavcodec/vvc/intra_template.c |  5 +++--
 6 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/libavcodec/vvc/cabac.c b/libavcodec/vvc/cabac.c
index 0d45eec751..5510144893 100644
--- a/libavcodec/vvc/cabac.c
+++ b/libavcodec/vvc/cabac.c
@@ -1257,11 +1257,19 @@ int ff_vvc_pred_mode_ibc_flag(VVCLocalContext *lc, const int is_chroma)
     return GET_CABAC(PRED_MODE_IBC_FLAG + inc);
 }
 
+static av_always_inline
+uint8_t get_mip_inc(VVCLocalContext *lc, const uint8_t *ctx)
+{
+    uint8_t left = 0, top = 0;
+    get_left_top(lc, &left, &top, lc->cu->x0, lc->cu->y0, ctx, ctx);
+    return (left & 1) + (top & 1);
+}
+
 int ff_vvc_intra_mip_flag(VVCLocalContext *lc, const uint8_t *intra_mip_flag)
 {
     const int w   = lc->cu->cb_width;
     const int h   = lc->cu->cb_height;
-    const int inc =  (w > h * 2 || h > w * 2) ? 3 : get_inc(lc, intra_mip_flag);
+    const int inc =  (w > h * 2 || h > w * 2) ? 3 : get_mip_inc(lc, intra_mip_flag);
     return GET_CABAC(INTRA_MIP_FLAG + inc);
 }
 
diff --git a/libavcodec/vvc/ctu.c b/libavcodec/vvc/ctu.c
index 126748360c..3624337fd7 100644
--- a/libavcodec/vvc/ctu.c
+++ b/libavcodec/vvc/ctu.c
@@ -946,6 +946,12 @@ static void derive_chroma_intra_pred_mode(VVCLocalContext *lc,
     }
 }
 
+static av_always_inline uint8_t pack_mip_info(int intra_mip_flag,
+    int intra_mip_transposed_flag, int intra_mip_mode)
+{
+    return (intra_mip_mode << 2) | (intra_mip_transposed_flag << 1) | intra_mip_flag;
+}
+
 static void intra_luma_pred_modes(VVCLocalContext *lc)
 {
     VVCFrameContext *fc             = lc->fc;
@@ -974,9 +980,9 @@ static void intra_luma_pred_modes(VVCLocalContext *lc)
             int x = y_cb * pps->min_cb_width + x_cb;
             for (int y = 0; y < (cb_height>>log2_min_cb_size); y++) {
                 int width = cb_width>>log2_min_cb_size;
-                memset(&fc->tab.imf[x],  cu->intra_mip_flag, width);
-                memset(&fc->tab.imtf[x], intra_mip_transposed_flag, width);
-                memset(&fc->tab.imm[x], intra_mip_mode, width);
+                const uint8_t mip_info = pack_mip_info(cu->intra_mip_flag,
+                        intra_mip_transposed_flag, intra_mip_mode);
+                memset(&fc->tab.imf[x], mip_info, width);
                 x += pps->min_cb_width;
             }
             cu->intra_pred_mode_y = intra_mip_mode;
diff --git a/libavcodec/vvc/dec.c b/libavcodec/vvc/dec.c
index 50be9f9922..fef7339294 100644
--- a/libavcodec/vvc/dec.c
+++ b/libavcodec/vvc/dec.c
@@ -128,7 +128,6 @@ static void min_cb_tl_init(TabList *l, VVCFrameContext *fc)
     tl_init(l, 1, changed);
 
     TL_ADD(imf,  pic_size_in_min_cb);
-    TL_ADD(imm,  pic_size_in_min_cb);
 
     for (int i = LUMA; i <= CHROMA; i++)
         TL_ADD(cb_width[i],  pic_size_in_min_cb);   //is_a0_available requires this
@@ -143,7 +142,6 @@ static void min_cb_nz_tl_init(TabList *l, VVCFrameContext *fc)
     tl_init(l, 0, changed);
 
     TL_ADD(skip, pic_size_in_min_cb);
-    TL_ADD(imtf, pic_size_in_min_cb);
     TL_ADD(ipm,  pic_size_in_min_cb);
 
     for (int i = LUMA; i <= CHROMA; i++) {
diff --git a/libavcodec/vvc/dec.h b/libavcodec/vvc/dec.h
index f7cd5b678c..0f8f1f721d 100644
--- a/libavcodec/vvc/dec.h
+++ b/libavcodec/vvc/dec.h
@@ -161,9 +161,7 @@ typedef struct VVCFrameContext {
         uint8_t *skip;                                  ///< CuSkipFlag[][]
         uint8_t *ispmf;                                 ///< intra_sub_partitions_mode_flag
         uint8_t *msm[2];                                ///< MttSplitMode[][][] in 32 pixels
-        uint8_t *imf;                                   ///< IntraMipFlag[][]
-        uint8_t *imtf;                                  ///< intra_mip_transposed_flag[][]
-        uint8_t *imm;                                   ///< intra_mip_mode[][]
+        uint8_t *imf;                                   ///< IntraMipFlag[][], intra_mip_transposed_flag[][], intra_mip_mode[][]
         uint8_t *ipm;                                   ///< IntraPredModeY[][]
         uint8_t *cpm[2];                                ///< CuPredMode[][][]
         uint8_t *msf;                                   ///< MergeSubblockFlag[][]
diff --git a/libavcodec/vvc/dsp.c b/libavcodec/vvc/dsp.c
index 9bfa46b03d..af392f2754 100644
--- a/libavcodec/vvc/dsp.c
+++ b/libavcodec/vvc/dsp.c
@@ -44,6 +44,15 @@ static int vvc_sad(const int16_t *src0, const int16_t *src1, int dx, int dy,
     return sad;
 }
 
+static av_always_inline void unpack_mip_info(int *intra_mip_transposed_flag,
+    int *intra_mip_mode, const uint8_t mip_info)
+{
+    if (intra_mip_transposed_flag)
+        *intra_mip_transposed_flag = (mip_info >> 1) & 0x1;
+    if (intra_mip_mode)
+        *intra_mip_mode = (mip_info >> 2) & 0xf;
+}
+
 typedef struct IntraEdgeParams {
     uint8_t* top;
     uint8_t* left;
diff --git a/libavcodec/vvc/intra_template.c b/libavcodec/vvc/intra_template.c
index 62342c8142..440ac5b6cc 100644
--- a/libavcodec/vvc/intra_template.c
+++ b/libavcodec/vvc/intra_template.c
@@ -627,8 +627,9 @@ static void FUNC(intra_pred)(const VVCLocalContext *lc, int x0, int y0,
     FUNC(prepare_intra_edge_params)(lc, &edge, src, stride, x, y, w, h, c_idx, is_intra_mip, mode, ref_idx, need_pdpc);
 
     if (is_intra_mip) {
-        int intra_mip_transposed_flag = SAMPLE_CTB(fc->tab.imtf, x_cb, y_cb);
-        int intra_mip_mode = SAMPLE_CTB(fc->tab.imm, x_cb, y_cb);
+        int intra_mip_transposed_flag;
+        int intra_mip_mode;
+        unpack_mip_info(&intra_mip_transposed_flag, &intra_mip_mode, intra_mip_flag);
 
         fc->vvcdsp.intra.pred_mip((uint8_t *)src, edge.top, edge.left,
                         w, h, stride, intra_mip_mode, intra_mip_transposed_flag);



More information about the ffmpeg-cvslog mailing list