diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-05-06 21:39:52 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-05-06 21:39:52 +0400 |
commit | cbbc4724672ec5839427f9b4129051fac9de390b (patch) | |
tree | 512a06c9a7b0e53529ffed7b1835bf1d587cd473 /libswresample/x86 | |
parent | f10aeab69ca094f2059bad992a8b68bc767a46c9 (diff) |
swr-x86-simd: add ff_unpack_2ch_int16_to_int16/int32/float_a_ssse3
more than 10% faster (tested on sandybridge)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libswresample/x86')
-rw-r--r-- | libswresample/x86/audio_convert.asm | 25 | ||||
-rw-r--r-- | libswresample/x86/swresample_x86.c | 12 |
2 files changed, 34 insertions, 3 deletions
diff --git a/libswresample/x86/audio_convert.asm b/libswresample/x86/audio_convert.asm index cbf749697f..5768405733 100644 --- a/libswresample/x86/audio_convert.asm +++ b/libswresample/x86/audio_convert.asm @@ -27,6 +27,8 @@ flt2pm31: times 8 dd 4.6566129e-10 flt2p31 : times 8 dd 2147483648.0 flt2p15 : times 8 dd 32768.0 +word_unpack_shuf : db 0, 1, 4, 5, 8, 9,12,13, 2, 3, 6, 7,10,11,14,15 + SECTION .text @@ -89,7 +91,7 @@ pack_2ch_%2_to_%1_u_int %+ SUFFIX %endmacro %macro UNPACK_2CH 5-7 -cglobal unpack_2ch_%2_to_%1_%3, 3, 4, 6, dst, src, len, dst2 +cglobal unpack_2ch_%2_to_%1_%3, 3, 4, 7, dst, src, len, dst2 mov dst2q , [dstq+gprsize] mov srcq , [srcq] mov dstq , [dstq] @@ -108,11 +110,19 @@ unpack_2ch_%2_to_%1_u_int %+ SUFFIX lea dst2q, [dst2q + (1<<%4)*lenq] neg lenq %7 + mova m6, [word_unpack_shuf] .next: mov%3 m0, [ srcq +(2<<%5)*lenq] - mova m1, m0 mov%3 m2, [ mmsize + srcq +(2<<%5)*lenq] %if %5 == 1 +%ifidn SUFFIX, _ssse3 + pshufb m0, m6 + mova m1, m0 + pshufb m2, m6 + punpcklqdq m0,m2 + punpckhqdq m1,m2 +%else + mova m1, m0 punpcklwd m0,m2 punpckhwd m1,m2 @@ -123,7 +133,9 @@ unpack_2ch_%2_to_%1_u_int %+ SUFFIX mova m1, m0 punpcklwd m0,m2 punpckhwd m1,m2 +%endif %else + mova m1, m0 shufps m0, m2, 10001000b shufps m1, m2, 11011101b %endif @@ -322,6 +334,15 @@ UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT UNPACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT UNPACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT + +INIT_XMM ssse3 +UNPACK_2CH int16, int16, u, 1, 1 +UNPACK_2CH int16, int16, a, 1, 1 +UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N +UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N +UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT +UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT + %if HAVE_AVX INIT_YMM avx CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT diff --git a/libswresample/x86/swresample_x86.c b/libswresample/x86/swresample_x86.c index 936bb8fa3c..e600100deb 100644 --- a/libswresample/x86/swresample_x86.c +++ b/libswresample/x86/swresample_x86.c @@ -24,7 +24,7 @@ #define PROTO(pre, in, out, cap) void ff ## pre ## _ ##in## _to_ ##out## _a_ ##cap(uint8_t **dst, const uint8_t **src, int len); #define PROTO2(pre, out, cap) PROTO(pre, int16, out, cap) PROTO(pre, int32, out, cap) PROTO(pre, float, out, cap) #define PROTO3(pre, cap) PROTO2(pre, int16, cap) PROTO2(pre, int32, cap) PROTO2(pre, float, cap) -#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, avx) +#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, avx) PROTO4() PROTO4(_pack_2ch) PROTO4(_unpack_2ch) @@ -101,6 +101,16 @@ MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE, sse) ac->simd_f = ff_unpack_2ch_float_to_int16_a_sse2; } } + if(mm_flags & AV_CPU_FLAG_SSSE3) { + if(channels == 2) { + if( out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S16) + ac->simd_f = ff_unpack_2ch_int16_to_int16_a_ssse3; + if( out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16) + ac->simd_f = ff_unpack_2ch_int16_to_int32_a_ssse3; + if( out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16) + ac->simd_f = ff_unpack_2ch_int16_to_float_a_ssse3; + } + } if(HAVE_AVX && mm_flags & AV_CPU_FLAG_AVX) { if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P) ac->simd_f = ff_int32_to_float_a_avx; |