• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg 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.
10  *
11  * FFmpeg 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.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "config.h"
22 #include "libavutil/cpu.h"
23 #include "libavutil/x86/cpu.h"
24 #include "libavresample/audio_convert.h"
25 
26 /* flat conversions */
27 
28 void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len);
29 
30 void ff_conv_s16_to_flt_sse2(float *dst, const int16_t *src, int len);
31 void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len);
32 
33 void ff_conv_s32_to_s16_mmx (int16_t *dst, const int32_t *src, int len);
34 void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len);
35 
36 void ff_conv_s32_to_flt_sse2(float *dst, const int32_t *src, int len);
37 void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len);
38 
39 void ff_conv_flt_to_s16_sse2(int16_t *dst, const float *src, int len);
40 
41 void ff_conv_flt_to_s32_sse2(int32_t *dst, const float *src, int len);
42 void ff_conv_flt_to_s32_avx (int32_t *dst, const float *src, int len);
43 
44 /* interleave conversions */
45 
46 void ff_conv_s16p_to_s16_2ch_sse2(int16_t *dst, int16_t *const *src,
47                                   int len, int channels);
48 void ff_conv_s16p_to_s16_2ch_avx (int16_t *dst, int16_t *const *src,
49                                   int len, int channels);
50 
51 void ff_conv_s16p_to_s16_6ch_sse2(int16_t *dst, int16_t *const *src,
52                                   int len, int channels);
53 void ff_conv_s16p_to_s16_6ch_sse2slow(int16_t *dst, int16_t *const *src,
54                                       int len, int channels);
55 void ff_conv_s16p_to_s16_6ch_avx (int16_t *dst, int16_t *const *src,
56                                   int len, int channels);
57 
58 void ff_conv_s16p_to_flt_2ch_sse2(float *dst, int16_t *const *src,
59                                   int len, int channels);
60 void ff_conv_s16p_to_flt_2ch_avx (float *dst, int16_t *const *src,
61                                   int len, int channels);
62 
63 void ff_conv_s16p_to_flt_6ch_sse2 (float *dst, int16_t *const *src,
64                                    int len, int channels);
65 void ff_conv_s16p_to_flt_6ch_ssse3(float *dst, int16_t *const *src,
66                                   int len, int channels);
67 void ff_conv_s16p_to_flt_6ch_avx  (float *dst, int16_t *const *src,
68                                    int len, int channels);
69 
70 void ff_conv_fltp_to_s16_2ch_sse2 (int16_t *dst, float *const *src,
71                                    int len, int channels);
72 void ff_conv_fltp_to_s16_2ch_ssse3(int16_t *dst, float *const *src,
73                                    int len, int channels);
74 
75 void ff_conv_fltp_to_s16_6ch_sse (int16_t *dst, float *const *src,
76                                   int len, int channels);
77 void ff_conv_fltp_to_s16_6ch_sse2(int16_t *dst, float *const *src,
78                                   int len, int channels);
79 void ff_conv_fltp_to_s16_6ch_avx (int16_t *dst, float *const *src,
80                                   int len, int channels);
81 
82 void ff_conv_fltp_to_flt_2ch_sse(float *dst, float *const *src, int len,
83                                  int channels);
84 void ff_conv_fltp_to_flt_2ch_avx(float *dst, float *const *src, int len,
85                                  int channels);
86 
87 void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len,
88                                   int channels);
89 void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len,
90                                   int channels);
91 void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len,
92                                   int channels);
93 
94 /* deinterleave conversions */
95 
96 void ff_conv_s16_to_s16p_2ch_sse2(int16_t *const *dst, int16_t *src,
97                                   int len, int channels);
98 void ff_conv_s16_to_s16p_2ch_ssse3(int16_t *const *dst, int16_t *src,
99                                    int len, int channels);
100 void ff_conv_s16_to_s16p_2ch_avx (int16_t *const *dst, int16_t *src,
101                                   int len, int channels);
102 
103 void ff_conv_s16_to_s16p_6ch_sse2 (int16_t *const *dst, int16_t *src,
104                                    int len, int channels);
105 void ff_conv_s16_to_s16p_6ch_ssse3(int16_t *const *dst, int16_t *src,
106                                    int len, int channels);
107 void ff_conv_s16_to_s16p_6ch_avx  (int16_t *const *dst, int16_t *src,
108                                    int len, int channels);
109 
110 void ff_conv_s16_to_fltp_2ch_sse2(float *const *dst, int16_t *src,
111                                   int len, int channels);
112 void ff_conv_s16_to_fltp_2ch_avx (float *const *dst, int16_t *src,
113                                   int len, int channels);
114 
115 void ff_conv_s16_to_fltp_6ch_sse2 (float *const *dst, int16_t *src,
116                                    int len, int channels);
117 void ff_conv_s16_to_fltp_6ch_ssse3(float *const *dst, int16_t *src,
118                                    int len, int channels);
119 void ff_conv_s16_to_fltp_6ch_sse4 (float *const *dst, int16_t *src,
120                                    int len, int channels);
121 void ff_conv_s16_to_fltp_6ch_avx  (float *const *dst, int16_t *src,
122                                    int len, int channels);
123 
124 void ff_conv_flt_to_s16p_2ch_sse2(int16_t *const *dst, float *src,
125                                   int len, int channels);
126 void ff_conv_flt_to_s16p_2ch_avx (int16_t *const *dst, float *src,
127                                   int len, int channels);
128 
129 void ff_conv_flt_to_s16p_6ch_sse2 (int16_t *const *dst, float *src,
130                                    int len, int channels);
131 void ff_conv_flt_to_s16p_6ch_ssse3(int16_t *const *dst, float *src,
132                                    int len, int channels);
133 void ff_conv_flt_to_s16p_6ch_avx  (int16_t *const *dst, float *src,
134                                    int len, int channels);
135 
136 void ff_conv_flt_to_fltp_2ch_sse(float *const *dst, float *src, int len,
137                                  int channels);
138 void ff_conv_flt_to_fltp_2ch_avx(float *const *dst, float *src, int len,
139                                  int channels);
140 
141 void ff_conv_flt_to_fltp_6ch_sse2(float *const *dst, float *src, int len,
142                                   int channels);
143 void ff_conv_flt_to_fltp_6ch_avx (float *const *dst, float *src, int len,
144                                   int channels);
145 
ff_audio_convert_init_x86(AudioConvert * ac)146 av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
147 {
148     int cpu_flags = av_get_cpu_flags();
149 
150     if (EXTERNAL_MMX(cpu_flags)) {
151         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
152                                   0, 1, 8, "MMX", ff_conv_s32_to_s16_mmx);
153         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
154                                   6, 1, 4, "MMX", ff_conv_fltp_to_flt_6ch_mmx);
155     }
156     if (EXTERNAL_SSE(cpu_flags)) {
157         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
158                                   6, 1, 2, "SSE", ff_conv_fltp_to_s16_6ch_sse);
159         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
160                                   2, 16, 8, "SSE", ff_conv_fltp_to_flt_2ch_sse);
161         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
162                                   2, 16, 4, "SSE", ff_conv_flt_to_fltp_2ch_sse);
163     }
164     if (EXTERNAL_SSE2(cpu_flags)) {
165         if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
166             ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
167                                       0, 16, 16, "SSE2", ff_conv_s32_to_s16_sse2);
168             ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
169                                       6, 16, 8, "SSE2", ff_conv_s16p_to_s16_6ch_sse2);
170             ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
171                                       6, 16, 4, "SSE2", ff_conv_fltp_to_s16_6ch_sse2);
172         } else {
173             ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
174                                       6, 1, 4, "SSE2SLOW", ff_conv_s16p_to_s16_6ch_sse2slow);
175         }
176         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16,
177                                   0, 16, 8, "SSE2", ff_conv_s16_to_s32_sse2);
178         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
179                                   0, 16, 8, "SSE2", ff_conv_s16_to_flt_sse2);
180         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
181                                   0, 16, 8, "SSE2", ff_conv_s32_to_flt_sse2);
182         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT,
183                                   0, 16, 16, "SSE2", ff_conv_flt_to_s16_sse2);
184         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
185                                   0, 16, 16, "SSE2", ff_conv_flt_to_s32_sse2);
186         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
187                                   2, 16, 16, "SSE2", ff_conv_s16p_to_s16_2ch_sse2);
188         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
189                                   2, 16, 8, "SSE2", ff_conv_s16p_to_flt_2ch_sse2);
190         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
191                                   6, 16, 4, "SSE2", ff_conv_s16p_to_flt_6ch_sse2);
192         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
193                                   2, 16, 4, "SSE2", ff_conv_fltp_to_s16_2ch_sse2);
194         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
195                                   2, 16, 8, "SSE2", ff_conv_s16_to_s16p_2ch_sse2);
196         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
197                                   6, 16, 4, "SSE2", ff_conv_s16_to_s16p_6ch_sse2);
198         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
199                                   2, 16, 8, "SSE2", ff_conv_s16_to_fltp_2ch_sse2);
200         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
201                                   6, 16, 4, "SSE2", ff_conv_s16_to_fltp_6ch_sse2);
202         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
203                                   2, 16, 8, "SSE2", ff_conv_flt_to_s16p_2ch_sse2);
204         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
205                                   6, 16, 4, "SSE2", ff_conv_flt_to_s16p_6ch_sse2);
206         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
207                                   6, 16, 4, "SSE2", ff_conv_flt_to_fltp_6ch_sse2);
208     }
209     if (EXTERNAL_SSSE3(cpu_flags)) {
210         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
211                                   6, 16, 4, "SSSE3", ff_conv_s16p_to_flt_6ch_ssse3);
212         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
213                                   2, 16, 4, "SSSE3", ff_conv_fltp_to_s16_2ch_ssse3);
214         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
215                                   2, 16, 8, "SSSE3", ff_conv_s16_to_s16p_2ch_ssse3);
216         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
217                                   6, 16, 4, "SSSE3", ff_conv_s16_to_s16p_6ch_ssse3);
218         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
219                                   6, 16, 4, "SSSE3", ff_conv_s16_to_fltp_6ch_ssse3);
220         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
221                                   6, 16, 4, "SSSE3", ff_conv_flt_to_s16p_6ch_ssse3);
222     }
223     if (EXTERNAL_SSE4(cpu_flags)) {
224         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
225                                   0, 16, 8, "SSE4", ff_conv_s16_to_flt_sse4);
226         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
227                                   6, 16, 4, "SSE4", ff_conv_fltp_to_flt_6ch_sse4);
228     }
229     if (EXTERNAL_AVX_FAST(cpu_flags)) {
230         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
231                                   0, 32, 16, "AVX", ff_conv_s32_to_flt_avx);
232         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
233                                   0, 32, 32, "AVX", ff_conv_flt_to_s32_avx);
234     }
235     if (EXTERNAL_AVX(cpu_flags)) {
236         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
237                                   2, 16, 16, "AVX", ff_conv_s16p_to_s16_2ch_avx);
238         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
239                                   6, 16, 8, "AVX", ff_conv_s16p_to_s16_6ch_avx);
240         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
241                                   2, 16, 8, "AVX", ff_conv_s16p_to_flt_2ch_avx);
242         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
243                                   6, 16, 4, "AVX", ff_conv_s16p_to_flt_6ch_avx);
244         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
245                                   6, 16, 4, "AVX", ff_conv_fltp_to_s16_6ch_avx);
246         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
247                                   6, 16, 4, "AVX", ff_conv_fltp_to_flt_6ch_avx);
248         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
249                                   2, 16, 8, "AVX", ff_conv_s16_to_s16p_2ch_avx);
250         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S16,
251                                   6, 16, 4, "AVX", ff_conv_s16_to_s16p_6ch_avx);
252         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
253                                   2, 16, 8, "AVX", ff_conv_s16_to_fltp_2ch_avx);
254         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16,
255                                   6, 16, 4, "AVX", ff_conv_s16_to_fltp_6ch_avx);
256         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
257                                   2, 16, 8, "AVX", ff_conv_flt_to_s16p_2ch_avx);
258         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
259                                   6, 16, 4, "AVX", ff_conv_flt_to_s16p_6ch_avx);
260         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
261                                   2, 16, 4, "AVX", ff_conv_flt_to_fltp_2ch_avx);
262         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
263                                   6, 16, 4, "AVX", ff_conv_flt_to_fltp_6ch_avx);
264     }
265 }
266