[FFmpeg-devel] [PATCH] libswresample/riscv:add RVV optimized for conv_flt_to_s16
daichengrong at iscas.ac.cn
daichengrong at iscas.ac.cn
Thu Mar 20 11:30:01 EET 2025
From: daichengrong <daichengrong at iscas.ac.cn>
This patch introduces RVV optimized for conv_flt_to_s16.
On Banana PI F3, it gets an average improvement of 5% for 20000 SAMPLES.
---
libswresample/audioconvert.c | 2 +
libswresample/riscv/Makefile | 3 ++
libswresample/riscv/audio_convert_init.c | 50 ++++++++++++++++++++++++
libswresample/riscv/audio_convert_rvv.S | 46 ++++++++++++++++++++++
libswresample/swresample_internal.h | 4 ++
5 files changed, 105 insertions(+)
create mode 100644 libswresample/riscv/Makefile
create mode 100644 libswresample/riscv/audio_convert_init.c
create mode 100644 libswresample/riscv/audio_convert_rvv.S
diff --git a/libswresample/audioconvert.c b/libswresample/audioconvert.c
index 04108fb966..49b56b6b5e 100644
--- a/libswresample/audioconvert.c
+++ b/libswresample/audioconvert.c
@@ -182,6 +182,8 @@ AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt,
swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);
#elif ARCH_AARCH64
swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);
+#elif ARCH_RISCV
+ swri_audio_convert_init_riscv(ctx, out_fmt, in_fmt, channels);
#endif
return ctx;
diff --git a/libswresample/riscv/Makefile b/libswresample/riscv/Makefile
new file mode 100644
index 0000000000..01943cec64
--- /dev/null
+++ b/libswresample/riscv/Makefile
@@ -0,0 +1,3 @@
+OBJS += riscv/audio_convert_init.o
+
+RVV-OBJS += riscv/audio_convert_rvv.o
diff --git a/libswresample/riscv/audio_convert_init.c b/libswresample/riscv/audio_convert_init.c
new file mode 100644
index 0000000000..7bea7e6eb4
--- /dev/null
+++ b/libswresample/riscv/audio_convert_init.c
@@ -0,0 +1,50 @@
+/*
+ * This file is part of libswresample.
+ *
+ * libswresample 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.
+ *
+ * libswresample 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 libswresample; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/riscv/cpu.h"
+#include "libavutil/samplefmt.h"
+#include "libswresample/swresample_internal.h"
+#include "libswresample/audioconvert.h"
+
+void swri_oldapi_conv_flt_to_s16_rvv(int16_t *dst, const float *src, int len);
+
+static void conv_flt_to_s16_rvv(uint8_t **dst, const uint8_t **src, int len){
+ swri_oldapi_conv_flt_to_s16_rvv((int16_t*)*dst, (const float*)*src, len);
+}
+
+av_cold void swri_audio_convert_init_riscv(struct AudioConvert *ac,
+ enum AVSampleFormat out_fmt,
+ enum AVSampleFormat in_fmt,
+ int channels)
+{
+ int flags = av_get_cpu_flags();
+
+ ac->simd_f= NULL;
+
+#if HAVE_RVV
+ if (flags & AV_CPU_FLAG_RVV_F32) {
+ if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP)
+ ac->simd_f = conv_flt_to_s16_rvv;
+ }
+#endif
+}
diff --git a/libswresample/riscv/audio_convert_rvv.S b/libswresample/riscv/audio_convert_rvv.S
new file mode 100644
index 0000000000..d9d58d6d5e
--- /dev/null
+++ b/libswresample/riscv/audio_convert_rvv.S
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2025 daichengrong <daichengrong at iscas.ac.cn>
+ *
+ * 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/riscv/asm.S"
+
+func swri_oldapi_conv_flt_to_s16_rvv, zve32f
+ mv t1, a0
+ mv t2, a1
+ #mv t3, a2
+1: vsetvli a4,a2,e32,m8,ta,ma
+ vle32.v v8,(t2)
+ sub a2, a2, a4
+ li t0, (1<<15)
+ sext.w t0,t0
+ fcvt.s.w fa2, t0
+ vfmul.vf v16, v8, fa2
+ vfcvt.x.f.v v8, v16
+ vsetvli zero,zero,e16,m4,ta,ma
+ vnclip.wi v16, v8, 0
+ vse16.v v16,(t1)
+ sll a4,a4,0x1
+ add t1, t1, a4
+ sll a4, a4, 0x1
+ add t2, t2, a4
+ bnez a2, 1b
+ mv a0, t1
+ ret
+endfunc
\ No newline at end of file
diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h
index 7e46b16fb2..257f69f6dd 100644
--- a/libswresample/swresample_internal.h
+++ b/libswresample/swresample_internal.h
@@ -216,5 +216,9 @@ void swri_audio_convert_init_x86(struct AudioConvert *ac,
enum AVSampleFormat out_fmt,
enum AVSampleFormat in_fmt,
int channels);
+void swri_audio_convert_init_riscv(struct AudioConvert *ac,
+ enum AVSampleFormat out_fmt,
+ enum AVSampleFormat in_fmt,
+ int channels);
#endif
--
2.43.0
More information about the ffmpeg-devel
mailing list