PR #22906 opened by R-Camacho URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22906 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22906.patch
The first commit moves ff_limiter_init into a header file so checkasm does not depend on vf_limiter.o. The second implements the actual test, using ff_limiter_init. >From 97035c2c335e52411a4df7bf190035fe8e1d2174 Mon Sep 17 00:00:00 2001 From: Rodrigo Camacho <[email protected]> Date: Thu, 23 Apr 2026 23:49:13 +0100 Subject: [PATCH 1/2] avfilter/vf_limiter: Move ff_limiter_init into a header This change allows ff_limiter_init to be inlined without depending on vf_limiter.o Signed-off-by: Rodrigo Camacho <[email protected]> --- libavfilter/limiter.h | 14 ++++++++ libavfilter/vf_limiter.c | 48 ++------------------------ libavfilter/vf_limiter_init.h | 65 +++++++++++++++++++++++++++++++++++ tests/fate/checkasm.mak | 1 + 4 files changed, 82 insertions(+), 46 deletions(-) create mode 100644 libavfilter/vf_limiter_init.h diff --git a/libavfilter/limiter.h b/libavfilter/limiter.h index 54d423d1f4..7c978a35ad 100644 --- a/libavfilter/limiter.h +++ b/libavfilter/limiter.h @@ -21,6 +21,7 @@ #include <stddef.h> #include <stdint.h> +#include "avfilter.h" typedef struct LimiterDSPContext { void (*limiter)(const uint8_t *src, uint8_t *dst, @@ -28,6 +29,19 @@ typedef struct LimiterDSPContext { int w, int h, int min, int max); } LimiterDSPContext; +typedef struct LimiterContext { + const AVClass *class; + int min; + int max; + int planes; + int nb_planes; + int linesize[4]; + int width[4]; + int height[4]; + + LimiterDSPContext dsp; +} LimiterContext; + void ff_limiter_init_x86(LimiterDSPContext *dsp, int bpp); #endif /* AVFILTER_LIMITER_H */ diff --git a/libavfilter/vf_limiter.c b/libavfilter/vf_limiter.c index 4f50ace386..4adfa48078 100644 --- a/libavfilter/vf_limiter.c +++ b/libavfilter/vf_limiter.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavfilter/vf_limiter_init.h" #include "libavutil/attributes.h" #include "libavutil/common.h" #include "libavutil/imgutils.h" @@ -31,19 +32,6 @@ typedef struct ThreadData { AVFrame *out; } ThreadData; -typedef struct LimiterContext { - const AVClass *class; - int min; - int max; - int planes; - int nb_planes; - int linesize[4]; - int width[4]; - int height[4]; - - LimiterDSPContext dsp; -} LimiterContext; - #define OFFSET(x) offsetof(LimiterContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM @@ -87,30 +75,6 @@ static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_NONE }; -#define LIMITER(n, type) \ -static void limiter##n(const uint8_t *ssrc, uint8_t *ddst, \ - ptrdiff_t slinesize, ptrdiff_t dlinesize,\ - int w, int h, int min, int max) \ -{ \ - const type *src = (const type *)ssrc; \ - type *dst = (type *)ddst; \ - \ - dlinesize /= sizeof(type); \ - slinesize /= sizeof(type); \ - \ - for (int y = 0; y < h; y++) { \ - for (int x = 0; x < w; x++) { \ - dst[x] = av_clip(src[x], min, max); \ - } \ - \ - dst += dlinesize; \ - src += slinesize; \ - } \ -} - -LIMITER(8, uint8_t) -LIMITER(16, uint16_t) - static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; @@ -134,15 +98,7 @@ static int config_input(AVFilterLink *inlink) s->max = FFMIN(s->max, (1 << depth) - 1); s->min = FFMIN(s->min, (1 << depth) - 1); - if (depth == 8) { - s->dsp.limiter = limiter8; - } else { - s->dsp.limiter = limiter16; - } - -#if ARCH_X86 && HAVE_X86ASM - ff_limiter_init_x86(&s->dsp, desc->comp[0].depth); -#endif + ff_limiter_init(s, depth); return 0; } diff --git a/libavfilter/vf_limiter_init.h b/libavfilter/vf_limiter_init.h new file mode 100644 index 0000000000..f8e0a3319d --- /dev/null +++ b/libavfilter/vf_limiter_init.h @@ -0,0 +1,65 @@ +/* + * 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 AVFILTER_LIMITER_INIT_H +#define AVFILTER_LIMITER_INIT_H + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/common.h" +#include "limiter.h" + +#define LIMITER(n, type) \ +static void limiter##n(const uint8_t *ssrc, uint8_t *ddst, \ + ptrdiff_t slinesize, ptrdiff_t dlinesize,\ + int w, int h, int min, int max) \ +{ \ + const type *src = (const type *)ssrc; \ + type *dst = (type *)ddst; \ + \ + dlinesize /= sizeof(type); \ + slinesize /= sizeof(type); \ + \ + for (int y = 0; y < h; y++) { \ + for (int x = 0; x < w; x++) { \ + dst[x] = av_clip(src[x], min, max); \ + } \ + \ + dst += dlinesize; \ + src += slinesize; \ + } \ +} + +LIMITER(8, uint8_t) +LIMITER(16, uint16_t) + +static av_unused void ff_limiter_init(LimiterContext *s, int depth) +{ + if (depth == 8) { + s->dsp.limiter = limiter8; + } else { + s->dsp.limiter = limiter16; + } + +#if ARCH_X86 && HAVE_X86ASM + ff_limiter_init_x86(&s->dsp, depth); +#endif + +} + +#endif /* AVFILTER_LIMITER_INIT_H */ diff --git a/tests/fate/checkasm.mak b/tests/fate/checkasm.mak index b7392fa745..9c513bca55 100644 --- a/tests/fate/checkasm.mak +++ b/tests/fate/checkasm.mak @@ -82,6 +82,7 @@ FATE_CHECKASM = fate-checkasm-aacencdsp \ fate-checkasm-vf_gblur \ fate-checkasm-vf_hflip \ fate-checkasm-vf_idet \ + fate-checkasm-vf_limiter \ fate-checkasm-vf_nlmeans \ fate-checkasm-vf_threshold \ fate-checkasm-vf_sobel \ -- 2.52.0 >From a2e55d84c998e10687451ae0d407aaea075ebbdb Mon Sep 17 00:00:00 2001 From: Rodrigo Camacho <[email protected]> Date: Thu, 23 Apr 2026 23:56:17 +0100 Subject: [PATCH 2/2] tests/checkasm: add test for vf_limiter Signed-off-by: Rodrigo Camacho <[email protected]> --- tests/checkasm/Makefile | 1 + tests/checkasm/checkasm.c | 3 ++ tests/checkasm/checkasm.h | 1 + tests/checkasm/vf_limiter.c | 75 +++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 tests/checkasm/vf_limiter.c diff --git a/tests/checkasm/Makefile b/tests/checkasm/Makefile index 55d2527047..4a23c16578 100644 --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile @@ -76,6 +76,7 @@ AVFILTEROBJS-$(CONFIG_FSPP_FILTER) += vf_fspp.o AVFILTEROBJS-$(CONFIG_GBLUR_FILTER) += vf_gblur.o AVFILTEROBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o AVFILTEROBJS-$(CONFIG_IDET_FILTER) += vf_idet.o +AVFILTEROBJS-$(CONFIG_LIMITER_FILTER) += vf_limiter.o AVFILTEROBJS-$(CONFIG_THRESHOLD_FILTER) += vf_threshold.o AVFILTEROBJS-$(CONFIG_NLMEANS_FILTER) += vf_nlmeans.o AVFILTEROBJS-$(CONFIG_SOBEL_FILTER) += vf_convolution.o diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c index e863ff6eed..99fb6130da 100644 --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c @@ -342,6 +342,9 @@ static const struct { #if CONFIG_NLMEANS_FILTER { "vf_nlmeans", checkasm_check_nlmeans }, #endif + #if CONFIG_LIMITER_FILTER + { "vf_limiter", checkasm_check_vf_limiter }, + #endif #if CONFIG_THRESHOLD_FILTER { "vf_threshold", checkasm_check_vf_threshold }, #endif diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index 72a1404163..6dd09b8939 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -162,6 +162,7 @@ void checkasm_check_vf_eq(void); void checkasm_check_vf_fspp(void); void checkasm_check_vf_gblur(void); void checkasm_check_vf_hflip(void); +void checkasm_check_vf_limiter(void); void checkasm_check_vf_threshold(void); void checkasm_check_vf_sobel(void); void checkasm_check_vp3dsp(void); diff --git a/tests/checkasm/vf_limiter.c b/tests/checkasm/vf_limiter.c new file mode 100644 index 0000000000..e191bb9614 --- /dev/null +++ b/tests/checkasm/vf_limiter.c @@ -0,0 +1,75 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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 "checkasm.h" +#include "libavfilter/limiter.h" +#include "libavfilter/vf_limiter_init.h" +#include "libavutil/mem_internal.h" +#include <stddef.h> +#include <stdint.h> + +#define WIDTH 256 +#define HEIGHT 16 +#define WIDTH_PADDED (WIDTH + 32) + +static void check_limiter(int depth) +{ + LOCAL_ALIGNED_32(uint8_t, src, [HEIGHT * WIDTH_PADDED]); + LOCAL_ALIGNED_32(uint8_t, dst_ref, [HEIGHT * WIDTH_PADDED]); + LOCAL_ALIGNED_32(uint8_t, dst_new, [HEIGHT * WIDTH_PADDED]); + + declare_func(void, const uint8_t *, uint8_t *, + ptrdiff_t, ptrdiff_t, int, int, int, int); + + memset(dst_ref, 0, HEIGHT * WIDTH_PADDED); + memset(dst_new, 0, HEIGHT * WIDTH_PADDED); + memset(src, 0, HEIGHT * WIDTH_PADDED); + for (int y = 0; y < HEIGHT; y++) { + for (int x = 0; x < WIDTH; x++) + src[y * WIDTH_PADDED + x] = rnd() & 0xFF; + } + + const int min = 16 << (depth - 8); + const int max = 235 << (depth - 8); + + int w = WIDTH; + if (depth == 16) + w /= 2; + + LimiterContext s; + ff_limiter_init(&s, depth); + + if (check_func(s.dsp.limiter, "limiter%d", depth)) { + call_ref(src, dst_ref, WIDTH_PADDED, WIDTH_PADDED, w, HEIGHT, min, max); + call_new(src, dst_new, WIDTH_PADDED, WIDTH_PADDED, w, HEIGHT, min, max); + + if (memcmp(dst_ref, dst_new, HEIGHT * WIDTH_PADDED)) + fail(); + + bench_new(src, dst_new, WIDTH_PADDED, WIDTH_PADDED, w, HEIGHT, min, max); + } +} + +void checkasm_check_vf_limiter(void) +{ + check_limiter(8); + report("limiter8"); + + check_limiter(16); + report("limiter16"); +} -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
