1 /*
2 * Copyright (C) 2003-2011 Michael Niedermayer <michaelni@gmx.at>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <inttypes.h>
25 #include <stdarg.h>
26
27 #undef HAVE_AV_CONFIG_H
37
39
40 /* HACK Duplicated from swscale_internal.h.
41 * Should be removed when a cleaner pixel format system exists. */
43 ((x) == AV_PIX_FMT_GRAY8 || \
44 (x) == AV_PIX_FMT_YA8 || \
45 (x) == AV_PIX_FMT_GRAY16BE || \
46 (x) == AV_PIX_FMT_GRAY16LE || \
47 (x) == AV_PIX_FMT_YA16BE || \
48 (x) == AV_PIX_FMT_YA16LE)
49 #define hasChroma(x) \
50 (!(isGray(x) || \
51 (x) == AV_PIX_FMT_MONOBLACK || \
52 (x) == AV_PIX_FMT_MONOWHITE))
53
55 {
58 }
59
62
64 int stride1,
int stride2,
int w,
int h)
65 {
66 int x, y;
67 uint64_t ssd = 0;
68
69 for (y = 0; y <
h; y++) {
70 for (x = 0; x <
w; x++) {
71 int d =
src1[x + y * stride1] -
src2[x + y * stride2];
73 }
74 }
75 return ssd;
76 }
77
80 {
81 int x, y;
82 uint64_t ssd = 0;
83
84 for (y = 0; y <
h; y++) {
85 for (x = 0; x <
w; x++) {
88 }
89 }
90 return ssd;
91 }
92
99 };
100
101 // test by ref -> src -> dst -> out & compare out against ref
102 // ref & out are YV12
103 static int doTest(
const uint8_t *
const ref[4],
int refStride[4],
int w,
int h,
105 int srcW,
int srcH,
int dstW,
int dstH,
int flags,
107 {
112 static int cur_srcW, cur_srcH;
113 static const uint8_t *
src[4];
114 static int srcStride[4];
115 uint8_t *dst[4] = { 0 };
116 uint8_t *
out[4] = { 0 };
117 int dstStride[4] = {0};
119 uint64_t ssdY, ssdU = 0, ssdV = 0, ssdA = 0;
121 uint32_t crc = 0;
122 int res = 0;
123
125 return 0;
126
129 int p;
130
131 for (p = 0; p < 4; p++)
133
135 if (res < 0) {
136 fprintf(stderr, "av_image_fill_linesizes failed\n");
137 goto end;
138 }
139 for (p = 0; p < 4; p++) {
140 srcStride[p] =
FFALIGN(srcStride[p], 16);
141 if (srcStride[p])
143 if (srcStride[p] && !
src[p]) {
144 perror("Malloc");
145 res = -1;
146 goto end;
147 }
148 }
151 if (!srcContext) {
152 fprintf(stderr, "Failed to get %s ---> %s\n",
155 res = -1;
156 goto end;
157 }
159 (uint8_t *
const *)
src, srcStride);
161
165 }
166
168 if (res < 0) {
169 fprintf(stderr, "av_image_fill_linesizes failed\n");
170 goto end;
171 }
172
173 for (
i = 0;
i < 4;
i++) {
174 /* Image buffers passed into libswscale can be allocated any way you
175 * prefer, as long as they're aligned enough for the architecture, and
176 * they're freed appropriately (such as using av_free for buffers
177 * allocated with av_malloc). */
178 /* An extra 16 bytes is being allocated because some scalers may write
179 * out of bounds. */
180 dstStride[
i] =
FFALIGN(dstStride[
i], 16);
183 if (dstStride[
i] && !dst[
i]) {
184 perror("Malloc");
185 res = -1;
186
187 goto end;
188 }
189 }
190
192 if (!dstContext) {
193 fprintf(stderr, "Failed to alloc %s ---> %s\n",
195 res = -1;
196 goto end;
197 }
198
206 av_opt_set(dstContext,
"alphablend",
"none", 0);
207
210 fprintf(stderr, "Failed to init %s ---> %s\n",
212 res = -1;
213 goto end;
214 }
215
216 printf(
" %s %dx%d -> %s %3dx%3d flags=%2d",
220 fflush(stdout);
221
222 sws_scale(dstContext, (
const uint8_t *
const*)
src, srcStride, 0,
srcH, dst, dstStride);
223
224 for (
i = 0;
i < 4 && dstStride[
i];
i++)
226 dstStride[
i] *
dstH);
227
228 if (
r && crc ==
r->crc) {
233 } else {
234 for (
i = 0;
i < 4;
i++) {
235 refStride[
i] =
FFALIGN(refStride[
i], 16);
238 if (refStride[
i] && !
out[
i]) {
239 perror("Malloc");
240 res = -1;
241 goto end;
242 }
243 }
247 if (!outContext) {
248 fprintf(stderr, "Failed to get %s ---> %s\n",
250 desc_yuva420p->
name);
251 res = -1;
252 goto end;
253 }
254 sws_scale(outContext, (
const uint8_t *
const *) dst, dstStride, 0,
dstH,
256
259 //FIXME check that output is really gray
260 ssdU =
getSSD(
ref[1],
out[1], refStride[1], refStride[1],
261 (
w + 1) >> 1, (
h + 1) >> 1);
262 ssdV =
getSSD(
ref[2],
out[2], refStride[2], refStride[2],
263 (
w + 1) >> 1, (
h + 1) >> 1);
264 } else {
266 (
w + 1) >> 1, (
h + 1) >> 1);
268 (
w + 1) >> 1, (
h + 1) >> 1);
269 }
272 } else {
274 }
275
280
282
283 for (
i = 0;
i < 4;
i++)
286 }
287
289 if(ssdY>
r->ssdY*1.02+1 || ssdU>
r->ssdU*1.02+1 || ssdV>
r->ssdV*1.02+1|| ssdA>
r->ssdA*1.02+1)
290 printf(
"WORSE SSD=%5"PRId64
",%5"PRId64
",%5"PRId64
",%5"PRId64
"",
291 r->ssdY,
r->ssdU,
r->ssdV,
r->ssdA);
292 else if(ssdY>
r->ssdY || ssdU>
r->ssdU || ssdV>
r->ssdV|| ssdA>
r->ssdA)
293 printf(
"worse SSD=%5"PRId64
",%5"PRId64
",%5"PRId64
",%5"PRId64
"",
294 r->ssdY,
r->ssdU,
r->ssdV,
r->ssdA);
295 }
296
297 printf(
" CRC=%08x SSD=%5"PRId64
",%5"PRId64
",%5"PRId64
",%5"PRId64
"\n",
298 crc, ssdY, ssdU, ssdV, ssdA);
299
300 end:
302
303 for (
i = 0;
i < 4;
i++)
306
307 return !!res;
308 }
309
310 static void selfTest(
const uint8_t *
const ref[4],
int refStride[4],
314 {
325
330 continue;
331
333
337 int res = 0;
338
341 continue;
342
344
346 fflush(stdout);
347
348 for (k = 0;
flags[k] && !res; k++)
349 for (
i = 0;
dstW[
i] && !res;
i++)
350 for (j = 0;
dstH[j] && !res; j++)
356 break;
357 }
359 break;
360 }
361 }
362
363 static int fileTest(
const uint8_t *
const ref[4],
int refStride[4],
364 int w,
int h, FILE *
fp,
367 {
368 char buf[256];
369
370 while (fgets(buf,
sizeof(buf),
fp)) {
373 char srcStr[21];
374 int srcW = 0, srcH = 0;
376 char dstStr[21];
377 int dstW = 0, dstH = 0;
380
382 " %20s %dx%d -> %20s %dx%d flags=%d CRC=%x"
383 " SSD=%"SCNu64 ", %"SCNu64 ", %"SCNu64 ", %"SCNu64 "\n",
384 srcStr, &srcW, &srcH, dstStr, &dstW, &dstH,
385 &
flags, &
r.crc, &
r.ssdY, &
r.ssdU, &
r.ssdV, &
r.ssdA);
387 srcStr[0] = dstStr[0] = 0;
388 ret = sscanf(buf,
"%20s -> %20s\n", srcStr, dstStr);
389 }
390
393
395 srcW > 8192
U || srcH > 8192
U || dstW > 8192
U || dstH > 8192
U) {
396 fprintf(stderr, "malformed input file\n");
397 return -1;
398 }
401 continue;
404 continue;
405 }
406
408 srcFormat, dstFormat,
409 srcW, srcH, dstW, dstH,
flags,
411 }
412
413 return 0;
414 }
415
418
419 int main(
int argc,
char **argv)
420 {
424 const uint8_t *
const rgb_src[4] = { rgb_data,
NULL,
NULL,
NULL };
425 int rgb_stride[4] = { 4 *
W, 0, 0, 0 };
429 int x, y;
432 int res = -1;
435
436 if (!rgb_data || !
data)
437 return -1;
438
439 for (
i = 1;
i < argc;
i += 2) {
440 if (!strcmp(argv[
i],
"-help") || !strcmp(argv[
i],
"--help")) {
441 fprintf(stderr,
442 "swscale [options...]\n"
443 " -help\n"
444 " This text\n"
445 " -ref <file>\n"
446 " Uses file as reference to compae tests againsts. Tests that have become worse will contain the string worse or WORSE\n"
447 " -p <number between 0.0 and 1.0>\n"
448 " The percentage of tests or comparissions to perform. Doing all tests will take long and generate over a hundread MB text output\n"
449 " It is often convenient to perform a random subset\n"
450 " -dst <pixfmt>\n"
451 " Only test the specified destination pixel format\n"
452 " -src <pixfmt>\n"
453 " Only test the specified source pixel format\n"
454 " -cpuflags <cpuflags>\n"
455 " Uses the specified cpuflags in teh tests\n"
456 );
458 }
459 if (argv[
i][0] !=
'-' ||
i + 1 == argc)
460 goto bad_option;
461 if (!strcmp(argv[
i],
"-ref")) {
462 fp = fopen(argv[
i + 1],
"r");
464 fprintf(stderr,
"could not open '%s'\n", argv[
i + 1]);
466 }
467 }
else if (!strcmp(argv[
i],
"-cpuflags")) {
471 fprintf(stderr,
"invalid cpu flags %s\n", argv[
i + 1]);
473 }
475 }
else if (!strcmp(argv[
i],
"-src")) {
478 fprintf(stderr,
"invalid pixel format %s\n", argv[
i + 1]);
479 return -1;
480 }
481 }
else if (!strcmp(argv[
i],
"-dst")) {
484 fprintf(stderr,
"invalid pixel format %s\n", argv[
i + 1]);
485 return -1;
486 }
487 }
else if (!strcmp(argv[
i],
"-p")) {
488 prob = atof(argv[
i + 1]);
489 } else {
490 bad_option:
491 fprintf(stderr,
"bad option or argument missing (%s) see -help\n", argv[
i]);
493 }
494 }
495
497
500
502
503 for (y = 0; y <
H; y++)
504 for (x = 0; x <
W * 4; x++)
507 if (res < 0 || res !=
H) {
508 res = -1;
510 }
513
517 } else {
519 res = 0;
520 }
523
524 return res;
525 }