From ef55dc925fd82cd5811108ae59bdac532470eb11 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Fri, 7 Mar 2025 16:12:42 +0100 Subject: [PATCH 01/17] avcodec/vlc: Merge VLCElem and RL_VLC_ELEM It will simplify creating RL-VLCs (which until now used a stack-based VLC as temporary buffer). Notice that there would be another option to merge them, namely: struct VLCElem { union { VLCBaseType sym; int16_t level; }; int8_t len; uint8_t run; }; The main difference to the current patch is that this would change the type of the length field of VLCElem to int8_t from int16_t. It turns out that that this would entail additional sign extensions on ppc, see https://godbolt.org/z/behWYEYE7. I have therefore refrained from doing so, although it would make the patch simpler. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/cfhd.h | 2 +- libavcodec/cfhddata.c | 10 +++++----- libavcodec/dvdec.c | 12 ++++++------ libavcodec/get_bits.h | 6 +++--- libavcodec/mpeg12.c | 2 +- libavcodec/rl.c | 2 +- libavcodec/vlc.h | 22 +++++++++++++++------- 7 files changed, 32 insertions(+), 24 deletions(-) diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h index 9b09c91262..586d3360b6 100644 --- a/libavcodec/cfhd.h +++ b/libavcodec/cfhd.h @@ -98,7 +98,7 @@ enum CFHDParam { typedef struct CFHD_RL_VLC_ELEM { int16_t level; - int8_t len; + int8_t len8; uint16_t run; } CFHD_RL_VLC_ELEM; diff --git a/libavcodec/cfhddata.c b/libavcodec/cfhddata.c index a3948a14ca..72b14baf27 100644 --- a/libavcodec/cfhddata.c +++ b/libavcodec/cfhddata.c @@ -136,22 +136,22 @@ static av_cold int cfhd_init_vlc(CFHD_RL_VLC_ELEM out[], unsigned out_size, /** Similar to dv.c, generate signed VLC tables **/ for (unsigned i = j = 0; i < table_size; i++, j++) { - tmp[j].len = table_vlc[i].len; + tmp[j].len8 = table_vlc[i].len; tmp[j].run = table_vlc[i].run; tmp[j].level = table_vlc[i].level; /* Don't include the zero level nor escape bits */ if (table_vlc[i].level && table_vlc[i].run) { - tmp[j].len++; + tmp[j].len8++; j++; - tmp[j].len = table_vlc[i].len + 1; + tmp[j].len8 = table_vlc[i].len + 1; tmp[j].run = table_vlc[i].run; tmp[j].level = -table_vlc[i].level; } } ret = ff_vlc_init_from_lengths(&vlc, VLC_BITS, j, - &tmp[0].len, sizeof(tmp[0]), + &tmp[0].len8, sizeof(tmp[0]), NULL, 0, 0, 0, 0, logctx); if (ret < 0) return ret; @@ -169,7 +169,7 @@ static av_cold int cfhd_init_vlc(CFHD_RL_VLC_ELEM out[], unsigned out_size, run = tmp[code].run; level = tmp[code].level; } - out[i].len = len; + out[i].len8 = len; out[i].level = level; out[i].run = run; } diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index 8297b6d2f3..242708c70a 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -159,15 +159,15 @@ static av_cold void dv_init_static(void) /* it's faster to include sign bit in a generic VLC parsing scheme */ for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) { - tmp[j].len = ff_dv_vlc_len[i]; + tmp[j].len8 = ff_dv_vlc_len[i]; tmp[j].run = ff_dv_vlc_run[i]; tmp[j].level = ff_dv_vlc_level[i]; if (ff_dv_vlc_level[i]) { - tmp[j].len++; + tmp[j].len8++; j++; - tmp[j].len = ff_dv_vlc_len[i] + 1; + tmp[j].len8 = ff_dv_vlc_len[i] + 1; tmp[j].run = ff_dv_vlc_run[i]; tmp[j].level = -ff_dv_vlc_level[i]; } @@ -176,7 +176,7 @@ static av_cold void dv_init_static(void) /* NOTE: as a trick, we use the fact the no codes are unused * to accelerate the parsing of partial codes */ ff_vlc_init_from_lengths(&dv_vlc, TEX_VLC_BITS, j, - &tmp[0].len, sizeof(tmp[0]), + &tmp[0].len8, sizeof(tmp[0]), NULL, 0, 0, 0, VLC_INIT_USE_STATIC, NULL); av_assert1(dv_vlc.table_size == 1664); @@ -193,7 +193,7 @@ static av_cold void dv_init_static(void) run = tmp[code].run + 1; level = tmp[code].level; } - dv_rl_vlc[i].len = len; + dv_rl_vlc[i].len8 = len; dv_rl_vlc[i].level = level; dv_rl_vlc[i].run = run; } @@ -301,7 +301,7 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, int16_t *block) pos, SHOW_UBITS(re, gb, 16), re_index); /* our own optimized GET_RL_VLC */ index = NEG_USR32(re_cache, TEX_VLC_BITS); - vlc_len = dv_rl_vlc[index].len; + vlc_len = dv_rl_vlc[index].len8; if (vlc_len < 0) { index = NEG_USR32((unsigned) re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level; diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index 39d8e5bc1e..1954296569 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -594,7 +594,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) \ index = SHOW_UBITS(name, gb, bits); \ level = table[index].level; \ - n = table[index].len; \ + n = table[index].len8; \ \ if (max_depth > 1 && n < 0) { \ SKIP_BITS(name, gb, bits); \ @@ -606,7 +606,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) \ index = SHOW_UBITS(name, gb, nb_bits) + level; \ level = table[index].level; \ - n = table[index].len; \ + n = table[index].len8; \ if (max_depth > 2 && n < 0) { \ LAST_SKIP_BITS(name, gb, nb_bits); \ if (need_update) { \ @@ -616,7 +616,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) \ index = SHOW_UBITS(name, gb, nb_bits) + level; \ level = table[index].level; \ - n = table[index].len; \ + n = table[index].len8; \ } \ } \ run = table[index].run; \ diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 444ea83f3c..0d4a36be04 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -119,7 +119,7 @@ av_cold void ff_init_2d_vlc_rl(const uint16_t table_vlc[][2], RL_VLC_ELEM rl_vlc level = table_level[code]; } } - rl_vlc[i].len = len; + rl_vlc[i].len8 = len; rl_vlc[i].level = level; rl_vlc[i].run = run; } diff --git a/libavcodec/rl.c b/libavcodec/rl.c index a78242d488..b45cf117c1 100644 --- a/libavcodec/rl.c +++ b/libavcodec/rl.c @@ -118,7 +118,7 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size) if (code >= rl->last) run += 192; } } - rl->rl_vlc[q][i].len = len; + rl->rl_vlc[q][i].len8 = len; rl->rl_vlc[q][i].level = level; rl->rl_vlc[q][i].run = run; } diff --git a/libavcodec/vlc.h b/libavcodec/vlc.h index bf7b0e65b4..7eecd9651f 100644 --- a/libavcodec/vlc.h +++ b/libavcodec/vlc.h @@ -30,9 +30,23 @@ typedef int16_t VLCBaseType; typedef struct VLCElem { - VLCBaseType sym, len; + union { + /// The struct is for use as ordinary VLC (with get_vlc2()) + struct { + VLCBaseType sym; + VLCBaseType len; + }; + /// This struct is for use as run-length VLC (with GET_RL_VLC) + struct { + int16_t level; + int8_t len8; + uint8_t run; + }; + }; } VLCElem; +typedef VLCElem RL_VLC_ELEM; + typedef struct VLC { int bits; VLCElem *table; @@ -53,12 +67,6 @@ typedef struct VLC_MULTI { int table_size, table_allocated; } VLC_MULTI; -typedef struct RL_VLC_ELEM { - int16_t level; - int8_t len; - uint8_t run; -} RL_VLC_ELEM; - #define vlc_init(vlc, nb_bits, nb_codes, \ bits, bits_wrap, bits_size, \ codes, codes_wrap, codes_size, \ -- 2.45.2