FFmpeg
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 > 10.00 ? "\033[1;94m" : /* bold blue */
83  ratio > 2.00 ? "\033[1;32m" : /* bold green */
84  ratio > 1.02 ? "\033[32m" : /* green */
85  ratio > 0.98 ? "" : /* default */
86  ratio > 0.90 ? "\033[33m" : /* yellow */
87  ratio > 0.75 ? "\033[31m" : /* red */
88  "\033[1;31m"; /* bold red */
89 }
90 
91 static void exit_handler(int sig)
92 {
93  if (speedup_count) {
94  double ratio = exp(speedup_logavg / speedup_count);
95  printf("Overall speedup=%.3fx %s%s\033[0m, min=%.3fx max=%.3fx\n", ratio,
96  speedup_color(ratio), ratio >= 1.0 ? "faster" : "slower",
98  }
99 
100  exit(sig);
101 }
102 
103 /* Estimate luma variance assuming uniform dither noise distribution */
105 {
107  float variance = 1.0 / 12;
108  if (desc->comp[0].depth < 8) {
109  /* Extra headroom for very low bit depth output */
110  variance *= (8 - desc->comp[0].depth);
111  }
112 
113  if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
114  return 0.0;
115  } else if (desc->flags & AV_PIX_FMT_FLAG_RGB) {
116  const float r = 0.299 / (1 << desc->comp[0].depth);
117  const float g = 0.587 / (1 << desc->comp[1].depth);
118  const float b = 0.114 / (1 << desc->comp[2].depth);
119  return (r * r + g * g + b * b) * variance;
120  } else {
121  const float y = 1.0 / (1 << desc->comp[0].depth);
122  return y * y * variance;
123  }
124 }
125 
126 static int fmt_comps(enum AVPixelFormat fmt)
127 {
129  int comps = desc->nb_components >= 3 ? 0b111 : 0b1;
130  if (desc->flags & AV_PIX_FMT_FLAG_ALPHA)
131  comps |= 0b1000;
132  return comps;
133 }
134 
135 static void get_ssim(float ssim[4], const AVFrame *out, const AVFrame *ref, int comps)
136 {
137  av_assert1(out->format == AV_PIX_FMT_YUVA444P);
138  av_assert1(ref->format == out->format);
139  av_assert1(ref->width == out->width && ref->height == out->height);
140 
141  for (int p = 0; p < 4; p++) {
142  const int stride_a = out->linesize[p];
143  const int stride_b = ref->linesize[p];
144  const int w = out->width;
145  const int h = out->height;
146 
147  const int is_chroma = p == 1 || p == 2;
148  const uint8_t def = is_chroma ? 128 : 0xFF;
149  const int has_ref = comps & (1 << p);
150  double sum = 0;
151  int count = 0;
152 
153  /* 4x4 SSIM */
154  for (int y = 0; y < (h & ~3); y += 4) {
155  for (int x = 0; x < (w & ~3); x += 4) {
156  const float c1 = .01 * .01 * 255 * 255 * 64;
157  const float c2 = .03 * .03 * 255 * 255 * 64 * 63;
158  int s1 = 0, s2 = 0, ss = 0, s12 = 0, var, covar;
159 
160  for (int yy = 0; yy < 4; yy++) {
161  for (int xx = 0; xx < 4; xx++) {
162  int a = out->data[p][(y + yy) * stride_a + x + xx];
163  int b = has_ref ? ref->data[p][(y + yy) * stride_b + x + xx] : def;
164  s1 += a;
165  s2 += b;
166  ss += a * a + b * b;
167  s12 += a * b;
168  }
169  }
170 
171  var = ss * 64 - s1 * s1 - s2 * s2;
172  covar = s12 * 64 - s1 * s2;
173  sum += (2 * s1 * s2 + c1) * (2 * covar + c2) /
174  ((s1 * s1 + s2 * s2 + c1) * (var + c2));
175  count++;
176  }
177  }
178 
179  ssim[p] = count ? sum / count : 0.0;
180  }
181 }
182 
183 static float get_loss(const float ssim[4])
184 {
185  const float weights[3] = { 0.8, 0.1, 0.1 }; /* tuned for Y'CrCr */
186 
187  float sum = 0;
188  for (int i = 0; i < 3; i++)
189  sum += weights[i] * ssim[i];
190  sum *= ssim[3]; /* ensure alpha errors get caught */
191 
192  return 1.0 - sum;
193 }
194 
195 static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode,
196  struct options opts)
197 {
198  SwsContext *sws_legacy;
199  int ret;
200 
201  sws_legacy = sws_alloc_context();
202  if (!sws_legacy)
203  return -1;
204 
205  sws_legacy->src_w = src->width;
206  sws_legacy->src_h = src->height;
207  sws_legacy->src_format = src->format;
208  sws_legacy->dst_w = dst->width;
209  sws_legacy->dst_h = dst->height;
210  sws_legacy->dst_format = dst->format;
211  sws_legacy->flags = mode.flags;
212  sws_legacy->dither = mode.dither;
213  sws_legacy->threads = opts.threads;
214 
215  if ((ret = sws_init_context(sws_legacy, NULL, NULL)) < 0)
216  goto error;
217 
218  for (int i = 0; ret >= 0 && i < opts.iters; i++)
219  ret = sws_scale_frame(sws_legacy, dst, src);
220 
221 error:
222  sws_freeContext(sws_legacy);
223  return ret;
224 }
225 
226 /* Runs a series of ref -> src -> dst -> out, and compares out vs ref */
227 static int run_test(enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt,
228  int dst_w, int dst_h, struct mode mode, struct options opts,
229  const AVFrame *ref, const float ssim_ref[4])
230 {
231  AVFrame *src = NULL, *dst = NULL, *out = NULL;
232  float ssim[4], ssim_sws[4];
233  const int comps = fmt_comps(src_fmt) & fmt_comps(dst_fmt);
234  int64_t time, time_ref = 0;
235  int ret = -1;
236 
237  /* Estimate the expected amount of loss from bit depth reduction */
238  const float c1 = 0.01 * 0.01; /* stabilization constant */
239  const float ref_var = 1.0 / 12.0; /* uniformly distributed signal */
240  const float src_var = estimate_quantization_noise(src_fmt);
241  const float dst_var = estimate_quantization_noise(dst_fmt);
242  const float out_var = estimate_quantization_noise(ref->format);
243  const float total_var = src_var + dst_var + out_var;
244  const float ssim_luma = (2 * ref_var + c1) / (2 * ref_var + total_var + c1);
245  const float ssim_expected[4] = { ssim_luma, 1, 1, 1 }; /* for simplicity */
246  const float expected_loss = get_loss(ssim_expected);
247  float loss;
248 
249  src = av_frame_alloc();
250  dst = av_frame_alloc();
251  out = av_frame_alloc();
252  if (!src || !dst || !out)
253  goto error;
254 
258  src->width = out->width = ref->width;
259  src->height = out->height = ref->height;
260  out->format = ref->format;
261  src->format = src_fmt;
262  dst->format = dst_fmt;
263  dst->width = dst_w;
264  dst->height = dst_h;
265 
266  if (sws_scale_frame(sws[0], src, ref) < 0) {
267  fprintf(stderr, "Failed %s ---> %s\n", av_get_pix_fmt_name(ref->format),
268  av_get_pix_fmt_name(src->format));
269  goto error;
270  }
271 
272  sws[1]->flags = mode.flags;
273  sws[1]->dither = mode.dither;
274  sws[1]->threads = opts.threads;
275 
276  time = av_gettime_relative();
277 
278  for (int i = 0; i < opts.iters; i++) {
279  if (sws_scale_frame(sws[1], dst, src) < 0) {
280  fprintf(stderr, "Failed %s ---> %s\n", av_get_pix_fmt_name(src->format),
281  av_get_pix_fmt_name(dst->format));
282  goto error;
283  }
284  }
285 
286  time = av_gettime_relative() - time;
287 
288  if (sws_scale_frame(sws[2], out, dst) < 0) {
289  fprintf(stderr, "Failed %s ---> %s\n", av_get_pix_fmt_name(dst->format),
290  av_get_pix_fmt_name(out->format));
291  goto error;
292  }
293 
294  get_ssim(ssim, out, ref, comps);
295  printf("%s %dx%d -> %s %3dx%3d, flags=0x%x dither=%u, "
296  "SSIM {Y=%f U=%f V=%f A=%f}\n",
297  av_get_pix_fmt_name(src->format), src->width, src->height,
298  av_get_pix_fmt_name(dst->format), dst->width, dst->height,
300  ssim[0], ssim[1], ssim[2], ssim[3]);
301 
302  loss = get_loss(ssim);
303  if (loss - expected_loss > 1e-4 && dst_w >= ref->width && dst_h >= ref->height) {
304  int bad = loss - expected_loss > 1e-2;
305  printf("\033[1;31m loss %g is %s by %g, expected loss %g\033[0m\n",
306  loss, bad ? "WORSE" : "worse", loss - expected_loss, expected_loss);
307  if (bad)
308  goto error;
309  }
310 
311  if (!ssim_ref && sws_isSupportedInput(src->format) && sws_isSupportedOutput(dst->format)) {
312  /* Compare against the legacy swscale API as a reference */
313  time_ref = av_gettime_relative();
314  if (scale_legacy(dst, src, mode, opts) < 0) {
315  fprintf(stderr, "Failed ref %s ---> %s\n", av_get_pix_fmt_name(src->format),
316  av_get_pix_fmt_name(dst->format));
317  goto error;
318  }
319  time_ref = av_gettime_relative() - time_ref;
320 
321  if (sws_scale_frame(sws[2], out, dst) < 0)
322  goto error;
323 
324  get_ssim(ssim_sws, out, ref, comps);
325 
326  /* Legacy swscale does not perform bit accurate upconversions of low
327  * bit depth RGB. This artificially improves the SSIM score because the
328  * resulting error deletes some of the input dither noise. This gives
329  * it an unfair advantage when compared against a bit exact reference.
330  * Work around this by ensuring that the reference SSIM score is not
331  * higher than it theoretically "should" be. */
332  if (src_var > dst_var) {
333  const float src_loss = (2 * ref_var + c1) / (2 * ref_var + src_var + c1);
334  ssim_sws[0] = FFMIN(ssim_sws[0], src_loss);
335  }
336 
337  ssim_ref = ssim_sws;
338  }
339 
340  if (ssim_ref) {
341  const float loss_ref = get_loss(ssim_ref);
342  if (loss - loss_ref > 1e-4) {
343  int bad = loss - loss_ref > 1e-2;
344  printf("\033[1;31m loss %g is %s by %g, ref loss %g, "
345  "SSIM {Y=%f U=%f V=%f A=%f}\033[0m\n",
346  loss, bad ? "WORSE" : "worse", loss - loss_ref, loss_ref,
347  ssim_ref[0], ssim_ref[1], ssim_ref[2], ssim_ref[3]);
348  if (bad)
349  goto error;
350  }
351  }
352 
353  if (opts.bench && time_ref) {
354  double ratio = (double) time_ref / time;
355  if (FFMIN(time, time_ref) > 100 /* don't pollute stats with low precision */) {
356  speedup_min = FFMIN(speedup_min, ratio);
357  speedup_max = FFMAX(speedup_max, ratio);
358  speedup_logavg += log(ratio);
359  speedup_count++;
360  }
361 
362  printf(" time=%"PRId64" us, ref=%"PRId64" us, speedup=%.3fx %s%s\033[0m\n",
363  time / opts.iters, time_ref / opts.iters, ratio,
364  speedup_color(ratio), ratio >= 1.0 ? "faster" : "slower");
365  } else if (opts.bench) {
366  printf(" time=%"PRId64" us\n", time / opts.iters);
367  }
368 
369  fflush(stdout);
370  ret = 0; /* fall through */
371  error:
372  av_frame_free(&src);
373  av_frame_free(&dst);
374  av_frame_free(&out);
375  return ret;
376 }
377 
378 static inline int fmt_is_subsampled(enum AVPixelFormat fmt)
379 {
380  return av_pix_fmt_desc_get(fmt)->log2_chroma_w != 0 ||
382 }
383 
384 static int run_self_tests(const AVFrame *ref, struct options opts)
385 {
386  const int dst_w[] = { opts.w, opts.w - opts.w / 3, opts.w + opts.w / 3 };
387  const int dst_h[] = { opts.h, opts.h - opts.h / 3, opts.h + opts.h / 3 };
388 
389  enum AVPixelFormat src_fmt, dst_fmt,
390  src_fmt_min = 0,
391  dst_fmt_min = 0,
392  src_fmt_max = AV_PIX_FMT_NB - 1,
393  dst_fmt_max = AV_PIX_FMT_NB - 1;
394 
395  if (opts.src_fmt != AV_PIX_FMT_NONE)
396  src_fmt_min = src_fmt_max = opts.src_fmt;
397  if (opts.dst_fmt != AV_PIX_FMT_NONE)
398  dst_fmt_min = dst_fmt_max = opts.dst_fmt;
399 
400  for (src_fmt = src_fmt_min; src_fmt <= src_fmt_max; src_fmt++) {
401  if (opts.unscaled && fmt_is_subsampled(src_fmt))
402  continue;
403  if (!sws_test_format(src_fmt, 0) || !sws_test_format(src_fmt, 1))
404  continue;
405  for (dst_fmt = dst_fmt_min; dst_fmt <= dst_fmt_max; dst_fmt++) {
406  if (opts.unscaled && fmt_is_subsampled(dst_fmt))
407  continue;
408  if (!sws_test_format(dst_fmt, 0) || !sws_test_format(dst_fmt, 1))
409  continue;
410  for (int h = 0; h < FF_ARRAY_ELEMS(dst_h); h++) {
411  for (int w = 0; w < FF_ARRAY_ELEMS(dst_w); w++) {
412  for (int f = 0; f < FF_ARRAY_ELEMS(flags); f++) {
413  struct mode mode = {
414  .flags = opts.flags >= 0 ? opts.flags : flags[f],
415  .dither = opts.dither >= 0 ? opts.dither : SWS_DITHER_AUTO,
416  };
417 
418  if (ff_sfc64_get(&prng_state) > UINT64_MAX * opts.prob)
419  continue;
420 
421  if (run_test(src_fmt, dst_fmt, dst_w[w], dst_h[h],
422  mode, opts, ref, NULL) < 0)
423  return -1;
424 
425  if (opts.flags >= 0 || opts.unscaled)
426  break;
427  }
428  if (opts.unscaled)
429  break;
430  }
431  if (opts.unscaled)
432  break;
433  }
434  }
435  }
436 
437  return 0;
438 }
439 
440 static int run_file_tests(const AVFrame *ref, FILE *fp, struct options opts)
441 {
442  char buf[256];
443  int ret;
444 
445  while (fgets(buf, sizeof(buf), fp)) {
446  char src_fmt_str[21], dst_fmt_str[21];
447  enum AVPixelFormat src_fmt;
448  enum AVPixelFormat dst_fmt;
449  int sw, sh, dw, dh;
450  float ssim[4];
451  struct mode mode;
452 
453  ret = sscanf(buf,
454  "%20s %dx%d -> %20s %dx%d, flags=0x%x dither=%u, "
455  "SSIM {Y=%f U=%f V=%f A=%f}\n",
456  src_fmt_str, &sw, &sh, dst_fmt_str, &dw, &dh,
457  &mode.flags, &mode.dither,
458  &ssim[0], &ssim[1], &ssim[2], &ssim[3]);
459  if (ret != 12) {
460  printf("%s", buf);
461  continue;
462  }
463 
464  src_fmt = av_get_pix_fmt(src_fmt_str);
465  dst_fmt = av_get_pix_fmt(dst_fmt_str);
466  if (src_fmt == AV_PIX_FMT_NONE || dst_fmt == AV_PIX_FMT_NONE ||
467  sw != ref->width || sh != ref->height || dw > 8192 || dh > 8192 ||
469  fprintf(stderr, "malformed input file\n");
470  return -1;
471  }
472 
473  if (opts.src_fmt != AV_PIX_FMT_NONE && src_fmt != opts.src_fmt ||
474  opts.dst_fmt != AV_PIX_FMT_NONE && dst_fmt != opts.dst_fmt)
475  continue;
476 
477  if (run_test(src_fmt, dst_fmt, dw, dh, mode, opts, ref, ssim) < 0)
478  return -1;
479  }
480 
481  return 0;
482 }
483 
484 int main(int argc, char **argv)
485 {
486  struct options opts = {
487  .src_fmt = AV_PIX_FMT_NONE,
488  .dst_fmt = AV_PIX_FMT_NONE,
489  .w = 96,
490  .h = 96,
491  .threads = 1,
492  .iters = 1,
493  .prob = 1.0,
494  .flags = -1,
495  .dither = -1,
496  };
497 
498  AVFrame *rgb = NULL, *ref = NULL;
499  FILE *fp = NULL;
500  AVLFG rand;
501  int ret = -1;
502 
503  for (int i = 1; i < argc; i += 2) {
504  if (!strcmp(argv[i], "-help") || !strcmp(argv[i], "--help")) {
505  fprintf(stderr,
506  "swscale [options...]\n"
507  " -help\n"
508  " This text\n"
509  " -ref <file>\n"
510  " Uses file as reference to compare tests againsts. Tests that have become worse will contain the string worse or WORSE\n"
511  " -p <number between 0.0 and 1.0>\n"
512  " The percentage of tests or comparisons to perform. Doing all tests will take long and generate over a hundred MB text output\n"
513  " It is often convenient to perform a random subset\n"
514  " -dst <pixfmt>\n"
515  " Only test the specified destination pixel format\n"
516  " -src <pixfmt>\n"
517  " Only test the specified source pixel format\n"
518  " -bench <iters>\n"
519  " Run benchmarks with the specified number of iterations. This mode also increases the size of the test images\n"
520  " -flags <flags>\n"
521  " Test with a specific combination of flags\n"
522  " -dither <mode>\n"
523  " Test with a specific dither mode\n"
524  " -unscaled <1 or 0>\n"
525  " If 1, test only conversions that do not involve scaling\n"
526  " -threads <threads>\n"
527  " Use the specified number of threads\n"
528  " -cpuflags <cpuflags>\n"
529  " Uses the specified cpuflags in the tests\n"
530  " -v <level>\n"
531  " Enable log verbosity at given level\n"
532  );
533  return 0;
534  }
535  if (argv[i][0] != '-' || i + 1 == argc)
536  goto bad_option;
537  if (!strcmp(argv[i], "-ref")) {
538  fp = fopen(argv[i + 1], "r");
539  if (!fp) {
540  fprintf(stderr, "could not open '%s'\n", argv[i + 1]);
541  goto error;
542  }
543  } else if (!strcmp(argv[i], "-cpuflags")) {
544  unsigned flags = av_get_cpu_flags();
545  int res = av_parse_cpu_caps(&flags, argv[i + 1]);
546  if (res < 0) {
547  fprintf(stderr, "invalid cpu flags %s\n", argv[i + 1]);
548  goto error;
549  }
551  } else if (!strcmp(argv[i], "-src")) {
552  opts.src_fmt = av_get_pix_fmt(argv[i + 1]);
553  if (opts.src_fmt == AV_PIX_FMT_NONE) {
554  fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
555  goto error;
556  }
557  } else if (!strcmp(argv[i], "-dst")) {
558  opts.dst_fmt = av_get_pix_fmt(argv[i + 1]);
559  if (opts.dst_fmt == AV_PIX_FMT_NONE) {
560  fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
561  goto error;
562  }
563  } else if (!strcmp(argv[i], "-bench")) {
564  opts.bench = 1;
565  opts.iters = atoi(argv[i + 1]);
566  opts.iters = FFMAX(opts.iters, 1);
567  opts.w = 1920;
568  opts.h = 1080;
569  } else if (!strcmp(argv[i], "-flags")) {
570  opts.flags = strtol(argv[i + 1], NULL, 0);
571  } else if (!strcmp(argv[i], "-dither")) {
572  opts.dither = atoi(argv[i + 1]);
573  } else if (!strcmp(argv[i], "-unscaled")) {
574  opts.unscaled = atoi(argv[i + 1]);
575  } else if (!strcmp(argv[i], "-threads")) {
576  opts.threads = atoi(argv[i + 1]);
577  } else if (!strcmp(argv[i], "-p")) {
578  opts.prob = atof(argv[i + 1]);
579  } else if (!strcmp(argv[i], "-v")) {
580  av_log_set_level(atoi(argv[i + 1]));
581  } else {
582 bad_option:
583  fprintf(stderr, "bad option or argument missing (%s) see -help\n", argv[i]);
584  goto error;
585  }
586  }
587 
588  ff_sfc64_init(&prng_state, 0, 0, 0, 12);
589  av_lfg_init(&rand, 1);
590  signal(SIGINT, exit_handler);
591 
592  for (int i = 0; i < 3; i++) {
593  sws[i] = sws_alloc_context();
594  if (!sws[i])
595  goto error;
596  sws[i]->flags = SWS_BILINEAR;
597  }
598 
599  rgb = av_frame_alloc();
600  if (!rgb)
601  goto error;
602  rgb->width = opts.w / 12;
603  rgb->height = opts.h / 12;
604  rgb->format = AV_PIX_FMT_RGBA;
605  if (av_frame_get_buffer(rgb, 32) < 0)
606  goto error;
607 
608  for (int y = 0; y < rgb->height; y++) {
609  for (int x = 0; x < rgb->width; x++) {
610  for (int c = 0; c < 4; c++)
611  rgb->data[0][y * rgb->linesize[0] + x * 4 + c] = av_lfg_get(&rand);
612  }
613  }
614 
615  ref = av_frame_alloc();
616  if (!ref)
617  goto error;
618  ref->width = opts.w;
619  ref->height = opts.h;
620  ref->format = AV_PIX_FMT_YUVA444P;
621 
622  if (sws_scale_frame(sws[0], ref, rgb) < 0)
623  goto error;
624 
625  ret = fp ? run_file_tests(ref, fp, opts)
626  : run_self_tests(ref, opts);
627 
628  /* fall through */
629 error:
630  for (int i = 0; i < 3; i++)
632  av_frame_free(&rgb);
633  av_frame_free(&ref);
634  if (fp)
635  fclose(fp);
636  exit_handler(ret);
637 }
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
printf
__device__ int printf(const char *,...)
opt.h
scale_legacy
static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode, struct options opts)
Definition: swscale.c:195
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:378
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:104
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:440
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:384
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:227
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:87
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:91
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:183
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:474
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:57
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:135
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:484
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:126
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