flacdsp: arm optimised lpc filter
authorMans Rullgard <mans@mansr.com>
Thu, 5 Jul 2012 21:47:41 +0000 (22:47 +0100)
committerMans Rullgard <mans@mansr.com>
Sat, 15 Sep 2012 22:54:21 +0000 (23:54 +0100)
libavcodec/arm/Makefile
libavcodec/arm/flacdsp_arm.S [new file with mode: 0644]
libavcodec/arm/flacdsp_init_arm.c [new file with mode: 0644]
libavcodec/flacdsp.c
libavcodec/flacdsp.h
libavutil/arm/asm.S

index a8e531c..745a5bd 100644 (file)
@@ -8,6 +8,9 @@ OBJS-$(CONFIG_DCA_DECODER)             += arm/dcadsp_init_arm.o         \
 
 ARMV6-OBJS-$(CONFIG_AC3DSP)            += arm/ac3dsp_armv6.o
 
+OBJS-$(CONFIG_FLAC_DECODER)            += arm/flacdsp_init_arm.o        \
+                                          arm/flacdsp_arm.o             \
+
 OBJS-$(CONFIG_MPEGAUDIODSP)            += arm/mpegaudiodsp_init_arm.o
 ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP)      += arm/mpegaudiodsp_fixed_armv6.o
 
