From 34c6ad0a077aea97068fe63502e2edd761891d9d Mon Sep 17 00:00:00 2001 From: Frank Plowman Date: Tue, 3 Dec 2024 20:47:25 +0000 Subject: [PATCH] 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 Signed-off-by: Frank Plowman --- 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);