FFmpeg
Loading...
Searching...
No Matches
fdctdsp_altivec.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2003 James Klicman <james@klicman.org>
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
25
26#include "libavcodec/avcodec.h"
27#include "libavcodec/fdctdsp.h"
28
29#include "fdct.h"
30
31#define vs16(v) ((vector signed short) (v))
32#define vs32(v) ((vector signed int) (v))
33#define vu8(v) ((vector unsigned char) (v))
34#define vu16(v) ((vector unsigned short) (v))
35#define vu32(v) ((vector unsigned int) (v))
36
37#define C1 0.98078528040323044912618224 /* cos(1 * PI / 16) */
38#define C2 0.92387953251128675612818319 /* cos(2 * PI / 16) */
39#define C3 0.83146961230254523707878838 /* cos(3 * PI / 16) */
40#define C4 0.70710678118654752440084436 /* cos(4 * PI / 16) */
41#define C5 0.55557023301960222474283081 /* cos(5 * PI / 16) */
42#define C6 0.38268343236508977172845998 /* cos(6 * PI / 16) */
43#define C7 0.19509032201612826784828487 /* cos(7 * PI / 16) */
44
45#define W0 -(2 * C2)
46#define W1 (2 * C6)
47#define W2 (M_SQRT2 * C6)
48#define W3 (M_SQRT2 * C3)
49#define W4 (M_SQRT2 * (-C1 + C3 + C5 - C7))
50#define W5 (M_SQRT2 * (C1 + C3 - C5 + C7))
51#define W6 (M_SQRT2 * (C1 + C3 + C5 - C7))
52#define W7 (M_SQRT2 * (C1 + C3 - C5 - C7))
53#define W8 (M_SQRT2 * (C7 - C3))
54#define W9 (M_SQRT2 * (-C1 - C3))
55#define WA (M_SQRT2 * (-C3 - C5))
56#define WB (M_SQRT2 * (C5 - C3))
57
58static const vector float fdctconsts[3] = {
59 { W0, W1, W2, W3 },
60 { W4, W5, W6, W7 },
61 { W8, W9, WA, WB }
62};
63
64#define LD_W0 vec_splat(cnsts0, 0)
65#define LD_W1 vec_splat(cnsts0, 1)
66#define LD_W2 vec_splat(cnsts0, 2)
67#define LD_W3 vec_splat(cnsts0, 3)
68#define LD_W4 vec_splat(cnsts1, 0)
69#define LD_W5 vec_splat(cnsts1, 1)
70#define LD_W6 vec_splat(cnsts1, 2)
71#define LD_W7 vec_splat(cnsts1, 3)
72#define LD_W8 vec_splat(cnsts2, 0)
73#define LD_W9 vec_splat(cnsts2, 1)
74#define LD_WA vec_splat(cnsts2, 2)
75#define LD_WB vec_splat(cnsts2, 3)
76
77#define FDCTROW(b0, b1, b2, b3, b4, b5, b6, b7) /* {{{ */ \
78 x0 = vec_add(b0, b7); /* x0 = b0 + b7; */ \
79 x7 = vec_sub(b0, b7); /* x7 = b0 - b7; */ \
80 x1 = vec_add(b1, b6); /* x1 = b1 + b6; */ \
81 x6 = vec_sub(b1, b6); /* x6 = b1 - b6; */ \
82 x2 = vec_add(b2, b5); /* x2 = b2 + b5; */ \
83 x5 = vec_sub(b2, b5); /* x5 = b2 - b5; */ \
84 x3 = vec_add(b3, b4); /* x3 = b3 + b4; */ \
85 x4 = vec_sub(b3, b4); /* x4 = b3 - b4; */ \
86 \
87 b7 = vec_add(x0, x3); /* b7 = x0 + x3; */ \
88 b1 = vec_add(x1, x2); /* b1 = x1 + x2; */ \
89 b0 = vec_add(b7, b1); /* b0 = b7 + b1; */ \
90 b4 = vec_sub(b7, b1); /* b4 = b7 - b1; */ \
91 \
92 b2 = vec_sub(x0, x3); /* b2 = x0 - x3; */ \
93 b6 = vec_sub(x1, x2); /* b6 = x1 - x2; */ \
94 b5 = vec_add(b6, b2); /* b5 = b6 + b2; */ \
95 cnst = LD_W2; \
96 b5 = vec_madd(cnst, b5, mzero); /* b5 = b5 * W2; */ \
97 cnst = LD_W1; \
98 b2 = vec_madd(cnst, b2, b5); /* b2 = b5 + b2 * W1; */ \
99 cnst = LD_W0; \
100 b6 = vec_madd(cnst, b6, b5); /* b6 = b5 + b6 * W0; */ \
101 \
102 x0 = vec_add(x4, x7); /* x0 = x4 + x7; */ \
103 x1 = vec_add(x5, x6); /* x1 = x5 + x6; */ \
104 x2 = vec_add(x4, x6); /* x2 = x4 + x6; */ \
105 x3 = vec_add(x5, x7); /* x3 = x5 + x7; */ \
106 x8 = vec_add(x2, x3); /* x8 = x2 + x3; */ \
107 cnst = LD_W3; \
108 x8 = vec_madd(cnst, x8, mzero); /* x8 = x8 * W3; */ \
109 \
110 cnst = LD_W8; \
111 x0 = vec_madd(cnst, x0, mzero); /* x0 *= W8; */ \
112 cnst = LD_W9; \
113 x1 = vec_madd(cnst, x1, mzero); /* x1 *= W9; */ \
114 cnst = LD_WA; \
115 x2 = vec_madd(cnst, x2, x8); /* x2 = x2 * WA + x8; */ \
116 cnst = LD_WB; \
117 x3 = vec_madd(cnst, x3, x8); /* x3 = x3 * WB + x8; */ \
118 \
119 cnst = LD_W4; \
120 b7 = vec_madd(cnst, x4, x0); /* b7 = x4 * W4 + x0; */ \
121 cnst = LD_W5; \
122 b5 = vec_madd(cnst, x5, x1); /* b5 = x5 * W5 + x1; */ \
123 cnst = LD_W6; \
124 b3 = vec_madd(cnst, x6, x1); /* b3 = x6 * W6 + x1; */ \
125 cnst = LD_W7; \
126 b1 = vec_madd(cnst, x7, x0); /* b1 = x7 * W7 + x0; */ \
127 \
128 b7 = vec_add(b7, x2); /* b7 = b7 + x2; */ \
129 b5 = vec_add(b5, x3); /* b5 = b5 + x3; */ \
130 b3 = vec_add(b3, x2); /* b3 = b3 + x2; */ \
131 b1 = vec_add(b1, x3) /* b1 = b1 + x3; */ \
132 /* }}} */
133
134#define FDCTCOL(b0, b1, b2, b3, b4, b5, b6, b7) /* {{{ */ \
135 x0 = vec_add(b0, b7); /* x0 = b0 + b7; */ \
136 x7 = vec_sub(b0, b7); /* x7 = b0 - b7; */ \
137 x1 = vec_add(b1, b6); /* x1 = b1 + b6; */ \
138 x6 = vec_sub(b1, b6); /* x6 = b1 - b6; */ \
139 x2 = vec_add(b2, b5); /* x2 = b2 + b5; */ \
140 x5 = vec_sub(b2, b5); /* x5 = b2 - b5; */ \
141 x3 = vec_add(b3, b4); /* x3 = b3 + b4; */ \
142 x4 = vec_sub(b3, b4); /* x4 = b3 - b4; */ \
143 \
144 b7 = vec_add(x0, x3); /* b7 = x0 + x3; */ \
145 b1 = vec_add(x1, x2); /* b1 = x1 + x2; */ \
146 b0 = vec_add(b7, b1); /* b0 = b7 + b1; */ \
147 b4 = vec_sub(b7, b1); /* b4 = b7 - b1; */ \
148 \
149 b2 = vec_sub(x0, x3); /* b2 = x0 - x3; */ \
150 b6 = vec_sub(x1, x2); /* b6 = x1 - x2; */ \
151 b5 = vec_add(b6, b2); /* b5 = b6 + b2; */ \
152 cnst = LD_W2; \
153 b5 = vec_madd(cnst, b5, mzero); /* b5 = b5 * W2; */ \
154 cnst = LD_W1; \
155 b2 = vec_madd(cnst, b2, b5); /* b2 = b5 + b2 * W1; */ \
156 cnst = LD_W0; \
157 b6 = vec_madd(cnst, b6, b5); /* b6 = b5 + b6 * W0; */ \
158 \
159 x0 = vec_add(x4, x7); /* x0 = x4 + x7; */ \
160 x1 = vec_add(x5, x6); /* x1 = x5 + x6; */ \
161 x2 = vec_add(x4, x6); /* x2 = x4 + x6; */ \
162 x3 = vec_add(x5, x7); /* x3 = x5 + x7; */ \
163 x8 = vec_add(x2, x3); /* x8 = x2 + x3; */ \
164 cnst = LD_W3; \
165 x8 = vec_madd(cnst, x8, mzero); /* x8 = x8 * W3; */ \
166 \
167 cnst = LD_W8; \
168 x0 = vec_madd(cnst, x0, mzero); /* x0 *= W8; */ \
169 cnst = LD_W9; \
170 x1 = vec_madd(cnst, x1, mzero); /* x1 *= W9; */ \
171 cnst = LD_WA; \
172 x2 = vec_madd(cnst, x2, x8); /* x2 = x2 * WA + x8; */ \
173 cnst = LD_WB; \
174 x3 = vec_madd(cnst, x3, x8); /* x3 = x3 * WB + x8; */ \
175 \
176 cnst = LD_W4; \
177 b7 = vec_madd(cnst, x4, x0); /* b7 = x4 * W4 + x0; */ \
178 cnst = LD_W5; \
179 b5 = vec_madd(cnst, x5, x1); /* b5 = x5 * W5 + x1; */ \
180 cnst = LD_W6; \
181 b3 = vec_madd(cnst, x6, x1); /* b3 = x6 * W6 + x1; */ \
182 cnst = LD_W7; \
183 b1 = vec_madd(cnst, x7, x0); /* b1 = x7 * W7 + x0; */ \
184 \
185 b7 = vec_add(b7, x2); /* b7 += x2; */ \
186 b5 = vec_add(b5, x3); /* b5 += x3; */ \
187 b3 = vec_add(b3, x2); /* b3 += x2; */ \
188 b1 = vec_add(b1, x3) /* b1 += x3; */ \
189 /* }}} */
190
191/* two dimensional discrete cosine transform */
192void ff_fdct_altivec(int16_t *block)
193{
194 vector signed short *bp;
195 const vector float *cp = fdctconsts;
196 vector float b00, b10, b20, b30, b40, b50, b60, b70;
197 vector float b01, b11, b21, b31, b41, b51, b61, b71;
198 vector float mzero, cnst, cnsts0, cnsts1, cnsts2;
199 vector float x0, x1, x2, x3, x4, x5, x6, x7, x8;
200
201 /* setup constants {{{ */
202 /* mzero = -0.0 */
203 mzero = ((vector float) vec_splat_u32(-1));
204 mzero = ((vector float) vec_sl(vu32(mzero), vu32(mzero)));
205 cnsts0 = vec_ld(0, cp);
206 cp++;
207 cnsts1 = vec_ld(0, cp);
208 cp++;
209 cnsts2 = vec_ld(0, cp);
210 /* }}} */
211
212 /* 8x8 matrix transpose (vector short[8]) {{{ */
213#define MERGE_S16(hl, a, b) vec_merge ## hl(vs16(a), vs16(b))
214
215 bp = (vector signed short *) block;
216 b00 = ((vector float) vec_ld(0, bp));
217 b40 = ((vector float) vec_ld(16 * 4, bp));
218 b01 = ((vector float) MERGE_S16(h, b00, b40));
219 b11 = ((vector float) MERGE_S16(l, b00, b40));
220 bp++;
221 b10 = ((vector float) vec_ld(0, bp));
222 b50 = ((vector float) vec_ld(16 * 4, bp));
223 b21 = ((vector float) MERGE_S16(h, b10, b50));
224 b31 = ((vector float) MERGE_S16(l, b10, b50));
225 bp++;
226 b20 = ((vector float) vec_ld(0, bp));
227 b60 = ((vector float) vec_ld(16 * 4, bp));
228 b41 = ((vector float) MERGE_S16(h, b20, b60));
229 b51 = ((vector float) MERGE_S16(l, b20, b60));
230 bp++;
231 b30 = ((vector float) vec_ld(0, bp));
232 b70 = ((vector float) vec_ld(16 * 4, bp));
233 b61 = ((vector float) MERGE_S16(h, b30, b70));
234 b71 = ((vector float) MERGE_S16(l, b30, b70));
235
236 x0 = ((vector float) MERGE_S16(h, b01, b41));
237 x1 = ((vector float) MERGE_S16(l, b01, b41));
238 x2 = ((vector float) MERGE_S16(h, b11, b51));
239 x3 = ((vector float) MERGE_S16(l, b11, b51));
240 x4 = ((vector float) MERGE_S16(h, b21, b61));
241 x5 = ((vector float) MERGE_S16(l, b21, b61));
242 x6 = ((vector float) MERGE_S16(h, b31, b71));
243 x7 = ((vector float) MERGE_S16(l, b31, b71));
244
245 b00 = ((vector float) MERGE_S16(h, x0, x4));
246 b10 = ((vector float) MERGE_S16(l, x0, x4));
247 b20 = ((vector float) MERGE_S16(h, x1, x5));
248 b30 = ((vector float) MERGE_S16(l, x1, x5));
249 b40 = ((vector float) MERGE_S16(h, x2, x6));
250 b50 = ((vector float) MERGE_S16(l, x2, x6));
251 b60 = ((vector float) MERGE_S16(h, x3, x7));
252 b70 = ((vector float) MERGE_S16(l, x3, x7));
253
254#undef MERGE_S16
255 /* }}} */
256
257 /* Some of the initial calculations can be done as vector short
258 * before conversion to vector float. The following code section
259 * takes advantage of this. */
260
261 /* fdct rows {{{ */
262 x0 = ((vector float) vec_add(vs16(b00), vs16(b70)));
263 x7 = ((vector float) vec_sub(vs16(b00), vs16(b70)));
264 x1 = ((vector float) vec_add(vs16(b10), vs16(b60)));
265 x6 = ((vector float) vec_sub(vs16(b10), vs16(b60)));
266 x2 = ((vector float) vec_add(vs16(b20), vs16(b50)));
267 x5 = ((vector float) vec_sub(vs16(b20), vs16(b50)));
268 x3 = ((vector float) vec_add(vs16(b30), vs16(b40)));
269 x4 = ((vector float) vec_sub(vs16(b30), vs16(b40)));
270
271 b70 = ((vector float) vec_add(vs16(x0), vs16(x3)));
272 b10 = ((vector float) vec_add(vs16(x1), vs16(x2)));
273
274 b00 = ((vector float) vec_add(vs16(b70), vs16(b10)));
275 b40 = ((vector float) vec_sub(vs16(b70), vs16(b10)));
276
277#define CTF0(n) \
278 b ## n ## 1 = ((vector float) vec_unpackl(vs16(b ## n ## 0))); \
279 b ## n ## 0 = ((vector float) vec_unpackh(vs16(b ## n ## 0))); \
280 b ## n ## 1 = vec_ctf(vs32(b ## n ## 1), 0); \
281 b ## n ## 0 = vec_ctf(vs32(b ## n ## 0), 0)
282
283 CTF0(0);
284 CTF0(4);
285
286 b20 = ((vector float) vec_sub(vs16(x0), vs16(x3)));
287 b60 = ((vector float) vec_sub(vs16(x1), vs16(x2)));
288
289 CTF0(2);
290 CTF0(6);
291
292#undef CTF0
293
294 x0 = vec_add(b60, b20);
295 x1 = vec_add(b61, b21);
296
297 cnst = LD_W2;
298 x0 = vec_madd(cnst, x0, mzero);
299 x1 = vec_madd(cnst, x1, mzero);
300 cnst = LD_W1;
301 b20 = vec_madd(cnst, b20, x0);
302 b21 = vec_madd(cnst, b21, x1);
303 cnst = LD_W0;
304 b60 = vec_madd(cnst, b60, x0);
305 b61 = vec_madd(cnst, b61, x1);
306
307#define CTFX(x, b) \
308 b ## 0 = ((vector float) vec_unpackh(vs16(x))); \
309 b ## 1 = ((vector float) vec_unpackl(vs16(x))); \
310 b ## 0 = vec_ctf(vs32(b ## 0), 0); \
311 b ## 1 = vec_ctf(vs32(b ## 1), 0)
312
313 CTFX(x4, b7);
314 CTFX(x5, b5);
315 CTFX(x6, b3);
316 CTFX(x7, b1);
317
318#undef CTFX
319
320 x0 = vec_add(b70, b10);
321 x1 = vec_add(b50, b30);
322 x2 = vec_add(b70, b30);
323 x3 = vec_add(b50, b10);
324 x8 = vec_add(x2, x3);
325 cnst = LD_W3;
326 x8 = vec_madd(cnst, x8, mzero);
327
328 cnst = LD_W8;
329 x0 = vec_madd(cnst, x0, mzero);
330 cnst = LD_W9;
331 x1 = vec_madd(cnst, x1, mzero);
332 cnst = LD_WA;
333 x2 = vec_madd(cnst, x2, x8);
334 cnst = LD_WB;
335 x3 = vec_madd(cnst, x3, x8);
336
337 cnst = LD_W4;
338 b70 = vec_madd(cnst, b70, x0);
339 cnst = LD_W5;
340 b50 = vec_madd(cnst, b50, x1);
341 cnst = LD_W6;
342 b30 = vec_madd(cnst, b30, x1);
343 cnst = LD_W7;
344 b10 = vec_madd(cnst, b10, x0);
345
346 b70 = vec_add(b70, x2);
347 b50 = vec_add(b50, x3);
348 b30 = vec_add(b30, x2);
349 b10 = vec_add(b10, x3);
350
351 x0 = vec_add(b71, b11);
352 x1 = vec_add(b51, b31);
353 x2 = vec_add(b71, b31);
354 x3 = vec_add(b51, b11);
355 x8 = vec_add(x2, x3);
356 cnst = LD_W3;
357 x8 = vec_madd(cnst, x8, mzero);
358
359 cnst = LD_W8;
360 x0 = vec_madd(cnst, x0, mzero);
361 cnst = LD_W9;
362 x1 = vec_madd(cnst, x1, mzero);
363 cnst = LD_WA;
364 x2 = vec_madd(cnst, x2, x8);
365 cnst = LD_WB;
366 x3 = vec_madd(cnst, x3, x8);
367
368 cnst = LD_W4;
369 b71 = vec_madd(cnst, b71, x0);
370 cnst = LD_W5;
371 b51 = vec_madd(cnst, b51, x1);
372 cnst = LD_W6;
373 b31 = vec_madd(cnst, b31, x1);
374 cnst = LD_W7;
375 b11 = vec_madd(cnst, b11, x0);
376
377 b71 = vec_add(b71, x2);
378 b51 = vec_add(b51, x3);
379 b31 = vec_add(b31, x2);
380 b11 = vec_add(b11, x3);
381 /* }}} */
382
383 /* 8x8 matrix transpose (vector float[8][2]) {{{ */
384 x0 = vec_mergel(b00, b20);
385 x1 = vec_mergeh(b00, b20);
386 x2 = vec_mergel(b10, b30);
387 x3 = vec_mergeh(b10, b30);
388
389 b00 = vec_mergeh(x1, x3);
390 b10 = vec_mergel(x1, x3);
391 b20 = vec_mergeh(x0, x2);
392 b30 = vec_mergel(x0, x2);
393
394 x4 = vec_mergel(b41, b61);
395 x5 = vec_mergeh(b41, b61);
396 x6 = vec_mergel(b51, b71);
397 x7 = vec_mergeh(b51, b71);
398
399 b41 = vec_mergeh(x5, x7);
400 b51 = vec_mergel(x5, x7);
401 b61 = vec_mergeh(x4, x6);
402 b71 = vec_mergel(x4, x6);
403
404 x0 = vec_mergel(b01, b21);
405 x1 = vec_mergeh(b01, b21);
406 x2 = vec_mergel(b11, b31);
407 x3 = vec_mergeh(b11, b31);
408
409 x4 = vec_mergel(b40, b60);
410 x5 = vec_mergeh(b40, b60);
411 x6 = vec_mergel(b50, b70);
412 x7 = vec_mergeh(b50, b70);
413
414 b40 = vec_mergeh(x1, x3);
415 b50 = vec_mergel(x1, x3);
416 b60 = vec_mergeh(x0, x2);
417 b70 = vec_mergel(x0, x2);
418
419 b01 = vec_mergeh(x5, x7);
420 b11 = vec_mergel(x5, x7);
421 b21 = vec_mergeh(x4, x6);
422 b31 = vec_mergel(x4, x6);
423 /* }}} */
424
425 FDCTCOL(b00, b10, b20, b30, b40, b50, b60, b70);
426 FDCTCOL(b01, b11, b21, b31, b41, b51, b61, b71);
427
428 /* round, convert back to short {{{ */
429#define CTS(n) \
430 b ## n ## 0 = vec_round(b ## n ## 0); \
431 b ## n ## 1 = vec_round(b ## n ## 1); \
432 b ## n ## 0 = ((vector float) vec_cts(b ## n ## 0, 0)); \
433 b ## n ## 1 = ((vector float) vec_cts(b ## n ## 1, 0)); \
434 b ## n ## 0 = ((vector float) vec_pack(vs32(b ## n ## 0), \
435 vs32(b ## n ## 1))); \
436 vec_st(vs16(b ## n ## 0), 0, bp)
437
438 bp = (vector signed short *) block;
439 CTS(0);
440 bp++;
441 CTS(1);
442 bp++;
443 CTS(2);
444 bp++;
445 CTS(3);
446 bp++;
447 CTS(4);
448 bp++;
449 CTS(5);
450 bp++;
451 CTS(6);
452 bp++;
453 CTS(7);
454
455#undef CTS
456 /* }}} */
457}
Libavcodec external API header.
static int16_t block[64]
Definition dct.c:125
#define LD_W5
#define LD_W4
#define FDCTCOL(b0, b1, b2, b3, b4, b5, b6, b7)
#define LD_W1
#define vs16(v)
#define LD_W0
#define CTFX(x, b)
#define LD_W7
#define LD_WB
void ff_fdct_altivec(int16_t *block)
#define LD_W8
#define LD_W9
#define LD_WA
#define MERGE_S16(hl, a, b)
static const vector float fdctconsts[3]
#define WB
#define WA
#define CTF0(n)
#define LD_W2
#define W9
#define vu32(v)
#define W8
#define LD_W3
#define CTS(n)
#define LD_W6
Macro definitions for various function/variable attributes.
#define W3
#define W6
#define W5
#define W7
#define W1
#define W2
#define W4
Contains misc utility macros and inline functions.
static double b1(void *priv, double x, double y)
Definition vf_xfade.c:2041
static double b3(void *priv, double x, double y)
Definition vf_xfade.c:2043
#define W0
Definition wmv2dsp_mmi.c:28