2 * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at)
4 * This file is part of libswresample
6 * libswresample is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * libswresample is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with libswresample; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "libswresample/swresample_internal.h"
22 #include "libswresample/audioconvert.h"
24 #define MULTI_CAPS_FUNC_DECL(cap) \
25 void ff_int16_to_int32_a_ ## cap(uint8_t **dst, const uint8_t **src, int len);\
26 void ff_int32_to_int16_a_ ## cap(uint8_t **dst, const uint8_t **src, int len);\
28 MULTI_CAPS_FUNC_DECL(mmx)
29 MULTI_CAPS_FUNC_DECL(sse)
31 void ff_int32_to_float_a_sse2(uint8_t **dst, const uint8_t **src, int len);
32 void ff_int16_to_float_a_sse2(uint8_t **dst, const uint8_t **src, int len);
33 void ff_float_to_int32_a_sse2(uint8_t **dst, const uint8_t **src, int len);
34 void ff_float_to_int16_a_sse2(uint8_t **dst, const uint8_t **src, int len);
36 void ff_int32_to_float_a_avx(uint8_t **dst, const uint8_t **src, int len);
38 void ff_pack_2ch_int16_to_int16_a_sse(uint8_t **dst, const uint8_t **src, int len);
39 void ff_pack_2ch_int32_to_int32_a_sse(uint8_t **dst, const uint8_t **src, int len);
40 void ff_pack_2ch_int16_to_int32_a_sse(uint8_t **dst, const uint8_t **src, int len);
41 void ff_pack_2ch_int32_to_int16_a_sse(uint8_t **dst, const uint8_t **src, int len);
43 void ff_pack_2ch_int32_to_float_a_sse2(uint8_t **dst, const uint8_t **src, int len);
44 void ff_pack_2ch_float_to_int32_a_sse2(uint8_t **dst, const uint8_t **src, int len);
45 void ff_pack_2ch_int16_to_float_a_sse2(uint8_t **dst, const uint8_t **src, int len);
46 void ff_pack_2ch_float_to_int16_a_sse2(uint8_t **dst, const uint8_t **src, int len);
48 void swri_audio_convert_init_x86(struct AudioConvert *ac,
49 enum AVSampleFormat out_fmt,
50 enum AVSampleFormat in_fmt,
52 int mm_flags = av_get_cpu_flags();
56 //FIXME add memcpy case
58 #define MULTI_CAPS_FUNC(flag, cap) \
59 if (mm_flags & flag) {\
60 if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16P)\
61 ac->simd_f = ff_int16_to_int32_a_ ## cap;\
62 if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S32P)\
63 ac->simd_f = ff_int32_to_int16_a_ ## cap;\
66 MULTI_CAPS_FUNC(AV_CPU_FLAG_MMX, mmx)
67 MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE, sse)
69 if(mm_flags & AV_CPU_FLAG_SSE) {
71 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)
72 ac->simd_f = ff_pack_2ch_int32_to_int32_a_sse;
73 if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S16P)
74 ac->simd_f = ff_pack_2ch_int16_to_int16_a_sse;
75 if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S16P)
76 ac->simd_f = ff_pack_2ch_int16_to_int32_a_sse;
77 if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_S32P)
78 ac->simd_f = ff_pack_2ch_int32_to_int16_a_sse;
82 if(mm_flags & AV_CPU_FLAG_SSE2) {
83 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)
84 ac->simd_f = ff_int32_to_float_a_sse2;
85 if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16P)
86 ac->simd_f = ff_int16_to_float_a_sse2;
87 if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLTP)
88 ac->simd_f = ff_float_to_int32_a_sse2;
89 if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP)
90 ac->simd_f = ff_float_to_int16_a_sse2;
93 if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S32P)
94 ac->simd_f = ff_pack_2ch_int32_to_float_a_sse2;
95 if( out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_FLTP)
96 ac->simd_f = ff_pack_2ch_float_to_int32_a_sse2;
97 if( out_fmt == AV_SAMPLE_FMT_FLT && in_fmt == AV_SAMPLE_FMT_S16P)
98 ac->simd_f = ff_pack_2ch_int16_to_float_a_sse2;
99 if( out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP)
100 ac->simd_f = ff_pack_2ch_float_to_int16_a_sse2;
103 if(HAVE_AVX && mm_flags & AV_CPU_FLAG_AVX) {
104 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)
105 ac->simd_f = ff_int32_to_float_a_avx;