diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index 6cbb0b9070..2a2ca977ab 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -35,6 +35,8 @@ 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 +OBJS-$(CONFIG_ADPCM_G722_ENCODER) += arm/g722dsp_init_arm.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 @@ -131,6 +133,8 @@ NEON-OBJS-$(CONFIG_AAC_DECODER) += arm/aacpsdsp_neon.o \ NEON-OBJS-$(CONFIG_APE_DECODER) += arm/apedsp_neon.o NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_neon.o \ arm/synth_filter_neon.o +NEON-OBJS-$(CONFIG_ADPCM_G722_DECODER) += arm/g722dsp_neon.o +NEON-OBJS-$(CONFIG_ADPCM_G722_ENCODER) += arm/g722dsp_neon.o NEON-OBJS-$(CONFIG_RV30_DECODER) += arm/rv34dsp_neon.o NEON-OBJS-$(CONFIG_RV40_DECODER) += arm/rv34dsp_neon.o \ arm/rv40dsp_neon.o diff --git a/libavcodec/arm/g722dsp_init_arm.c b/libavcodec/arm/g722dsp_init_arm.c new file mode 100644 index 0000000000..5edf619f17 --- /dev/null +++ b/libavcodec/arm/g722dsp_init_arm.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 Peter Meerwald + * + * 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 + +#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 0000000000..5fa3c279e9 --- /dev/null +++ b/libavcodec/arm/g722dsp_neon.S @@ -0,0 +1,69 @@ +/* + * ARM NEON optimised DSP functions for G722 coding + * Copyright (c) 2015 Peter Meerwald + * + * 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 "libavutil/arm/asm.S" + +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 {d16,d17,d18}, [r3,:64]! /* load qmf_coeffs */ + vmull.s16 q0, d2, d16 + vmlal.s16 q0, d3, d17 + vmlal.s16 q0, d4, d18 + + vld1.s16 {d5,d6,d7}, [r0]! /* load prev_samples */ + vld1.s16 {d19,d20,d21}, [r3,:64]! /* load qmf_coeffs */ + vmlal.s16 q0, d5, d19 + vmlal.s16 q0, d6, d20 + vmlal.s16 q0, d7, d21 + + vadd.s32 d0, d1, d0 + vrev64.32 d0, d0 + vst1.s32 {d0}, [r1] + bx lr +endfunc + +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 f28b1a317c..c7e41ff9c7 100644 --- a/libavcodec/g722dsp.c +++ b/libavcodec/g722dsp.c @@ -68,4 +68,7 @@ static void g722_apply_qmf(const int16_t *prev_samples, int xout[2]) av_cold void ff_g722dsp_init(G722DSPContext *c) { c->apply_qmf = g722_apply_qmf; + + if (ARCH_ARM) + ff_g722dsp_init_arm(c); } diff --git a/libavcodec/g722dsp.h b/libavcodec/g722dsp.h index 2cc50d9a50..ecd6a47fcb 100644 --- a/libavcodec/g722dsp.h +++ b/libavcodec/g722dsp.h @@ -28,5 +28,6 @@ typedef struct G722DSPContext { } G722DSPContext; void ff_g722dsp_init(G722DSPContext *c); +void ff_g722dsp_init_arm(G722DSPContext *c); #endif /* AVCODEC_G722DSP_H */