diff --git a/libavfilter/riscv/Makefile b/libavfilter/riscv/Makefile index 14a4470d96..32b07eec1a 100644 --- a/libavfilter/riscv/Makefile +++ b/libavfilter/riscv/Makefile @@ -1,4 +1,6 @@ OBJS-$(CONFIG_AFIR_FILTER) += riscv/af_afir_init.o RVV-OBJS-$(CONFIG_AFIR_FILTER) += riscv/af_afir_rvv.o +OBJS-$(CONFIG_BLACKDETECT_FILTER) += riscv/vf_blackdetect_init.o +RVV-OBJS-$(CONFIG_BLACKDETECT_FILTER) += riscv/vf_blackdetect_rvv.o SHLIBOBJS += riscv/cpu_common.o diff --git a/libavfilter/riscv/vf_blackdetect_init.c b/libavfilter/riscv/vf_blackdetect_init.c new file mode 100644 index 0000000000..665603c114 --- /dev/null +++ b/libavfilter/riscv/vf_blackdetect_init.c @@ -0,0 +1,42 @@ +/* + * Copyright © 2025 Rémi Denis-Courmont. + * + * 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 "config.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavfilter/vf_blackdetect.h" + +unsigned ff_count_pixels_8_rvv(const uint8_t *src, ptrdiff_t stride, + ptrdiff_t width, ptrdiff_t height, + unsigned threshold); + +ff_blackdetect_fn ff_blackdetect_get_fn_riscv(int depth) +{ +#if HAVE_RVV + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_RVV_I32) { + if (depth <= 8) + return ff_count_pixels_8_rvv; + } +#endif + return NULL; +} diff --git a/libavfilter/riscv/vf_blackdetect_rvv.S b/libavfilter/riscv/vf_blackdetect_rvv.S new file mode 100644 index 0000000000..bd753effc0 --- /dev/null +++ b/libavfilter/riscv/vf_blackdetect_rvv.S @@ -0,0 +1,45 @@ +/* + * Copyright © 2025 Rémi Denis-Courmont. + * + * 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/riscv/asm.S" + +func ff_count_pixels_8_rvv, zve32x + lpad 0 + mv a5, zero + sub a1, a1, a2 +1: + mv t2, a2 + addi a3, a3, -1 +2: + vsetvli t1, t2, e8, m8, ta, ma + vle8.v v8, (a0) + sub t2, t2, t1 + vmsleu.vx v0, v8, a4 + add a0, t1, a0 + vcpop.m t3, v0 + add a5, t3, a5 + bnez t2, 2b + + add a0, a0, a1 + bnez a3, 1b + + mv a0, a5 + ret +endfunc diff --git a/libavfilter/vf_blackdetect.h b/libavfilter/vf_blackdetect.h index e51beda3a4..e5b3aa8833 100644 --- a/libavfilter/vf_blackdetect.h +++ b/libavfilter/vf_blackdetect.h @@ -28,6 +28,7 @@ typedef unsigned (*ff_blackdetect_fn)(const uint8_t *src, ptrdiff_t stride, ptrdiff_t width, ptrdiff_t height, unsigned threshold); +ff_blackdetect_fn ff_blackdetect_get_fn_riscv(int depth); ff_blackdetect_fn ff_blackdetect_get_fn_x86(int depth); static unsigned count_pixels8_c(const uint8_t *src, ptrdiff_t stride, @@ -60,9 +61,14 @@ static unsigned count_pixels16_c(const uint8_t *src, ptrdiff_t stride, static inline ff_blackdetect_fn ff_blackdetect_get_fn(int depth) { - ff_blackdetect_fn fn = NULL; -#if ARCH_X86 && HAVE_X86ASM + ff_blackdetect_fn fn; + +#if ARCH_RISCV + fn = ff_blackdetect_get_fn_riscv(depth); +#elif ARCH_X86 && HAVE_X86ASM fn = ff_blackdetect_get_fn_x86(depth); +#else + fn = NULL; #endif if (!fn)