FFmpeg
me_cmp.c
Go to the documentation of this file.
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 FFmpeg.
7  *
8  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <stddef.h>
24 
25 #include "libavutil/attributes.h"
26 #include "libavutil/internal.h"
27 #include "libavutil/mem_internal.h"
28 #include "avcodec.h"
29 #include "copy_block.h"
30 #include "mathops.h"
31 #include "simple_idct.h"
32 #include "me_cmp.h"
33 #include "mpegvideoenc.h"
34 #include "config.h"
35 #include "config_components.h"
36 
37 static int sse4_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
38  ptrdiff_t stride, int h)
39 {
40  int s = 0, i;
41  const uint32_t *sq = ff_square_tab + 256;
42 
43  for (i = 0; i < h; i++) {
44  s += sq[pix1[0] - pix2[0]];
45  s += sq[pix1[1] - pix2[1]];
46  s += sq[pix1[2] - pix2[2]];
47  s += sq[pix1[3] - pix2[3]];
48  pix1 += stride;
49  pix2 += stride;
50  }
51  return s;
52 }
53 
54 static int sse8_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
55  ptrdiff_t stride, int h)
56 {
57  int s = 0, i;
58  const uint32_t *sq = ff_square_tab + 256;
59 
60  for (i = 0; i < h; i++) {
61  s += sq[pix1[0] - pix2[0]];
62  s += sq[pix1[1] - pix2[1]];
63  s += sq[pix1[2] - pix2[2]];
64  s += sq[pix1[3] - pix2[3]];
65  s += sq[pix1[4] - pix2[4]];
66  s += sq[pix1[5] - pix2[5]];
67  s += sq[pix1[6] - pix2[6]];
68  s += sq[pix1[7] - pix2[7]];
69  pix1 += stride;
70  pix2 += stride;
71  }
72  return s;
73 }
74 
75 static int sse16_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
76  ptrdiff_t stride, int h)
77 {
78  int s = 0, i;
79  const uint32_t *sq = ff_square_tab + 256;
80 
81  for (i = 0; i < h; i++) {
82  s += sq[pix1[0] - pix2[0]];
83  s += sq[pix1[1] - pix2[1]];
84  s += sq[pix1[2] - pix2[2]];
85  s += sq[pix1[3] - pix2[3]];
86  s += sq[pix1[4] - pix2[4]];
87  s += sq[pix1[5] - pix2[5]];
88  s += sq[pix1[6] - pix2[6]];
89  s += sq[pix1[7] - pix2[7]];
90  s += sq[pix1[8] - pix2[8]];
91  s += sq[pix1[9] - pix2[9]];
92  s += sq[pix1[10] - pix2[10]];
93  s += sq[pix1[11] - pix2[11]];
94  s += sq[pix1[12] - pix2[12]];
95  s += sq[pix1[13] - pix2[13]];
96  s += sq[pix1[14] - pix2[14]];
97  s += sq[pix1[15] - pix2[15]];
98 
99  pix1 += stride;
100  pix2 += stride;
101  }
102  return s;
103 }
104 
105 static int sum_abs_dctelem_c(const int16_t *block)
106 {
107  int sum = 0, i;
108 
109  for (i = 0; i < 64; i++)
110  sum += FFABS(block[i]);
111  return sum;
112 }
113 
114 #define avg2(a, b) (((a) + (b) + 1) >> 1)
115 #define avg4(a, b, c, d) (((a) + (b) + (c) + (d) + 2) >> 2)
116 
117 static inline int pix_abs16_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
118  ptrdiff_t stride, int h)
119 {
120  int s = 0, i;
121 
122  for (i = 0; i < h; i++) {
123  s += abs(pix1[0] - pix2[0]);
124  s += abs(pix1[1] - pix2[1]);
125  s += abs(pix1[2] - pix2[2]);
126  s += abs(pix1[3] - pix2[3]);
127  s += abs(pix1[4] - pix2[4]);
128  s += abs(pix1[5] - pix2[5]);
129  s += abs(pix1[6] - pix2[6]);
130  s += abs(pix1[7] - pix2[7]);
131  s += abs(pix1[8] - pix2[8]);
132  s += abs(pix1[9] - pix2[9]);
133  s += abs(pix1[10] - pix2[10]);
134  s += abs(pix1[11] - pix2[11]);
135  s += abs(pix1[12] - pix2[12]);
136  s += abs(pix1[13] - pix2[13]);
137  s += abs(pix1[14] - pix2[14]);
138  s += abs(pix1[15] - pix2[15]);
139  pix1 += stride;
140  pix2 += stride;
141  }
142  return s;
143 }
144 
145 static inline int pix_median_abs16_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
146  ptrdiff_t stride, int h)
147 {
148  int s = 0, i, j;
149 
150 #define V(x) (pix1[x] - pix2[x])
151 
152  s += abs(V(0));
153  s += abs(V(1) - V(0));
154  s += abs(V(2) - V(1));
155  s += abs(V(3) - V(2));
156  s += abs(V(4) - V(3));
157  s += abs(V(5) - V(4));
158  s += abs(V(6) - V(5));
159  s += abs(V(7) - V(6));
160  s += abs(V(8) - V(7));
161  s += abs(V(9) - V(8));
162  s += abs(V(10) - V(9));
163  s += abs(V(11) - V(10));
164  s += abs(V(12) - V(11));
165  s += abs(V(13) - V(12));
166  s += abs(V(14) - V(13));
167  s += abs(V(15) - V(14));
168 
169  pix1 += stride;
170  pix2 += stride;
171 
172  for (i = 1; i < h; i++) {
173  s += abs(V(0) - V(-stride));
174  for (j = 1; j < 16; j++)
175  s += abs(V(j) - mid_pred(V(j-stride), V(j-1), V(j-stride) + V(j-1) - V(j-stride-1)));
176  pix1 += stride;
177  pix2 += stride;
178 
179  }
180 #undef V
181  return s;
182 }
183 
184 static int pix_abs16_x2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
185  ptrdiff_t stride, int h)
186 {
187  int s = 0, i;
188 
189  for (i = 0; i < h; i++) {
190  s += abs(pix1[0] - avg2(pix2[0], pix2[1]));
191  s += abs(pix1[1] - avg2(pix2[1], pix2[2]));
192  s += abs(pix1[2] - avg2(pix2[2], pix2[3]));
193  s += abs(pix1[3] - avg2(pix2[3], pix2[4]));
194  s += abs(pix1[4] - avg2(pix2[4], pix2[5]));
195  s += abs(pix1[5] - avg2(pix2[5], pix2[6]));
196  s += abs(pix1[6] - avg2(pix2[6], pix2[7]));
197  s += abs(pix1[7] - avg2(pix2[7], pix2[8]));
198  s += abs(pix1[8] - avg2(pix2[8], pix2[9]));
199  s += abs(pix1[9] - avg2(pix2[9], pix2[10]));
200  s += abs(pix1[10] - avg2(pix2[10], pix2[11]));
201  s += abs(pix1[11] - avg2(pix2[11], pix2[12]));
202  s += abs(pix1[12] - avg2(pix2[12], pix2[13]));
203  s += abs(pix1[13] - avg2(pix2[13], pix2[14]));
204  s += abs(pix1[14] - avg2(pix2[14], pix2[15]));
205  s += abs(pix1[15] - avg2(pix2[15], pix2[16]));
206  pix1 += stride;
207  pix2 += stride;
208  }
209  return s;
210 }
211 
212 static int pix_abs16_y2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
213  ptrdiff_t stride, int h)
214 {
215  int s = 0, i;
216  const uint8_t *pix3 = pix2 + stride;
217 
218  for (i = 0; i < h; i++) {
219  s += abs(pix1[0] - avg2(pix2[0], pix3[0]));
220  s += abs(pix1[1] - avg2(pix2[1], pix3[1]));
221  s += abs(pix1[2] - avg2(pix2[2], pix3[2]));
222  s += abs(pix1[3] - avg2(pix2[3], pix3[3]));
223  s += abs(pix1[4] - avg2(pix2[4], pix3[4]));
224  s += abs(pix1[5] - avg2(pix2[5], pix3[5]));
225  s += abs(pix1[6] - avg2(pix2[6], pix3[6]));
226  s += abs(pix1[7] - avg2(pix2[7], pix3[7]));
227  s += abs(pix1[8] - avg2(pix2[8], pix3[8]));
228  s += abs(pix1[9] - avg2(pix2[9], pix3[9]));
229  s += abs(pix1[10] - avg2(pix2[10], pix3[10]));
230  s += abs(pix1[11] - avg2(pix2[11], pix3[11]));
231  s += abs(pix1[12] - avg2(pix2[12], pix3[12]));
232  s += abs(pix1[13] - avg2(pix2[13], pix3[13]));
233  s += abs(pix1[14] - avg2(pix2[14], pix3[14]));
234  s += abs(pix1[15] - avg2(pix2[15], pix3[15]));
235  pix1 += stride;
236  pix2 += stride;
237  pix3 += stride;
238  }
239  return s;
240 }
241 
242 static int pix_abs16_xy2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
243  ptrdiff_t stride, int h)
244 {
245  int s = 0, i;
246  const uint8_t *pix3 = pix2 + stride;
247 
248  for (i = 0; i < h; i++) {
249  s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
250  s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2]));
251  s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3]));
252  s += abs(pix1[3] - avg4(pix2[3], pix2[4], pix3[3], pix3[4]));
253  s += abs(pix1[4] - avg4(pix2[4], pix2[5], pix3[4], pix3[5]));
254  s += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6]));
255  s += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7]));
256  s += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8]));
257  s += abs(pix1[8] - avg4(pix2[8], pix2[9], pix3[8], pix3[9]));
258  s += abs(pix1[9] - avg4(pix2[9], pix2[10], pix3[9], pix3[10]));
259  s += abs(pix1[10] - avg4(pix2[10], pix2[11], pix3[10], pix3[11]));
260  s += abs(pix1[11] - avg4(pix2[11], pix2[12], pix3[11], pix3[12]));
261  s += abs(pix1[12] - avg4(pix2[12], pix2[13], pix3[12], pix3[13]));
262  s += abs(pix1[13] - avg4(pix2[13], pix2[14], pix3[13], pix3[14]));
263  s += abs(pix1[14] - avg4(pix2[14], pix2[15], pix3[14], pix3[15]));
264  s += abs(pix1[15] - avg4(pix2[15], pix2[16], pix3[15], pix3[16]));
265  pix1 += stride;
266  pix2 += stride;
267  pix3 += stride;
268  }
269  return s;
270 }
271 
272 static inline int pix_abs8_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
273  ptrdiff_t stride, int h)
274 {
275  int s = 0, i;
276 
277  for (i = 0; i < h; i++) {
278  s += abs(pix1[0] - pix2[0]);
279  s += abs(pix1[1] - pix2[1]);
280  s += abs(pix1[2] - pix2[2]);
281  s += abs(pix1[3] - pix2[3]);
282  s += abs(pix1[4] - pix2[4]);
283  s += abs(pix1[5] - pix2[5]);
284  s += abs(pix1[6] - pix2[6]);
285  s += abs(pix1[7] - pix2[7]);
286  pix1 += stride;
287  pix2 += stride;
288  }
289  return s;
290 }
291 
292 static inline int pix_median_abs8_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
293  ptrdiff_t stride, int h)
294 {
295  int s = 0, i, j;
296 
297 #define V(x) (pix1[x] - pix2[x])
298 
299  s += abs(V(0));
300  s += abs(V(1) - V(0));
301  s += abs(V(2) - V(1));
302  s += abs(V(3) - V(2));
303  s += abs(V(4) - V(3));
304  s += abs(V(5) - V(4));
305  s += abs(V(6) - V(5));
306  s += abs(V(7) - V(6));
307 
308  pix1 += stride;
309  pix2 += stride;
310 
311  for (i = 1; i < h; i++) {
312  s += abs(V(0) - V(-stride));
313  for (j = 1; j < 8; j++)
314  s += abs(V(j) - mid_pred(V(j-stride), V(j-1), V(j-stride) + V(j-1) - V(j-stride-1)));
315  pix1 += stride;
316  pix2 += stride;
317 
318  }
319 #undef V
320  return s;
321 }
322 
323 static int pix_abs8_x2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
324  ptrdiff_t stride, int h)
325 {
326  int s = 0, i;
327 
328  for (i = 0; i < h; i++) {
329  s += abs(pix1[0] - avg2(pix2[0], pix2[1]));
330  s += abs(pix1[1] - avg2(pix2[1], pix2[2]));
331  s += abs(pix1[2] - avg2(pix2[2], pix2[3]));
332  s += abs(pix1[3] - avg2(pix2[3], pix2[4]));
333  s += abs(pix1[4] - avg2(pix2[4], pix2[5]));
334  s += abs(pix1[5] - avg2(pix2[5], pix2[6]));
335  s += abs(pix1[6] - avg2(pix2[6], pix2[7]));
336  s += abs(pix1[7] - avg2(pix2[7], pix2[8]));
337  pix1 += stride;
338  pix2 += stride;
339  }
340  return s;
341 }
342 
343 static int pix_abs8_y2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
344  ptrdiff_t stride, int h)
345 {
346  int s = 0, i;
347  const uint8_t *pix3 = pix2 + stride;
348 
349  for (i = 0; i < h; i++) {
350  s += abs(pix1[0] - avg2(pix2[0], pix3[0]));
351  s += abs(pix1[1] - avg2(pix2[1], pix3[1]));
352  s += abs(pix1[2] - avg2(pix2[2], pix3[2]));
353  s += abs(pix1[3] - avg2(pix2[3], pix3[3]));
354  s += abs(pix1[4] - avg2(pix2[4], pix3[4]));
355  s += abs(pix1[5] - avg2(pix2[5], pix3[5]));
356  s += abs(pix1[6] - avg2(pix2[6], pix3[6]));
357  s += abs(pix1[7] - avg2(pix2[7], pix3[7]));
358  pix1 += stride;
359  pix2 += stride;
360  pix3 += stride;
361  }
362  return s;
363 }
364 
365 static int pix_abs8_xy2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2,
366  ptrdiff_t stride, int h)
367 {
368  int s = 0, i;
369  const uint8_t *pix3 = pix2 + stride;
370 
371  for (i = 0; i < h; i++) {
372  s += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
373  s += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2]));
374  s += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3]));
375  s += abs(pix1[3] - avg4(pix2[3], pix2[4], pix3[3], pix3[4]));
376  s += abs(pix1[4] - avg4(pix2[4], pix2[5], pix3[4], pix3[5]));
377  s += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6]));
378  s += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7]));
379  s += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8]));
380  pix1 += stride;
381  pix2 += stride;
382  pix3 += stride;
383  }
384  return s;
385 }
386 
387 static int nsse16_c(MPVEncContext *const c, const uint8_t *s1, const uint8_t *s2,
388  ptrdiff_t stride, int h)
389 {
390  int score1 = 0, score2 = 0, x, y;
391 
392  for (y = 0; y < h; y++) {
393  for (x = 0; x < 16; x++)
394  score1 += (s1[x] - s2[x]) * (s1[x] - s2[x]);
395  if (y + 1 < h) {
396  for (x = 0; x < 15; x++)
397  score2 += FFABS(s1[x] - s1[x + stride] -
398  s1[x + 1] + s1[x + stride + 1]) -
399  FFABS(s2[x] - s2[x + stride] -
400  s2[x + 1] + s2[x + stride + 1]);
401  }
402  s1 += stride;
403  s2 += stride;
404  }
405 
406  if (c)
407  return score1 + FFABS(score2) * c->c.avctx->nsse_weight;
408  else
409  return score1 + FFABS(score2) * 8;
410 }
411 
412 static int nsse8_c(MPVEncContext *const c, const uint8_t *s1, const uint8_t *s2,
413  ptrdiff_t stride, int h)
414 {
415  int score1 = 0, score2 = 0, x, y;
416 
417  for (y = 0; y < h; y++) {
418  for (x = 0; x < 8; x++)
419  score1 += (s1[x] - s2[x]) * (s1[x] - s2[x]);
420  if (y + 1 < h) {
421  for (x = 0; x < 7; x++)
422  score2 += FFABS(s1[x] - s1[x + stride] -
423  s1[x + 1] + s1[x + stride + 1]) -
424  FFABS(s2[x] - s2[x + stride] -
425  s2[x + 1] + s2[x + stride + 1]);
426  }
427  s1 += stride;
428  s2 += stride;
429  }
430 
431  if (c)
432  return score1 + FFABS(score2) * c->c.avctx->nsse_weight;
433  else
434  return score1 + FFABS(score2) * 8;
435 }
436 
437 static int zero_cmp(MPVEncContext *s, const uint8_t *a, const uint8_t *b,
438  ptrdiff_t stride, int h)
439 {
440  return 0;
441 }
442 
443 av_cold int ff_set_cmp(const MECmpContext *c, me_cmp_func *cmp, int type, int mpvenc)
444 {
445 #define ENTRY(CMP_FLAG, ARRAY, MPVENC_ONLY) \
446  [FF_CMP_ ## CMP_FLAG] = { \
447  .offset = offsetof(MECmpContext, ARRAY), \
448  .mpv_only = MPVENC_ONLY, \
449  .available = 1, \
450  }
451  static const struct {
452  char available;
453  char mpv_only;
454  uint16_t offset;
455  } cmp_func_list[] = {
456  ENTRY(SAD, sad, 0),
457  ENTRY(SSE, sse, 0),
458  ENTRY(SATD, hadamard8_diff, 0),
459  ENTRY(DCT, dct_sad, 1),
460  ENTRY(PSNR, quant_psnr, 1),
461  ENTRY(BIT, bit, 1),
462  ENTRY(RD, rd, 1),
463  ENTRY(VSAD, vsad, 0),
464  ENTRY(VSSE, vsse, 0),
465  ENTRY(NSSE, nsse, 0),
466 #if CONFIG_SNOW_DECODER || CONFIG_SNOW_ENCODER
467  ENTRY(W53, w53, 0),
468  ENTRY(W97, w97, 0),
469 #endif
470  ENTRY(DCTMAX, dct_max, 1),
471 #if CONFIG_GPL
472  ENTRY(DCT264, dct264_sad, 1),
473 #endif
474  ENTRY(MEDIAN_SAD, median_sad, 0),
475  };
476  const me_cmp_func *me_cmp_func_array;
477 
478  type &= 0xFF;
479 
480  if (type == FF_CMP_ZERO) {
481  for (int i = 0; i < 6; i++)
482  cmp[i] = zero_cmp;
483  return 0;
484  }
485  if (type >= FF_ARRAY_ELEMS(cmp_func_list) ||
486  !cmp_func_list[type].available ||
487  !mpvenc && cmp_func_list[type].mpv_only) {
489  "invalid cmp function selection\n");
490  return AVERROR(EINVAL);
491  }
492  me_cmp_func_array = (const me_cmp_func*)(((const char*)c) + cmp_func_list[type].offset);
493  for (int i = 0; i < 6; i++)
494  cmp[i] = me_cmp_func_array[i];
495 
496  return 0;
497 }
498 
499 #define BUTTERFLY2(o1, o2, i1, i2) \
500  o1 = (i1) + (i2); \
501  o2 = (i1) - (i2);
502 
503 #define BUTTERFLY1(x, y) \
504  { \
505  int a, b; \
506  a = x; \
507  b = y; \
508  x = a + b; \
509  y = a - b; \
510  }
511 
512 #define BUTTERFLYA(x, y) (FFABS((x) + (y)) + FFABS((x) - (y)))
513 
514 static int hadamard8_diff8x8_c(MPVEncContext *unused, const uint8_t *dst,
515  const uint8_t *src, ptrdiff_t stride, int h)
516 {
517  int i, temp[64], sum = 0;
518 
519  for (i = 0; i < 8; i++) {
520  // FIXME: try pointer walks
521  BUTTERFLY2(temp[8 * i + 0], temp[8 * i + 1],
522  src[stride * i + 0] - dst[stride * i + 0],
523  src[stride * i + 1] - dst[stride * i + 1]);
524  BUTTERFLY2(temp[8 * i + 2], temp[8 * i + 3],
525  src[stride * i + 2] - dst[stride * i + 2],
526  src[stride * i + 3] - dst[stride * i + 3]);
527  BUTTERFLY2(temp[8 * i + 4], temp[8 * i + 5],
528  src[stride * i + 4] - dst[stride * i + 4],
529  src[stride * i + 5] - dst[stride * i + 5]);
530  BUTTERFLY2(temp[8 * i + 6], temp[8 * i + 7],
531  src[stride * i + 6] - dst[stride * i + 6],
532  src[stride * i + 7] - dst[stride * i + 7]);
533 
534  BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 2]);
535  BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 3]);
536  BUTTERFLY1(temp[8 * i + 4], temp[8 * i + 6]);
537  BUTTERFLY1(temp[8 * i + 5], temp[8 * i + 7]);
538 
539  BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 4]);
540  BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 5]);
541  BUTTERFLY1(temp[8 * i + 2], temp[8 * i + 6]);
542  BUTTERFLY1(temp[8 * i + 3], temp[8 * i + 7]);
543  }
544 
545  for (i = 0; i < 8; i++) {
546  BUTTERFLY1(temp[8 * 0 + i], temp[8 * 1 + i]);
547  BUTTERFLY1(temp[8 * 2 + i], temp[8 * 3 + i]);
548  BUTTERFLY1(temp[8 * 4 + i], temp[8 * 5 + i]);
549  BUTTERFLY1(temp[8 * 6 + i], temp[8 * 7 + i]);
550 
551  BUTTERFLY1(temp[8 * 0 + i], temp[8 * 2 + i]);
552  BUTTERFLY1(temp[8 * 1 + i], temp[8 * 3 + i]);
553  BUTTERFLY1(temp[8 * 4 + i], temp[8 * 6 + i]);
554  BUTTERFLY1(temp[8 * 5 + i], temp[8 * 7 + i]);
555 
556  sum += BUTTERFLYA(temp[8 * 0 + i], temp[8 * 4 + i]) +
557  BUTTERFLYA(temp[8 * 1 + i], temp[8 * 5 + i]) +
558  BUTTERFLYA(temp[8 * 2 + i], temp[8 * 6 + i]) +
559  BUTTERFLYA(temp[8 * 3 + i], temp[8 * 7 + i]);
560  }
561  return sum;
562 }
563 
564 static int hadamard8_intra8x8_c(MPVEncContext *unused, const uint8_t *src,
565  const uint8_t *dummy, ptrdiff_t stride, int h)
566 {
567  int i, temp[64], sum = 0;
568 
569  for (i = 0; i < 8; i++) {
570  // FIXME: try pointer walks
571  BUTTERFLY2(temp[8 * i + 0], temp[8 * i + 1],
572  src[stride * i + 0], src[stride * i + 1]);
573  BUTTERFLY2(temp[8 * i + 2], temp[8 * i + 3],
574  src[stride * i + 2], src[stride * i + 3]);
575  BUTTERFLY2(temp[8 * i + 4], temp[8 * i + 5],
576  src[stride * i + 4], src[stride * i + 5]);
577  BUTTERFLY2(temp[8 * i + 6], temp[8 * i + 7],
578  src[stride * i + 6], src[stride * i + 7]);
579 
580  BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 2]);
581  BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 3]);
582  BUTTERFLY1(temp[8 * i + 4], temp[8 * i + 6]);
583  BUTTERFLY1(temp[8 * i + 5], temp[8 * i + 7]);
584 
585  BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 4]);
586  BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 5]);
587  BUTTERFLY1(temp[8 * i + 2], temp[8 * i + 6]);
588  BUTTERFLY1(temp[8 * i + 3], temp[8 * i + 7]);
589  }
590 
591  for (i = 0; i < 8; i++) {
592  BUTTERFLY1(temp[8 * 0 + i], temp[8 * 1 + i]);
593  BUTTERFLY1(temp[8 * 2 + i], temp[8 * 3 + i]);
594  BUTTERFLY1(temp[8 * 4 + i], temp[8 * 5 + i]);
595  BUTTERFLY1(temp[8 * 6 + i], temp[8 * 7 + i]);
596 
597  BUTTERFLY1(temp[8 * 0 + i], temp[8 * 2 + i]);
598  BUTTERFLY1(temp[8 * 1 + i], temp[8 * 3 + i]);
599  BUTTERFLY1(temp[8 * 4 + i], temp[8 * 6 + i]);
600  BUTTERFLY1(temp[8 * 5 + i], temp[8 * 7 + i]);
601 
602  sum +=
603  BUTTERFLYA(temp[8 * 0 + i], temp[8 * 4 + i])
604  + BUTTERFLYA(temp[8 * 1 + i], temp[8 * 5 + i])
605  + BUTTERFLYA(temp[8 * 2 + i], temp[8 * 6 + i])
606  + BUTTERFLYA(temp[8 * 3 + i], temp[8 * 7 + i]);
607  }
608 
609  sum -= FFABS(temp[8 * 0] + temp[8 * 4]); // -mean
610 
611  return sum;
612 }
613 
614 static int dct_sad8x8_c(MPVEncContext *const s, const uint8_t *src1,
615  const uint8_t *src2, ptrdiff_t stride, int h)
616 {
617  LOCAL_ALIGNED_16(int16_t, temp, [64]);
618 
619  s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride);
620  s->fdsp.fdct(temp);
621  return s->sum_abs_dctelem(temp);
622 }
623 
624 #if CONFIG_GPL
625 #define DCT8_1D \
626  { \
627  const int s07 = SRC(0) + SRC(7); \
628  const int s16 = SRC(1) + SRC(6); \
629  const int s25 = SRC(2) + SRC(5); \
630  const int s34 = SRC(3) + SRC(4); \
631  const int a0 = s07 + s34; \
632  const int a1 = s16 + s25; \
633  const int a2 = s07 - s34; \
634  const int a3 = s16 - s25; \
635  const int d07 = SRC(0) - SRC(7); \
636  const int d16 = SRC(1) - SRC(6); \
637  const int d25 = SRC(2) - SRC(5); \
638  const int d34 = SRC(3) - SRC(4); \
639  const int a4 = d16 + d25 + (d07 + (d07 >> 1)); \
640  const int a5 = d07 - d34 - (d25 + (d25 >> 1)); \
641  const int a6 = d07 + d34 - (d16 + (d16 >> 1)); \
642  const int a7 = d16 - d25 + (d34 + (d34 >> 1)); \
643  DST(0, a0 + a1); \
644  DST(1, a4 + (a7 >> 2)); \
645  DST(2, a2 + (a3 >> 1)); \
646  DST(3, a5 + (a6 >> 2)); \
647  DST(4, a0 - a1); \
648  DST(5, a6 - (a5 >> 2)); \
649  DST(6, (a2 >> 1) - a3); \
650  DST(7, (a4 >> 2) - a7); \
651  }
652 
653 static int dct264_sad8x8_c(MPVEncContext *const s, const uint8_t *src1,
654  const uint8_t *src2, ptrdiff_t stride, int h)
655 {
656  int16_t dct[8][8];
657  int i, sum = 0;
658 
659  s->pdsp.diff_pixels_unaligned(dct[0], src1, src2, stride);
660 
661 #define SRC(x) dct[i][x]
662 #define DST(x, v) dct[i][x] = v
663  for (i = 0; i < 8; i++)
664  DCT8_1D
665 #undef SRC
666 #undef DST
667 
668 #define SRC(x) dct[x][i]
669 #define DST(x, v) sum += FFABS(v)
670  for (i = 0; i < 8; i++)
671  DCT8_1D
672 #undef SRC
673 #undef DST
674  return sum;
675 }
676 #endif
677 
678 static int dct_max8x8_c(MPVEncContext *const s, const uint8_t *src1,
679  const uint8_t *src2, ptrdiff_t stride, int h)
680 {
681  LOCAL_ALIGNED_16(int16_t, temp, [64]);
682  int sum = 0, i;
683 
684  s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride);
685  s->fdsp.fdct(temp);
686 
687  for (i = 0; i < 64; i++)
688  sum = FFMAX(sum, FFABS(temp[i]));
689 
690  return sum;
691 }
692 
693 static int quant_psnr8x8_c(MPVEncContext *const s, const uint8_t *src1,
694  const uint8_t *src2, ptrdiff_t stride, int h)
695 {
696  LOCAL_ALIGNED_16(int16_t, temp, [64 * 2]);
697  int16_t *const bak = temp + 64;
698  int sum = 0, i;
699 
700  s->c.mb_intra = 0;
701 
702  s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride);
703 
704  memcpy(bak, temp, 64 * sizeof(int16_t));
705 
706  s->c.block_last_index[0 /* FIXME */] =
707  s->dct_quantize(s, temp, 0 /* FIXME */, s->c.qscale, &i);
708  s->c.dct_unquantize_inter(&s->c, temp, 0, s->c.qscale);
710 
711  for (i = 0; i < 64; i++)
712  sum += (temp[i] - bak[i]) * (temp[i] - bak[i]);
713 
714  return sum;
715 }
716 
717 static int rd8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2,
718  ptrdiff_t stride, int h)
719 {
720  const uint8_t *scantable = s->c.intra_scantable.permutated;
721  LOCAL_ALIGNED_16(int16_t, temp, [64]);
722  LOCAL_ALIGNED_16(uint8_t, lsrc1, [64]);
723  LOCAL_ALIGNED_16(uint8_t, lsrc2, [64]);
724  int i, last, run, bits, level, distortion, start_i;
725  const int esc_length = s->ac_esc_length;
726  const uint8_t *length, *last_length;
727 
728  copy_block8(lsrc1, src1, 8, stride, 8);
729  copy_block8(lsrc2, src2, 8, stride, 8);
730 
731  s->pdsp.diff_pixels(temp, lsrc1, lsrc2, 8);
732 
733  s->c.block_last_index[0 /* FIXME */] =
734  last =
735  s->dct_quantize(s, temp, 0 /* FIXME */, s->c.qscale, &i);
736 
737  bits = 0;
738 
739  if (s->c.mb_intra) {
740  start_i = 1;
741  length = s->intra_ac_vlc_length;
742  last_length = s->intra_ac_vlc_last_length;
743  bits += s->luma_dc_vlc_length[temp[0] + 256]; // FIXME: chroma
744  } else {
745  start_i = 0;
746  length = s->inter_ac_vlc_length;
747  last_length = s->inter_ac_vlc_last_length;
748  }
749 
750  if (last >= start_i) {
751  run = 0;
752  for (i = start_i; i < last; i++) {
753  int j = scantable[i];
754  level = temp[j];
755 
756  if (level) {
757  level += 64;
758  if ((level & (~127)) == 0)
759  bits += length[UNI_AC_ENC_INDEX(run, level)];
760  else
761  bits += esc_length;
762  run = 0;
763  } else
764  run++;
765  }
766  i = scantable[last];
767 
768  level = temp[i] + 64;
769 
770  av_assert2(level - 64);
771 
772  if ((level & (~127)) == 0) {
773  bits += last_length[UNI_AC_ENC_INDEX(run, level)];
774  } else
775  bits += esc_length;
776  }
777 
778  if (last >= 0) {
779  if (s->c.mb_intra)
780  s->c.dct_unquantize_intra(&s->c, temp, 0, s->c.qscale);
781  else
782  s->c.dct_unquantize_inter(&s->c, temp, 0, s->c.qscale);
783  }
784 
785  s->c.idsp.idct_add(lsrc2, 8, temp);
786 
787  distortion = s->sse_cmp[1](NULL, lsrc2, lsrc1, 8, 8);
788 
789  return distortion + ((bits * s->c.qscale * s->c.qscale * 109 + 64) >> 7);
790 }
791 
792 static int bit8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2,
793  ptrdiff_t stride, int h)
794 {
795  const uint8_t *scantable = s->c.intra_scantable.permutated;
796  LOCAL_ALIGNED_16(int16_t, temp, [64]);
797  int i, last, run, bits, level, start_i;
798  const int esc_length = s->ac_esc_length;
799  const uint8_t *length, *last_length;
800 
801  s->pdsp.diff_pixels_unaligned(temp, src1, src2, stride);
802 
803  s->c.block_last_index[0 /* FIXME */] =
804  last =
805  s->dct_quantize(s, temp, 0 /* FIXME */, s->c.qscale, &i);
806 
807  bits = 0;
808 
809  if (s->c.mb_intra) {
810  start_i = 1;
811  length = s->intra_ac_vlc_length;
812  last_length = s->intra_ac_vlc_last_length;
813  bits += s->luma_dc_vlc_length[temp[0] + 256]; // FIXME: chroma
814  } else {
815  start_i = 0;
816  length = s->inter_ac_vlc_length;
817  last_length = s->inter_ac_vlc_last_length;
818  }
819 
820  if (last >= start_i) {
821  run = 0;
822  for (i = start_i; i < last; i++) {
823  int j = scantable[i];
824  level = temp[j];
825 
826  if (level) {
827  level += 64;
828  if ((level & (~127)) == 0)
829  bits += length[UNI_AC_ENC_INDEX(run, level)];
830  else
831  bits += esc_length;
832  run = 0;
833  } else
834  run++;
835  }
836  i = scantable[last];
837 
838  level = temp[i] + 64;
839 
840  av_assert2(level - 64);
841 
842  if ((level & (~127)) == 0)
843  bits += last_length[UNI_AC_ENC_INDEX(run, level)];
844  else
845  bits += esc_length;
846  }
847 
848  return bits;
849 }
850 
851 #define VSAD_INTRA(size) \
852 static int vsad_intra ## size ## _c(MPVEncContext *unused, \
853  const uint8_t *s, const uint8_t *dummy, \
854  ptrdiff_t stride, int h) \
855 { \
856  int score = 0, x, y; \
857  \
858  for (y = 1; y < h; y++) { \
859  for (x = 0; x < size; x += 4) { \
860  score += FFABS(s[x] - s[x + stride]) + \
861  FFABS(s[x + 1] - s[x + stride + 1]) + \
862  FFABS(s[x + 2] - s[x + 2 + stride]) + \
863  FFABS(s[x + 3] - s[x + 3 + stride]); \
864  } \
865  s += stride; \
866  } \
867  \
868  return score; \
869 }
870 VSAD_INTRA(8)
871 VSAD_INTRA(16)
872 
873 #define VSAD(size) \
874 static int vsad ## size ## _c(MPVEncContext *unused, \
875  const uint8_t *s1, const uint8_t *s2, \
876  ptrdiff_t stride, int h) \
877 { \
878  int score = 0, x, y; \
879  \
880  for (y = 1; y < h; y++) { \
881  for (x = 0; x < size; x++) \
882  score += FFABS(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]); \
883  s1 += stride; \
884  s2 += stride; \
885  } \
886  \
887  return score; \
888 }
889 VSAD(8)
890 VSAD(16)
891 
892 #define SQ(a) ((a) * (a))
893 #define VSSE_INTRA(size) \
894 static int vsse_intra ## size ## _c(MPVEncContext *unused, \
895  const uint8_t *s, const uint8_t *dummy, \
896  ptrdiff_t stride, int h) \
897 { \
898  int score = 0, x, y; \
899  \
900  for (y = 1; y < h; y++) { \
901  for (x = 0; x < size; x += 4) { \
902  score += SQ(s[x] - s[x + stride]) + \
903  SQ(s[x + 1] - s[x + stride + 1]) + \
904  SQ(s[x + 2] - s[x + stride + 2]) + \
905  SQ(s[x + 3] - s[x + stride + 3]); \
906  } \
907  s += stride; \
908  } \
909  \
910  return score; \
911 }
912 VSSE_INTRA(8)
913 VSSE_INTRA(16)
914 
915 #define VSSE(size) \
916 static int vsse ## size ## _c(MPVEncContext *unused, const uint8_t *s1, \
917  const uint8_t *s2, ptrdiff_t stride, int h) \
918 { \
919  int score = 0, x, y; \
920  \
921  for (y = 1; y < h; y++) { \
922  for (x = 0; x < size; x++) \
923  score += SQ(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]); \
924  s1 += stride; \
925  s2 += stride; \
926  } \
927  \
928  return score; \
929 }
930 VSSE(8)
931 VSSE(16)
932 
933 #define WRAPPER8_16_SQ(name8, name16) \
934 static int name16(MPVEncContext *const s, const uint8_t *dst, \
935  const uint8_t *src, ptrdiff_t stride, int h) \
936 { \
937  int score = 0; \
938  \
939  score += name8(s, dst, src, stride, 8); \
940  score += name8(s, dst + 8, src + 8, stride, 8); \
941  if (h == 16) { \
942  dst += 8 * stride; \
943  src += 8 * stride; \
944  score += name8(s, dst, src, stride, 8); \
945  score += name8(s, dst + 8, src + 8, stride, 8); \
946  } \
947  return score; \
948 }
949 
950 WRAPPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c)
951 WRAPPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c)
952 WRAPPER8_16_SQ(dct_sad8x8_c, dct_sad16_c)
953 #if CONFIG_GPL
954 WRAPPER8_16_SQ(dct264_sad8x8_c, dct264_sad16_c)
955 #endif
956 WRAPPER8_16_SQ(dct_max8x8_c, dct_max16_c)
957 WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c)
958 WRAPPER8_16_SQ(rd8x8_c, rd16_c)
959 WRAPPER8_16_SQ(bit8x8_c, bit16_c)
960 
962 {
963  memset(c, 0, sizeof(*c));
964 
965  c->sum_abs_dctelem = sum_abs_dctelem_c;
966 
967  /* TODO [0] 16 [1] 8 */
968  c->pix_abs[0][0] = pix_abs16_c;
969  c->pix_abs[0][1] = pix_abs16_x2_c;
970  c->pix_abs[0][2] = pix_abs16_y2_c;
971  c->pix_abs[0][3] = pix_abs16_xy2_c;
972  c->pix_abs[1][0] = pix_abs8_c;
973  c->pix_abs[1][1] = pix_abs8_x2_c;
974  c->pix_abs[1][2] = pix_abs8_y2_c;
975  c->pix_abs[1][3] = pix_abs8_xy2_c;
976 
977 #define SET_CMP_FUNC(name) \
978  c->name[0] = name ## 16_c; \
979  c->name[1] = name ## 8x8_c;
980 
981  SET_CMP_FUNC(hadamard8_diff)
982  c->hadamard8_diff[4] = hadamard8_intra16_c;
983  c->hadamard8_diff[5] = hadamard8_intra8x8_c;
984  SET_CMP_FUNC(dct_sad)
985  SET_CMP_FUNC(dct_max)
986 #if CONFIG_GPL
987  SET_CMP_FUNC(dct264_sad)
988 #endif
989  c->sad[0] = pix_abs16_c;
990  c->sad[1] = pix_abs8_c;
991  c->sse[0] = sse16_c;
992  c->sse[1] = sse8_c;
993  c->sse[2] = sse4_c;
994  SET_CMP_FUNC(quant_psnr)
995  SET_CMP_FUNC(rd)
997  c->vsad[0] = vsad16_c;
998  c->vsad[1] = vsad8_c;
999  c->vsad[4] = vsad_intra16_c;
1000  c->vsad[5] = vsad_intra8_c;
1001  c->vsse[0] = vsse16_c;
1002  c->vsse[1] = vsse8_c;
1003  c->vsse[4] = vsse_intra16_c;
1004  c->vsse[5] = vsse_intra8_c;
1005  c->nsse[0] = nsse16_c;
1006  c->nsse[1] = nsse8_c;
1007 #if CONFIG_SNOW_DECODER || CONFIG_SNOW_ENCODER
1009 #endif
1010 
1011  c->median_sad[0] = pix_median_abs16_c;
1012  c->median_sad[1] = pix_median_abs8_c;
1013 
1014 #if ARCH_AARCH64
1015  ff_me_cmp_init_aarch64(c, avctx);
1016 #elif ARCH_ARM
1017  ff_me_cmp_init_arm(c, avctx);
1018 #elif ARCH_PPC
1019  ff_me_cmp_init_ppc(c, avctx);
1020 #elif ARCH_RISCV
1021  ff_me_cmp_init_riscv(c, avctx);
1022 #elif ARCH_X86
1023  ff_me_cmp_init_x86(c, avctx);
1024 #elif ARCH_MIPS
1025  ff_me_cmp_init_mips(c, avctx);
1026 #endif
1027 
1028 }
dct_sad8x8_c
static int dct_sad8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2, ptrdiff_t stride, int h)
Definition: me_cmp.c:614
sum_abs_dctelem_c
static int sum_abs_dctelem_c(const int16_t *block)
Definition: me_cmp.c:105
level
uint8_t level
Definition: svq3.c:208
MPVEncContext
Definition: mpegvideoenc.h:46
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
mem_internal.h
pix_median_abs16_c
static int pix_median_abs16_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:145
nsse16_c
static int nsse16_c(MPVEncContext *const c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h)
Definition: me_cmp.c:387
src1
const pixel * src1
Definition: h264pred_template.c:420
mpegvideoenc.h
sse
static int sse(const MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2, int w, int h, int stride)
Definition: mpegvideo_enc.c:2781
VSSE_INTRA
#define VSSE_INTRA(size)
Definition: me_cmp.c:893
b
#define b
Definition: input.c:42
avg2
#define avg2(a, b)
Definition: me_cmp.c:114
copy_block8
static void copy_block8(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)
Definition: copy_block.h:47
ff_me_cmp_init_x86
void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx)
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
BUTTERFLYA
#define BUTTERFLYA(x, y)
Definition: me_cmp.c:512
quant_psnr8x8_c
static int quant_psnr8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2, ptrdiff_t stride, int h)
Definition: me_cmp.c:693
bit
#define bit(string, value)
Definition: cbs_mpeg2.c:56
ENTRY
#define ENTRY(CMP_FLAG, ARRAY, MPVENC_ONLY)
dummy
int dummy
Definition: motion.c:66
hadamard8_diff8x8_c
static int hadamard8_diff8x8_c(MPVEncContext *unused, const uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h)
Definition: me_cmp.c:514
ff_me_cmp_init
av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp.c:961
pix_abs8_x2_c
static int pix_abs8_x2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:323
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
pix_median_abs8_c
static int pix_median_abs8_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:292
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
me_cmp_func
int(* me_cmp_func)(MPVEncContext *c, const uint8_t *blk1, const uint8_t *blk2, ptrdiff_t stride, int h)
Definition: me_cmp.h:45
s
#define s(width, name)
Definition: cbs_vp9.c:198
bits
uint8_t bits
Definition: vp3data.h:128
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:130
pix_abs16_c
static int pix_abs16_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:117
simple_idct.h
VSAD_INTRA
#define VSAD_INTRA(size)
Definition: me_cmp.c:851
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
MECmpContext
Definition: me_cmp.h:50
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:207
VSSE
#define VSSE(size)
Definition: me_cmp.c:915
mathops.h
abs
#define abs(x)
Definition: cuda_runtime.h:35
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
ff_me_cmp_init_mips
void ff_me_cmp_init_mips(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp_init_mips.c:25
pix_abs16_y2_c
static int pix_abs16_y2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:212
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
zero_cmp
static int zero_cmp(MPVEncContext *s, const uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h)
Definition: me_cmp.c:437
cmp
static av_always_inline int cmp(MPVEncContext *const s, const int x, const int y, const int subx, const int suby, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags)
compares a block (either a full macroblock or a partition thereof) against a proposed motion-compensa...
Definition: motion_est.c:263
ff_set_cmp
av_cold int ff_set_cmp(const MECmpContext *c, me_cmp_func *cmp, int type, int mpvenc)
Fill the function pointer array cmp[6] with me_cmp_funcs from c based upon type.
Definition: me_cmp.c:443
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
FF_CMP_ZERO
#define FF_CMP_ZERO
Definition: avcodec.h:876
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
pix_abs8_c
static int pix_abs8_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:272
attributes.h
BUTTERFLY1
#define BUTTERFLY1(x, y)
Definition: me_cmp.c:503
SRC
#define SRC(x, y)
Definition: h264pred_template.c:822
UNI_AC_ENC_INDEX
#define UNI_AC_ENC_INDEX(run, level)
Definition: mpegvideoenc.h:286
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
ff_me_cmp_init_aarch64
av_cold void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp_init_aarch64.c:87
ff_simple_idct_int16_8bit
void ff_simple_idct_int16_8bit(int16_t *block)
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
copy_block.h
internal.h
available
if no frame is available
Definition: filter_design.txt:166
src2
const pixel * src2
Definition: h264pred_template.c:421
dct_max8x8_c
static int dct_max8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2, ptrdiff_t stride, int h)
Definition: me_cmp.c:678
dct
static void dct(AudioRNNContext *s, float *out, const float *in)
Definition: af_arnndn.c:1010
ff_square_tab
const EXTERN uint32_t ff_square_tab[512]
Definition: mathops.h:35
sse16_c
static int sse16_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:75
avcodec.h
stride
#define stride
Definition: h264pred_template.c:536
mid_pred
#define mid_pred
Definition: mathops.h:97
sse4_c
static int sse4_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:37
me_cmp.h
pix_abs8_y2_c
static int pix_abs8_y2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:343
pix_abs8_xy2_c
static int pix_abs8_xy2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:365
pix_abs16_xy2_c
static int pix_abs16_xy2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:242
AVCodecContext
main external API structure.
Definition: avcodec.h:431
WRAPPER8_16_SQ
#define WRAPPER8_16_SQ(name8, name16)
Definition: me_cmp.c:933
hadamard8_intra8x8_c
static int hadamard8_intra8x8_c(MPVEncContext *unused, const uint8_t *src, const uint8_t *dummy, ptrdiff_t stride, int h)
Definition: me_cmp.c:564
ff_me_cmp_init_riscv
void ff_me_cmp_init_riscv(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp_init.c:80
avg4
#define avg4(a, b, c, d)
Definition: me_cmp.c:115
temp
else temp
Definition: vf_mcdeint.c:271
bit8x8_c
static int bit8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2, ptrdiff_t stride, int h)
Definition: me_cmp.c:792
DCT8_1D
#define DCT8_1D(src, srcstride, dst, dststride)
Definition: h264dsp.c:94
nsse8_c
static int nsse8_c(MPVEncContext *const c, const uint8_t *s1, const uint8_t *s2, ptrdiff_t stride, int h)
Definition: me_cmp.c:412
ff_me_cmp_init_arm
av_cold void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp_init_arm.c:40
DST
#define DST(x, y)
Definition: vp9dsp_template.c:813
pix_abs16_x2_c
static int pix_abs16_x2_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:184
ff_me_cmp_init_ppc
av_cold void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx)
Definition: me_cmp.c:726
ff_dsputil_init_dwt
void ff_dsputil_init_dwt(MECmpContext *c)
Definition: snow_dwt.c:843
SET_CMP_FUNC
#define SET_CMP_FUNC(name)
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
V
#define V(x)
h
h
Definition: vp9dsp_template.c:2070
VSAD
#define VSAD(size)
Definition: me_cmp.c:873
BUTTERFLY2
#define BUTTERFLY2(o1, o2, i1, i2)
Definition: me_cmp.c:499
rd8x8_c
static int rd8x8_c(MPVEncContext *const s, const uint8_t *src1, const uint8_t *src2, ptrdiff_t stride, int h)
Definition: me_cmp.c:717
src
#define src
Definition: vp8dsp.c:248
sse8_c
static int sse8_c(MPVEncContext *unused, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t stride, int h)
Definition: me_cmp.c:54