[FFmpeg-cvslog] swr-x86-simd: add ff_unpack_2ch_int16_to_int16/int32/float_a_ssse3

Michael Niedermayer git at videolan.org
Sun May 6 19:58:45 CEST 2012


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Sun May  6 19:39:52 2012 +0200| [cbbc4724672ec5839427f9b4129051fac9de390b] | committer: Michael Niedermayer

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 at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=cbbc4724672ec5839427f9b4129051fac9de390b
---

 libswresample/x86/audio_convert.asm |   25 +++++++++++++++++++++++--
 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 cbf7496..5768405 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 936bb8f..e600100 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;



More information about the ffmpeg-cvslog mailing list