From 1275029955768a373c571a261ed5f9aab362d124 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Wed, 9 Apr 2025 16:26:56 +0200 Subject: [PATCH 01/10] avcodec/hq{xvlc,_hqadata}: Deduplicate and hardcode cbp table This table is so small (32 elements amounting to 128 bytes) that it is more efficient size-wise to hardcode it instead of initializing it at runtime. Also stop duplicating it in hq_hqa.o and hqx.o. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/Makefile | 4 ++-- libavcodec/hq_common.c | 44 +++++++++++++++++++++++++++++++++++++++++ libavcodec/hq_common.h | 29 +++++++++++++++++++++++++++ libavcodec/hq_hqa.c | 10 +++------- libavcodec/hq_hqadata.h | 9 --------- libavcodec/hqx.c | 7 +++---- libavcodec/hqxvlc.h | 16 +-------------- 7 files changed, 82 insertions(+), 37 deletions(-) create mode 100644 libavcodec/hq_common.c create mode 100644 libavcodec/hq_common.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 3c3ac640e0..5ec2b7f5ad 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -465,8 +465,8 @@ OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o OBJS-$(CONFIG_HEVC_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o -OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadsp.o canopus.o -OBJS-$(CONFIG_HQX_DECODER) += hqx.o hqxdsp.o canopus.o +OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadsp.o hq_common.o canopus.o +OBJS-$(CONFIG_HQX_DECODER) += hqx.o hqxdsp.o hq_common.o canopus.o OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o huffyuvdec.o OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o huffyuvenc.o OBJS-$(CONFIG_HYMT_DECODER) += huffyuv.o huffyuvdec.o diff --git a/libavcodec/hq_common.c b/libavcodec/hq_common.c new file mode 100644 index 0000000000..3cb793f2f6 --- /dev/null +++ b/libavcodec/hq_common.c @@ -0,0 +1,44 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "hq_common.h" + +#define REPEAT(x) x x +#define ELEM(_sym, _len) {.sym = _sym, .len = _len }, +#define LEN5(sym) ELEM(sym, 5) +#define LEN4(sym) REPEAT(ELEM(sym, 4)) +#define LEN2(sym) REPEAT(REPEAT(REPEAT(ELEM(sym, 2)))) + +const VLCElem ff_hq_cbp_vlc[1 << HQ_CBP_VLC_BITS] = { + LEN2(0xF) + LEN4(0x0) + LEN4(0xE) + LEN4(0xD) + LEN4(0xB) + LEN4(0x7) + LEN4(0x3) + LEN4(0xC) + LEN4(0x5) + LEN4(0xA) + LEN5(0x9) + LEN5(0x6) + LEN5(0x1) + LEN5(0x2) + LEN5(0x4) + LEN5(0x8) +}; \ No newline at end of file diff --git a/libavcodec/hq_common.h b/libavcodec/hq_common.h new file mode 100644 index 0000000000..e438ac7d07 --- /dev/null +++ b/libavcodec/hq_common.h @@ -0,0 +1,29 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_HQ_COMMON_H +#define AVCODEC_HQ_COMMON_H + +#include "vlc.h" +#include "libavutil/attributes_internal.h" + +#define HQ_CBP_VLC_BITS 5 + +EXTERN const VLCElem ff_hq_cbp_vlc[1 << HQ_CBP_VLC_BITS]; + +#endif /* AVCODEC_HQ_COMMON_H */ diff --git a/libavcodec/hq_hqa.c b/libavcodec/hq_hqa.c index 738ed9868d..76af754115 100644 --- a/libavcodec/hq_hqa.c +++ b/libavcodec/hq_hqa.c @@ -30,6 +30,7 @@ #include "codec_internal.h" #include "decode.h" #include "get_bits.h" +#include "hq_common.h" #include "hq_hqadata.h" #include "hq_hqadsp.h" #include "vlc.h" @@ -58,7 +59,6 @@ typedef struct HQContext { } HQContext; static VLCElem hq_ac_vlc[1184]; -static VLCElem hqa_cbp_vlc[32]; static inline void put_blocks(HQContext *c, AVFrame *pic, int plane, int x, int y, int ilace, @@ -192,18 +192,17 @@ static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup, GetBitContext *gb, int x, int y) { int flag = 0; - int i, ret, cbp; + int i, ret; if (get_bits_left(gb) < 1) return AVERROR_INVALIDDATA; - cbp = get_vlc2(gb, hqa_cbp_vlc, 5, 1); - for (i = 0; i < 12; i++) memset(c->block[i], 0, sizeof(*c->block)); for (i = 0; i < 12; i++) c->block[i][0] = -128 * (1 << 6); + int cbp = get_vlc2(gb, ff_hq_cbp_vlc, HQ_CBP_VLC_BITS, 1); if (cbp) { flag = get_bits1(gb); @@ -373,9 +372,6 @@ static int hq_hqa_decode_frame(AVCodecContext *avctx, AVFrame *pic, static av_cold void hq_init_vlcs(void) { - VLC_INIT_STATIC_TABLE(hqa_cbp_vlc, 5, FF_ARRAY_ELEMS(cbp_vlc_lens), - cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0); - VLC_INIT_STATIC_TABLE(hq_ac_vlc, 9, NUM_HQ_AC_ENTRIES, hq_ac_bits, 1, 1, hq_ac_codes, 2, 2, 0); } diff --git a/libavcodec/hq_hqadata.h b/libavcodec/hq_hqadata.h index 2faf47f003..d592ac0c21 100644 --- a/libavcodec/hq_hqadata.h +++ b/libavcodec/hq_hqadata.h @@ -36,15 +36,6 @@ typedef struct HQProfile { #define MAT_SIZE 64 -static const uint8_t cbp_vlc_bits[16] = { - 0x04, 0x1C, 0x1D, 0x09, 0x1E, 0x0B, 0x1B, 0x08, - 0x1F, 0x1A, 0x0C, 0x07, 0x0A, 0x06, 0x05, 0x00, -}; - -static const uint8_t cbp_vlc_lens[16] = { - 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2, -}; - static const int32_t qmat00[MAT_SIZE] = { 0x0040000, 0x000B18B, 0x00058C5, 0x000B1B1, 0x00082D3, 0x000B1B1, 0x000A953, 0x000827B, 0x00104F7, 0x000A953, 0x0009000, 0x000EADD, diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c index 2e9698ee6c..0819575aa4 100644 --- a/libavcodec/hqx.c +++ b/libavcodec/hqx.c @@ -35,6 +35,7 @@ #include "hqxdsp.h" #include "hqxvlc.h" +#include "hq_common.h" /* HQX has four modes - 422, 444, 422alpha and 444alpha - all 12-bit */ enum HQXFormat { @@ -219,13 +220,12 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y) int flag = 0; int last_dc; int i, ret; - int cbp; memset(slice->block, 0, sizeof(*slice->block) * 12); for (i = 0; i < 12; i++) slice->block[i][0] = -0x800; - cbp = get_vlc2(gb, cbp_vlc, HQX_CBP_VLC_BITS, 1); + int cbp = get_vlc2(gb, ff_hq_cbp_vlc, HQ_CBP_VLC_BITS, 1); if (cbp) { const unsigned *quants; @@ -305,13 +305,12 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y) int flag = 0; int last_dc; int i, ret; - int cbp; memset(slice->block, 0, sizeof(*slice->block) * 16); for (i = 0; i < 16; i++) slice->block[i][0] = -0x800; - cbp = get_vlc2(gb, cbp_vlc, HQX_CBP_VLC_BITS, 1); + int cbp = get_vlc2(gb, ff_hq_cbp_vlc, HQ_CBP_VLC_BITS, 1); if (cbp) { const unsigned *quants; diff --git a/libavcodec/hqxvlc.h b/libavcodec/hqxvlc.h index 28c55b20e0..abf81f60ad 100644 --- a/libavcodec/hqxvlc.h +++ b/libavcodec/hqxvlc.h @@ -28,7 +28,6 @@ #include "libavutil/attributes.h" #include "libavutil/macros.h" -#define HQX_CBP_VLC_BITS 5 #define HQX_DC_VLC_BITS 9 enum HQXACMode { @@ -46,15 +45,6 @@ typedef struct HQXAC { const RL_VLC_ELEM *lut; } HQXAC; -static const uint8_t cbp_vlc_bits[16] = { - 0x04, 0x1C, 0x1D, 0x09, 0x1E, 0x0B, 0x1B, 0x08, - 0x1F, 0x1A, 0x0C, 0x07, 0x0A, 0x06, 0x05, 0x00, -}; - -static const uint8_t cbp_vlc_lens[16] = { - 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2, -}; - static const uint16_t dc9_vlc_bits[512] = { 0x0010, 0x0008, 0x0022, 0x0024, 0x0026, 0x0028, 0x002A, 0x002C, 0x002E, 0x0030, 0x0032, 0x0034, 0x0074, 0x0076, 0x0078, 0x007A, @@ -1529,11 +1519,10 @@ static const uint8_t hqx_ac_lens[] = { static const uint16_t hqx_ac_nb_elems[] = { 815, 907, 512, 354, 257, 194 }; -static VLCElem cbp_vlc[(1 << HQX_CBP_VLC_BITS) + 896 /* dc9 */ + 1344 /* dc10 */ +static VLCElem cbp_vlc[896 /* dc9 */ + 1344 /* dc10 */ + 15630 /* RL_VLC_ELEMS for hqx_ac */]; static const VLCElem *dc_vlc[2]; - #define INIT_DC_TABLE(idx, name) \ do { \ dc_vlc[idx] = ff_vlc_init_tables(&state, HQX_DC_VLC_BITS, \ @@ -1548,9 +1537,6 @@ static av_cold av_unused void hqx_init_static(void) const uint8_t *lens = hqx_ac_lens; const int16_t *run_level = hqx_ac_run_level; - ff_vlc_init_tables(&state, HQX_CBP_VLC_BITS, FF_ARRAY_ELEMS(cbp_vlc_lens), - cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0); - INIT_DC_TABLE(0, dc9); INIT_DC_TABLE(1, dc10); -- 2.45.2