FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
swscale.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2024 Nikles Haas
3  * Copyright (C) 2003-2011 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <inttypes.h>
26 #include <stdarg.h>
27 #include <signal.h>
28 
29 #undef HAVE_AV_CONFIG_H
30 #include "libavutil/cpu.h"
31 #include "libavutil/pixdesc.h"
32 #include "libavutil/lfg.h"
33 #include "libavutil/sfc64.h"
34 #include "libavutil/frame.h"
35 #include "libavutil/opt.h"
36 #include "libavutil/time.h"
37 #include "libavutil/pixfmt.h"
38 #include "libavutil/avassert.h"
39 #include "libavutil/macros.h"
40 
41 #include "libswscale/swscale.h"
42 
43 struct options {
46  double prob;
47  int w, h;
48  int threads;
49  int iters;
50  int bench;
51  int flags;
52  int dither;
53  int unscaled;
54 };
55 
56 struct mode {
59 };
60 
61 const SwsFlags flags[] = {
62  0, // test defaults
67  SWS_POINT,
70 };
71 
73 static SwsContext *sws[3]; /* reused between tests for efficiency */
74 
75 static double speedup_logavg;
76 static double speedup_min = 1e10;
77 static double speedup_max = 0;
78 static int speedup_count;
79 
80 static const char *speedup_color(double ratio)
81 {
82  return ratio > 1.10 ? "\033[1;32m" : /* bold green */
83  ratio > 1.02 ? "\033[32m" : /* green */
84  ratio > 0.98 ? "" : /* default */
85  ratio > 0.95 ? "\033[33m" : /* yellow */
86  ratio > 0.90 ? "\033[31m" : /* red */
87  "\033[1;31m"; /* bold red */
88 }
89 
90 static void exit_handler(int sig)
91 {
92  if (speedup_count) {
93  double ratio = exp(speedup_logavg / speedup_count);
94  printf("Overall speedup=%.3fx %s%s\033[0m, min=%.3fx max=%.3fx\n", ratio,
95  speedup_color(ratio), ratio >= 1.0 ? "faster" : "slower",
97  }
98 
99  exit(sig);
100 }
101 
102 /* Estimate luma variance assuming uniform dither noise distribution */
104 {
106  float variance = 1.0 / 12;
107  if (desc->comp[0].depth < 8) {
108  /* Extra headroom for very low bit depth output */
109  variance *= (8 - desc->comp[0].depth);
110  }
111 
112  if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
113  return 0.0;
114  } else if (desc->flags & AV_PIX_FMT_FLAG_RGB) {
115  const float r = 0.299 / (1 << desc->comp[0].depth);
116  const float g = 0.587 / (1 << desc->comp[1].depth);
117  const float b = 0.114 / (1 << desc->comp[2].depth);
118  return (r * r + g * g + b * b) * variance;
119  } else {
120  const float y = 1.0 / (1 << desc->comp[0].depth);
121  return y * y * variance;
122  }
123 }
124 
125 static int fmt_comps(enum AVPixelFormat fmt)
126 {
128  int comps = desc->nb_components >= 3 ? 0b111 : 0b1;
129  if (desc->flags & AV_PIX_FMT_FLAG_ALPHA)
130  comps |= 0b1000;
131  return comps;
132 }
133 
134 static void get_ssim(float ssim[4], const AVFrame *out, const AVFrame *ref, int comps)
135 {
136  av_assert1(out->format == AV_PIX_FMT_YUVA444P);
137  av_assert1(ref->format == out->format);
138  av_assert1(ref->width == out->width && ref->height == out->height);
139 
140  for (int p = 0; p < 4; p++) {
141  const int stride_a = out->linesize[p];
142  const int stride_b = ref->linesize[p];
143  const int w = out->width;
144  const int h = out->height;
145 
146  const int is_chroma = p == 1 || p == 2;
147  const uint8_t def = is_chroma ? 128 : 0xFF;
148  const int has_ref = comps & (1 << p);
149  double sum = 0;
150  int count = 0;
151 
152  /* 4x4 SSIM */
153  for (int y = 0; y < (h & ~3); y += 4) {
154  for (int x = 0; x < (w & ~3); x += 4) {
155  const float c1 = .01 * .01 * 255 * 255 * 64;
156  const float c2 = .03 * .03 * 255 * 255 * 64 * 63;
157  int s1 = 0, s2 = 0, ss = 0, s12 = 0, var, covar;
158 
159  for (int yy = 0; yy < 4; yy++) {
160  for (int xx = 0; xx < 4; xx++) {
161  int a = out->data[p][(y + yy) * stride_a + x + xx];
162  int b = has_ref ? ref->data[p][(y + yy) * stride_b + x + xx] : def;
163  s1 += a;
164  s2 += b;
165  ss += a * a + b * b;
166  s12 += a * b;
167  }
168  }
169 
170  var = ss * 64 - s1 * s1 - s2 * s2;
171  covar = s12 * 64 - s1 * s2;
172  sum += (2 * s1 * s2 + c1) * (2 * covar + c2) /
173  ((s1 * s1 + s2 * s2 + c1) * (var + c2));
174  count++;
175  }
176  }
177 
178  ssim[p] = count ? sum / count : 0.0;
179  }
180 }
181 
182 static float get_loss(const float ssim[4])
183 {
184  const float weights[3] = { 0.8, 0.1, 0.1 }; /* tuned for Y'CrCr */
185 
186  float sum = 0;
187  for (int i = 0; i < 3; i++)
188  sum += weights[i] * ssim[i];
189  sum *= ssim[3]; /* ensure alpha errors get caught */
190 
191  return 1.0 - sum;
192 }
193 
194 static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode,
195  struct options opts)
196 {
197  SwsContext *sws_legacy;
198  int ret;
199 
200  sws_legacy = sws_alloc_context();
201  if (!sws_legacy)
202  return -1;
203 
204  sws_legacy->src_w = src->width;
205  sws_legacy->src_h = src->height;
206  sws_legacy->src_format = src->format;
207  sws_legacy->dst_w = dst->width;
208  sws_legacy->dst_h = dst->height;
209  sws_legacy->dst_format = dst->format;
210  sws_legacy->flags = mode.flags;
211  sws_legacy->dither = mode.dither;
212  sws_legacy->threads = opts.threads;
213 
214  if ((ret = sws_init_context(sws_legacy, NULL, NULL)) < 0)
215  goto error;
216 
217  for (int i = 0; ret >= 0 && i < opts.iters; i++)
218  ret = sws_scale_frame(sws_legacy, dst, src);
219 
220 error:
221  sws_freeContext(sws_legacy);
222  return ret;
223 }
224 
225 /* Runs a series of ref -> src -> dst -> out, and compares out vs ref */
226 static int run_test(enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt,
227  int dst_w, int dst_h, struct mode mode, struct options opts,
228  const AVFrame *ref, const float ssim_ref[4])
229 {
230  AVFrame *src = NULL, *dst = NULL, *out = NULL;
231  float ssim[4], ssim_sws[4];
232  const int comps = fmt_comps(src_fmt) & fmt_comps(dst_fmt);
233  int64_t time, time_ref = 0;
234  int ret = -1;
235 
236  /* Estimate the expected amount of loss from bit depth reduction */
237  const float c1 = 0.01 * 0.01; /* stabilization constant */
238  const float ref_var = 1.0 / 12.0; /* uniformly distributed signal */
239  const float src_var = estimate_quantization_noise(src_fmt);
240  const float dst_var = estimate_quantization_noise(dst_fmt);
241  const float out_var = estimate_quantization_noise(ref->format);
242  const float total_var = src_var + dst_var + out_var;
243  const float ssim_luma = (2 * ref_var + c1) / (2 * ref_var + total_var + c1);
244  const float ssim_expected[4] = { ssim_luma, 1, 1, 1 }; /* for simplicity */
245  const float expected_loss = get_loss(ssim_expected);
246  float loss;
247 
248  src = av_frame_alloc();
249  dst = av_frame_alloc();
250  out = av_frame_alloc();
251  if (!src || !dst || !out)
252  goto error;
253 
257  src->width = out->width = ref->width;
258  src->height = out->height = ref->height;
259  out->format = ref->format;
260  src->format = src_fmt;
261  dst->format = dst_fmt;
262  dst->width = dst_w;
263  dst->height = dst_h;
264 
265  if (sws_scale_frame(sws[0], src, ref) < 0) {
266  fprintf(stderr, "Failed %s ---> %s\n", av_get_pix_fmt_name(ref->format),
267  av_get_pix_fmt_name(src->format));
268  goto error;
269  }
270 
271  sws[1]->flags = mode.flags;
272  sws[1]->dither = mode.dither;
273  sws[1]->threads = opts.threads;
274 
275  time = av_gettime_relative();
276 
277  for (int i = 0; i < opts.iters; i++) {
278  if (sws_scale_frame(sws[1], dst, src) < 0) {
279  fprintf(stderr, "Failed %s ---> %s\n", av_get_pix_fmt_name(src->format),
280  av_get_pix_fmt_name(dst->format));
281  goto error;
282  }
283  }
284 
285  time = av_gettime_relative() - time;
286 
287  if (sws_scale_frame(sws[2], out, dst) < 0) {
288  fprintf(stderr, "Failed %s ---> %s\n", av_get_pix_fmt_name(dst->format),
289  av_get_pix_fmt_name(out->format));
290  goto error;
291  }
292 
293  get_ssim(ssim, out, ref, comps);
294  printf("%s %dx%d -> %s %3dx%3d, flags=0x%x dither=%u, "
295  "SSIM {Y=%f U=%f V=%f A=%f}\n",
296  av_get_pix_fmt_name(src->format), src->width, src->height,
297  av_get_pix_fmt_name(dst->format), dst->width, dst->height,
299  ssim[0], ssim[1], ssim[2], ssim[3]);
300 
301  loss = get_loss(ssim);
302  if (loss - expected_loss > 1e-4 && dst_w >= ref->width && dst_h >= ref->height) {
303  int bad = loss - expected_loss > 1e-2;
304  printf("\033[1;31m loss %g is %s by %g, expected loss %g\033[0m\n",
305  loss, bad ? "WORSE" : "worse", loss - expected_loss, expected_loss);
306  if (bad)
307  goto error;
308  }
309 
310  if (!ssim_ref && sws_isSupportedInput(src->format) && sws_isSupportedOutput(dst->format)) {
311  /* Compare against the legacy swscale API as a reference */
312  time_ref = av_gettime_relative();
313  if (scale_legacy(dst, src, mode, opts) < 0) {
314  fprintf(stderr, "Failed ref %s ---> %s\n", av_get_pix_fmt_name(src->format),
315  av_get_pix_fmt_name(dst->format));
316  goto error;
317  }
318  time_ref = av_gettime_relative() - time_ref;
319 
320  if (sws_scale_frame(sws[2], out, dst) < 0)
321  goto error;
322 
323  get_ssim(ssim_sws, out, ref, comps);
324 
325  /* Legacy swscale does not perform bit accurate upconversions of low
326  * bit depth RGB. This artificially improves the SSIM score because the
327  * resulting error deletes some of the input dither noise. This gives
328  * it an unfair advantage when compared against a bit exact reference.
329  * Work around this by ensuring that the reference SSIM score is not
330  * higher than it theoretically "should" be. */
331  if (src_var > dst_var) {
332  const float src_loss = (2 * ref_var + c1) / (2 * ref_var + src_var + c1);
333  ssim_sws[0] = FFMIN(ssim_sws[0], src_loss);
334  }
335 
336  ssim_ref = ssim_sws;
337  }
338 
339  if (ssim_ref) {
340  const float loss_ref = get_loss(ssim_ref);
341  if (loss - loss_ref > 1e-4) {
342  int bad = loss - loss_ref > 1e-2;
343  printf("\033[1;31m loss %g is %s by %g, ref loss %g, "
344  "SSIM {Y=%f U=%f V=%f A=%f}\033[0m\n",
345  loss, bad ? "WORSE" : "worse", loss - loss_ref, loss_ref,
346  ssim_ref[0], ssim_ref[1], ssim_ref[2], ssim_ref[3]);
347  if (bad)
348  goto error;
349  }
350  }
351 
352  if (opts.bench && time_ref) {
353  double ratio = (double) time_ref / time;
354  if (FFMIN(time, time_ref) > 100 /* don't pollute stats with low precision */) {
355  speedup_min = FFMIN(speedup_min, ratio);
356  speedup_max = FFMAX(speedup_max, ratio);
357  speedup_logavg += log(ratio);
358  speedup_count++;
359  }
360 
361  printf(" time=%"PRId64" us, ref=%"PRId64" us, speedup=%.3fx %s%s\033[0m\n",
362  time / opts.iters, time_ref / opts.iters, ratio,
363  speedup_color(ratio), ratio >= 1.0 ? "faster" : "slower");
364  } else if (opts.bench) {
365  printf(" time=%"PRId64" us\n", time / opts.iters);
366  }
367 
368  fflush(stdout);
369  ret = 0; /* fall through */
370  error:
371  av_frame_free(&src);
372  av_frame_free(&dst);
373  av_frame_free(&out);
374  return ret;
375 }
376 
377 static inline int fmt_is_subsampled(enum AVPixelFormat fmt)
378 {
379  return av_pix_fmt_desc_get(fmt)->log2_chroma_w != 0 ||
381 }
382 
383 static int run_self_tests(const AVFrame *ref, struct options opts)
384 {
385  const int dst_w[] = { opts.w, opts.w - opts.w / 3, opts.w + opts.w / 3 };
386  const int dst_h[] = { opts.h, opts.h - opts.h / 3, opts.h + opts.h / 3 };
387 
388  enum AVPixelFormat src_fmt, dst_fmt,
389  src_fmt_min = 0,
390  dst_fmt_min = 0,
391  src_fmt_max = AV_PIX_FMT_NB - 1,
392  dst_fmt_max = AV_PIX_FMT_NB - 1;
393 
394  if (opts.src_fmt != AV_PIX_FMT_NONE)
395  src_fmt_min = src_fmt_max = opts.src_fmt;
396  if (opts.dst_fmt != AV_PIX_FMT_NONE)
397  dst_fmt_min = dst_fmt_max = opts.dst_fmt;
398 
399  for (src_fmt = src_fmt_min; src_fmt <= src_fmt_max; src_fmt++) {
400  if (opts.unscaled && fmt_is_subsampled(src_fmt))
401  continue;
402  if (!sws_test_format(src_fmt, 0) || !sws_test_format(src_fmt, 1))
403  continue;
404  for (dst_fmt = dst_fmt_min; dst_fmt <= dst_fmt_max; dst_fmt++) {
405  if (opts.unscaled && fmt_is_subsampled(dst_fmt))
406  continue;
407  if (!sws_test_format(dst_fmt, 0) || !sws_test_format(dst_fmt, 1))
408  continue;
409  for (int h = 0; h < FF_ARRAY_ELEMS(dst_h); h++) {
410  for (int w = 0; w < FF_ARRAY_ELEMS(dst_w); w++) {
411  for (int f = 0; f < FF_ARRAY_ELEMS(flags); f++) {
412  struct mode mode = {
413  .flags = opts.flags >= 0 ? opts.flags : flags[f],
414  .dither = opts.dither >= 0 ? opts.dither : SWS_DITHER_AUTO,
415  };
416 
417  if (ff_sfc64_get(&prng_state) > UINT64_MAX * opts.prob)
418  continue;
419 
420  if (run_test(src_fmt, dst_fmt, dst_w[w], dst_h[h],
421  mode, opts, ref, NULL) < 0)
422  return -1;
423 
424  if (opts.flags >= 0 || opts.unscaled)
425  break;
426  }
427  if (opts.unscaled)
428  break;
429  }
430  if (opts.unscaled)
431  break;
432  }
433  }
434  }
435 
436  return 0;
437 }
438 
439 static int run_file_tests(const AVFrame *ref, FILE *fp, struct options opts)
440 {
441  char buf[256];
442  int ret;
443 
444  while (fgets(buf, sizeof(buf), fp)) {
445  char src_fmt_str[21], dst_fmt_str[21];
446  enum AVPixelFormat src_fmt;
447  enum AVPixelFormat dst_fmt;
448  int sw, sh, dw, dh;
449  float ssim[4];
450  struct mode mode;
451 
452  ret = sscanf(buf,
453  "%20s %dx%d -> %20s %dx%d, flags=0x%x dither=%u, "
454  "SSIM {Y=%f U=%f V=%f A=%f}\n",
455  src_fmt_str, &sw, &sh, dst_fmt_str, &dw, &dh,
456  &mode.flags, &mode.dither,
457  &ssim[0], &ssim[1], &ssim[2], &ssim[3]);
458  if (ret != 12) {
459  printf("%s", buf);
460  continue;
461  }
462 
463  src_fmt = av_get_pix_fmt(src_fmt_str);
464  dst_fmt = av_get_pix_fmt(dst_fmt_str);
465  if (src_fmt == AV_PIX_FMT_NONE || dst_fmt == AV_PIX_FMT_NONE ||
466  sw != ref->width || sh != ref->height || dw > 8192 || dh > 8192 ||
468  fprintf(stderr, "malformed input file\n");
469  return -1;
470  }
471 
472  if (opts.src_fmt != AV_PIX_FMT_NONE && src_fmt != opts.src_fmt ||
473  opts.dst_fmt != AV_PIX_FMT_NONE && dst_fmt != opts.dst_fmt)
474  continue;
475 
476  if (run_test(src_fmt, dst_fmt, dw, dh, mode, opts, ref, ssim) < 0)
477  return -1;
478  }
479 
480  return 0;
481 }
482 
483 int main(int argc, char **argv)
484 {
485  struct options opts = {
486  .src_fmt = AV_PIX_FMT_NONE,
487  .dst_fmt = AV_PIX_FMT_NONE,
488  .w = 96,
489  .h = 96,
490  .threads = 1,
491  .iters = 1,
492  .prob = 1.0,
493  .flags = -1,
494  .dither = -1,
495  };
496 
497  AVFrame *rgb = NULL, *ref = NULL;
498  FILE *fp = NULL;
499  AVLFG rand;
500  int ret = -1;
501 
502  for (int i = 1; i < argc; i += 2) {
503  if (!strcmp(argv[i], "-help") || !strcmp(argv[i], "--help")) {
504  fprintf(stderr,
505  "swscale [options...]\n"
506  " -help\n"
507  " This text\n"
508  " -ref <file>\n"
509  " Uses file as reference to compare tests againsts. Tests that have become worse will contain the string worse or WORSE\n"
510  " -p <number between 0.0 and 1.0>\n"
511  " The percentage of tests or comparisons to perform. Doing all tests will take long and generate over a hundred MB text output\n"
512  " It is often convenient to perform a random subset\n"
513  " -dst <pixfmt>\n"
514  " Only test the specified destination pixel format\n"
515  " -src <pixfmt>\n"
516  " Only test the specified source pixel format\n"
517  " -bench <iters>\n"
518  " Run benchmarks with the specified number of iterations. This mode also increases the size of the test images\n"
519  " -flags <flags>\n"
520  " Test with a specific combination of flags\n"
521  " -dither <mode>\n"
522  " Test with a specific dither mode\n"
523  " -unscaled <1 or 0>\n"
524  " If 1, test only conversions that do not involve scaling\n"
525  " -threads <threads>\n"
526  " Use the specified number of threads\n"
527  " -cpuflags <cpuflags>\n"
528  " Uses the specified cpuflags in the tests\n"
529  " -v <level>\n"
530  " Enable log verbosity at given level\n"
531  );
532  return 0;
533  }
534  if (argv[i][0] != '-' || i + 1 == argc)
535  goto bad_option;
536  if (!strcmp(argv[i], "-ref")) {
537  fp = fopen(argv[i + 1], "r");
538  if (!fp) {
539  fprintf(stderr, "could not open '%s'\n", argv[i + 1]);
540  goto error;
541  }
542  } else if (!strcmp(argv[i], "-cpuflags")) {
543  unsigned flags = av_get_cpu_flags();
544  int res = av_parse_cpu_caps(&flags, argv[i + 1]);
545  if (res < 0) {
546  fprintf(stderr, "invalid cpu flags %s\n", argv[i + 1]);
547  goto error;
548  }
550  } else if (!strcmp(argv[i], "-src")) {
551  opts.src_fmt = av_get_pix_fmt(argv[i + 1]);
552  if (opts.src_fmt == AV_PIX_FMT_NONE) {
553  fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
554  goto error;
555  }
556  } else if (!strcmp(argv[i], "-dst")) {
557  opts.dst_fmt = av_get_pix_fmt(argv[i + 1]);
558  if (opts.dst_fmt == AV_PIX_FMT_NONE) {
559  fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
560  goto error;
561  }
562  } else if (!strcmp(argv[i], "-bench")) {
563  opts.bench = 1;
564  opts.iters = atoi(argv[i + 1]);
565  opts.iters = FFMAX(opts.iters, 1);
566  opts.w = 1920;
567  opts.h = 1080;
568  } else if (!strcmp(argv[i], "-flags")) {
569  opts.flags = strtol(argv[i + 1], NULL, 0);
570  } else if (!strcmp(argv[i], "-dither")) {
571  opts.dither = atoi(argv[i + 1]);
572  } else if (!strcmp(argv[i], "-unscaled")) {
573  opts.unscaled = atoi(argv[i + 1]);
574  } else if (!strcmp(argv[i], "-threads")) {
575  opts.threads = atoi(argv[i + 1]);
576  } else if (!strcmp(argv[i], "-p")) {
577  opts.prob = atof(argv[i + 1]);
578  } else if (!strcmp(argv[i], "-v")) {
579  av_log_set_level(atoi(argv[i + 1]));
580  } else {
581 bad_option:
582  fprintf(stderr, "bad option or argument missing (%s) see -help\n", argv[i]);
583  goto error;
584  }
585  }
586 
587  ff_sfc64_init(&prng_state, 0, 0, 0, 12);
588  av_lfg_init(&rand, 1);
589  signal(SIGINT, exit_handler);
590 
591  for (int i = 0; i < 3; i++) {
592  sws[i] = sws_alloc_context();
593  if (!sws[i])
594  goto error;
595  sws[i]->flags = SWS_BILINEAR;
596  }
597 
598  rgb = av_frame_alloc();
599  if (!rgb)
600  goto error;
601  rgb->width = opts.w / 12;
602  rgb->height = opts.h / 12;
603  rgb->format = AV_PIX_FMT_RGBA;
604  if (av_frame_get_buffer(rgb, 32) < 0)
605  goto error;
606 
607  for (int y = 0; y < rgb->height; y++) {
608  for (int x = 0; x < rgb->width; x++) {
609  for (int c = 0; c < 4; c++)
610  rgb->data[0][y * rgb->linesize[0] + x * 4 + c] = av_lfg_get(&rand);
611  }
612  }
613 
614  ref = av_frame_alloc();
615  if (!ref)
616  goto error;
617  ref->width = opts.w;
618  ref->height = opts.h;
619  ref->format = AV_PIX_FMT_YUVA444P;
620 
621  if (sws_scale_frame(sws[0], ref, rgb) < 0)
622  goto error;
623 
624  ret = fp ? run_file_tests(ref, fp, opts)
625  : run_self_tests(ref, opts);
626 
627  /* fall through */
628 error:
629  for (int i = 0; i < 3; i++)
631  av_frame_free(&rgb);
632  av_frame_free(&ref);
633  if (fp)
634  fclose(fp);
635  exit_handler(ret);
636 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
flags
const SwsFlags flags[]
Definition: swscale.c:61
av_force_cpu_flags
void av_force_cpu_flags(int arg)
Disables cpu detection and forces the specified flags.
Definition: cpu.c:81
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
SWS_DITHER_AUTO
@ SWS_DITHER_AUTO
Definition: swscale.h:81
r
const char * r
Definition: vf_curves.c:127
opt.h
scale_legacy
static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode, struct options opts)
Definition: swscale.c:194
out
FILE * out
Definition: movenc.c:55
sws_isSupportedOutput
#define sws_isSupportedOutput(x)
av_frame_get_buffer
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:205
av_lfg_init
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:32
fmt_is_subsampled
static int fmt_is_subsampled(enum AVPixelFormat fmt)
Definition: swscale.c:377
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3341
SwsContext::src_w
int src_w
Deprecated frame property overrides, for the legacy API only.
Definition: swscale.h:228
estimate_quantization_noise
static float estimate_quantization_noise(enum AVPixelFormat fmt)
Definition: swscale.c:103
int64_t
long long int64_t
Definition: coverity.c:34
AV_PIX_FMT_FLAG_FLOAT
#define AV_PIX_FMT_FLAG_FLOAT
The pixel format contains IEEE-754 floating point values.
Definition: pixdesc.h:158
sws_freeContext
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
Definition: utils.c:2233
normalize.log
log
Definition: normalize.py:21
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:63
options::unscaled
int unscaled
Definition: swscale.c:53
mode
Definition: swscale.c:56
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
speedup_color
static const char * speedup_color(double ratio)
Definition: swscale.c:80
SWS_BILINEAR
@ SWS_BILINEAR
bilinear filtering
Definition: swscale.h:99
SWS_BITEXACT
@ SWS_BITEXACT
Definition: swscale.h:156
b
#define b
Definition: input.c:42
options::dither
int dither
Definition: swscale.c:52
ff_sfc64_init
static void ff_sfc64_init(FFSFC64 *s, uint64_t seeda, uint64_t seedb, uint64_t seedc, int rounds)
Initialize sfc64 with up to 3 seeds.
Definition: sfc64.h:75
SwsContext::flags
unsigned flags
Bitmask of SWS_*.
Definition: swscale.h:195
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:109
c1
static const uint64_t c1
Definition: murmur3.c:52
mode::dither
SwsDither dither
Definition: swscale.c:58
prng_state
static FFSFC64 prng_state
Definition: swscale.c:72
run_file_tests
static int run_file_tests(const AVFrame *ref, FILE *fp, struct options opts)
Definition: swscale.c:439
speedup_max
static double speedup_max
Definition: swscale.c:77
AV_PIX_FMT_NB
@ AV_PIX_FMT_NB
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition: pixfmt.h:491
SWS_FAST_BILINEAR
@ SWS_FAST_BILINEAR
Scaler selection options.
Definition: swscale.h:98
rgb
Definition: rpzaenc.c:60
b1
static double b1(void *priv, double x, double y)
Definition: vf_xfade.c:2034
SWS_FULL_CHR_H_INP
@ SWS_FULL_CHR_H_INP
Perform full chroma interpolation when downscaling RGB sources.
Definition: swscale.h:145
macros.h
FFSFC64
Definition: sfc64.h:37
SwsDither
SwsDither
Definition: swscale.h:77
options::iters
int iters
Definition: swscale.c:49
av_parse_cpu_caps
int av_parse_cpu_caps(unsigned *flags, const char *s)
Parse CPU caps from a string and update the given AV_CPU_* flags based on that.
Definition: cpu.c:119
sws_init_context
av_warn_unused_result int sws_init_context(SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition: utils.c:1868
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:51
avassert.h
options::dst_fmt
enum AVPixelFormat dst_fmt
Definition: swscale.c:45
options::w
int w
Definition: swscale.c:47
SWS_AREA
@ SWS_AREA
area averaging
Definition: swscale.h:103
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
speedup_min
static double speedup_min
Definition: swscale.c:76
SwsContext::dither
SwsDither dither
Dither mode.
Definition: swscale.h:210
options::h
int h
Definition: swscale.c:47
SwsFlags
SwsFlags
Definition: swscale.h:94
SwsContext::threads
int threads
How many threads to use for processing, or 0 for automatic selection.
Definition: swscale.h:205
av_lfg_get
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:53
g
const char * g
Definition: vf_curves.c:128
lfg.h
run_self_tests
static int run_self_tests(const AVFrame *ref, struct options opts)
Definition: swscale.c:383
AV_PIX_FMT_FLAG_ALPHA
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:147
sfc64.h
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
opts
AVDictionary * opts
Definition: movenc.c:51
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:601
SWS_BICUBIC
@ SWS_BICUBIC
2-tap cubic B-spline
Definition: swscale.h:100
options::threads
int threads
Definition: swscale.c:48
run_test
static int run_test(enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt, int dst_w, int dst_h, struct mode mode, struct options opts, const AVFrame *ref, const float ssim_ref[4])
Definition: swscale.c:226
options
Definition: swscale.c:43
sws_test_format
int sws_test_format(enum AVPixelFormat format, int output)
Test if a given pixel format is supported.
Definition: format.c:503
double
double
Definition: af_crystalizer.c:132
time.h
exp
int8_t exp
Definition: eval.c:73
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
options::src_fmt
enum AVPixelFormat src_fmt
Definition: swscale.c:44
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
f
f
Definition: af_crystalizer.c:122
sws_alloc_context
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition: utils.c:1009
AV_PIX_FMT_FLAG_RGB
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:136
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
cpu.h
mode::flags
SwsFlags flags
Definition: swscale.c:57
SWS_POINT
@ SWS_POINT
nearest neighbor
Definition: swscale.h:102
SwsContext::src_h
int src_h
Width and height of the source frame.
Definition: swscale.h:228
exit_handler
static void exit_handler(int sig)
Definition: swscale.c:90
printf
printf("static const uint8_t my_array[100] = {\n")
frame.h
options::prob
double prob
Definition: swscale.c:46
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
get_loss
static float get_loss(const float ssim[4])
Definition: swscale.c:182
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:174
SWS_DITHER_NB
@ SWS_DITHER_NB
Definition: swscale.h:86
SwsContext::dst_format
int dst_format
Destination pixel format.
Definition: swscale.h:231
sws_isSupportedInput
#define sws_isSupportedInput(x)
options::flags
int flags
Definition: swscale.c:51
sws
static SwsContext * sws[3]
Definition: swscale.c:73
av_log_set_level
void av_log_set_level(int level)
Set the log level.
Definition: log.c:473
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
SWS_X
@ SWS_X
experimental
Definition: swscale.h:101
weights
static const int weights[]
Definition: hevc_pel.c:32
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
SwsContext::dst_h
int dst_h
Width and height of the destination frame.
Definition: swscale.h:229
ff_sfc64_get
static uint64_t ff_sfc64_get(FFSFC64 *s)
Definition: sfc64.h:41
ret
ret
Definition: filter_design.txt:187
pixfmt.h
SWS_FULL_CHR_H_INT
@ SWS_FULL_CHR_H_INT
Perform full chroma upsampling when upscaling to RGB.
Definition: swscale.h:132
get_ssim
static void get_ssim(float ssim[4], const AVFrame *out, const AVFrame *ref, int comps)
Definition: swscale.c:134
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:3273
speedup_count
static int speedup_count
Definition: swscale.c:78
c2
static const uint64_t c2
Definition: murmur3.c:53
main
int main(int argc, char **argv)
Definition: swscale.c:483
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
bad
static int bad(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:130
desc
const char * desc
Definition: libsvtav1.c:79
SwsContext::dst_w
int dst_w
Definition: swscale.h:229
SwsContext::src_format
int src_format
Source pixel format.
Definition: swscale.h:230
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
options::bench
int bench
Definition: swscale.c:50
sws_free_context
void sws_free_context(SwsContext **ctx)
Free the context and everything associated with it, and write NULL to the provided pointer.
Definition: utils.c:2315
sws_scale_frame
int sws_scale_frame(SwsContext *sws, AVFrame *dst, const AVFrame *src)
Scale source data from src and write the output to dst.
Definition: swscale.c:1355
SWS_ACCURATE_RND
@ SWS_ACCURATE_RND
Force bit-exact output.
Definition: swscale.h:155
h
h
Definition: vp9dsp_template.c:2070
SwsContext
Main external API structure.
Definition: swscale.h:182
fmt_comps
static int fmt_comps(enum AVPixelFormat fmt)
Definition: swscale.c:125
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
src
#define src
Definition: vp8dsp.c:248
swscale.h
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3261
speedup_logavg
static double speedup_logavg
Definition: swscale.c:75