dsputil: Move draw_edges() to mpegvideoencdsp
[ffmpeg.git] / libavcodec / dsputil.c
1 /*
2  * DSP utils
3  * Copyright (c) 2000, 2001 Fabrice Bellard
4  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5  *
6  * This file is part of Libav.
7  *
8  * Libav is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * Libav is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with Libav; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 /**
24  * @file
25  * DSP utils
26  */
27
28 #include "libavutil/attributes.h"
29 #include "avcodec.h"
30 #include "copy_block.h"
31 #include "dct.h"
32 #include "dsputil.h"
33 #include "simple_idct.h"
34 #include "faandct.h"
35 #include "mpegvideo.h"
36 #include "config.h"
37
38 uint32_t ff_square_tab[512] = { 0, };
39
40 #define BIT_DEPTH 16
41 #include "dsputilenc_template.c"
42 #undef BIT_DEPTH
43
44 #define BIT_DEPTH 8
45 #include "dsputilenc_template.c"
46
47 static int sse4_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
48                   int line_size, int h)
49 {
50     int s = 0, i;
51     uint32_t *sq = ff_square_tab + 256;
52
53     for (i = 0; i < h; i++) {
54         s    += sq[pix1[0] - pix2[0]];
55         s    += sq[pix1[1] - pix2[1]];
56         s    += sq[pix1[2] - pix2[2]];
57         s    += sq[pix1[3] - pix2[3]];
58         pix1 += line_size;
59         pix2 += line_size;
60     }
61     return s;
62 }
63
64 static int sse8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
65                   int line_size, int h)
66 {
67     int s = 0, i;
68     uint32_t *sq = ff_square_tab + 256;
69
70     for (i = 0; i < h; i++) {
71         s    += sq[pix1[0] - pix2[0]];
72         s    += sq[pix1[1] - pix2[1]];
73         s    += sq[pix1[2] - pix2[2]];
74         s    += sq[pix1[3] - pix2[3]];
75         s    += sq[pix1[4] - pix2[4]];
76         s    += sq[pix1[5] - pix2[5]];
77         s    += sq[pix1[6] - pix2[6]];
78         s    += sq[pix1[7] - pix2[7]];
79         pix1 += line_size;
80         pix2 += line_size;
81     }
82     return s;
83 }
84
85 static int sse16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
86                    int line_size, int h)
87 {
88     int s = 0, i;
89     uint32_t *sq = ff_square_tab + 256;
90
91     for (i = 0; i < h; i++) {
92         s += sq[pix1[0]  - pix2[0]];
93         s += sq[pix1[1]  - pix2[1]];
94         s += sq[pix1[2]  - pix2[2]];
95         s += sq[pix1[3]  - pix2[3]];
96         s += sq[pix1[4]  - pix2[4]];
97         s += sq[pix1[5]  - pix2[5]];
98         s += sq[pix1[6]  - pix2[6]];
99         s += sq[pix1[7]  - pix2[7]];
100         s += sq[pix1[8]  - pix2[8]];
101         s += sq[pix1[9]  - pix2[9]];
102         s += sq[pix1[10] - pix2[10]];
103         s += sq[pix1[11] - pix2[11]];
104         s += sq[pix1[12] - pix2[12]];
105         s += sq[pix1[13] - pix2[13]];
106         s += sq[pix1[14] - pix2[14]];
107         s += sq[pix1[15] - pix2[15]];
108
109         pix1 += line_size;
110         pix2 += line_size;
111     }
112     return s;
113 }
114
115 static void diff_pixels_c(int16_t *restrict block, const uint8_t *s1,
116                           const uint8_t *s2, int stride)
117 {
118     int i;
119
120     /* read the pixels */
121     for (i = 0; i < 8; i++) {
122         block[0] = s1[0] - s2[0];
123         block[1] = s1[1] - s2[1];
124         block[2] = s1[2] - s2[2];
125         block[3] = s1[3] - s2[3];
126         block[4] = s1[4] - s2[4];
127         block[5] = s1[5] - s2[5];
128         block[6] = s1[6] - s2[6];
129         block[7] = s1[7] - s2[7];
130         s1      += stride;
131         s2      += stride;
132         block   += 8;
133     }
134 }
135
136 static int sum_abs_dctelem_c(int16_t *block)
137 {
138     int sum = 0, i;
139
140     for (i = 0; i < 64; i++)
141         sum += FFABS(block[i]);
142     return sum;
143 }
144
145 #define avg2(a, b) ((a + b + 1) >> 1)
146 #define avg4(a, b, c, d) ((a + b + c + d + 2) >> 2)
147
148 static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
149                               int line_size, int h)
150 {
151     int s = 0, i;
152
153     for (i = 0; i < h; i++) {
154         s    += abs(pix1[0]  - pix2[0]);
155         s    += abs(pix1[1]  - pix2[1]);
156         s    += abs(pix1[2]  - pix2[2]);
157         s    += abs(pix1[3]  - pix2[3]);
158         s    += abs(pix1[4]  - pix2[4]);
159         s    += abs(pix1[5]  - pix2[5]);
160         s    += abs(pix1[6]  - pix2[6]);
161         s    += abs(pix1[7]  - pix2[7]);
162         s    += abs(pix1[8]  - pix2[8]);
163         s    += abs(pix1[9]  - pix2[9]);
164         s    += abs(pix1[10] - pix2[10]);
165         s    += abs(pix1[11] - pix2[11]);
166         s    += abs(pix1[12] - pix2[12]);
167         s    += abs(pix1[13] - pix2[13]);
168         s    += abs(pix1[14] - pix2[14]);
169         s    += abs(pix1[15] - pix2[15]);
170         pix1 += line_size;
171         pix2 += line_size;
172     }
173     return s;
174 }
175
176 static int pix_abs16_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
177                           int line_size, int h)
178 {
179     int s = 0, i;
180
181     for (i = 0; i < h; i++) {
182         s    += abs(pix1[0]  - avg2(pix2[0],  pix2[1]));
183         s    += abs(pix1[1]  - avg2(pix2[1],  pix2[2]));
184         s    += abs(pix1[2]  - avg2(pix2[2],  pix2[3]));
185         s    += abs(pix1[3]  - avg2(pix2[3],  pix2[4]));
186         s    += abs(pix1[4]  - avg2(pix2[4],  pix2[5]));
187         s    += abs(pix1[5]  - avg2(pix2[5],  pix2[6]));
188         s    += abs(pix1[6]  - avg2(pix2[6],  pix2[7]));
189         s    += abs(pix1[7]  - avg2(pix2[7],  pix2[8]));
190         s    += abs(pix1[8]  - avg2(pix2[8],  pix2[9]));
191         s    += abs(pix1[9]  - avg2(pix2[9],  pix2[10]));
192         s    += abs(pix1[10] - avg2(pix2[10], pix2[11]));
193         s    += abs(pix1[11] - avg2(pix2[11], pix2[12]));
194         s    += abs(pix1[12] - avg2(pix2[12], pix2[13]));
195         s    += abs(pix1[13] - avg2(pix2[13], pix2[14]));
196         s    += abs(pix1[14] - avg2(pix2[14], pix2[15]));
197         s    += abs(pix1[15] - avg2(pix2[15], pix2[16]));
198         pix1 += line_size;
199         pix2 += line_size;
200     }
201     return s;
202 }
203
204 static int pix_abs16_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
205                           int line_size, int h)
206 {
207     int s = 0, i;
208     uint8_t *pix3 = pix2 + line_size;
209
210     for (i = 0; i < h; i++) {
211         s    += abs(pix1[0]  - avg2(pix2[0],  pix3[0]));
212         s    += abs(pix1[1]  - avg2(pix2[1],  pix3[1]));
213         s    += abs(pix1[2]  - avg2(pix2[2],  pix3[2]));
214         s    += abs(pix1[3]  - avg2(pix2[3],  pix3[3]));
215         s    += abs(pix1[4]  - avg2(pix2[4],  pix3[4]));
216         s    += abs(pix1[5]  - avg2(pix2[5],  pix3[5]));
217         s    += abs(pix1[6]  - avg2(pix2[6],  pix3[6]));
218         s    += abs(pix1[7]  - avg2(pix2[7],  pix3[7]));
219         s    += abs(pix1[8]  - avg2(pix2[8],  pix3[8]));
220         s    += abs(pix1[9]  - avg2(pix2[9],  pix3[9]));
221         s    += abs(pix1[10] - avg2(pix2[10], pix3[10]));
222         s    += abs(pix1[11] - avg2(pix2[11], pix3[11]));
223         s    += abs(pix1[12] - avg2(pix2[12], pix3[12]));
224         s    += abs(pix1[13] - avg2(pix2[13], pix3[13]));
225         s    += abs(pix1[14] - avg2(pix2[14], pix3[14]));
226         s    += abs(pix1[15] - avg2(pix2[15], pix3[15]));
227         pix1 += line_size;
228         pix2 += line_size;
229         pix3 += line_size;
230     }
231     return s;
232 }
233
234 static int pix_abs16_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
235                            int line_size, int h)
236 {
237     int s = 0, i;
238     uint8_t *pix3 = pix2 + line_size;
239
240     for (i = 0; i < h; i++) {
241         s    += abs(pix1[0]  - avg4(pix2[0],  pix2[1],  pix3[0],  pix3[1]));
242         s    += abs(pix1[1]  - avg4(pix2[1],  pix2[2],  pix3[1],  pix3[2]));
243         s    += abs(pix1[2]  - avg4(pix2[2],  pix2[3],  pix3[2],  pix3[3]));
244         s    += abs(pix1[3]  - avg4(pix2[3],  pix2[4],  pix3[3],  pix3[4]));
245         s    += abs(pix1[4]  - avg4(pix2[4],  pix2[5],  pix3[4],  pix3[5]));
246         s    += abs(pix1[5]  - avg4(pix2[5],  pix2[6],  pix3[5],  pix3[6]));
247         s    += abs(pix1[6]  - avg4(pix2[6],  pix2[7],  pix3[6],  pix3[7]));
248         s    += abs(pix1[7]  - avg4(pix2[7],  pix2[8],  pix3[7],  pix3[8]));
249         s    += abs(pix1[8]  - avg4(pix2[8],  pix2[9],  pix3[8],  pix3[9]));
250         s    += abs(pix1[9]  - avg4(pix2[9],  pix2[10], pix3[9],  pix3[10]));
251         s    += abs(pix1[10] - avg4(pix2[10], pix2[11], pix3[10], pix3[11]));
252         s    += abs(pix1[11] - avg4(pix2[11], pix2[12], pix3[11], pix3[12]));
253         s    += abs(pix1[12] - avg4(pix2[12], pix2[13], pix3[12], pix3[13]));
254         s    += abs(pix1[13] - avg4(pix2[13], pix2[14], pix3[13], pix3[14]));
255         s    += abs(pix1[14] - avg4(pix2[14], pix2[15], pix3[14], pix3[15]));
256         s    += abs(pix1[15] - avg4(pix2[15], pix2[16], pix3[15], pix3[16]));
257         pix1 += line_size;
258         pix2 += line_size;
259         pix3 += line_size;
260     }
261     return s;
262 }
263
264 static inline int pix_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
265                              int line_size, int h)
266 {
267     int s = 0, i;
268
269     for (i = 0; i < h; i++) {
270         s    += abs(pix1[0] - pix2[0]);
271         s    += abs(pix1[1] - pix2[1]);
272         s    += abs(pix1[2] - pix2[2]);
273         s    += abs(pix1[3] - pix2[3]);
274         s    += abs(pix1[4] - pix2[4]);
275         s    += abs(pix1[5] - pix2[5]);
276         s    += abs(pix1[6] - pix2[6]);
277         s    += abs(pix1[7] - pix2[7]);
278         pix1 += line_size;
279         pix2 += line_size;
280     }
281     return s;
282 }
283
284 static int pix_abs8_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
285                          int line_size, int h)
286 {
287     int s = 0, i;
288
289     for (i = 0; i < h; i++) {
290         s    += abs(pix1[0] - avg2(pix2[0], pix2[1]));
291         s    += abs(pix1[1] - avg2(pix2[1], pix2[2]));
292         s    += abs(pix1[2] - avg2(pix2[2], pix2[3]));
293         s    += abs(pix1[3] - avg2(pix2[3], pix2[4]));
294         s    += abs(pix1[4] - avg2(pix2[4], pix2[5]));
295         s    += abs(pix1[5] - avg2(pix2[5], pix2[6]));
296         s    += abs(pix1[6] - avg2(pix2[6], pix2[7]));
297         s    += abs(pix1[7] - avg2(pix2[7], pix2[8]));
298         pix1 += line_size;
299         pix2 += line_size;
300     }
301     return s;
302 }
303
304 static int pix_abs8_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
305                          int line_size, int h)
306 {
307     int s = 0, i;
308     uint8_t *pix3 = pix2 + line_size;
309
310     for (i = 0; i < h; i++) {
311         s    += abs(pix1[0] - avg2(pix2[0], pix3[0]));
312         s    += abs(pix1[1] - avg2(pix2[1], pix3[1]));
313         s    += abs(pix1[2] - avg2(pix2[2], pix3[2]));
314         s    += abs(pix1[3] - avg2(pix2[3], pix3[3]));
315         s    += abs(pix1[4] - avg2(pix2[4], pix3[4]));
316         s    += abs(pix1[5] - avg2(pix2[5], pix3[5]));
317         s    += abs(pix1[6] - avg2(pix2[6], pix3[6]));
318         s    += abs(pix1[7] - avg2(pix2[7], pix3[7]));
319         pix1 += line_size;
320         pix2 += line_size;
321         pix3 += line_size;
322     }
323     return s;
324 }
325
326 static int pix_abs8_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
327                           int line_size, int h)
328 {
329     int s = 0, i;
330     uint8_t *pix3 = pix2 + line_size;
331
332     for (i = 0; i < h; i++) {
333         s    += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
334         s    += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2]));
335         s    += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3]));
336         s    += abs(pix1[3] - avg4(pix2[3], pix2[4], pix3[3], pix3[4]));
337         s    += abs(pix1[4] - avg4(pix2[4], pix2[5], pix3[4], pix3[5]));
338         s    += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6]));
339         s    += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7]));
340         s    += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8]));
341         pix1 += line_size;
342         pix2 += line_size;
343         pix3 += line_size;
344     }
345     return s;
346 }
347
348 static int nsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int h)
349 {
350     int score1 = 0, score2 = 0, x, y;
351
352     for (y = 0; y < h; y++) {
353         for (x = 0; x < 16; x++)
354             score1 += (s1[x] - s2[x]) * (s1[x] - s2[x]);
355         if (y + 1 < h) {
356             for (x = 0; x < 15; x++)
357                 score2 += FFABS(s1[x]     - s1[x + stride] -
358                                 s1[x + 1] + s1[x + stride + 1]) -
359                           FFABS(s2[x]     - s2[x + stride] -
360                                 s2[x + 1] + s2[x + stride + 1]);
361         }
362         s1 += stride;
363         s2 += stride;
364     }
365
366     if (c)
367         return score1 + FFABS(score2) * c->avctx->nsse_weight;
368     else
369         return score1 + FFABS(score2) * 8;
370 }
371
372 static int nsse8_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int h)
373 {
374     int score1 = 0, score2 = 0, x, y;
375
376     for (y = 0; y < h; y++) {
377         for (x = 0; x < 8; x++)
378             score1 += (s1[x] - s2[x]) * (s1[x] - s2[x]);
379         if (y + 1 < h) {
380             for (x = 0; x < 7; x++)
381                 score2 += FFABS(s1[x]     - s1[x + stride] -
382                                 s1[x + 1] + s1[x + stride + 1]) -
383                           FFABS(s2[x]     - s2[x + stride] -
384                                 s2[x + 1] + s2[x + stride + 1]);
385         }
386         s1 += stride;
387         s2 += stride;
388     }
389
390     if (c)
391         return score1 + FFABS(score2) * c->avctx->nsse_weight;
392     else
393         return score1 + FFABS(score2) * 8;
394 }
395
396 static int zero_cmp(MpegEncContext *s, uint8_t *a, uint8_t *b,
397                     int stride, int h)
398 {
399     return 0;
400 }
401
402 void ff_set_cmp(DSPContext *c, me_cmp_func *cmp, int type)
403 {
404     int i;
405
406     memset(cmp, 0, sizeof(void *) * 6);
407
408     for (i = 0; i < 6; i++) {
409         switch (type & 0xFF) {
410         case FF_CMP_SAD:
411             cmp[i] = c->sad[i];
412             break;
413         case FF_CMP_SATD:
414             cmp[i] = c->hadamard8_diff[i];
415             break;
416         case FF_CMP_SSE:
417             cmp[i] = c->sse[i];
418             break;
419         case FF_CMP_DCT:
420             cmp[i] = c->dct_sad[i];
421             break;
422         case FF_CMP_DCT264:
423             cmp[i] = c->dct264_sad[i];
424             break;
425         case FF_CMP_DCTMAX:
426             cmp[i] = c->dct_max[i];
427             break;
428         case FF_CMP_PSNR:
429             cmp[i] = c->quant_psnr[i];
430             break;
431         case FF_CMP_BIT:
432             cmp[i] = c->bit[i];
433             break;
434         case FF_CMP_RD:
435             cmp[i] = c->rd[i];
436             break;
437         case FF_CMP_VSAD:
438             cmp[i] = c->vsad[i];
439             break;
440         case FF_CMP_VSSE:
441             cmp[i] = c->vsse[i];
442             break;
443         case FF_CMP_ZERO:
444             cmp[i] = zero_cmp;
445             break;
446         case FF_CMP_NSSE:
447             cmp[i] = c->nsse[i];
448             break;
449         default:
450             av_log(NULL, AV_LOG_ERROR,
451                    "internal error in cmp function selection\n");
452         }
453     }
454 }
455
456 #define BUTTERFLY2(o1, o2, i1, i2)              \
457     o1 = (i1) + (i2);                           \
458     o2 = (i1) - (i2);
459
460 #define BUTTERFLY1(x, y)                        \
461     {                                           \
462         int a, b;                               \
463         a = x;                                  \
464         b = y;                                  \
465         x = a + b;                              \
466         y = a - b;                              \
467     }
468
469 #define BUTTERFLYA(x, y) (FFABS((x) + (y)) + FFABS((x) - (y)))
470
471 static int hadamard8_diff8x8_c(MpegEncContext *s, uint8_t *dst,
472                                uint8_t *src, int stride, int h)
473 {
474     int i, temp[64], sum = 0;
475
476     assert(h == 8);
477
478     for (i = 0; i < 8; i++) {
479         // FIXME: try pointer walks
480         BUTTERFLY2(temp[8 * i + 0], temp[8 * i + 1],
481                    src[stride * i + 0] - dst[stride * i + 0],
482                    src[stride * i + 1] - dst[stride * i + 1]);
483         BUTTERFLY2(temp[8 * i + 2], temp[8 * i + 3],
484                    src[stride * i + 2] - dst[stride * i + 2],
485                    src[stride * i + 3] - dst[stride * i + 3]);
486         BUTTERFLY2(temp[8 * i + 4], temp[8 * i + 5],
487                    src[stride * i + 4] - dst[stride * i + 4],
488                    src[stride * i + 5] - dst[stride * i + 5]);
489         BUTTERFLY2(temp[8 * i + 6], temp[8 * i + 7],
490                    src[stride * i + 6] - dst[stride * i + 6],
491                    src[stride * i + 7] - dst[stride * i + 7]);
492
493         BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 2]);
494         BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 3]);
495         BUTTERFLY1(temp[8 * i + 4], temp[8 * i + 6]);
496         BUTTERFLY1(temp[8 * i + 5], temp[8 * i + 7]);
497
498         BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 4]);
499         BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 5]);
500         BUTTERFLY1(temp[8 * i + 2], temp[8 * i + 6]);
501         BUTTERFLY1(temp[8 * i + 3], temp[8 * i + 7]);
502     }
503
504     for (i = 0; i < 8; i++) {
505         BUTTERFLY1(temp[8 * 0 + i], temp[8 * 1 + i]);
506         BUTTERFLY1(temp[8 * 2 + i], temp[8 * 3 + i]);
507         BUTTERFLY1(temp[8 * 4 + i], temp[8 * 5 + i]);
508         BUTTERFLY1(temp[8 * 6 + i], temp[8 * 7 + i]);
509
510         BUTTERFLY1(temp[8 * 0 + i], temp[8 * 2 + i]);
511         BUTTERFLY1(temp[8 * 1 + i], temp[8 * 3 + i]);
512         BUTTERFLY1(temp[8 * 4 + i], temp[8 * 6 + i]);
513         BUTTERFLY1(temp[8 * 5 + i], temp[8 * 7 + i]);
514
515         sum += BUTTERFLYA(temp[8 * 0 + i], temp[8 * 4 + i]) +
516                BUTTERFLYA(temp[8 * 1 + i], temp[8 * 5 + i]) +
517                BUTTERFLYA(temp[8 * 2 + i], temp[8 * 6 + i]) +
518                BUTTERFLYA(temp[8 * 3 + i], temp[8 * 7 + i]);
519     }
520     return sum;
521 }
522
523 static int hadamard8_intra8x8_c(MpegEncContext *s, uint8_t *src,
524                                 uint8_t *dummy, int stride, int h)
525 {
526     int i, temp[64], sum = 0;
527
528     assert(h == 8);
529
530     for (i = 0; i < 8; i++) {
531         // FIXME: try pointer walks
532         BUTTERFLY2(temp[8 * i + 0], temp[8 * i + 1],
533                    src[stride * i + 0], src[stride * i + 1]);
534         BUTTERFLY2(temp[8 * i + 2], temp[8 * i + 3],
535                    src[stride * i + 2], src[stride * i + 3]);
536         BUTTERFLY2(temp[8 * i + 4], temp[8 * i + 5],
537                    src[stride * i + 4], src[stride * i + 5]);
538         BUTTERFLY2(temp[8 * i + 6], temp[8 * i + 7],
539                    src[stride * i + 6], src[stride * i + 7]);
540
541         BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 2]);
542         BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 3]);
543         BUTTERFLY1(temp[8 * i + 4], temp[8 * i + 6]);
544         BUTTERFLY1(temp[8 * i + 5], temp[8 * i + 7]);
545
546         BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 4]);
547         BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 5]);
548         BUTTERFLY1(temp[8 * i + 2], temp[8 * i + 6]);
549         BUTTERFLY1(temp[8 * i + 3], temp[8 * i + 7]);
550     }
551
552     for (i = 0; i < 8; i++) {
553         BUTTERFLY1(temp[8 * 0 + i], temp[8 * 1 + i]);
554         BUTTERFLY1(temp[8 * 2 + i], temp[8 * 3 + i]);
555         BUTTERFLY1(temp[8 * 4 + i], temp[8 * 5 + i]);
556         BUTTERFLY1(temp[8 * 6 + i], temp[8 * 7 + i]);
557
558         BUTTERFLY1(temp[8 * 0 + i], temp[8 * 2 + i]);
559         BUTTERFLY1(temp[8 * 1 + i], temp[8 * 3 + i]);
560         BUTTERFLY1(temp[8 * 4 + i], temp[8 * 6 + i]);
561         BUTTERFLY1(temp[8 * 5 + i], temp[8 * 7 + i]);
562
563         sum +=
564             BUTTERFLYA(temp[8 * 0 + i], temp[8 * 4 + i])
565             + BUTTERFLYA(temp[8 * 1 + i], temp[8 * 5 + i])
566             + BUTTERFLYA(temp[8 * 2 + i], temp[8 * 6 + i])
567             + BUTTERFLYA(temp[8 * 3 + i], temp[8 * 7 + i]);
568     }
569
570     sum -= FFABS(temp[8 * 0] + temp[8 * 4]); // -mean
571
572     return sum;
573 }
574
575 static int dct_sad8x8_c(MpegEncContext *s, uint8_t *src1,
576                         uint8_t *src2, int stride, int h)
577 {
578     LOCAL_ALIGNED_16(int16_t, temp, [64]);
579
580     assert(h == 8);
581
582     s->dsp.diff_pixels(temp, src1, src2, stride);
583     s->dsp.fdct(temp);
584     return s->dsp.sum_abs_dctelem(temp);
585 }
586
587 #if CONFIG_GPL
588 #define DCT8_1D                                         \
589     {                                                   \
590         const int s07 = SRC(0) + SRC(7);                \
591         const int s16 = SRC(1) + SRC(6);                \
592         const int s25 = SRC(2) + SRC(5);                \
593         const int s34 = SRC(3) + SRC(4);                \
594         const int a0  = s07 + s34;                      \
595         const int a1  = s16 + s25;                      \
596         const int a2  = s07 - s34;                      \
597         const int a3  = s16 - s25;                      \
598         const int d07 = SRC(0) - SRC(7);                \
599         const int d16 = SRC(1) - SRC(6);                \
600         const int d25 = SRC(2) - SRC(5);                \
601         const int d34 = SRC(3) - SRC(4);                \
602         const int a4  = d16 + d25 + (d07 + (d07 >> 1)); \
603         const int a5  = d07 - d34 - (d25 + (d25 >> 1)); \
604         const int a6  = d07 + d34 - (d16 + (d16 >> 1)); \
605         const int a7  = d16 - d25 + (d34 + (d34 >> 1)); \
606         DST(0, a0 + a1);                                \
607         DST(1, a4 + (a7 >> 2));                         \
608         DST(2, a2 + (a3 >> 1));                         \
609         DST(3, a5 + (a6 >> 2));                         \
610         DST(4, a0 - a1);                                \
611         DST(5, a6 - (a5 >> 2));                         \
612         DST(6, (a2 >> 1) - a3);                         \
613         DST(7, (a4 >> 2) - a7);                         \
614     }
615
616 static int dct264_sad8x8_c(MpegEncContext *s, uint8_t *src1,
617                            uint8_t *src2, int stride, int h)
618 {
619     int16_t dct[8][8];
620     int i, sum = 0;
621
622     s->dsp.diff_pixels(dct[0], src1, src2, stride);
623
624 #define SRC(x) dct[i][x]
625 #define DST(x, v) dct[i][x] = v
626     for (i = 0; i < 8; i++)
627         DCT8_1D
628 #undef SRC
629 #undef DST
630
631 #define SRC(x) dct[x][i]
632 #define DST(x, v) sum += FFABS(v)
633         for (i = 0; i < 8; i++)
634             DCT8_1D
635 #undef SRC
636 #undef DST
637             return sum;
638 }
639 #endif
640
641 static int dct_max8x8_c(MpegEncContext *s, uint8_t *src1,
642                         uint8_t *src2, int stride, int h)
643 {
644     LOCAL_ALIGNED_16(int16_t, temp, [64]);
645     int sum = 0, i;
646
647     assert(h == 8);
648
649     s->dsp.diff_pixels(temp, src1, src2, stride);
650     s->dsp.fdct(temp);
651
652     for (i = 0; i < 64; i++)
653         sum = FFMAX(sum, FFABS(temp[i]));
654
655     return sum;
656 }
657
658 static int quant_psnr8x8_c(MpegEncContext *s, uint8_t *src1,
659                            uint8_t *src2, int stride, int h)
660 {
661     LOCAL_ALIGNED_16(int16_t, temp, [64 * 2]);
662     int16_t *const bak = temp + 64;
663     int sum = 0, i;
664
665     assert(h == 8);
666     s->mb_intra = 0;
667
668     s->dsp.diff_pixels(temp, src1, src2, stride);
669
670     memcpy(bak, temp, 64 * sizeof(int16_t));
671
672     s->block_last_index[0 /* FIXME */] =
673         s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i);
674     s->dct_unquantize_inter(s, temp, 0, s->qscale);
675     ff_simple_idct_8(temp); // FIXME
676
677     for (i = 0; i < 64; i++)
678         sum += (temp[i] - bak[i]) * (temp[i] - bak[i]);
679
680     return sum;
681 }
682
683 static int rd8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2,
684                    int stride, int h)
685 {
686     const uint8_t *scantable = s->intra_scantable.permutated;
687     LOCAL_ALIGNED_16(int16_t, temp, [64]);
688     LOCAL_ALIGNED_16(uint8_t, lsrc1, [64]);
689     LOCAL_ALIGNED_16(uint8_t, lsrc2, [64]);
690     int i, last, run, bits, level, distortion, start_i;
691     const int esc_length = s->ac_esc_length;
692     uint8_t *length, *last_length;
693
694     assert(h == 8);
695
696     copy_block8(lsrc1, src1, 8, stride, 8);
697     copy_block8(lsrc2, src2, 8, stride, 8);
698
699     s->dsp.diff_pixels(temp, lsrc1, lsrc2, 8);
700
701     s->block_last_index[0 /* FIXME */] =
702     last                               =
703         s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i);
704
705     bits = 0;
706
707     if (s->mb_intra) {
708         start_i     = 1;
709         length      = s->intra_ac_vlc_length;
710         last_length = s->intra_ac_vlc_last_length;
711         bits       += s->luma_dc_vlc_length[temp[0] + 256]; // FIXME: chroma
712     } else {
713         start_i     = 0;
714         length      = s->inter_ac_vlc_length;
715         last_length = s->inter_ac_vlc_last_length;
716     }
717
718     if (last >= start_i) {
719         run = 0;
720         for (i = start_i; i < last; i++) {
721             int j = scantable[i];
722             level = temp[j];
723
724             if (level) {
725                 level += 64;
726                 if ((level & (~127)) == 0)
727                     bits += length[UNI_AC_ENC_INDEX(run, level)];
728                 else
729                     bits += esc_length;
730                 run = 0;
731             } else
732                 run++;
733         }
734         i = scantable[last];
735
736         level = temp[i] + 64;
737
738         assert(level - 64);
739
740         if ((level & (~127)) == 0) {
741             bits += last_length[UNI_AC_ENC_INDEX(run, level)];
742         } else
743             bits += esc_length;
744     }
745
746     if (last >= 0) {
747         if (s->mb_intra)
748             s->dct_unquantize_intra(s, temp, 0, s->qscale);
749         else
750             s->dct_unquantize_inter(s, temp, 0, s->qscale);
751     }
752
753     s->idsp.idct_add(lsrc2, 8, temp);
754
755     distortion = s->dsp.sse[1](NULL, lsrc2, lsrc1, 8, 8);
756
757     return distortion + ((bits * s->qscale * s->qscale * 109 + 64) >> 7);
758 }
759
760 static int bit8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2,
761                     int stride, int h)
762 {
763     const uint8_t *scantable = s->intra_scantable.permutated;
764     LOCAL_ALIGNED_16(int16_t, temp, [64]);
765     int i, last, run, bits, level, start_i;
766     const int esc_length = s->ac_esc_length;
767     uint8_t *length, *last_length;
768
769     assert(h == 8);
770
771     s->dsp.diff_pixels(temp, src1, src2, stride);
772
773     s->block_last_index[0 /* FIXME */] =
774     last                               =
775         s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i);
776
777     bits = 0;
778
779     if (s->mb_intra) {
780         start_i     = 1;
781         length      = s->intra_ac_vlc_length;
782         last_length = s->intra_ac_vlc_last_length;
783         bits       += s->luma_dc_vlc_length[temp[0] + 256]; // FIXME: chroma
784     } else {
785         start_i     = 0;
786         length      = s->inter_ac_vlc_length;
787         last_length = s->inter_ac_vlc_last_length;
788     }
789
790     if (last >= start_i) {
791         run = 0;
792         for (i = start_i; i < last; i++) {
793             int j = scantable[i];
794             level = temp[j];
795
796             if (level) {
797                 level += 64;
798                 if ((level & (~127)) == 0)
799                     bits += length[UNI_AC_ENC_INDEX(run, level)];
800                 else
801                     bits += esc_length;
802                 run = 0;
803             } else
804                 run++;
805         }
806         i = scantable[last];
807
808         level = temp[i] + 64;
809
810         assert(level - 64);
811
812         if ((level & (~127)) == 0)
813             bits += last_length[UNI_AC_ENC_INDEX(run, level)];
814         else
815             bits += esc_length;
816     }
817
818     return bits;
819 }
820
821 #define VSAD_INTRA(size)                                                \
822 static int vsad_intra ## size ## _c(MpegEncContext *c,                  \
823                                     uint8_t *s, uint8_t *dummy,         \
824                                     int stride, int h)                  \
825 {                                                                       \
826     int score = 0, x, y;                                                \
827                                                                         \
828     for (y = 1; y < h; y++) {                                           \
829         for (x = 0; x < size; x += 4) {                                 \
830             score += FFABS(s[x]     - s[x + stride])     +              \
831                      FFABS(s[x + 1] - s[x + stride + 1]) +              \
832                      FFABS(s[x + 2] - s[x + 2 + stride]) +              \
833                      FFABS(s[x + 3] - s[x + 3 + stride]);               \
834         }                                                               \
835         s += stride;                                                    \
836     }                                                                   \
837                                                                         \
838     return score;                                                       \
839 }
840 VSAD_INTRA(8)
841 VSAD_INTRA(16)
842
843 static int vsad16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2,
844                     int stride, int h)
845 {
846     int score = 0, x, y;
847
848     for (y = 1; y < h; y++) {
849         for (x = 0; x < 16; x++)
850             score += FFABS(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]);
851         s1 += stride;
852         s2 += stride;
853     }
854
855     return score;
856 }
857
858 #define SQ(a) ((a) * (a))
859 #define VSSE_INTRA(size)                                                \
860 static int vsse_intra ## size ## _c(MpegEncContext *c,                  \
861                                     uint8_t *s, uint8_t *dummy,         \
862                                     int stride, int h)                  \
863 {                                                                       \
864     int score = 0, x, y;                                                \
865                                                                         \
866     for (y = 1; y < h; y++) {                                           \
867         for (x = 0; x < size; x += 4) {                                 \
868             score += SQ(s[x]     - s[x + stride]) +                     \
869                      SQ(s[x + 1] - s[x + stride + 1]) +                 \
870                      SQ(s[x + 2] - s[x + stride + 2]) +                 \
871                      SQ(s[x + 3] - s[x + stride + 3]);                  \
872         }                                                               \
873         s += stride;                                                    \
874     }                                                                   \
875                                                                         \
876     return score;                                                       \
877 }
878 VSSE_INTRA(8)
879 VSSE_INTRA(16)
880
881 static int vsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2,
882                     int stride, int h)
883 {
884     int score = 0, x, y;
885
886     for (y = 1; y < h; y++) {
887         for (x = 0; x < 16; x++)
888             score += SQ(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]);
889         s1 += stride;
890         s2 += stride;
891     }
892
893     return score;
894 }
895
896 #define WRAPPER8_16_SQ(name8, name16)                                   \
897 static int name16(MpegEncContext *s, uint8_t *dst, uint8_t *src,        \
898                   int stride, int h)                                    \
899 {                                                                       \
900     int score = 0;                                                      \
901                                                                         \
902     score += name8(s, dst, src, stride, 8);                             \
903     score += name8(s, dst + 8, src + 8, stride, 8);                     \
904     if (h == 16) {                                                      \
905         dst   += 8 * stride;                                            \
906         src   += 8 * stride;                                            \
907         score += name8(s, dst, src, stride, 8);                         \
908         score += name8(s, dst + 8, src + 8, stride, 8);                 \
909     }                                                                   \
910     return score;                                                       \
911 }
912
913 WRAPPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c)
914 WRAPPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c)
915 WRAPPER8_16_SQ(dct_sad8x8_c, dct_sad16_c)
916 #if CONFIG_GPL
917 WRAPPER8_16_SQ(dct264_sad8x8_c, dct264_sad16_c)
918 #endif
919 WRAPPER8_16_SQ(dct_max8x8_c, dct_max16_c)
920 WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c)
921 WRAPPER8_16_SQ(rd8x8_c, rd16_c)
922 WRAPPER8_16_SQ(bit8x8_c, bit16_c)
923
924 /* init static data */
925 av_cold void ff_dsputil_static_init(void)
926 {
927     int i;
928
929     for (i = 0; i < 512; i++)
930         ff_square_tab[i] = (i - 256) * (i - 256);
931 }
932
933 av_cold void ff_dsputil_init(DSPContext *c, AVCodecContext *avctx)
934 {
935     const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8;
936
937 #if CONFIG_ENCODERS
938     if (avctx->bits_per_raw_sample == 10) {
939         c->fdct    = ff_jpeg_fdct_islow_10;
940         c->fdct248 = ff_fdct248_islow_10;
941     } else {
942         if (avctx->dct_algo == FF_DCT_FASTINT) {
943             c->fdct    = ff_fdct_ifast;
944             c->fdct248 = ff_fdct_ifast248;
945         } else if (avctx->dct_algo == FF_DCT_FAAN) {
946             c->fdct    = ff_faandct;
947             c->fdct248 = ff_faandct248;
948         } else {
949             c->fdct    = ff_jpeg_fdct_islow_8; // slow/accurate/default
950             c->fdct248 = ff_fdct248_islow_8;
951         }
952     }
953 #endif /* CONFIG_ENCODERS */
954
955     c->diff_pixels = diff_pixels_c;
956
957     c->sum_abs_dctelem = sum_abs_dctelem_c;
958
959     /* TODO [0] 16  [1] 8 */
960     c->pix_abs[0][0] = pix_abs16_c;
961     c->pix_abs[0][1] = pix_abs16_x2_c;
962     c->pix_abs[0][2] = pix_abs16_y2_c;
963     c->pix_abs[0][3] = pix_abs16_xy2_c;
964     c->pix_abs[1][0] = pix_abs8_c;
965     c->pix_abs[1][1] = pix_abs8_x2_c;
966     c->pix_abs[1][2] = pix_abs8_y2_c;
967     c->pix_abs[1][3] = pix_abs8_xy2_c;
968
969 #define SET_CMP_FUNC(name)                      \
970     c->name[0] = name ## 16_c;                  \
971     c->name[1] = name ## 8x8_c;
972
973     SET_CMP_FUNC(hadamard8_diff)
974     c->hadamard8_diff[4] = hadamard8_intra16_c;
975     c->hadamard8_diff[5] = hadamard8_intra8x8_c;
976     SET_CMP_FUNC(dct_sad)
977     SET_CMP_FUNC(dct_max)
978 #if CONFIG_GPL
979     SET_CMP_FUNC(dct264_sad)
980 #endif
981     c->sad[0] = pix_abs16_c;
982     c->sad[1] = pix_abs8_c;
983     c->sse[0] = sse16_c;
984     c->sse[1] = sse8_c;
985     c->sse[2] = sse4_c;
986     SET_CMP_FUNC(quant_psnr)
987     SET_CMP_FUNC(rd)
988     SET_CMP_FUNC(bit)
989     c->vsad[0] = vsad16_c;
990     c->vsad[4] = vsad_intra16_c;
991     c->vsad[5] = vsad_intra8_c;
992     c->vsse[0] = vsse16_c;
993     c->vsse[4] = vsse_intra16_c;
994     c->vsse[5] = vsse_intra8_c;
995     c->nsse[0] = nsse16_c;
996     c->nsse[1] = nsse8_c;
997
998     switch (avctx->bits_per_raw_sample) {
999     case 9:
1000     case 10:
1001         c->get_pixels = get_pixels_16_c;
1002         break;
1003     default:
1004         c->get_pixels = get_pixels_8_c;
1005         break;
1006     }
1007
1008     if (ARCH_ARM)
1009         ff_dsputil_init_arm(c, avctx, high_bit_depth);
1010     if (ARCH_PPC)
1011         ff_dsputil_init_ppc(c, avctx, high_bit_depth);
1012     if (ARCH_X86)
1013         ff_dsputil_init_x86(c, avctx, high_bit_depth);
1014 }