From e034cc6c60c77dce390b1ac31141b1862bdf8999 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 6 Jan 2013 23:47:30 -0500 Subject: lavc: Move vector_fmul_window to AVFloatDSPContext Signed-off-by: Luca Barbato --- libavutil/arm/float_dsp_init_neon.c | 4 ++ libavutil/arm/float_dsp_neon.S | 47 +++++++++++++++++++++++ libavutil/float_dsp.c | 20 ++++++++++ libavutil/float_dsp.h | 19 ++++++++++ libavutil/ppc/float_dsp_altivec.c | 33 ++++++++++++++++ libavutil/ppc/float_dsp_altivec.h | 4 ++ libavutil/ppc/float_dsp_init.c | 4 ++ libavutil/x86/float_dsp_init.c | 75 +++++++++++++++++++++++++++++++++++++ 8 files changed, 206 insertions(+) (limited to 'libavutil') diff --git a/libavutil/arm/float_dsp_init_neon.c b/libavutil/arm/float_dsp_init_neon.c index 88eb4b3d2a..16ea47154a 100644 --- a/libavutil/arm/float_dsp_init_neon.c +++ b/libavutil/arm/float_dsp_init_neon.c @@ -32,9 +32,13 @@ void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul, void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul, int len); +void ff_vector_fmul_window_neon(float *dst, const float *src0, + const float *src1, const float *win, int len); + void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp) { fdsp->vector_fmul = ff_vector_fmul_neon; fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon; fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_neon; + fdsp->vector_fmul_window = ff_vector_fmul_window_neon; } diff --git a/libavutil/arm/float_dsp_neon.S b/libavutil/arm/float_dsp_neon.S index 6d7bd5236e..540cfc6907 100644 --- a/libavutil/arm/float_dsp_neon.S +++ b/libavutil/arm/float_dsp_neon.S @@ -146,3 +146,50 @@ NOVFP vdup.32 q8, r2 bx lr .unreq len endfunc + +function ff_vector_fmul_window_neon, export=1 + push {r4,r5,lr} + ldr lr, [sp, #12] + sub r2, r2, #8 + sub r5, lr, #2 + add r2, r2, r5, lsl #2 + add r4, r3, r5, lsl #3 + add ip, r0, r5, lsl #3 + mov r5, #-16 + vld1.32 {d0,d1}, [r1,:128]! + vld1.32 {d2,d3}, [r2,:128], r5 + vld1.32 {d4,d5}, [r3,:128]! + vld1.32 {d6,d7}, [r4,:128], r5 +1: subs lr, lr, #4 + vmul.f32 d22, d0, d4 + vrev64.32 q3, q3 + vmul.f32 d23, d1, d5 + vrev64.32 q1, q1 + vmul.f32 d20, d0, d7 + vmul.f32 d21, d1, d6 + beq 2f + vmla.f32 d22, d3, d7 + vld1.32 {d0,d1}, [r1,:128]! + vmla.f32 d23, d2, d6 + vld1.32 {d18,d19},[r2,:128], r5 + vmls.f32 d20, d3, d4 + vld1.32 {d24,d25},[r3,:128]! + vmls.f32 d21, d2, d5 + vld1.32 {d6,d7}, [r4,:128], r5 + vmov q1, q9 + vrev64.32 q11, q11 + vmov q2, q12 + vswp d22, d23 + vst1.32 {d20,d21},[r0,:128]! + vst1.32 {d22,d23},[ip,:128], r5 + b 1b +2: vmla.f32 d22, d3, d7 + vmla.f32 d23, d2, d6 + vmls.f32 d20, d3, d4 + vmls.f32 d21, d2, d5 + vrev64.32 q11, q11 + vswp d22, d23 + vst1.32 {d20,d21},[r0,:128]! + vst1.32 {d22,d23},[ip,:128], r5 + pop {r4,r5,pc} +endfunc diff --git a/libavutil/float_dsp.c b/libavutil/float_dsp.c index 22139defe4..cf33df303c 100644 --- a/libavutil/float_dsp.c +++ b/libavutil/float_dsp.c @@ -52,12 +52,32 @@ static void vector_dmul_scalar_c(double *dst, const double *src, double mul, dst[i] = src[i] * mul; } +static void vector_fmul_window_c(float *dst, const float *src0, + const float *src1, const float *win, int len) +{ + int i, j; + + dst += len; + win += len; + src0 += len; + + for (i = -len, j = len - 1; i < 0; i++, j--) { + float s0 = src0[i]; + float s1 = src1[j]; + float wi = win[i]; + float wj = win[j]; + dst[i] = s0 * wj - s1 * wi; + dst[j] = s0 * wi + s1 * wj; + } +} + void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact) { fdsp->vector_fmul = vector_fmul_c; fdsp->vector_fmac_scalar = vector_fmac_scalar_c; fdsp->vector_fmul_scalar = vector_fmul_scalar_c; fdsp->vector_dmul_scalar = vector_dmul_scalar_c; + fdsp->vector_fmul_window = vector_fmul_window_c; #if ARCH_ARM ff_float_dsp_init_arm(fdsp); diff --git a/libavutil/float_dsp.h b/libavutil/float_dsp.h index 41b73c5b26..d0ceaaf5e1 100644 --- a/libavutil/float_dsp.h +++ b/libavutil/float_dsp.h @@ -81,6 +81,25 @@ typedef struct AVFloatDSPContext { */ void (*vector_dmul_scalar)(double *dst, const double *src, double mul, int len); + + /** + * Overlap/add with window function. + * Used primarily by MDCT-based audio codecs. + * Source and destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 16-byte aligned + * @param src0 first source vector + * constraints: 16-byte aligned + * @param src1 second source vector + * constraints: 16-byte aligned + * @param win half-window vector + * constraints: 16-byte aligned + * @param len length of vector + * constraints: multiple of 4 + */ + void (*vector_fmul_window)(float *dst, const float *src0, + const float *src1, const float *win, int len); } AVFloatDSPContext; /** diff --git a/libavutil/ppc/float_dsp_altivec.c b/libavutil/ppc/float_dsp_altivec.c index 55e3fbe91f..e5fd9aba33 100644 --- a/libavutil/ppc/float_dsp_altivec.c +++ b/libavutil/ppc/float_dsp_altivec.c @@ -36,3 +36,36 @@ void ff_vector_fmul_altivec(float *dst, const float *src0, const float *src1, vec_st(d1, 16, dst + i); } } + +void ff_vector_fmul_window_altivec(float *dst, const float *src0, + const float *src1, const float *win, int len) +{ + vector float zero, t0, t1, s0, s1, wi, wj; + const vector unsigned char reverse = vcprm(3, 2, 1, 0); + int i, j; + + dst += len; + win += len; + src0 += len; + + zero = (vector float)vec_splat_u32(0); + + for (i = -len * 4, j = len * 4 - 16; i < 0; i += 16, j -= 16) { + s0 = vec_ld(i, src0); + s1 = vec_ld(j, src1); + wi = vec_ld(i, win); + wj = vec_ld(j, win); + + s1 = vec_perm(s1, s1, reverse); + wj = vec_perm(wj, wj, reverse); + + t0 = vec_madd(s0, wj, zero); + t0 = vec_nmsub(s1, wi, t0); + t1 = vec_madd(s0, wi, zero); + t1 = vec_madd(s1, wj, t1); + t1 = vec_perm(t1, t1, reverse); + + vec_st(t0, i, dst); + vec_st(t1, j, dst); + } +} diff --git a/libavutil/ppc/float_dsp_altivec.h b/libavutil/ppc/float_dsp_altivec.h index 0b9425bef4..4d46edf61a 100644 --- a/libavutil/ppc/float_dsp_altivec.h +++ b/libavutil/ppc/float_dsp_altivec.h @@ -24,4 +24,8 @@ extern void ff_vector_fmul_altivec(float *dst, const float *src0, const float *src1, int len); +extern void ff_vector_fmul_window_altivec(float *dst, const float *src0, + const float *src1, const float *win, + int len); + #endif /* AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H */ diff --git a/libavutil/ppc/float_dsp_init.c b/libavutil/ppc/float_dsp_init.c index 20527642cc..1134b56926 100644 --- a/libavutil/ppc/float_dsp_init.c +++ b/libavutil/ppc/float_dsp_init.c @@ -32,5 +32,9 @@ void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact) return; fdsp->vector_fmul = ff_vector_fmul_altivec; + + if (!bit_exact) { + fdsp->vector_fmul_window = ff_vector_fmul_window_altivec; + } #endif } diff --git a/libavutil/x86/float_dsp_init.c b/libavutil/x86/float_dsp_init.c index b3b7ff4c3a..56fb32b0d5 100644 --- a/libavutil/x86/float_dsp_init.c +++ b/libavutil/x86/float_dsp_init.c @@ -21,6 +21,7 @@ #include "libavutil/cpu.h" #include "libavutil/float_dsp.h" #include "cpu.h" +#include "asm.h" extern void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1, int len); @@ -40,10 +41,84 @@ extern void ff_vector_dmul_scalar_sse2(double *dst, const double *src, extern void ff_vector_dmul_scalar_avx(double *dst, const double *src, double mul, int len); +#if HAVE_6REGS +static void vector_fmul_window_3dnowext(float *dst, const float *src0, + const float *src1, const float *win, + int len) +{ + x86_reg i = -len * 4; + x86_reg j = len * 4 - 8; + __asm__ volatile ( + "1: \n" + "pswapd (%5, %1), %%mm1 \n" + "movq (%5, %0), %%mm0 \n" + "pswapd (%4, %1), %%mm5 \n" + "movq (%3, %0), %%mm4 \n" + "movq %%mm0, %%mm2 \n" + "movq %%mm1, %%mm3 \n" + "pfmul %%mm4, %%mm2 \n" // src0[len + i] * win[len + i] + "pfmul %%mm5, %%mm3 \n" // src1[j] * win[len + j] + "pfmul %%mm4, %%mm1 \n" // src0[len + i] * win[len + j] + "pfmul %%mm5, %%mm0 \n" // src1[j] * win[len + i] + "pfadd %%mm3, %%mm2 \n" + "pfsub %%mm0, %%mm1 \n" + "pswapd %%mm2, %%mm2 \n" + "movq %%mm1, (%2, %0) \n" + "movq %%mm2, (%2, %1) \n" + "sub $8, %1 \n" + "add $8, %0 \n" + "jl 1b \n" + "femms \n" + : "+r"(i), "+r"(j) + : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len) + ); +} + +static void vector_fmul_window_sse(float *dst, const float *src0, + const float *src1, const float *win, int len) +{ + x86_reg i = -len * 4; + x86_reg j = len * 4 - 16; + __asm__ volatile ( + "1: \n" + "movaps (%5, %1), %%xmm1 \n" + "movaps (%5, %0), %%xmm0 \n" + "movaps (%4, %1), %%xmm5 \n" + "movaps (%3, %0), %%xmm4 \n" + "shufps $0x1b, %%xmm1, %%xmm1 \n" + "shufps $0x1b, %%xmm5, %%xmm5 \n" + "movaps %%xmm0, %%xmm2 \n" + "movaps %%xmm1, %%xmm3 \n" + "mulps %%xmm4, %%xmm2 \n" // src0[len + i] * win[len + i] + "mulps %%xmm5, %%xmm3 \n" // src1[j] * win[len + j] + "mulps %%xmm4, %%xmm1 \n" // src0[len + i] * win[len + j] + "mulps %%xmm5, %%xmm0 \n" // src1[j] * win[len + i] + "addps %%xmm3, %%xmm2 \n" + "subps %%xmm0, %%xmm1 \n" + "shufps $0x1b, %%xmm2, %%xmm2 \n" + "movaps %%xmm1, (%2, %0) \n" + "movaps %%xmm2, (%2, %1) \n" + "sub $16, %1 \n" + "add $16, %0 \n" + "jl 1b \n" + : "+r"(i), "+r"(j) + : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len) + ); +} +#endif /* HAVE_6REGS */ + void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) { int mm_flags = av_get_cpu_flags(); +#if HAVE_6REGS + if (INLINE_AMD3DNOWEXT(mm_flags)) { + fdsp->vector_fmul_window = vector_fmul_window_3dnowext; + } + if (INLINE_SSE(mm_flags)) { + fdsp->vector_fmul_window = vector_fmul_window_sse; + } +#endif if (EXTERNAL_SSE(mm_flags)) { fdsp->vector_fmul = ff_vector_fmul_sse; fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse; -- cgit v1.2.3