On Fri, 30 Jan 2015, Peter Meerwald wrote:
Signed-off-by: Peter Meerwald <[email protected]>
---
libavcodec/arm/Makefile | 4 +++
libavcodec/arm/asm-offsets.h | 5 +++
libavcodec/arm/g722dsp_init_arm.c | 34 ++++++++++++++++++++
libavcodec/arm/g722dsp_neon.S | 67 +++++++++++++++++++++++++++++++++++++++
libavcodec/g722dsp.c | 3 ++
libavcodec/g722dsp.h | 1 +
6 files changed, 114 insertions(+)
create mode 100644 libavcodec/arm/g722dsp_init_arm.c
create mode 100644 libavcodec/arm/g722dsp_neon.S
diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile
index 6cbb0b9..8435f86 100644
--- a/libavcodec/arm/Makefile
+++ b/libavcodec/arm/Makefile
@@ -35,6 +35,10 @@ OBJS-$(CONFIG_APE_DECODER) +=
arm/apedsp_init_arm.o
OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_init_arm.o
OBJS-$(CONFIG_FLAC_DECODER) += arm/flacdsp_init_arm.o \
arm/flacdsp_arm.o
+OBJS-$(CONFIG_ADPCM_G722_DECODER) += arm/g722dsp_init_arm.o \
+ arm/g722dsp_neon.o
+OBJS-$(CONFIG_ADPCM_G722_ENCODER) += arm/g722dsp_init_arm.o \
+ arm/g722dsp_neon.o
OBJS-$(CONFIG_MLP_DECODER) += arm/mlpdsp_init_arm.o
OBJS-$(CONFIG_VC1_DECODER) += arm/vc1dsp_init_arm.o
OBJS-$(CONFIG_VORBIS_DECODER) += arm/vorbisdsp_init_arm.o
diff --git a/libavcodec/arm/asm-offsets.h b/libavcodec/arm/asm-offsets.h
index 0ea2f04..97b1339 100644
--- a/libavcodec/arm/asm-offsets.h
+++ b/libavcodec/arm/asm-offsets.h
@@ -29,4 +29,9 @@
#define H263_AIC 0x40
#define INTER_SCANTAB_RASTER_END 0x88
+/* struct G722Band */
+#define S_ZERO 0x04
+#define DIFF_MEM 0x10
+#define ZERO_MEM 0x28
+
#endif /* AVCODEC_ARM_ASM_OFFSETS_H */
What are these constants needed for? A yet to be posted asm version of
s_zero, or a version of it that was investigated but turned out not to be
worthwhile? In any case it doesn't belong in this patch.
diff --git a/libavcodec/arm/g722dsp_init_arm.c
b/libavcodec/arm/g722dsp_init_arm.c
new file mode 100644
index 0000000..5d92338
--- /dev/null
+++ b/libavcodec/arm/g722dsp_init_arm.c
@@ -0,0 +1,34 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/g722dsp.h"
+
+extern void ff_g722_apply_qmf_neon(const int16_t *prev_samples, int xout[2]);
+
+av_cold void ff_g722dsp_init_arm(G722DSPContext *dsp)
+{
+ int cpu_flags = av_get_cpu_flags();
+
+ if (have_neon(cpu_flags))
+ dsp->apply_qmf = ff_g722_apply_qmf_neon;
+}
+
diff --git a/libavcodec/arm/g722dsp_neon.S b/libavcodec/arm/g722dsp_neon.S
new file mode 100644
index 0000000..639bb4c
--- /dev/null
+++ b/libavcodec/arm/g722dsp_neon.S
@@ -0,0 +1,67 @@
+/*
+ * ARM NEON optimised DSP functions for G722 coding
+ * Copyright (c) 2015 Peter Meerwald <[email protected]>
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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.
+ */
+
+#include "libavutil/arm/asm.S"
+#include "asm-offsets.h"
This include isn't necessary (yet at least)
+
+function ff_g722_apply_qmf_neon, export=1, align=4
+ movrel r3, qmf_coeffs
+ vld1.s16 {d2,d3,d4}, [r0]! /* load prev_samples */
+ vld1.s16 {d8,d9,d10}, [r3:64]! /* load qmf_coeffs */
All our existing arm assembly uses the form [r3,:64] for these loads, i.e.
an extra comma before the colon. gas-preprocessor (which we use for
reformatting the assembly for lesser assemblers, for iOS and Windows
builds) currently only matches the form with the extra comma. I'll fix
that, but to avoid forcing users to upgrade it immediately it'd probably
be better to use the common syntax here as well.
+ vmull.s16 q0, d2, d8
+ vmlal.s16 q0, d3, d9
+ vmlal.s16 q0, d4, d10
+
+ vld1.s16 {d5,d6,d7}, [r0]! /* load prev_samples */
+ vld1.s16 {d11,d12,d13}, [r3:64]! /* load qmf_coeffs */
+ vmlal.s16 q0, d5, d11
+ vmlal.s16 q0, d6, d12
+ vmlal.s16 q0, d7, d13
+
+ vadd.s32 d0, d1, d0
+ vrev64.32 d0, d0
+ vst1.s32 {d0}, [r1]
+ bx lr
+endfunc
This clobbers the callee-saved registers d8-d15 (q4-q7). Building with
--enable-neon-clobber-test can help catch such issues.
+
+const qmf_coeffs, align=4
+ .hword 3
+ .hword -11
+ .hword -11
+ .hword 53
+ .hword 12
+ .hword -156
+ .hword 32
+ .hword 362
+ .hword -210
+ .hword -805
+ .hword 951
+ .hword 3876
+ .hword 3876
+ .hword 951
+ .hword -805
+ .hword -210
+ .hword 362
+ .hword 32
+ .hword -156
+ .hword 12
+ .hword 53
+ .hword -11
+ .hword -11
+ .hword 3
+endconst
+
diff --git a/libavcodec/g722dsp.c b/libavcodec/g722dsp.c
index 7d8b23c..a303303 100644
--- a/libavcodec/g722dsp.c
+++ b/libavcodec/g722dsp.c
@@ -47,4 +47,7 @@ static void g722_apply_qmf(const int16_t *prev_samples, int
xout[2])
void ff_g722dsp_init(struct G722DSPContext *c) {
c->apply_qmf = g722_apply_qmf;
+
+ if (ARCH_ARM)
+ ff_g722dsp_init_arm(c);
}
The empty line had some trailing whitespace here
Other than that, this looks good.
// Martin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel