From 5a694d62c52a119729aa8234d097644a722f5f01 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Sun, 24 Sep 2023 18:35:22 +0200 Subject: [PATCH] avcodec/mpeg4videodec: Avoid superfluous VLC structures For all VLCs here, the number of bits of the VLC is write-only, because it is hardcoded at the call site. Therefore one can replace these VLC structures with the only thing that is actually used: The pointer to the VLCElem table. And in some cases one can even avoid this. Signed-off-by: Andreas Rheinhardt --- libavcodec/mpeg4videodec.c | 93 ++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index ff1f20d1f3..7e05f2eeca 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -58,12 +58,12 @@ #define MB_TYPE_B_VLC_BITS 4 #define STUDIO_INTRA_BITS 9 -static VLC dc_lum, dc_chrom; -static VLC sprite_trajectory; -static VLC mb_type_b_vlc; -static VLC studio_intra_tab[12]; -static VLC studio_luma_dc; -static VLC studio_chroma_dc; +static VLCElem dc_lum[512], dc_chrom[512]; +static VLCElem sprite_trajectory[128]; +static VLCElem mb_type_b_vlc[16]; +static const VLCElem *studio_intra_tab[12]; +static VLCElem studio_luma_dc[528]; +static VLCElem studio_chroma_dc[528]; static const uint8_t mpeg4_block_count[4] = { 0, 6, 8, 12 }; @@ -449,14 +449,14 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g int length; int x = 0, y = 0; - length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 2); + length = get_vlc2(gb, sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 2); if (length > 0) x = get_xbits(gb, length); if (!(ctx->divx_version == 500 && ctx->divx_build == 413)) check_marker(s->avctx, gb, "before sprite_trajectory"); - length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 2); + length = get_vlc2(gb, sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 2); if (length > 0) y = get_xbits(gb, length); @@ -891,9 +891,9 @@ static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr) int level, code; if (n < 4) - code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1); + code = get_vlc2(&s->gb, dc_lum, DC_VLC_BITS, 1); else - code = get_vlc2(&s->gb, dc_chrom.table, DC_VLC_BITS, 1); + code = get_vlc2(&s->gb, dc_chrom, DC_VLC_BITS, 1); if (code < 0 || code > 9 /* && s->nbit < 9 */) { av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n"); @@ -1840,7 +1840,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) cbp = 0; } else { modb2 = get_bits1(&s->gb); - mb_type = get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1); + mb_type = get_vlc2(&s->gb, mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 1); if (mb_type < 0) { av_log(s->avctx, AV_LOG_ERROR, "illegal MB_type\n"); return AVERROR_INVALIDDATA; @@ -2072,7 +2072,7 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n int cc, dct_dc_size, dct_diff, code, j, idx = 1, group = 0, run = 0, additional_code_len, sign, mismatch; - const VLC *cur_vlc = &studio_intra_tab[0]; + const VLCElem *cur_vlc = studio_intra_tab[0]; uint8_t *const scantable = s->intra_scantable.permutated; const uint16_t *quant_matrix; uint32_t flc; @@ -2086,14 +2086,14 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n if (n < 4) { cc = 0; - dct_dc_size = get_vlc2(&s->gb, studio_luma_dc.table, STUDIO_INTRA_BITS, 2); + dct_dc_size = get_vlc2(&s->gb, studio_luma_dc, STUDIO_INTRA_BITS, 2); quant_matrix = s->intra_matrix; } else { cc = (n & 1) + 1; if (ctx->rgb) - dct_dc_size = get_vlc2(&s->gb, studio_luma_dc.table, STUDIO_INTRA_BITS, 2); + dct_dc_size = get_vlc2(&s->gb, studio_luma_dc, STUDIO_INTRA_BITS, 2); else - dct_dc_size = get_vlc2(&s->gb, studio_chroma_dc.table, STUDIO_INTRA_BITS, 2); + dct_dc_size = get_vlc2(&s->gb, studio_chroma_dc, STUDIO_INTRA_BITS, 2); quant_matrix = s->chroma_intra_matrix; } @@ -2122,7 +2122,7 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n /* AC Coefficients */ while (1) { - group = get_vlc2(&s->gb, cur_vlc->table, STUDIO_INTRA_BITS, 2); + group = get_vlc2(&s->gb, cur_vlc, STUDIO_INTRA_BITS, 2); if (group < 0) { av_log(s->avctx, AV_LOG_ERROR, "illegal ac coefficient group vlc\n"); @@ -2130,7 +2130,7 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n } additional_code_len = ac_state_tab[group][0]; - cur_vlc = &studio_intra_tab[ac_state_tab[group][1]]; + cur_vlc = studio_intra_tab[ac_state_tab[group][1]]; if (group == 0) { /* End of Block */ @@ -3758,28 +3758,25 @@ static int mpeg4_update_thread_context_for_user(AVCodecContext *dst, static av_cold void mpeg4_init_static(void) { static uint8_t mpeg4_rvlc_rl_tables[2][2][2 * MAX_RUN + MAX_LEVEL + 3]; + static VLCElem vlc_buf[6498]; + VLCInitState state = VLC_INIT_STATE(vlc_buf); - VLC_INIT_STATIC_FROM_LENGTHS(&studio_luma_dc, STUDIO_INTRA_BITS, 19, - &ff_mpeg4_studio_dc_luma[0][1], 2, - &ff_mpeg4_studio_dc_luma[0][0], 2, 1, - 0, 0, 528); + VLC_INIT_STATIC_TABLE_FROM_LENGTHS(studio_luma_dc, STUDIO_INTRA_BITS, 19, + &ff_mpeg4_studio_dc_luma[0][1], 2, + &ff_mpeg4_studio_dc_luma[0][0], 2, 1, + 0, 0); - VLC_INIT_STATIC_FROM_LENGTHS(&studio_chroma_dc, STUDIO_INTRA_BITS, 19, - &ff_mpeg4_studio_dc_chroma[0][1], 2, - &ff_mpeg4_studio_dc_chroma[0][0], 2, 1, - 0, 0, 528); + VLC_INIT_STATIC_TABLE_FROM_LENGTHS(studio_chroma_dc, STUDIO_INTRA_BITS, 19, + &ff_mpeg4_studio_dc_chroma[0][1], 2, + &ff_mpeg4_studio_dc_chroma[0][0], 2, 1, + 0, 0); - for (unsigned i = 0, offset = 0; i < 12; i++) { - static VLCElem vlc_buf[6498]; - - studio_intra_tab[i].table = &vlc_buf[offset]; - studio_intra_tab[i].table_allocated = FF_ARRAY_ELEMS(vlc_buf) - offset; - ff_vlc_init_from_lengths(&studio_intra_tab[i], - STUDIO_INTRA_BITS, 24, - &ff_mpeg4_studio_intra[i][0][1], 2, - &ff_mpeg4_studio_intra[i][0][0], 2, 1, - 0, VLC_INIT_STATIC_OVERLONG, NULL); - offset += studio_intra_tab[i].table_size; + for (unsigned i = 0; i < 12; i++) { + studio_intra_tab[i] = + ff_vlc_init_tables_from_lengths(&state, STUDIO_INTRA_BITS, 24, + &ff_mpeg4_studio_intra[i][0][1], 2, + &ff_mpeg4_studio_intra[i][0][0], 2, 1, + 0, 0); } ff_mpeg4_init_rl_intra(); @@ -3788,18 +3785,18 @@ static av_cold void mpeg4_init_static(void) INIT_FIRST_VLC_RL(ff_mpeg4_rl_intra, 554); VLC_INIT_RL(ff_rvlc_rl_inter, 1072); INIT_FIRST_VLC_RL(ff_rvlc_rl_intra, 1072); - VLC_INIT_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_lum[0][1], 2, 1, - &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512); - VLC_INIT_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_chrom[0][1], 2, 1, - &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512); - VLC_INIT_STATIC_FROM_LENGTHS(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, - ff_sprite_trajectory_lens, 1, - NULL, 0, 0, 0, 0, 128); - VLC_INIT_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, - &ff_mb_type_b_tab[0][1], 2, 1, - &ff_mb_type_b_tab[0][0], 2, 1, 16); + VLC_INIT_STATIC_TABLE(dc_lum, DC_VLC_BITS, 10 /* 13 */, + &ff_mpeg4_DCtab_lum[0][1], 2, 1, + &ff_mpeg4_DCtab_lum[0][0], 2, 1, 0); + VLC_INIT_STATIC_TABLE(dc_chrom, DC_VLC_BITS, 10 /* 13 */, + &ff_mpeg4_DCtab_chrom[0][1], 2, 1, + &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 0); + VLC_INIT_STATIC_TABLE_FROM_LENGTHS(sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, + ff_sprite_trajectory_lens, 1, + NULL, 0, 0, 0, 0); + VLC_INIT_STATIC_TABLE(mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, + &ff_mb_type_b_tab[0][1], 2, 1, + &ff_mb_type_b_tab[0][0], 2, 1, 0); } static av_cold int decode_init(AVCodecContext *avctx)