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