This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit ff22978529e6219f65fbc5984cda2f0ee7ce5427 Author: DROOdotFOO <[email protected]> AuthorDate: Thu Jun 11 01:23:38 2026 +0200 Commit: Martin Storsjö <[email protected]> CommitDate: Wed Nov 4 20:14:23 2026 +0000 avfilter/aarch64: NEON threshold filter depth==8 routes to threshold8_neon (16 bytes/chunk); depth > 8 to threshold16_neon (8 shorts/chunk, covering 9/10/12/14/16). C is not auto-vectorized: four independent input streams defeat clang's vectorizer. Per chunk the NEON kernel is cmhs+bsl. checkasm --bench, Apple M1 (clang), speedup vs C: threshold8 15.0x threshold10 8.1x threshold12 8.2x threshold16 8.2x Signed-off-by: DROOdotFOO <[email protected]> --- libavfilter/aarch64/Makefile | 2 + libavfilter/aarch64/vf_threshold_init.c | 51 +++++++++++++++++ libavfilter/aarch64/vf_threshold_neon.S | 99 +++++++++++++++++++++++++++++++++ libavfilter/threshold.h | 1 + libavfilter/vf_threshold_init.h | 2 + 5 files changed, 155 insertions(+) diff --git a/libavfilter/aarch64/Makefile b/libavfilter/aarch64/Makefile index c7b7e18467..d09f7e4080 100644 --- a/libavfilter/aarch64/Makefile +++ b/libavfilter/aarch64/Makefile @@ -1,7 +1,9 @@ OBJS-$(CONFIG_BWDIF_FILTER) += aarch64/vf_bwdif_init_aarch64.o OBJS-$(CONFIG_COLORDETECT_FILTER) += aarch64/vf_colordetect_init.o OBJS-$(CONFIG_NLMEANS_FILTER) += aarch64/vf_nlmeans_init.o +OBJS-$(CONFIG_THRESHOLD_FILTER) += aarch64/vf_threshold_init.o NEON-OBJS-$(CONFIG_BWDIF_FILTER) += aarch64/vf_bwdif_neon.o NEON-OBJS-$(CONFIG_COLORDETECT_FILTER) += aarch64/vf_colordetect_neon.o NEON-OBJS-$(CONFIG_NLMEANS_FILTER) += aarch64/vf_nlmeans_neon.o +NEON-OBJS-$(CONFIG_THRESHOLD_FILTER) += aarch64/vf_threshold_neon.o diff --git a/libavfilter/aarch64/vf_threshold_init.c b/libavfilter/aarch64/vf_threshold_init.c new file mode 100644 index 0000000000..9b14d644a9 --- /dev/null +++ b/libavfilter/aarch64/vf_threshold_init.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2026 DROOdotFOO <[email protected]> + * + * 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 "libavutil/attributes.h" +#include "libavutil/aarch64/cpu.h" +#include "libavfilter/threshold.h" + +void ff_threshold8_neon(const uint8_t *in, const uint8_t *threshold, + const uint8_t *min, const uint8_t *max, + uint8_t *out, + ptrdiff_t ilinesize, ptrdiff_t tlinesize, + ptrdiff_t flinesize, ptrdiff_t slinesize, + ptrdiff_t olinesize, + int w, int h); + +void ff_threshold16_neon(const uint8_t *in, const uint8_t *threshold, + const uint8_t *min, const uint8_t *max, + uint8_t *out, + ptrdiff_t ilinesize, ptrdiff_t tlinesize, + ptrdiff_t flinesize, ptrdiff_t slinesize, + ptrdiff_t olinesize, + int w, int h); + +av_cold void ff_threshold_init_aarch64(ThresholdContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) { + if (s->depth == 8) + s->threshold = ff_threshold8_neon; + else + s->threshold = ff_threshold16_neon; + } +} diff --git a/libavfilter/aarch64/vf_threshold_neon.S b/libavfilter/aarch64/vf_threshold_neon.S new file mode 100644 index 0000000000..415f3974b9 --- /dev/null +++ b/libavfilter/aarch64/vf_threshold_neon.S @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2026 DROOdotFOO <[email protected]> + * + * 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 "libavutil/aarch64/asm.S" + +// Apple packs ints to 4 bytes on the stack; AAPCS-64 pads to 8. +#ifdef __APPLE__ +.set SP_INT, 4 +#else +.set SP_INT, 8 +#endif + +.macro THRESHOLD bits, vecsz, shape, ldop, stop, step +function ff_threshold\bits\()_neon, export=1 + stp x19, x20, [sp, #-16]! + ldp x8, x9, [sp, #16] // slinesize, olinesize + ldr w10, [sp, #32] // w + ldr w11, [sp, #32+SP_INT] // h + cmp w11, #0 + b.le 9f + cmp w10, #0 + b.le 9f +1: + mov x12, x0 + mov x13, x1 + mov x14, x2 + mov x15, x3 + mov x16, x4 + mov w17, w10 +2: + cmp w17, #(2*\vecsz) + b.lt 3f + ld1 {v0.16b, v1.16b}, [x12], #32 + ld1 {v2.16b, v3.16b}, [x13], #32 + ld1 {v4.16b, v5.16b}, [x14], #32 + ld1 {v6.16b, v7.16b}, [x15], #32 + cmhs v16.\shape, v2.\shape, v0.\shape // thr >= in + cmhs v17.\shape, v3.\shape, v1.\shape + bsl v16.16b, v4.16b, v6.16b // mask ? min : max + bsl v17.16b, v5.16b, v7.16b + st1 {v16.16b, v17.16b}, [x16], #32 + sub w17, w17, #(2*\vecsz) + b 2b +3: + cmp w17, #\vecsz + b.lt 4f + ld1 {v0.16b}, [x12], #16 + ld1 {v1.16b}, [x13], #16 + ld1 {v2.16b}, [x14], #16 + ld1 {v3.16b}, [x15], #16 + cmhs v4.\shape, v1.\shape, v0.\shape // thr >= in + bsl v4.16b, v2.16b, v3.16b // mask ? min : max + st1 {v4.16b}, [x16], #16 + sub w17, w17, #\vecsz +4: + cbz w17, 6f +5: + \ldop w19, [x12], #\step + \ldop w20, [x13], #\step + cmp w19, w20 + \ldop w19, [x14], #\step + \ldop w20, [x15], #\step + csel w19, w19, w20, ls + \stop w19, [x16], #\step + subs w17, w17, #1 + b.gt 5b +6: + add x0, x0, x5 + add x1, x1, x6 + add x2, x2, x7 + add x3, x3, x8 + add x4, x4, x9 + subs w11, w11, #1 + b.gt 1b +9: + ldp x19, x20, [sp], #16 + ret +endfunc +.endm + +THRESHOLD 8, 16, 16b, ldrb, strb, 1 +THRESHOLD 16, 8, 8h, ldrh, strh, 2 diff --git a/libavfilter/threshold.h b/libavfilter/threshold.h index 8b55ad6ba1..1efdc9d5e9 100644 --- a/libavfilter/threshold.h +++ b/libavfilter/threshold.h @@ -47,5 +47,6 @@ typedef struct ThresholdContext { } ThresholdContext; void ff_threshold_init_x86(ThresholdContext *s); +void ff_threshold_init_aarch64(ThresholdContext *s); #endif /* AVFILTER_THRESHOLD_H */ diff --git a/libavfilter/vf_threshold_init.h b/libavfilter/vf_threshold_init.h index fb319c6cf8..87e2ef20f9 100644 --- a/libavfilter/vf_threshold_init.h +++ b/libavfilter/vf_threshold_init.h @@ -86,6 +86,8 @@ av_unused static void ff_threshold_init(ThresholdContext *s) #if ARCH_X86 && HAVE_X86ASM ff_threshold_init_x86(s); +#elif ARCH_AARCH64 + ff_threshold_init_aarch64(s); #endif } -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