diff --git a/libavcodec/arm/flacdsp_arm.S b/libavcodec/arm/flacdsp_arm.S
new file mode 100644 (file)
index 0000000..d4441da
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
+ *
+ * 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 flac_lpc_16_1_arm
+        ldr             r12, [sp]
+        push            {r4, lr}
+        ldr             r1,  [r1]
+        subs            r12, r12, #2
+        ldr             lr,  [r0], #4
+        beq             2f
+        it              lt
+        poplt           {r4, pc}
+1:
+        mul             r4,  lr,  r1
+        ldm             r0,  {r2, lr}
+        add_sh          r2,  r2,  r4,  asr r3
+        mul             r4,  r2,  r1
+        subs            r12, r12, #2
+        add_sh          lr,  lr,  r4,  asr r3
+        stm             r0!, {r2, lr}
+        bgt             1b
+        it              lt
+        poplt           {r4, pc}
+2:
+        mul             r4,  lr,  r1
+        ldr             r2,  [r0]
+        add_sh          r2,  r2,  r4,  asr r3
+        str             r2,  [r0]
+        pop             {r4, pc}
+endfunc
+
+function flac_lpc_16_2_arm
+        ldr             r12, [sp]
+        subs            r12, r12, r2
+        it              le
+        bxle            lr
+
+        push            {r4-r9, lr}
+        ldm             r0!, {r6, r7}
+        ldm             r1,  {r8, r9}
+        subs            r12, r12, #1
+        beq             2f
+1:
+        mul             r4,  r6,  r8
+        mul             r5,  r7,  r8
+        mla             r4,  r7,  r9,  r4
+        ldm             r0,  {r6, r7}
+        add_sh          r6,  r6,  r4,  asr r3
+        mla             r5,  r6,  r9,  r5
+        add_sh          r7,  r7,  r5,  asr r3
+        stm             r0!, {r6, r7}
+        subs            r12, r12, #2
+        bgt             1b
+        it              lt
+        poplt           {r4-r9, pc}
+2:
+        mul             r4,  r6,  r8
+        mla             r4,  r7,  r9,  r4
+        ldr             r5,  [r0]
+        add_sh          r5,  r5,  r4,  asr r3
+        str             r5,  [r0]
+        pop             {r4-r9, pc}
+endfunc
+
+function ff_flac_lpc_16_arm, export=1
+        cmp             r2,  #2
+        blt             flac_lpc_16_1_arm
+        beq             flac_lpc_16_2_arm
+
+        ldr             r12, [sp]
+        subs            r12, r12, r2
+        it              le
+        bxle            lr
+
+        push            {r4-r9, lr}
+
+        subs            r12, r12, #1
+        beq             3f
+1:
+        sub             lr,  r2,  #2
+        mov             r4,  #0
+        mov             r5,  #0
+
+        ldr             r7,  [r0], #4
+        ldr             r9,  [r1], #4
+2:
+        mla             r4,  r7,  r9,  r4
+        ldm             r0!, {r6, r7}
+        mla             r5,  r6,  r9,  r5
+        ldm             r1!, {r8, r9}
+        mla             r4,  r6,  r8,  r4
+        subs            lr,  lr,  #2
+        mla             r5,  r7,  r8,  r5
+        bgt             2b
+        blt             6f
+
+        mla             r4,  r7,  r9,  r4
+        ldr             r7,  [r0], #4
+        mla             r5,  r7,  r9,  r5
+        ldr             r9,  [r1], #4
+6:
+        mla             r4,  r7,  r9,  r4
+        ldm             r0,  {r6, r7}
+        add_sh          r6,  r6,  r4,  asr r3
+        mla             r5,  r6,  r9,  r5
+        add_sh          r7,  r7,  r5,  asr r3
+        stm             r0!, {r6, r7}
+        sub             r0,  r0,  r2,  lsl #2
+        sub             r1,  r1,  r2,  lsl #2
+
+        subs            r12, r12, #2
+        bgt             1b
+        it              lt
+        poplt           {r4-r9, pc}
+3:
+        mov             r4,  #0
+4:
+        ldr             r5,  [r1], #4
+        ldr             r6,  [r0], #4
+        mla             r4,  r5,  r6,  r4
+        subs            r2,  r2,  #1
+        bgt             4b
+        ldr             r5,  [r0]
+        add_sh          r5,  r5,  r4,  asr r3
+        str             r5,  [r0]
+        pop             {r4-r9, pc}
+endfunc
diff --git a/libavcodec/arm/flacdsp_init_arm.c b/libavcodec/arm/flacdsp_init_arm.c
new file mode 100644 (file)
index 0000000..0530cf7
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
+ *
+ * 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 "libavcodec/flacdsp.h"
+#include "config.h"
+
+void ff_flac_lpc_16_arm(int32_t *samples, const int coeffs[32], int order,
+                        int qlevel, int len);
+
+av_cold void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt,
+                                 int bps)
+{
+    if (bps <= 16)
+        c->lpc = ff_flac_lpc_16_arm;
+}
index 88d689d..3f4f710 100644 (file)
@@ -21,6 +21,7 @@
 #include "libavutil/attributes.h"
 #include "libavutil/samplefmt.h"
 #include "flacdsp.h"
+#include "config.h"
 
 #define SAMPLE_SIZE 16
 #define PLANAR 0
@@ -119,4 +120,7 @@ av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt,
         c->decorrelate[3] = flac_decorrelate_ms_c_16p;
         break;
     }
+
+    if (ARCH_ARM)
+        ff_flacdsp_init_arm(c, fmt, bps);
 }
index 1651553..429daab 100644 (file)
@@ -30,5 +30,6 @@ typedef struct FLACDSPContext {
 } FLACDSPContext;
 
 void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int bps);
+void ff_flacdsp_init_arm(FLACDSPContext *c, enum AVSampleFormat fmt, int bps);
 
 #endif /* AVCODEC_FLACDSP_H */
index 1508180..7b3832a 100644 (file)
@@ -186,6 +186,12 @@ ELF     .size   \name, . - \name
 #endif
 .endm
 
+.macro  add_sh          rd,  rn,  rm,  sh:vararg
+A       add             \rd, \rn, \rm, \sh
+T       mov             \rm, \rm, \sh
+T       add             \rd, \rn, \rm
+.endm
+
 .macro  ldr_pre         rt,  rn,  rm:vararg
 A       ldr             \rt, [\rn, \rm]!
 T       add             \rn, \rn, \rm