[FFmpeg-devel] [PATCH v2] lavc/vvc: Use a bitfield to store MIP information
Nuo Mi
nuomi2021 at gmail.com
Sat Dec 7 11:42:24 EET 2024
Applied.
Thank you, Frank
On Wed, Dec 4, 2024 at 4:57 AM Frank Plowman <post at frankplowman.com> wrote:
> 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>
> ---
> Changes since v1 (posted as attachment in other thread).
> * Renamed (de)?structure_mip_info to (un)?pack_mip_info
> * Remove coerce_to_bool argument added to get_inc. Instead, define a
> variant of get_inc, get_mip_inc, particular to the MIP flag which
> performs the necessary transformations.
>
> I did also try implementing this patch as I mentioned I might on the
> other thread: by adding a function pointer argument to get_inc and
> get_left_top which can be used to transform values read from tables
> before they are used. I realised while doing so, however, that there is
> really no need for such complexity for get_left_top as it returns left
> and top separately, hence the caller can simply transform them itself.
> Then, get_inc is very simple and only called in two places, and so it is
> not fitting to employ such heavy-duty abstractions only for that
> function.
>
> ---
> 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 505099bc76..382fa582f4 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);
> --
> 2.47.0
>
>
More information about the ffmpeg-devel
mailing list