../../../ffmpeg/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
49 / 79
62.0%
Branches:
27 / 46
58.7%
Functions:
4 / 5
80.0%

libavutil/x86/tx_float_init.c
Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #define TX_FLOAT
20 #include "libavutil/tx_priv.h"
21 #include "libavutil/attributes.h"
22 #include "libavutil/mem.h"
23 #include "libavutil/x86/cpu.h"
24
25 #include "config.h"
26
27 TX_DECL_FN(fft2, sse3)
28 TX_DECL_FN(fft4_fwd, sse2)
29 TX_DECL_FN(fft4_inv, sse2)
30 TX_DECL_FN(fft8, sse3)
31 TX_DECL_FN(fft8_ns, sse3)
32 TX_DECL_FN(fft8, avx)
33 TX_DECL_FN(fft8_ns, avx)
34 TX_DECL_FN(fft15, avx2)
35 TX_DECL_FN(fft15_ns, avx2)
36 TX_DECL_FN(fft16, avx)
37 TX_DECL_FN(fft16_ns, avx)
38 TX_DECL_FN(fft16, fma3)
39 TX_DECL_FN(fft16_ns, fma3)
40 TX_DECL_FN(fft32, avx)
41 TX_DECL_FN(fft32_ns, avx)
42 TX_DECL_FN(fft32, fma3)
43 TX_DECL_FN(fft32_ns, fma3)
44 TX_DECL_FN(fft_sr, avx)
45 TX_DECL_FN(fft_sr_ns, avx)
46 TX_DECL_FN(fft_sr, fma3)
47 TX_DECL_FN(fft_sr_ns, fma3)
48 TX_DECL_FN(fft_sr, avx2)
49 TX_DECL_FN(fft_sr_ns, avx2)
50
51 TX_DECL_FN(fft_pfa_15xM, avx2)
52 TX_DECL_FN(fft_pfa_15xM_ns, avx2)
53
54 TX_DECL_FN(mdct_inv, avx2)
55
56 TX_DECL_FN(fft2_asm, sse3)
57 TX_DECL_FN(fft4_fwd_asm, sse2)
58 TX_DECL_FN(fft4_inv_asm, sse2)
59 TX_DECL_FN(fft8_asm, sse3)
60 TX_DECL_FN(fft8_asm, avx)
61 TX_DECL_FN(fft16_asm, avx)
62 TX_DECL_FN(fft16_asm, fma3)
63 TX_DECL_FN(fft32_asm, avx)
64 TX_DECL_FN(fft32_asm, fma3)
65 TX_DECL_FN(fft_sr_asm, avx)
66 TX_DECL_FN(fft_sr_asm, fma3)
67 TX_DECL_FN(fft_sr_asm, avx2)
68
69 TX_DECL_FN(fft_pfa_15xM_asm, avx2)
70
71 #define DECL_INIT_FN(basis, interleave) \
72 static av_cold int b ##basis## _i ##interleave(AVTXContext *s, \
73 const FFTXCodelet *cd, \
74 uint64_t flags, \
75 FFTXCodeletOptions *opts, \
76 int len, int inv, \
77 const void *scale) \
78 { \
79 ff_tx_init_tabs_float(len); \
80 if (cd->max_len == 2) \
81 return ff_tx_gen_ptwo_revtab(s, opts); \
82 else \
83 return ff_tx_gen_split_radix_parity_revtab(s, len, inv, opts, \
84 basis, interleave); \
85 }
86
87
2/2
✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 6 taken 411 times.
420 DECL_INIT_FN(8, 0)
88
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 2168 times.
2168 DECL_INIT_FN(8, 2)
89
90 #if ARCH_X86_64
91 ✗ static av_cold int factor_init(AVTXContext *s, const FFTXCodelet *cd,
92 uint64_t flags, FFTXCodeletOptions *opts,
93 int len, int inv, const void *scale)
94 {
95 int ret;
96
97 /* The transformations below are performed in the gather domain,
98 * so override the option and let the infrastructure convert the map
99 * to SCATTER if needed. */
100 ✗ FFTXCodeletOptions sub_opts = { .map_dir = FF_TX_MAP_GATHER };
101
102 ✗ TX_TAB(ff_tx_init_tabs)(len);
103
104
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ if (len == 15)
105 ✗ ret = ff_tx_gen_pfa_input_map(s, &sub_opts, 3, 5);
106 else
107 ✗ ret = ff_tx_gen_default_map(s, &sub_opts);
108
109
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 8 not taken.
✗ if (ret < 0)
110 ✗ return ret;
111
112
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 19 not taken.
✗ if (len == 15) {
113 ✗ int cnt = 0, tmp[15];
114
115 /* Special permutation to simplify loads in the pre-permuted version */
116 ✗ memcpy(tmp, s->map, 15*sizeof(*tmp));
117
0/2
✗ Branch 11 → 10 not taken.
✗ Branch 11 → 12 not taken.
✗ for (int i = 1; i < 15; i += 3) {
118 ✗ s->map[cnt] = tmp[i];
119 ✗ cnt++;
120 }
121
0/2
✗ Branch 14 → 13 not taken.
✗ Branch 14 → 15 not taken.
✗ for (int i = 2; i < 15; i += 3) {
122 ✗ s->map[cnt] = tmp[i];
123 ✗ cnt++;
124 }
125
0/2
✗ Branch 17 → 16 not taken.
✗ Branch 17 → 18 not taken.
✗ for (int i = 0; i < 15; i += 3) {
126 ✗ s->map[cnt] = tmp[i];
127 ✗ cnt++;
128 }
129 ✗ memmove(&s->map[7], &s->map[6], 4*sizeof(int));
130 ✗ memmove(&s->map[3], &s->map[1], 4*sizeof(int));
131 ✗ s->map[1] = tmp[2];
132 ✗ s->map[2] = tmp[0];
133 }
134
135 ✗ return 0;
136 }
137
138 2338 static av_cold int m_inv_init(AVTXContext *s, const FFTXCodelet *cd,
139 uint64_t flags, FFTXCodeletOptions *opts,
140 int len, int inv, const void *scale)
141 {
142 int ret;
143 2338 FFTXCodeletOptions sub_opts = { .map_dir = FF_TX_MAP_GATHER };
144
145 2338 s->scale_d = *((SCALE_TYPE *)scale);
146 2338 s->scale_f = s->scale_d;
147
148 2338 flags &= ~FF_TX_OUT_OF_PLACE; /* We want the subtransform to be */
149 2338 flags |= AV_TX_INPLACE; /* in-place */
150 2338 flags |= FF_TX_PRESHUFFLE; /* This function handles the permute step */
151 2338 flags |= FF_TX_ASM_CALL; /* We want an assembly function, not C */
152
153
2/2
✓ Branch 3 → 4 taken 302 times.
✓ Branch 3 → 5 taken 2036 times.
2338 if ((ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts, len >> 1,
154 inv, scale)))
155 302 return ret;
156
157 2036 s->map = av_malloc(len*sizeof(*s->map));
158
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 2036 times.
2036 if (!s->map)
159 ✗ return AVERROR(ENOMEM);
160
161 2036 memcpy(s->map, s->sub->map, (len >> 1)*sizeof(*s->map));
162 /* Invert lookup table for unstrided path */
163
2/2
✓ Branch 10 → 9 taken 402828 times.
✓ Branch 10 → 11 taken 2036 times.
404864 for (int i = 0; i < (len >> 1); i++)
164 402828 s->map[(len >> 1) + s->map[i]] = i;
165
166
1/2
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 2036 times.
2036 if ((ret = ff_tx_mdct_gen_exp_float(s, s->map)))
167 ✗ return ret;
168
169 2036 return 0;
170 }
171
172 863 static av_cold int fft_pfa_init(AVTXContext *s,
173 const FFTXCodelet *cd,
174 uint64_t flags,
175 FFTXCodeletOptions *opts,
176 int len, int inv,
177 const void *scale)
178 {
179 int ret;
180 863 int sub_len = len / cd->factors[0];
181 863 FFTXCodeletOptions sub_opts = { .map_dir = FF_TX_MAP_SCATTER };
182
183 863 flags &= ~FF_TX_OUT_OF_PLACE; /* We want the subtransform to be */
184 863 flags |= AV_TX_INPLACE; /* in-place */
185 863 flags |= FF_TX_PRESHUFFLE; /* This function handles the permute step */
186 863 flags |= FF_TX_ASM_CALL; /* We want an assembly function, not C */
187
188
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 863 times.
863 if ((ret = ff_tx_init_subtx(s, TX_TYPE(FFT), flags, &sub_opts,
189 sub_len, inv, scale)))
190 ✗ return ret;
191
192
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 863 times.
863 if ((ret = ff_tx_gen_compound_mapping(s, opts, s->inv, cd->factors[0], sub_len)))
193 ✗ return ret;
194
195
1/2
✓ Branch 8 → 9 taken 863 times.
✗ Branch 8 → 31 not taken.
863 if (cd->factors[0] == 15) {
196 int tmp[15];
197
198 /* Our 15-point transform is also a compound one, so embed its input map */
199
6/6
✓ Branch 13 → 12 taken 213180 times.
✓ Branch 13 → 14 taken 71060 times.
✓ Branch 15 → 11 taken 71060 times.
✓ Branch 15 → 16 taken 14212 times.
✓ Branch 17 → 10 taken 14212 times.
✓ Branch 17 → 18 taken 863 times.
299315 TX_EMBED_INPUT_PFA_MAP(s->map, len, 3, 5);
200
201 /* Special permutation to simplify loads in the pre-permuted version */
202
2/2
✓ Branch 29 → 19 taken 14212 times.
✓ Branch 29 → 30 taken 863 times.
15075 for (int k = 0; k < s->sub[0].len; k++) {
203 14212 int cnt = 0;
204 14212 memcpy(tmp, &s->map[k*15], 15*sizeof(*tmp));
205
2/2
✓ Branch 21 → 20 taken 71060 times.
✓ Branch 21 → 22 taken 14212 times.
85272 for (int i = 1; i < 15; i += 3) {
206 71060 s->map[k*15 + cnt] = tmp[i];
207 71060 cnt++;
208 }
209
2/2
✓ Branch 24 → 23 taken 71060 times.
✓ Branch 24 → 25 taken 14212 times.
85272 for (int i = 2; i < 15; i += 3) {
210 71060 s->map[k*15 + cnt] = tmp[i];
211 71060 cnt++;
212 }
213
2/2
✓ Branch 27 → 26 taken 71060 times.
✓ Branch 27 → 28 taken 14212 times.
85272 for (int i = 0; i < 15; i += 3) {
214 71060 s->map[k*15 + cnt] = tmp[i];
215 71060 cnt++;
216 }
217 14212 memmove(&s->map[k*15 + 7], &s->map[k*15 + 6], 4*sizeof(int));
218 14212 memmove(&s->map[k*15 + 3], &s->map[k*15 + 1], 4*sizeof(int));
219 14212 s->map[k*15 + 1] = tmp[2];
220 14212 s->map[k*15 + 2] = tmp[0];
221 }
222 }
223
224
1/2
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 34 taken 863 times.
863 if (!(s->tmp = av_malloc(len*sizeof(*s->tmp))))
225 ✗ return AVERROR(ENOMEM);
226
227 863 TX_TAB(ff_tx_init_tabs)(len / sub_len);
228
229 863 return 0;
230 }
231 #endif
232
233 const FFTXCodelet * const ff_tx_codelet_list_float_x86[] = {
234 TX_DEF(fft2, FFT, 2, 2, 2, 0, 128, NULL, sse3, SSE3, AV_TX_INPLACE, 0),
235 TX_DEF(fft2_asm, FFT, 2, 2, 2, 0, 192, b8_i0, sse3, SSE3,
236 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, 0),
237 TX_DEF(fft2, FFT, 2, 2, 2, 0, 192, b8_i0, sse3, SSE3, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0),
238 TX_DEF(fft4_fwd, FFT, 4, 4, 2, 0, 128, NULL, sse2, SSE2, AV_TX_INPLACE | FF_TX_FORWARD_ONLY, 0),
239 TX_DEF(fft4_fwd_asm, FFT, 4, 4, 2, 0, 192, b8_i0, sse2, SSE2,
240 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, 0),
241 TX_DEF(fft4_inv_asm, FFT, 4, 4, 2, 0, 128, NULL, sse2, SSE2,
242 AV_TX_INPLACE | FF_TX_INVERSE_ONLY | FF_TX_ASM_CALL, 0),
243 TX_DEF(fft4_fwd, FFT, 4, 4, 2, 0, 192, b8_i0, sse2, SSE2, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0),
244 TX_DEF(fft4_inv, FFT, 4, 4, 2, 0, 128, NULL, sse2, SSE2, AV_TX_INPLACE | FF_TX_INVERSE_ONLY, 0),
245 TX_DEF(fft8, FFT, 8, 8, 2, 0, 128, b8_i0, sse3, SSE3, AV_TX_INPLACE, 0),
246 TX_DEF(fft8_asm, FFT, 8, 8, 2, 0, 192, b8_i0, sse3, SSE3,
247 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, 0),
248 TX_DEF(fft8_ns, FFT, 8, 8, 2, 0, 192, b8_i0, sse3, SSE3, AV_TX_INPLACE | FF_TX_PRESHUFFLE, 0),
249 TX_DEF(fft8, FFT, 8, 8, 2, 0, 256, b8_i0, avx, AVX, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW),
250 TX_DEF(fft8_asm, FFT, 8, 8, 2, 0, 320, b8_i0, avx, AVX,
251 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
252 TX_DEF(fft8_ns, FFT, 8, 8, 2, 0, 320, b8_i0, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
253 AV_CPU_FLAG_AVXSLOW),
254 TX_DEF(fft16, FFT, 16, 16, 2, 0, 256, b8_i2, avx, AVX, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW),
255 TX_DEF(fft16_asm, FFT, 16, 16, 2, 0, 320, b8_i2, avx, AVX,
256 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
257 TX_DEF(fft16_ns, FFT, 16, 16, 2, 0, 320, b8_i2, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
258 AV_CPU_FLAG_AVXSLOW),
259 TX_DEF(fft16, FFT, 16, 16, 2, 0, 288, b8_i2, fma3, FMA3, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW),
260 TX_DEF(fft16_asm, FFT, 16, 16, 2, 0, 352, b8_i2, fma3, FMA3,
261 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
262 TX_DEF(fft16_ns, FFT, 16, 16, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
263 AV_CPU_FLAG_AVXSLOW),
264
265 #if ARCH_X86_64
266 TX_DEF(fft32, FFT, 32, 32, 2, 0, 256, b8_i2, avx, AVX, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW),
267 TX_DEF(fft32_asm, FFT, 32, 32, 2, 0, 320, b8_i2, avx, AVX,
268 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
269 TX_DEF(fft32_ns, FFT, 32, 32, 2, 0, 320, b8_i2, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
270 AV_CPU_FLAG_AVXSLOW),
271 TX_DEF(fft32, FFT, 32, 32, 2, 0, 288, b8_i2, fma3, FMA3, AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW),
272 TX_DEF(fft32_asm, FFT, 32, 32, 2, 0, 352, b8_i2, fma3, FMA3,
273 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
274 TX_DEF(fft32_ns, FFT, 32, 32, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
275 AV_CPU_FLAG_AVXSLOW),
276 TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 256, b8_i2, avx, AVX, 0, AV_CPU_FLAG_AVXSLOW),
277 TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 320, b8_i2, avx, AVX,
278 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
279 TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 320, b8_i2, avx, AVX, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
280 AV_CPU_FLAG_AVXSLOW),
281 TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 288, b8_i2, fma3, FMA3, 0, AV_CPU_FLAG_AVXSLOW),
282 TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 352, b8_i2, fma3, FMA3,
283 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW),
284 TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 352, b8_i2, fma3, FMA3, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
285 AV_CPU_FLAG_AVXSLOW),
286
287 TX_DEF(fft15, FFT, 15, 15, 15, 0, 320, factor_init, avx2, AVX2,
288 AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW),
289 TX_DEF(fft15_ns, FFT, 15, 15, 15, 0, 384, factor_init, avx2, AVX2,
290 AV_TX_INPLACE | FF_TX_PRESHUFFLE, AV_CPU_FLAG_AVXSLOW),
291
292 TX_DEF(fft_sr, FFT, 64, 131072, 2, 0, 320, b8_i2, avx2, AVX2, 0,
293 AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
294 TX_DEF(fft_sr_asm, FFT, 64, 131072, 2, 0, 384, b8_i2, avx2, AVX2,
295 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
296 TX_DEF(fft_sr_ns, FFT, 64, 131072, 2, 0, 384, b8_i2, avx2, AVX2, AV_TX_INPLACE | FF_TX_PRESHUFFLE,
297 AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
298
299 TX_DEF(fft_pfa_15xM, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 320, fft_pfa_init, avx2, AVX2,
300 AV_TX_INPLACE, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
301 TX_DEF(fft_pfa_15xM_asm, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 384, fft_pfa_init, avx2, AVX2,
302 AV_TX_INPLACE | FF_TX_PRESHUFFLE | FF_TX_ASM_CALL, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
303 TX_DEF(fft_pfa_15xM_ns, FFT, 60, TX_LEN_UNLIMITED, 15, 2, 384, fft_pfa_init, avx2, AVX2,
304 AV_TX_INPLACE | FF_TX_PRESHUFFLE, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
305
306 TX_DEF(mdct_inv, MDCT, 16, TX_LEN_UNLIMITED, 2, TX_FACTOR_ANY, 384, m_inv_init, avx2, AVX2,
307 FF_TX_INVERSE_ONLY, AV_CPU_FLAG_AVXSLOW | AV_CPU_FLAG_SLOW_GATHER),
308 #endif
309
310 NULL,
311 };
312