diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2012-05-13 19:09:01 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-05-13 19:31:59 +0200 |
commit | 6f67d9833b5a7d78d27c283d7e4238e6d3e5fd98 (patch) | |
tree | 916cc36d53394a026d938f7a1e0ed69ebe4e0d43 | |
parent | 6108e1be2fb97bdfa63e8f9a039b8daff3caec3d (diff) | |
download | ffmpeg-6f67d9833b5a7d78d27c283d7e4238e6d3e5fd98.tar.gz |
libswresample: Implement MMX, SSE4 and AVX 6ch float and int32 packing function.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libswresample/x86/audio_convert.asm | 78 | ||||
-rw-r--r-- | libswresample/x86/swresample_x86.c | 20 |
2 files changed, 97 insertions, 1 deletions
diff --git a/libswresample/x86/audio_convert.asm b/libswresample/x86/audio_convert.asm index 5768405733..1fa519aa84 100644 --- a/libswresample/x86/audio_convert.asm +++ b/libswresample/x86/audio_convert.asm @@ -199,6 +199,84 @@ cglobal %2_to_%1_%3, 3, 3, 6, dst, src, len REP_RET %endmacro +%macro CONV_FLTP_TO_FLT_6CH 3 +cglobal pack_6ch_%2_to_%1_%3, 2,8,7, dst, src, src1, src2, src3, src4, src5, len +%if ARCH_X86_64 + mov lend, r2d +%else + %define lend dword r2m +%endif + mov src1q, [srcq+1*gprsize] + mov src2q, [srcq+2*gprsize] + mov src3q, [srcq+3*gprsize] + mov src4q, [srcq+4*gprsize] + mov src5q, [srcq+5*gprsize] + mov srcq, [srcq] + mov dstq, [dstq] + sub src1q, srcq + sub src2q, srcq + sub src3q, srcq + sub src4q, srcq + sub src5q, srcq +.loop: + mova m0, [srcq ] + mova m1, [srcq+src1q] + mova m2, [srcq+src2q] + mova m3, [srcq+src3q] + mova m4, [srcq+src4q] + mova m5, [srcq+src5q] +%if cpuflag(sse4) + SBUTTERFLYPS 0, 1, 6 + SBUTTERFLYPS 2, 3, 6 + SBUTTERFLYPS 4, 5, 6 + + blendps m6, m4, m0, 1100b + movlhps m0, m2 + movhlps m4, m2 + blendps m2, m5, m1, 1100b + movlhps m1, m3 + movhlps m5, m3 + + movaps [dstq ], m0 + movaps [dstq+16], m6 + movaps [dstq+32], m4 + movaps [dstq+48], m1 + movaps [dstq+64], m2 + movaps [dstq+80], m5 +%else ; mmx + SBUTTERFLY dq, 0, 1, 6 + SBUTTERFLY dq, 2, 3, 6 + SBUTTERFLY dq, 4, 5, 6 + + movq [dstq ], m0 + movq [dstq+ 8], m2 + movq [dstq+16], m4 + movq [dstq+24], m1 + movq [dstq+32], m3 + movq [dstq+40], m5 +%endif + add srcq, mmsize + add dstq, mmsize*6 + sub lend, mmsize/4 + jg .loop +%if mmsize == 8 + emms + RET +%else + REP_RET +%endif +%endmacro + +INIT_MMX mmx +CONV_FLTP_TO_FLT_6CH float,float,a +INIT_XMM sse4 +CONV_FLTP_TO_FLT_6CH float,float,a +%if HAVE_AVX +INIT_XMM avx +CONV_FLTP_TO_FLT_6CH float,float,a +%endif + + %macro INT16_TO_INT32_N 0 pxor m2, m2 pxor m3, m3 diff --git a/libswresample/x86/swresample_x86.c b/libswresample/x86/swresample_x86.c index e600100deb..f2349b505a 100644 --- a/libswresample/x86/swresample_x86.c +++ b/libswresample/x86/swresample_x86.c @@ -24,9 +24,10 @@ #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, ssse3) PROTO3(pre, avx) +#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, sse4) PROTO3(pre, avx) PROTO4() PROTO4(_pack_2ch) +PROTO4(_pack_6ch) PROTO4(_unpack_2ch) void swri_audio_convert_init_x86(struct AudioConvert *ac, @@ -50,6 +51,13 @@ void swri_audio_convert_init_x86(struct AudioConvert *ac, MULTI_CAPS_FUNC(AV_CPU_FLAG_MMX, mmx) MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE, sse) + if(mm_flags & AV_CPU_FLAG_MMX) { + if(channels == 6) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_6ch_float_to_float_a_mmx; + } + } + if(mm_flags & AV_CPU_FLAG_SSE) { if(channels == 2) { if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) @@ -111,8 +119,18 @@ MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE, sse) ac->simd_f = ff_unpack_2ch_int16_to_float_a_ssse3; } } + if(mm_flags & AV_CPU_FLAG_SSE4) { + if(channels == 6) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_6ch_float_to_float_a_sse4; + } + } 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; + if(channels == 6) { + if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P) + ac->simd_f = ff_pack_6ch_float_to_float_a_avx; + } } } |