2 * This file is part of FFmpeg.
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "libavutil/avassert.h"
22 #include "libavutil/internal.h"
23 #include "libavutil/log.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/pixdesc.h"
26 #include "libavutil/pixelutils.c"
27 #include "libavutil/pixfmt.h"
34 static void check_pixfmt_descriptors(void)
36 const AVPixFmtDescriptor
*d
, *last
= NULL
;
39 for (i
= AV_PIX_FMT_NONE
, d
= NULL
; i
++, d
= av_pix_fmt_desc_next(d
);) {
40 uint8_t fill
[4][8 + 6 + 3] = {{ 0 }};
41 uint8_t *data
[4] = { fill
[0], fill
[1], fill
[2], fill
[3] };
42 int linesize
[4] = { 0, 0, 0, 0 };
45 av_assert0(d
->name
&& d
->name
[0]);
46 av_log(NULL
, AV_LOG_INFO
, "Checking: %s\n", d
->name
);
47 av_assert0(d
->log2_chroma_w
<= 3);
48 av_assert0(d
->log2_chroma_h
<= 3);
49 av_assert0(d
->nb_components
<= 4);
50 av_assert0(d
->nb_components
|| (d
->flags
& AV_PIX_FMT_FLAG_HWACCEL
));
51 av_assert0(av_get_pix_fmt(d
->name
) == av_pix_fmt_desc_get_id(d
));
53 /* The following two checks as well as the one after the loop
54 * would need to be changed if we changed the way the descriptors
56 av_assert0(i
== av_pix_fmt_desc_get_id(d
));
57 av_assert0(!last
|| last
+ 1 == d
);
59 for (int j
= 0; j
< FF_ARRAY_ELEMS(d
->comp
); j
++) {
60 const AVComponentDescriptor
*c
= &d
->comp
[j
];
64 if (d
->flags
& AV_PIX_FMT_FLAG_BITSTREAM
) {
65 av_assert0(c
->step
>= c
->depth
);
67 av_assert0(8*c
->step
>= c
->depth
);
69 if (d
->flags
& AV_PIX_FMT_FLAG_BAYER
)
71 av_read_image_line(tmp
, (void*)data
, linesize
, d
, 0, 0, j
, 2, 0);
72 av_assert0(tmp
[0] == 0 && tmp
[1] == 0);
73 tmp
[0] = tmp
[1] = (1ULL << c
->depth
) - 1;
74 av_write_image_line(tmp
, data
, linesize
, d
, 0, 0, j
, 2);
78 av_assert0(i
== AV_PIX_FMT_NB
);
81 static int run_single_test(const char *test
,
82 const uint8_t *block1
, ptrdiff_t stride1
,
83 const uint8_t *block2
, ptrdiff_t stride2
,
87 av_pixelutils_sad_fn f_ref
= sad_c
[n
- 1];
88 av_pixelutils_sad_fn f_out
= av_pixelutils_get_sad_fn(n
, n
, align
, NULL
);
91 case 0: block1
++; block2
++; break;
92 case 1: block2
++; break;
96 out
= f_out(block1
, stride1
, block2
, stride2
);
97 ref
= f_ref(block1
, stride1
, block2
, stride2
);
98 printf("[%s] [%c%c] SAD [%s] %dx%d=%d ref=%d\n",
99 out
== ref
? "OK" : "FAIL",
100 align
? 'A' : 'U', align
== 2 ? 'A' : 'U',
101 test
, 1<<n
, 1<<n
, out
, ref
);
105 static int run_test(const char *test
,
106 const uint8_t *b1
, const uint8_t *b2
)
110 for (a
= 0; a
< 3; a
++) {
111 for (i
= 1; i
<= FF_ARRAY_ELEMS(sad_c
); i
++) {
112 int r
= run_single_test(test
, b1
, W1
, b2
, W2
, a
, i
);
123 uint8_t *buf1
= av_malloc(W1
*H1
);
124 uint8_t *buf2
= av_malloc(W2
*H2
);
127 if (!buf1
|| !buf2
) {
128 fprintf(stderr
, "malloc failure\n");
133 check_pixfmt_descriptors();
135 #define RANDOM_INIT(buf, size) do { \
137 for (k = 0; k < size; k++) { \
138 state = state * 1664525 + 1013904223; \
139 buf[k] = state>>24; \
143 /* Normal test with different strides */
144 RANDOM_INIT(buf1
, W1
*H1
);
145 RANDOM_INIT(buf2
, W2
*H2
);
146 ret
= run_test("random", buf1
, buf2
);
150 /* Check for maximum SAD */
151 memset(buf1
, 0xff, W1
*H1
);
152 memset(buf2
, 0x00, W2
*H2
);
153 ret
= run_test("max", buf1
, buf2
);
157 /* Check for minimum SAD */
158 memset(buf1
, 0x90, W1
*H1
);
159 memset(buf2
, 0x90, W2
*H2
);
160 ret
= run_test("min", buf1
, buf2
);
164 /* Exact buffer sizes, to check for overreads */
165 for (i
= 1; i
<= 5; i
++) {
166 for (align
= 0; align
< 3; align
++) {
172 size1
= size2
= 1 << (i
<< 1);
175 case 0: size1
++; size2
++; break;
176 case 1: size2
++; break;
180 buf1
= av_malloc(size1
);
181 buf2
= av_malloc(size2
);
182 if (!buf1
|| !buf2
) {
183 fprintf(stderr
, "malloc failure\n");
187 RANDOM_INIT(buf1
, size1
);
188 RANDOM_INIT(buf2
, size2
);
189 ret
= run_single_test("small", buf1
, 1<<i
, buf2
, 1<<i
, align
, i
);