[PR] lavfi/scene_sad: add RISC-V V implementations (PR #23959)
mengbinghan via ffmpeg-devel <[email protected]> Thu, 30 Jul 2026 11:03:07 -0000
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <178540938784.51.10885155555131184836@29965ddac10e> |
PR #23959 opened by mengbinghan URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23959 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23959.patch # Summary of changes Add RISC-V Vector implementations of scene SAD for 8-bit and 16-bit pixel formats. # Testing - `fate-checkasm-scene_sad` passed on SpacemiT X100 - 100 repeated checkasm runs passed on SpacemiT X100 # Performance SpacemiT X100: scene_sad8_c: 91408.8 (1.00x) scene_sad8_rvv_i32: 12650.4 (7.22x) scene_sad16_c: 76539.0 (1.00x) scene_sad16_rvv_i32: 17237.9 (4.44x) >From 554fbeab27d783a344e708cd7be921e6e7292d0c Mon Sep 17 00:00:00 2001 From: mengbinghan <[email protected]> Date: Mon, 27 Jul 2026 16:22:10 +0800 Subject: [PATCH 1/2] lavfi/scene_sad: add RISC-V V 8-bit implementation SpacemiT X100: scene_sad8_c: 91408.8 (1.00x) scene_sad8_rvv_i32: 12650.4 (7.22x) Signed-off-by: mengbinghan <[email protected]> --- libavfilter/riscv/Makefile | 2 + libavfilter/riscv/scene_sad_init.c | 37 ++++++++++++++ libavfilter/riscv/scene_sad_rvv.S | 80 ++++++++++++++++++++++++++++++ libavfilter/scene_sad.c | 4 +- libavfilter/scene_sad.h | 2 + 5 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 libavfilter/riscv/scene_sad_init.c create mode 100644 libavfilter/riscv/scene_sad_rvv.S diff --git a/libavfilter/riscv/Makefile b/libavfilter/riscv/Makefile index 32b07eec1a..3934b3da8b 100644 --- a/libavfilter/riscv/Makefile +++ b/libavfilter/riscv/Makefile @@ -2,5 +2,7 @@ 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 +OBJS-$(CONFIG_SCENE_SAD) += riscv/scene_sad_init.o +RVV-OBJS-$(CONFIG_SCENE_SAD) += riscv/scene_sad_rvv.o SHLIBOBJS += riscv/cpu_common.o diff --git a/libavfilter/riscv/scene_sad_init.c b/libavfilter/riscv/scene_sad_init.c new file mode 100644 index 0000000000..e7ed3ad707 --- /dev/null +++ b/libavfilter/riscv/scene_sad_init.c @@ -0,0 +1,37 @@ +/* + * 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/cpu.h" +#include "libavfilter/scene_sad.h" + +void ff_scene_sad8_rvv(SCENE_SAD_PARAMS); + +ff_scene_sad_fn ff_scene_sad_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_scene_sad8_rvv; + } +#endif + return NULL; +} diff --git a/libavfilter/riscv/scene_sad_rvv.S b/libavfilter/riscv/scene_sad_rvv.S new file mode 100644 index 0000000000..95c398a5d5 --- /dev/null +++ b/libavfilter/riscv/scene_sad_rvv.S @@ -0,0 +1,80 @@ +/* + * 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" + +.macro scene_sad_accumulate value +#if __riscv_xlen >= 64 + add t3, t3, \value +#else + add t0, t3, \value + sltu \value, t0, t3 + mv t3, t0 + add t4, t4, \value +#endif +.endm + +.macro scene_sad_store +#if __riscv_xlen >= 64 + sd t3, (a6) +#else + sw t3, 0(a6) + sw t4, 4(a6) +#endif +.endm + +func ff_scene_sad8_rvv, zve32x + lpad 0 + mv t3, zero +#if __riscv_xlen < 64 + mv t4, zero +#endif + beqz a4, 3f + beqz a5, 3f + sub t5, a1, a4 + sub t6, a3, a4 +1: + mv t1, a4 +2: + vsetvli t0, t1, e8, m4, ta, ma + vle8.v v8, (a0) + sub t1, t1, t0 + vle8.v v12, (a2) + add a0, a0, t0 + vwsubu.vv v16, v8, v12 + add a2, a2, t0 + vwsubu.vv v24, v12, v8 + vsetvli zero, zero, e16, m8, ta, ma + vmax.vv v16, v16, v24 + vsetivli zero, 1, e32, m1, ta, ma + vmv.s.x v0, zero + vsetvli zero, t0, e16, m8, ta, ma + vwredsum.vs v0, v16, v0 + vsetivli zero, 1, e32, m1, ta, ma + vmv.x.s t2, v0 + scene_sad_accumulate t2 + bnez t1, 2b + + add a0, a0, t5 + add a2, a2, t6 + addi a5, a5, -1 + bnez a5, 1b +3: + scene_sad_store + ret +endfunc diff --git a/libavfilter/scene_sad.c b/libavfilter/scene_sad.c index 56177ced76..a8978d8161 100644 --- a/libavfilter/scene_sad.c +++ b/libavfilter/scene_sad.c @@ -59,7 +59,9 @@ void ff_scene_sad_c(SCENE_SAD_PARAMS) ff_scene_sad_fn ff_scene_sad_get_fn(int depth) { ff_scene_sad_fn sad = NULL; -#if ARCH_X86 && HAVE_X86ASM +#if ARCH_RISCV + sad = ff_scene_sad_get_fn_riscv(depth); +#elif ARCH_X86 && HAVE_X86ASM sad = ff_scene_sad_get_fn_x86(depth); #endif if (!sad) { diff --git a/libavfilter/scene_sad.h b/libavfilter/scene_sad.h index 173a051f2b..b76135dcff 100644 --- a/libavfilter/scene_sad.h +++ b/libavfilter/scene_sad.h @@ -37,6 +37,8 @@ void ff_scene_sad_c(SCENE_SAD_PARAMS); void ff_scene_sad16_c(SCENE_SAD_PARAMS); +ff_scene_sad_fn ff_scene_sad_get_fn_riscv(int depth); + ff_scene_sad_fn ff_scene_sad_get_fn_x86(int depth); ff_scene_sad_fn ff_scene_sad_get_fn(int depth); -- 2.52.0 >From 387ab597c461282bc98670abdefa36807905f657 Mon Sep 17 00:00:00 2001 From: mengbinghan <[email protected]> Date: Mon, 27 Jul 2026 16:22:36 +0800 Subject: [PATCH 2/2] lavfi/scene_sad: add RISC-V V 16-bit implementation SpacemiT X100: scene_sad16_c: 76539.0 (1.00x) scene_sad16_rvv_i32: 17237.9 (4.44x) Signed-off-by: mengbinghan <[email protected]> --- libavfilter/riscv/scene_sad_init.c | 3 +++ libavfilter/riscv/scene_sad_rvv.S | 42 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/libavfilter/riscv/scene_sad_init.c b/libavfilter/riscv/scene_sad_init.c index e7ed3ad707..b45d1e2941 100644 --- a/libavfilter/riscv/scene_sad_init.c +++ b/libavfilter/riscv/scene_sad_init.c @@ -22,6 +22,7 @@ #include "libavfilter/scene_sad.h" void ff_scene_sad8_rvv(SCENE_SAD_PARAMS); +void ff_scene_sad16_rvv(SCENE_SAD_PARAMS); ff_scene_sad_fn ff_scene_sad_get_fn_riscv(int depth) { @@ -31,6 +32,8 @@ ff_scene_sad_fn ff_scene_sad_get_fn_riscv(int depth) if (flags & AV_CPU_FLAG_RVV_I32) { if (depth <= 8) return ff_scene_sad8_rvv; + if (depth <= 16) + return ff_scene_sad16_rvv; } #endif return NULL; diff --git a/libavfilter/riscv/scene_sad_rvv.S b/libavfilter/riscv/scene_sad_rvv.S index 95c398a5d5..349bcb744e 100644 --- a/libavfilter/riscv/scene_sad_rvv.S +++ b/libavfilter/riscv/scene_sad_rvv.S @@ -78,3 +78,45 @@ func ff_scene_sad8_rvv, zve32x scene_sad_store ret endfunc + +func ff_scene_sad16_rvv, zve32x + lpad 0 + mv t3, zero +#if __riscv_xlen < 64 + mv t4, zero +#endif + beqz a4, 3f + beqz a5, 3f + slli t0, a4, 1 + sub t5, a1, t0 + sub t6, a3, t0 +1: + mv t1, a4 +2: + vsetvli t0, t1, e16, m4, ta, ma + vle16.v v8, (a0) + sub t1, t1, t0 + vle16.v v12, (a2) + slli t2, t0, 1 + add a0, a0, t2 + vmaxu.vv v16, v8, v12 + add a2, a2, t2 + vminu.vv v20, v8, v12 + vsub.vv v16, v16, v20 + vsetivli zero, 1, e32, m1, ta, ma + vmv.s.x v0, zero + vsetvli zero, t0, e16, m4, ta, ma + vwredsumu.vs v0, v16, v0 + vsetivli zero, 1, e32, m1, ta, ma + vmv.x.s t2, v0 + scene_sad_accumulate t2 + bnez t1, 2b + + add a0, a0, t5 + add a2, a2, t6 + addi a5, a5, -1 + bnez a5, 1b +3: + scene_sad_store + ret +endfunc -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]