FFmpeg
sw_ops.c
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2025 Niklas Haas
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include <string.h>
22 
23 #include "libavutil/avassert.h"
24 #include "libavutil/mem_internal.h"
25 #include "libavutil/refstruct.h"
26 
27 #include "libswscale/ops.h"
29 #include "libswscale/uops.h"
30 #include "libswscale/uops_macros.h"
31 
32 #include "checkasm.h"
33 
34 enum {
35  NB_PLANES = 4,
36  PIXELS = 64,
37  LINES = 16,
38 };
39 
40 enum {
45 };
46 
47 #define FMT(fmt, ...) tprintf((char[256]) {0}, 256, fmt, __VA_ARGS__)
48 static const char *tprintf(char buf[], size_t size, const char *fmt, ...)
49 {
50  va_list ap;
51  va_start(ap, fmt);
52  vsnprintf(buf, size, fmt, ap);
53  va_end(ap);
54  return buf;
55 }
56 
57 static int rw_pixel_bits(const SwsOp *op)
58 {
59  int elems = 0;
60  switch (op->rw.mode) {
61  case SWS_RW_PLANAR: elems = 1; break;
62  case SWS_RW_PACKED: elems = op->rw.elems; break;
63  }
64 
65  const int size = ff_sws_pixel_type_size(op->type);
66  const int bits = 8 >> op->rw.frac;
67  av_assert1(bits >= 1);
68  return elems * size * bits;
69 }
70 
71 static float rndf(void)
72 {
73  union { uint32_t u; float f; } x;
74  do {
75  x.u = rnd();
76  } while (!isnormal(x.f));
77  return x.f;
78 }
79 
80 static void fill32f(float *line, int num, unsigned range)
81 {
82  const float scale = (float) range / UINT32_MAX;
83  for (int i = 0; i < num; i++)
84  line[i] = range ? scale * rnd() : rndf();
85 }
86 
87 static void fill32(uint32_t *line, int num, unsigned range)
88 {
89  for (int i = 0; i < num; i++)
90  line[i] = (range && range < UINT_MAX) ? rnd() % (range + 1) : rnd();
91 }
92 
93 static void fill16(uint16_t *line, int num, unsigned range)
94 {
95  if (!range) {
96  fill32((uint32_t *) line, AV_CEIL_RSHIFT(num, 1), 0);
97  } else {
98  for (int i = 0; i < num; i++)
99  line[i] = rnd() % (range + 1);
100  }
101 }
102 
103 static void fill8(uint8_t *line, int num, unsigned range)
104 {
105  if (!range) {
106  fill32((uint32_t *) line, AV_CEIL_RSHIFT(num, 2), 0);
107  } else {
108  for (int i = 0; i < num; i++)
109  line[i] = rnd() % (range + 1);
110  }
111 }
112 
113 static void set_range(AVRational *rangeq, unsigned range, unsigned range_def)
114 {
115  if (!range)
116  range = range_def;
117  if (range && range <= INT_MAX)
118  *rangeq = (AVRational) { range, 1 };
119 }
120 
121 static void check_compiled(const char *name,
122  const SwsOp *read_op, const SwsOp *write_op,
123  const int ranges[NB_PLANES],
124  const SwsCompiledOp *comp_ref,
125  const SwsCompiledOp *comp_new)
126 {
127  /**
128  * We can't use `check_func()` alone because the actual function pointer
129  * may be a wrapper or entry point shared by multiple implementations.
130  * Solve it by hashing in the active CPU flags as well.
131  */
132  uintptr_t id = (uintptr_t) comp_new->func;
133  id ^= (id << 6) + (id >> 2) + 0x9e3779b97f4a7c15 + comp_new->cpu_flags;
134  if (!check_key(id, "%s", name))
135  return;
136 
137  declare_func(void, const SwsOpExec *, const void *, int bx, int y, int bx_end, int y_end);
138 
139  static DECLARE_ALIGNED_64(char, src0)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
140  static DECLARE_ALIGNED_64(char, src1)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
141  static DECLARE_ALIGNED_64(char, dst0)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
142  static DECLARE_ALIGNED_64(char, dst1)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
143 
144  av_assert0(PIXELS % comp_new->block_size == 0);
145  for (int p = 0; p < NB_PLANES; p++) {
146  void *plane = src0[p];
147  switch (read_op->type) {
148  case U8:
149  fill8(plane, sizeof(src0[p]) / sizeof(uint8_t), ranges[p]);
150  break;
151  case U16:
152  fill16(plane, sizeof(src0[p]) / sizeof(uint16_t), ranges[p]);
153  break;
154  case U32:
155  fill32(plane, sizeof(src0[p]) / sizeof(uint32_t), ranges[p]);
156  break;
157  case F32:
158  fill32f(plane, sizeof(src0[p]) / sizeof(uint32_t), ranges[p]);
159  break;
160  }
161  }
162 
163  memcpy(src1, src0, sizeof(src0));
164  memset(dst0, 0, sizeof(dst0));
165  memset(dst1, 0, sizeof(dst1));
166 
167  const int read_size = PIXELS * rw_pixel_bits(read_op) >> 3;
168  const int write_size = PIXELS * rw_pixel_bits(write_op) >> 3;
169 
170  SwsOpExec exec = {0};
171  exec.width = PIXELS;
172  exec.height = exec.slice_h = LINES;
173  for (int i = 0; i < NB_PLANES; i++) {
174  exec.in_stride[i] = sizeof(src0[i][0]);
175  exec.out_stride[i] = sizeof(dst0[i][0]);
176  exec.in_bump[i] = exec.in_stride[i] - read_size;
177  exec.out_bump[i] = exec.out_stride[i] - write_size;
178  }
179 
180  int32_t in_bump_y[LINES];
181  if (read_op->rw.filter.op == SWS_OP_FILTER_V) {
182  const int *offsets = read_op->rw.filter.kernel->offsets;
183  for (int y = 0; y < LINES - 1; y++)
184  in_bump_y[y] = offsets[y + 1] - offsets[y] - 1;
185  in_bump_y[LINES - 1] = 0;
186  exec.in_bump_y = in_bump_y;
187  }
188 
189  int32_t in_offset_x[PIXELS];
190  if (read_op->rw.filter.op == SWS_OP_FILTER_H) {
191  const int *offsets = read_op->rw.filter.kernel->offsets;
192  const int rw_bits = rw_pixel_bits(read_op);
193  for (int x = 0; x < PIXELS; x++)
194  in_offset_x[x] = offsets[x] * rw_bits >> 3;
195  exec.in_offset_x = in_offset_x;
196  }
197 
198  for (int i = 0; i < NB_PLANES; i++) {
199  exec.in[i] = (void *) src0[i];
200  exec.out[i] = (void *) dst0[i];
201  exec.block_size_in[i] = comp_ref->block_size * rw_pixel_bits(read_op) >> 3;
202  exec.block_size_out[i] = comp_ref->block_size * rw_pixel_bits(write_op) >> 3;
203  }
204  checkasm_call(comp_ref->func, &exec, comp_ref->priv, 0, 0, PIXELS / comp_ref->block_size, LINES);
205 
206  for (int i = 0; i < NB_PLANES; i++) {
207  exec.in[i] = (void *) src1[i];
208  exec.out[i] = (void *) dst1[i];
209  exec.block_size_in[i] = comp_new->block_size * rw_pixel_bits(read_op) >> 3;
210  exec.block_size_out[i] = comp_new->block_size * rw_pixel_bits(write_op) >> 3;
211  }
212  checkasm_call_checked(comp_new->func, &exec, comp_new->priv, 0, 0, PIXELS / comp_new->block_size, LINES);
213 
214  for (int i = 0; i < NB_PLANES; i++) {
215  const char *desc = FMT("%s[%d]", name, i);
216  const int stride = sizeof(dst0[i][0]);
217 
218  switch (write_op->type) {
219  case U8:
220  checkasm_check(uint8_t, (void *) dst0[i], stride,
221  (void *) dst1[i], stride,
222  write_size, LINES, desc);
223  break;
224  case U16:
225  checkasm_check(uint16_t, (void *) dst0[i], stride,
226  (void *) dst1[i], stride,
227  write_size >> 1, LINES, desc);
228  break;
229  case U32:
230  checkasm_check(uint32_t, (void *) dst0[i], stride,
231  (void *) dst1[i], stride,
232  write_size >> 2, LINES, desc);
233  break;
234  case F32:
235  checkasm_check(float_ulp, (void *) dst0[i], stride,
236  (void *) dst1[i], stride,
237  write_size >> 2, LINES, desc, 0);
238  break;
239  }
240 
241  if (write_op->rw.mode == SWS_RW_PACKED)
242  break;
243  }
244 
245  bench(comp_new->func, &exec, comp_new->priv, 0, 0, PIXELS / comp_new->block_size, LINES);
246 }
247 
248 static void check_ops(const char *name, const unsigned ranges[NB_PLANES],
249  const SwsOp *ops)
250 {
252  if (!ctx)
253  return;
255 
256  static const unsigned def_ranges[4] = {0};
257  if (!ranges)
258  ranges = def_ranges;
259 
260  const SwsOp *read_op, *write_op;
261  SwsOpList oplist = {
262  .ops = (SwsOp *) ops,
263  .plane_src = {0, 1, 2, 3},
264  .plane_dst = {0, 1, 2, 3},
265  };
266 
267  read_op = &ops[0];
268  for (oplist.num_ops = 0; ops[oplist.num_ops].op; oplist.num_ops++)
269  write_op = &ops[oplist.num_ops];
270 
271  for (int p = 0; p < NB_PLANES; p++) {
272  switch (read_op->type) {
273  case U8:
274  set_range(&oplist.comps_src.max[p], ranges[p], UINT8_MAX);
275  oplist.comps_src.min[p] = (AVRational) { 0, 1 };
276  break;
277  case U16:
278  set_range(&oplist.comps_src.max[p], ranges[p], UINT16_MAX);
279  oplist.comps_src.min[p] = (AVRational) { 0, 1 };
280  break;
281  case U32:
282  set_range(&oplist.comps_src.max[p], ranges[p], UINT32_MAX);
283  oplist.comps_src.min[p] = (AVRational) { 0, 1 };
284  break;
285  case F32:
286  if (ranges[p] && ranges[p] <= INT_MAX) {
287  oplist.comps_src.max[p] = (AVRational) { ranges[p], 1 };
288  oplist.comps_src.min[p] = (AVRational) { 0, 1 };
289  }
290  break;
291  }
292  }
293 
294  static const SwsOpBackend *backend_ref;
295  if (!backend_ref) {
296  for (int n = 0; ff_sws_op_backends[n]; n++) {
297  if (!strcmp(ff_sws_op_backends[n]->name, "c")) {
298  backend_ref = ff_sws_op_backends[n];
299  break;
300  }
301  }
302  av_assert0(backend_ref);
303  }
304 
305  /* Always compile `ops` using the C backend as a reference */
306  SwsCompiledOp comp_ref = {0};
307  int ret = ff_sws_ops_compile(ctx, backend_ref, &oplist, &comp_ref);
308  if (ret < 0) {
309  av_assert0(ret != AVERROR(ENOTSUP));
310  fail();
311  goto done;
312  }
313 
314  /* Check with the C backend to establish a reference */
315  check_compiled(name, read_op, write_op, ranges, &comp_ref, &comp_ref);
316 
317  /* Iterate over every other backend, and test it against the C reference */
318  for (int n = 0; ff_sws_op_backends[n]; n++) {
319  const SwsOpBackend *backend = ff_sws_op_backends[n];
320  if (backend->hw_format != AV_PIX_FMT_NONE || backend == backend_ref)
321  continue;
322 
323  SwsCompiledOp comp_new = {0};
324  int ret = ff_sws_ops_compile(ctx, backend, &oplist, &comp_new);
325  if (ret == AVERROR(ENOTSUP)) {
326  continue;
327  } else if (ret < 0) {
328  fail();
329  goto done;
330  }
331 
332  /* Distinguish backends from each other even with same CPU flags */
334  check_compiled(name, read_op, write_op, ranges, &comp_ref, &comp_new);
335  ff_sws_compiled_op_unref(&comp_new);
336  }
337 
338 done:
339  ff_sws_compiled_op_unref(&comp_ref);
341 }
342 
343 #define CHECK_RANGES(NAME, RANGES, N_IN, N_OUT, IN, OUT, ...) \
344  do { \
345  check_ops(NAME, RANGES, (SwsOp[]) { \
346  { \
347  .op = SWS_OP_READ, \
348  .type = IN, \
349  .rw.elems = N_IN, \
350  }, \
351  __VA_ARGS__, \
352  { \
353  .op = SWS_OP_WRITE, \
354  .type = OUT, \
355  .rw.elems = N_OUT, \
356  }, {0} \
357  }); \
358  } while (0)
359 
360 #define MK_RANGES(R) ((const unsigned[]) { R, R, R, R })
361 #define CHECK_RANGE(NAME, RANGE, N_IN, N_OUT, IN, OUT, ...) \
362  CHECK_RANGES(NAME, MK_RANGES(RANGE), N_IN, N_OUT, IN, OUT, __VA_ARGS__)
363 
364 #define CHECK(NAME, N_IN, N_OUT, IN, OUT, ...) \
365  CHECK_RANGE(NAME, 0, N_IN, N_OUT, IN, OUT, __VA_ARGS__)
366 
367 static inline int mask_num(const SwsCompMask mask)
368 {
369  switch (mask) {
370  case SWS_COMP_ELEMS(1): return 1;
371  case SWS_COMP_ELEMS(2): return 2;
372  case SWS_COMP_ELEMS(3): return 3;
373  case SWS_COMP_ELEMS(4): return 4;
374  default: return 0;
375  }
376 }
377 
378 #define CHECK_MASK(NAME, MASK, RANGES, IN, OUT, ...) \
379 do { \
380  const SwsCompMask mask = (MASK); \
381  const int num = mask_num(mask); \
382  if (!num) \
383  break; /* can't test these with current infrastructure */ \
384  CHECK_RANGES(NAME, RANGES, 4, num, IN, OUT, __VA_ARGS__); \
385 } while (0)
386 
388 {
389  const unsigned num = rnd();
390  if (ff_sws_pixel_type_is_int(t)) {
391  const int bits = ff_sws_pixel_type_size(t) * 8;
392  const unsigned mask = UINT_MAX >> (32 - bits);
393  return (AVRational) { num & mask, 1 };
394  } else {
395  const unsigned den = rnd();
396  return (AVRational) { num, den ? den : 1 };
397  }
398 }
399 
400 static void check_read(const char *name, const SwsUOp *uop)
401 {
403  switch (uop->uop) {
404  case SWS_UOP_READ_PACKED:
405  case SWS_UOP_READ_BIT:
406  case SWS_UOP_READ_NIBBLE: mode = SWS_RW_PACKED; break;
407  case SWS_UOP_READ_PLANAR: mode = SWS_RW_PLANAR; break;
408  default: return;
409  }
410 
411  const int num = mask_num(uop->mask);
412  check_ops(name, NULL, (SwsOp[]) {
413  {
414  .op = SWS_OP_READ,
415  .type = uop->type,
416  .rw.elems = num,
417  .rw.mode = mode,
418  .rw.frac = uop->uop == SWS_UOP_READ_BIT ? 3 :
419  uop->uop == SWS_UOP_READ_NIBBLE ? 1 : 0,
420  }, {
421  .op = SWS_OP_WRITE,
422  .type = uop->type,
423  .rw.elems = num,
424  }, {0}
425  });
426 }
427 
428 static void check_write(const char *name, const SwsUOp *uop)
429 {
431  switch (uop->uop) {
432  case SWS_UOP_WRITE_BIT:
434  case SWS_UOP_WRITE_PACKED: mode = SWS_RW_PACKED; break;
435  case SWS_UOP_WRITE_PLANAR: mode = SWS_RW_PLANAR; break;
436  default: return;
437  }
438 
439  const int frac = uop->uop == SWS_UOP_WRITE_BIT ? 3 :
440  uop->uop == SWS_UOP_WRITE_NIBBLE ? 1 : 0;
441  const int num = mask_num(uop->mask);
442  const int bits = 8 >> frac;
443  const unsigned range = (1 << bits) - 1;
444 
446  {
447  .op = SWS_OP_READ,
448  .type = uop->type,
449  .rw.elems = num,
450  }, {
451  .op = SWS_OP_WRITE,
452  .type = uop->type,
453  .rw.elems = num,
454  .rw.mode = mode,
455  .rw.frac = frac,
456  }, {0}
457  });
458 }
459 
460 static void check_filter(const char *name, const SwsUOp *uop)
461 {
462  const int num = mask_num(uop->mask);
463  const bool is_vert = uop->uop == SWS_UOP_READ_PLANAR_FV;
464 
465  SwsFilterParams par = {
467  .dst_size = is_vert ? LINES : PIXELS,
468  };
469 
470  const SwsScaler scalers[] = {
473  };
474 
475  for (int s = 0; s < FF_ARRAY_ELEMS(scalers); s++) {
476  par.scaler = scalers[s];
477 
478  for (par.src_size = 1; par.src_size <= par.dst_size; par.src_size <<= 1) {
480  if (ff_sws_filter_generate(NULL, &par, &filter) < 0) {
481  fail();
482  return;
483  }
484 
485  char desc[256];
486  snprintf(desc, sizeof(desc), "%s_%s_%d", name, filter->name, par.src_size);
487  check_ops(desc, NULL, (SwsOp[]) {
488  {
489  .op = SWS_OP_READ,
490  .type = uop->type,
491  .rw.elems = num,
492  .rw.filter = {
493  .op = is_vert ? SWS_OP_FILTER_V : SWS_OP_FILTER_H,
494  .kernel = filter,
495  .type = SWS_PIXEL_F32,
496  },
497  }, {
498  .op = SWS_OP_WRITE,
499  .type = SWS_PIXEL_F32,
500  .rw.elems = num,
501  }, {0}
502  });
503 
505  }
506  }
507 }
508 
509 static void check_cast(const char *name, const SwsUOp *uop)
510 {
512  switch (uop->uop) {
513  case SWS_UOP_TO_U8: dst = SWS_PIXEL_U8; break;
514  case SWS_UOP_TO_U16: dst = SWS_PIXEL_U16; break;
515  case SWS_UOP_TO_U32: dst = SWS_PIXEL_U32; break;
516  case SWS_UOP_TO_F32: dst = SWS_PIXEL_F32; break;
517  default: return;
518  }
519 
520  const int isize = ff_sws_pixel_type_size(uop->type);
521  const int osize = ff_sws_pixel_type_size(dst);
522  unsigned range = UINT32_MAX >> (32 - osize * 8);
523  if (isize < osize || !ff_sws_pixel_type_is_int(dst))
524  range = 0;
525 
526  CHECK_MASK(name, uop->mask, MK_RANGES(range), uop->type, dst, {
527  .op = SWS_OP_CONVERT,
528  .type = uop->type,
529  .convert.to = dst,
530  });
531 }
532 
533 static void check_expand_bit(const char *name, const SwsUOp *uop)
534 {
535  AVRational factor = { .den = 1 };
536  switch (uop->type) {
537  case SWS_PIXEL_U8: factor.num = UINT8_MAX; break;
538  case SWS_PIXEL_U16: factor.num = UINT16_MAX; break;
539  case SWS_PIXEL_U32: factor.num = UINT32_MAX; break;
540  default: return;
541  }
542 
543  CHECK_MASK(name, uop->mask, MK_RANGES(1), uop->type, uop->type, {
544  .op = SWS_OP_SCALE,
545  .type = uop->type,
546  .scale.factor = factor,
547  });
548 }
549 
550 static void check_expand(const char *name, const SwsUOp *uop)
551 {
553  switch (uop->uop) {
554  case SWS_UOP_EXPAND_PAIR: dst = SWS_PIXEL_U16; break;
555  case SWS_UOP_EXPAND_QUAD: dst = SWS_PIXEL_U32; break;
556  }
557 
558  av_assert0(uop->type == SWS_PIXEL_U8);
559  CHECK_MASK(name, uop->mask, NULL, uop->type, dst, {
560  .op = SWS_OP_CONVERT,
561  .type = uop->type,
562  .convert = {
563  .to = dst,
564  .expand = true,
565  },
566  });
567 }
568 
569 static void check_swizzle(const char *name, const SwsUOp *uop)
570 {
571  const SwsSwizzleUOp *swiz = &uop->par.swizzle;
572  CHECK_MASK(name, uop->mask, NULL, uop->type, uop->type, {
573  .op = SWS_OP_SWIZZLE,
574  .type = uop->type,
575  .swizzle.in = { swiz->in[0], swiz->in[1], swiz->in[2], swiz->in[3] },
576  });
577 }
578 
579 static void check_scale(const char *name, const SwsUOp *uop)
580 {
581  unsigned range = 0;
583 
584  if (ff_sws_pixel_type_is_int(uop->type)) {
585  /* Ensure the result won't exceed the value range */
586  const int bits = ff_sws_pixel_type_size(uop->type) * 8;
587  const unsigned max = UINT32_MAX >> (32 - bits);
588  scale = (AVRational) { rnd() & (max >> 1), 1 };
589  range = max / (scale.num ? scale.num : 1);
590  } else {
591  scale = rndq(uop->type);
592  }
593 
594  CHECK_MASK(name, uop->mask, MK_RANGES(range), uop->type, uop->type, {
595  .op = SWS_OP_SCALE,
596  .type = uop->type,
597  .scale.factor = scale,
598  });
599 }
600 
601 static void check_clamp(const char *name, const SwsUOp *uop)
602 {
603  const SwsPixelType t = uop->type;
604  CHECK_MASK(name, uop->mask, NULL, t, t, {
605  .op = uop->uop == SWS_UOP_MIN ? SWS_OP_MIN : SWS_OP_MAX,
606  .type = t,
607  .clamp.limit = { rndq(t), rndq(t), rndq(t), rndq(t) },
608  });
609 }
610 
611 static void check_swap_bytes(const char *name, const SwsUOp *uop)
612 {
613  CHECK_MASK(name, uop->mask, NULL, uop->type, uop->type, {
614  .op = SWS_OP_SWAP_BYTES,
615  .type = uop->type,
616  });
617 }
618 
619 static void check_unpack(const char *name, const SwsUOp *uop)
620 {
621  const uint8_t *pat = uop->par.pack.pattern;
622  const int num = pat[3] ? 4 : 3;
623  const int total = pat[0] + pat[1] + pat[2] + pat[3];
624  const unsigned range = UINT32_MAX >> (32 - total);
625 
626  CHECK_RANGE(name, range, 1, num, uop->type, uop->type, {
627  .op = SWS_OP_UNPACK,
628  .type = uop->type,
629  .pack.pattern = { pat[0], pat[1], pat[2], pat[3] },
630  });
631 }
632 
633 static void check_pack(const char *name, const SwsUOp *uop)
634 {
635  const uint8_t *pat = uop->par.pack.pattern;
636  const unsigned ranges[4] = {
637  (1 << pat[0]) - 1, (1 << pat[1]) - 1,
638  (1 << pat[2]) - 1, (1 << pat[3]) - 1,
639  };
640 
641  CHECK_RANGES(name, ranges, 4, 1, uop->type, uop->type, {
642  .op = SWS_OP_PACK,
643  .type = uop->type,
644  .pack.pattern = { pat[0], pat[1], pat[2], pat[3] },
645  });
646 }
647 
648 static void check_shift(const char *name, const SwsUOp *uop)
649 {
650  CHECK_MASK(name, uop->mask, NULL, uop->type, uop->type, {
651  .op = uop->uop == SWS_UOP_LSHIFT ? SWS_OP_LSHIFT : SWS_OP_RSHIFT,
652  .type = uop->type,
653  .shift.amount = uop->par.shift.amount,
654  });
655 }
656 
657 static void check_clear(const char *name, const SwsUOp *uop)
658 {
659  const SwsPixelType type = uop->type;
660  const int bits = ff_sws_pixel_type_size(type) * 8;
661  const unsigned range = UINT32_MAX >> (32 - bits);
662  const AVRational one = (AVRational) { (int) range, 1};
663  const AVRational zero = (AVRational) { 0, 1};
664  const AVRational val = { (rand() & 0x7F) | 1, 1 };
665 
666  SwsClearOp clear = { .mask = uop->mask };
667  for (int i = 0; i < 4; i++) {
668  if (SWS_COMP_TEST(uop->par.clear.one, i))
669  clear.value[i] = one;
670  else if (SWS_COMP_TEST(uop->par.clear.zero, i))
671  clear.value[i] = zero;
672  else
673  clear.value[i] = val;
674  }
675 
676  CHECK(name, 4, 4, type, type, {
677  .op = SWS_OP_CLEAR,
678  .type = type,
679  .clear = clear,
680  });
681 }
682 
683 static void check_linear(const char *name, const SwsUOp *uop)
684 {
685  const SwsPixelType type = uop->type;
687 
688  SwsLinearOp lin;
689  for (int i = 0; i < 4; i++) {
690  for (int j = 0; j < 5; j++) {
691  if (uop->par.lin.one & SWS_MASK(i, j))
692  lin.m[i][j] = (AVRational) { 1, 1 };
693  else if (uop->par.lin.zero & SWS_MASK(i, j))
694  lin.m[i][j] = (AVRational) { 0, 1 };
695  else
696  lin.m[i][j] = rndq(type);
697  }
698  }
699 
700  lin.mask = ff_sws_linear_mask(lin);
701  CHECK(name, 4, 4, type, type, {
702  .op = SWS_OP_LINEAR,
703  .type = type,
704  .lin = lin,
705  });
706 }
707 
708 static void check_dither(const char *name, const SwsUOp *uop)
709 {
710  const SwsPixelType type = uop->type;
712 
713  SwsDitherOp dither = { .size_log2 = uop->par.dither.size_log2 };
714  const int size = 1 << dither.size_log2;
715  const uint8_t *y_offset = uop->par.dither.y_offset;
716  for (int i = 0; i < 4; i++)
717  dither.y_offset[i] = SWS_COMP_TEST(uop->mask, i) ? y_offset[i] : -1;
718 
719  dither.matrix = av_refstruct_allocz(size * size * sizeof(*dither.matrix));
720  if (!dither.matrix) {
721  fail();
722  return;
723  }
724 
725  for (int i = 0; i < size * size; i++)
726  dither.matrix[i] = rndq(type);
727 
728  CHECK(name, 4, 4, type, type, {
729  .op = SWS_OP_DITHER,
730  .type = type,
731  .dither = dither,
732  });
733 
734  av_refstruct_unref(&dither.matrix);
735 }
736 
737 static void check_add(const char *name, const SwsUOp *uop)
738 {
739  /* SwsOp has no concept of SWS_OP_ADD; this is only used for
740  * SWS_OP_DITHER with a 1x1 dither matrix; so translate the uop */
741  check_dither(name, &(SwsUOp) {
742  .uop = SWS_UOP_DITHER,
743  .type = uop->type,
744  .mask = uop->mask,
745  .par.dither.size_log2 = 0,
746  });
747 }
748 
749 #define CHECK_FUNCTION(CHECK, NAME, ...) \
750  CHECK(#NAME, &(SwsUOp) { __VA_ARGS__ });
751 
752 #define CHECK_FOR(UOP, CHECK) \
753  SWS_FOR_STRUCT(U8, UOP, CHECK_FUNCTION, CHECK) \
754  SWS_FOR_STRUCT(U16, UOP, CHECK_FUNCTION, CHECK) \
755  SWS_FOR_STRUCT(U32, UOP, CHECK_FUNCTION, CHECK) \
756  SWS_FOR_STRUCT(F32, UOP, CHECK_FUNCTION, CHECK) \
757  report(#UOP)
758 
760 {
761  CHECK_FOR(READ_PLANAR, check_read);
762  CHECK_FOR(READ_PLANAR_FH, check_filter);
763  CHECK_FOR(READ_PLANAR_FV, check_filter);
764  CHECK_FOR(READ_PACKED, check_read);
765  CHECK_FOR(READ_NIBBLE, check_read);
766  CHECK_FOR(READ_BIT, check_read);
767  CHECK_FOR(WRITE_PLANAR, check_write);
768  CHECK_FOR(WRITE_PACKED, check_write);
769  CHECK_FOR(WRITE_NIBBLE, check_write);
770  CHECK_FOR(WRITE_BIT, check_write);
771  CHECK_FOR(PERMUTE, check_swizzle);
773  CHECK_FOR(EXPAND_BIT, check_expand_bit);
774  CHECK_FOR(EXPAND_PAIR, check_expand);
775  CHECK_FOR(EXPAND_QUAD, check_expand);
776  CHECK_FOR(SWAP_BYTES, check_swap_bytes);
777  CHECK_FOR(TO_U8, check_cast);
778  CHECK_FOR(TO_U16, check_cast);
779  CHECK_FOR(TO_U32, check_cast);
780  CHECK_FOR(TO_F32, check_cast);
785  CHECK_FOR(UNPACK, check_unpack);
786  CHECK_FOR(PACK, check_pack);
787  CHECK_FOR(LSHIFT, check_shift);
791  CHECK_FOR(DITHER, check_dither);
792 }
SWS_OP_READ
@ SWS_OP_READ
Definition: ops.h:38
factor
static const int factor[16]
Definition: vf_pp7.c:98
U8
@ U8
Definition: sw_ops.c:41
name
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 default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
mask_num
static int mask_num(const SwsCompMask mask)
Definition: sw_ops.c:367
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
SwsCompiledOp::func
SwsOpFunc func
Definition: ops_dispatch.h:103
MAX
#define MAX
Definition: blend_modes.c:46
SwsClearOp::value
AVRational value[4]
Definition: ops.h:157
SwsClearOp
Definition: ops.h:155
SWS_RW_PLANAR
@ SWS_RW_PLANAR
Note: 1-component reads are either SWS_RW_PLANAR or SWS_RW_PACKED, depending on the underlying interp...
Definition: ops.h:97
mem_internal.h
check_linear
static void check_linear(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:683
SwsFilterParams::src_size
int src_size
The relative sizes of the input and output images.
Definition: filters.h:57
SwsOpList::comps_src
SwsComps comps_src
Source component metadata associated with pixel values from each corresponding component (in plane/me...
Definition: ops.h:300
checkasm_get_cpu_suffix
static const char * checkasm_get_cpu_suffix(void)
Get the suffix for the current CPU flag, or "c" if none.
Definition: checkasm.h:326
SWS_PIXEL_NONE
@ SWS_PIXEL_NONE
Definition: uops.h:39
SwsOpExec::in_bump
ptrdiff_t in_bump[4]
Pointer bump, difference between stride and processed line size.
Definition: ops_dispatch.h:51
SWS_OP_CLEAR
@ SWS_OP_CLEAR
Definition: ops.h:50
SwsClearUOp::zero
SwsCompMask zero
Definition: uops.h:168
ff_sws_linear_mask
uint32_t ff_sws_linear_mask(const SwsLinearOp c)
Definition: ops.c:776
SwsOpExec::in
const uint8_t * in[4]
Definition: ops_dispatch.h:37
SwsOpExec::out_stride
ptrdiff_t out_stride[4]
Definition: ops_dispatch.h:42
checkasm_call_checked
#define checkasm_call_checked(func,...)
Definition: aarch64.h:93
SwsLinearOp::m
AVRational m[4][5]
Generalized 5x5 affine transformation: [ Out.x ] = [ A B C D E ] [ Out.y ] = [ F G H I J ] * [ x y z ...
Definition: ops.h:193
src1
const pixel * src1
Definition: h264pred_template.c:420
check_pack
static void check_pack(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:633
SwsSwizzleUOp
Definition: uops.h:148
mask
int mask
Definition: mediacodecdec_common.c:154
SwsOp::rw
SwsReadWriteOp rw
Definition: ops.h:231
mode
Definition: swscale.c:71
check_shift
static void check_shift(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:648
ops.h
u
#define u(width, name, range_min, range_max)
Definition: cbs_apv.c:68
SWS_OP_DITHER
@ SWS_OP_DITHER
Definition: ops.h:58
SwsFilterWeights
Represents a computed filter kernel.
Definition: filters.h:64
checkasm_check_sw_ops
void checkasm_check_sw_ops(void)
Definition: sw_ops.c:759
SWS_BITEXACT
@ SWS_BITEXACT
Definition: swscale.h:180
SwsOpExec::block_size_out
int32_t block_size_out[4]
Definition: ops_dispatch.h:58
check_unpack
static void check_unpack(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:619
SwsFilterWeights::offsets
int * offsets
The computed source pixel positions for each row of the filter.
Definition: filters.h:84
SwsCompiledOp::cpu_flags
int cpu_flags
Definition: ops_dispatch.h:119
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
max
#define max(a, b)
Definition: cuda_runtime.h:33
SwsFilterParams
Definition: filters.h:45
ops_dispatch.h
SwsOpExec::in_stride
ptrdiff_t in_stride[4]
Definition: ops_dispatch.h:41
SwsUOpParams::swizzle
SwsSwizzleUOp swizzle
Definition: uops.h:193
SwsLinearUOp::one
uint32_t one
Definition: uops.h:172
SwsOpBackend::name
const char * name
Definition: ops_dispatch.h:134
ff_sws_pixel_type_size
int ff_sws_pixel_type_size(SwsPixelType type)
Definition: ops.c:77
U32
@ U32
Definition: sw_ops.c:43
rndf
static float rndf(void)
Definition: sw_ops.c:71
ff_sws_filter_generate
int ff_sws_filter_generate(void *log, const SwsFilterParams *params, SwsFilterWeights **out)
Generate a filter kernel for the given parameters.
Definition: filters.c:187
DECLARE_ALIGNED_64
#define DECLARE_ALIGNED_64(t, v)
Definition: mem_internal.h:114
check_key
#define check_key
Definition: test.h:481
CHECK_RANGE
#define CHECK_RANGE(NAME, RANGE, N_IN, N_OUT, IN, OUT,...)
Definition: sw_ops.c:361
SwsComps::max
AVRational max[4]
Definition: ops.h:84
SwsClearOp::mask
SwsCompMask mask
Definition: ops.h:156
SWS_COMP_TEST
#define SWS_COMP_TEST(mask, X)
Definition: uops.h:71
ff_sws_op_backends
const SwsOpBackend *const ff_sws_op_backends[]
Definition: ops.c:45
SWS_UOP_TO_U16
@ SWS_UOP_TO_U16
Definition: uops.h:116
SwsOpList::num_ops
int num_ops
Definition: ops.h:283
SwsFilterParams::dst_size
int dst_size
Definition: filters.h:58
SwsDitherOp
Definition: ops.h:173
SwsUOpParams::pack
SwsPackUOp pack
Definition: uops.h:195
checkasm.h
check_dither
static void check_dither(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:708
ff_sws_pixel_type_is_int
bool ff_sws_pixel_type_is_int(SwsPixelType type)
Definition: ops.c:92
val
static double val(void *priv, double ch)
Definition: aeval.c:77
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
SwsOpExec::block_size_in
int32_t block_size_in[4]
Definition: ops_dispatch.h:57
SwsOpBackend::hw_format
enum AVPixelFormat hw_format
If NONE, backend only supports software frames.
Definition: ops_dispatch.h:150
SWS_COMP_ELEMS
#define SWS_COMP_ELEMS(N)
Definition: uops.h:73
refstruct.h
checkasm_call
#define checkasm_call(func,...)
Call a function with signal handling.
Definition: test.h:252
SwsLinearOp::mask
uint32_t mask
Definition: ops.h:194
av_refstruct_allocz
static void * av_refstruct_allocz(size_t size)
Equivalent to av_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition: refstruct.h:105
CHECK_FOR
#define CHECK_FOR(UOP, CHECK)
Definition: sw_ops.c:752
CHECK_MASK
#define CHECK_MASK(NAME, MASK, RANGES, IN, OUT,...)
Definition: sw_ops.c:378
SwsOp::op
SwsOpType op
Definition: ops.h:227
SWS_RW_PACKED
@ SWS_RW_PACKED
Definition: ops.h:98
avassert.h
checkasm_set_func_variant
CHECKASM_API CheckasmKey CHECKASM_API void checkasm_set_func_variant(const char *id,...) CHECKASM_PRINTF(1
Set a custom variant identifier for the next checkasm_check_func() call.
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
SWS_UOP_WRITE_NIBBLE
@ SWS_UOP_WRITE_NIBBLE
Definition: uops.h:102
uops_macros.h
float
float
Definition: af_crystalizer.c:122
dither
static const uint16_t dither[8][8]
Definition: vf_gradfun.c:46
s
#define s(width, name)
Definition: cbs_vp9.c:198
SwsUOp::uop
SwsUOpType uop
Definition: uops.h:204
offsets
static const int offsets[]
Definition: hevc_pel.c:34
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1465
SwsOpExec::in_bump_y
int32_t * in_bump_y
Line bump; determines how many additional lines to advance (after incrementing normally to the next l...
Definition: ops_dispatch.h:72
SwsComps::min
AVRational min[4]
Definition: ops.h:84
SWS_UOP_WRITE_PLANAR
@ SWS_UOP_WRITE_PLANAR
Definition: uops.h:100
op
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:76
SCALE
#define SCALE(c)
Definition: dcadata.c:7338
declare_func
#define declare_func
Definition: test.h:488
bits
uint8_t bits
Definition: vp3data.h:128
LINEAR
#define LINEAR
Definition: vf_perspective.c:36
SWS_UOP_TO_F32
@ SWS_UOP_TO_F32
Definition: uops.h:118
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
fill32
static void fill32(uint32_t *line, int num, unsigned range)
Definition: sw_ops.c:87
MK_RANGES
#define MK_RANGES(R)
Definition: sw_ops.c:360
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
bench
#define bench(...)
Definition: checkasm.h:142
SwsCompMask
uint8_t SwsCompMask
Bit-mask of components.
Definition: uops.h:61
FMT
#define FMT(fmt,...)
Definition: sw_ops.c:47
SWS_UOP_READ_PACKED
@ SWS_UOP_READ_PACKED
Definition: uops.h:96
SWS_OP_LINEAR
@ SWS_OP_LINEAR
Definition: ops.h:57
SWS_OP_FILTER_H
@ SWS_OP_FILTER_H
Definition: ops.h:61
COPY
#define COPY(src, name)
RSHIFT
#define RSHIFT(a, b)
Definition: common.h:56
SwsOpBackend
Definition: ops_dispatch.h:133
if
if(ret)
Definition: filter_design.txt:179
SwsOpExec::height
int32_t height
Definition: ops_dispatch.h:55
SwsOpExec
Copyright (C) 2026 Niklas Haas.
Definition: ops_dispatch.h:35
SwsReadWriteOp::kernel
SwsFilterWeights * kernel
Definition: ops.h:123
fill16
static void fill16(uint16_t *line, int num, unsigned range)
Definition: sw_ops.c:93
fail
#define fail
Definition: test.h:478
rw_pixel_bits
static int rw_pixel_bits(const SwsOp *op)
Definition: sw_ops.c:57
NULL
#define NULL
Definition: coverity.c:32
ADD
#define ADD(a, b)
Definition: dct32_template.c:123
tprintf
static const char * tprintf(char buf[], size_t size, const char *fmt,...)
Definition: sw_ops.c:48
ff_sws_compiled_op_unref
void ff_sws_compiled_op_unref(SwsCompiledOp *comp)
Definition: ops_dispatch.c:121
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
check_cast
static void check_cast(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:509
SwsClearUOp::one
SwsCompMask one
Definition: uops.h:167
U16
@ U16
Definition: sw_ops.c:42
check_swizzle
static void check_swizzle(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:569
SWS_OP_FILTER_V
@ SWS_OP_FILTER_V
Definition: ops.h:62
SwsScaler
SwsScaler
Definition: swscale.h:96
SWS_UOP_READ_NIBBLE
@ SWS_UOP_READ_NIBBLE
Definition: uops.h:97
SwsOpExec::slice_h
int32_t slice_h
Definition: ops_dispatch.h:56
check_scale
static void check_scale(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:579
SWS_MASK
#define SWS_MASK(I, J)
Definition: ops.h:197
check_write
static void check_write(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:428
SwsPixelType
SwsPixelType
Definition: uops.h:38
SwsUOp::par
SwsUOpParams par
Definition: uops.h:206
SWS_UOP_TO_U32
@ SWS_UOP_TO_U32
Definition: uops.h:117
SWS_SCALE_SINC
@ SWS_SCALE_SINC
unwindowed sinc
Definition: swscale.h:103
SWS_PARAM_DEFAULT
#define SWS_PARAM_DEFAULT
Definition: swscale.h:458
SwsUOp
Definition: uops.h:201
SWS_UOP_WRITE_BIT
@ SWS_UOP_WRITE_BIT
Definition: uops.h:103
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:1043
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
SwsOp::type
SwsPixelType type
Definition: ops.h:228
SwsLinearUOp::zero
uint32_t zero
Definition: uops.h:173
SwsUOp::mask
SwsCompMask mask
Definition: uops.h:205
SwsDitherUOp::size_log2
uint8_t size_log2
Definition: uops.h:181
size
int size
Definition: twinvq_data.h:10344
rnd
#define rnd
Definition: checkasm.h:140
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2594
SWS_OP_WRITE
@ SWS_OP_WRITE
Definition: ops.h:39
SWS_PIXEL_U32
@ SWS_PIXEL_U32
Definition: uops.h:42
line
Definition: graph2dot.c:48
F32
@ F32
Definition: sw_ops.c:44
SwsLinearOp
Definition: ops.h:180
zero
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:121
SwsReadWriteOp::op
SwsOpType op
Definition: ops.h:122
av_refstruct_unref
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
fill32f
static void fill32f(float *line, int num, unsigned range)
Definition: sw_ops.c:80
SwsOpExec::out
uint8_t * out[4]
Definition: ops_dispatch.h:38
SWS_SCALE_POINT
@ SWS_SCALE_POINT
nearest neighbor (point sampling)
Definition: swscale.h:100
check_clamp
static void check_clamp(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:601
SwsOpExec::in_offset_x
int32_t * in_offset_x
Pixel offset map; for horizontal scaling, in bytes.
Definition: ops_dispatch.h:80
SWS_UOP_TO_U8
@ SWS_UOP_TO_U8
Definition: uops.h:115
SWS_UOP_READ_PLANAR
@ SWS_UOP_READ_PLANAR
Definition: uops.h:92
SwsOpList::ops
SwsOp * ops
Definition: ops.h:282
vsnprintf
#define vsnprintf
Definition: snprintf.h:36
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:58
SWS_PIXEL_U8
@ SWS_PIXEL_U8
Definition: uops.h:40
check_expand
static void check_expand(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:550
MIN
#define MIN(a, b)
Definition: qt-faststart.c:45
check_expand_bit
static void check_expand_bit(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:533
SwsFilterParams::scaler_params
double scaler_params[SWS_NUM_SCALER_PARAMS]
Definition: filters.h:50
SwsReadWriteMode
SwsReadWriteMode
Definition: ops.h:87
SwsOp
Definition: ops.h:226
SwsOpExec::width
int32_t width
Definition: ops_dispatch.h:55
SwsUOpParams::lin
SwsLinearUOp lin
Definition: uops.h:197
SwsCompiledOp::priv
void * priv
Definition: ops_dispatch.h:127
SwsPackUOp::pattern
uint8_t pattern[4]
Definition: uops.h:163
SwsUOp::type
SwsPixelType type
Definition: uops.h:203
SwsCompiledOp::block_size
int block_size
Definition: ops_dispatch.h:122
ret
ret
Definition: filter_design.txt:187
SwsCompiledOp
Definition: ops_dispatch.h:100
SwsReadWriteOp::filter
struct SwsReadWriteOp::@571 filter
Filter kernel to apply to each plane while sampling.
check_compiled
static void check_compiled(const char *name, const SwsOp *read_op, const SwsOp *write_op, const int ranges[NB_PLANES], const SwsCompiledOp *comp_ref, const SwsCompiledOp *comp_new)
Definition: sw_ops.c:121
PIXELS
@ PIXELS
Definition: sw_ops.c:36
check_add
static void check_add(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:737
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
CLEAR
#define CLEAR(destin)
Definition: wavpackenc.c:50
SwsDitherUOp::y_offset
uint8_t y_offset[4]
Definition: uops.h:180
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
check_swap_bytes
static void check_swap_bytes(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:611
src0
const pixel *const src0
Definition: h264pred_template.c:419
check_clear
static void check_clear(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:657
SWS_UOP_DITHER
@ SWS_UOP_DITHER
Definition: uops.h:134
SWS_UOP_WRITE_PACKED
@ SWS_UOP_WRITE_PACKED
Definition: uops.h:101
rndq
static AVRational rndq(SwsPixelType t)
Definition: sw_ops.c:387
desc
const char * desc
Definition: libsvtav1.c:83
SwsUOpParams::dither
SwsDitherUOp dither
Definition: uops.h:198
SWS_PIXEL_F32
@ SWS_PIXEL_F32
Definition: uops.h:43
SWS_UOP_READ_PLANAR_FV
@ SWS_UOP_READ_PLANAR_FV
Definition: uops.h:94
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:278
uops.h
SWS_UOP_EXPAND_QUAD
@ SWS_UOP_EXPAND_QUAD
Definition: uops.h:114
NB_PLANES
@ NB_PLANES
Definition: sw_ops.c:35
check_read
static void check_read(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:400
fill8
static void fill8(uint8_t *line, int num, unsigned range)
Definition: sw_ops.c:103
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:2381
set_range
static void set_range(AVRational *rangeq, unsigned range, unsigned range_def)
Definition: sw_ops.c:113
int32_t
int32_t
Definition: audioconvert.c:56
check_ops
static void check_ops(const char *name, const unsigned ranges[NB_PLANES], const SwsOp *ops)
Definition: sw_ops.c:248
SWS_UOP_READ_BIT
@ SWS_UOP_READ_BIT
Definition: uops.h:98
stride
#define stride
Definition: h264pred_template.c:536
SwsReadWriteOp::mode
SwsReadWriteMode mode
Examples: rgba = 4x u8 packed yuv444p = 3x u8 rgb565 = 1x u16 <- use SWS_OP_UNPACK to unpack monow = ...
Definition: ops.h:110
SwsOpList
Helper struct for representing a list of operations.
Definition: ops.h:281
LINES
@ LINES
Definition: sw_ops.c:37
SwsContext
Main external API structure.
Definition: swscale.h:229
SWS_PIXEL_U16
@ SWS_PIXEL_U16
Definition: uops.h:41
CHECK
#define CHECK(NAME, N_IN, N_OUT, IN, OUT,...)
Definition: sw_ops.c:364
SwsFilterParams::scaler
SwsScaler scaler
The filter kernel and parameters to use.
Definition: filters.h:49
snprintf
#define snprintf
Definition: snprintf.h:34
SwsUOpParams::clear
SwsClearUOp clear
Definition: uops.h:196
CHECK_RANGES
#define CHECK_RANGES(NAME, RANGES, N_IN, N_OUT, IN, OUT,...)
Definition: sw_ops.c:343
SwsOpExec::out_bump
ptrdiff_t out_bump[4]
Definition: ops_dispatch.h:52
SWS_UOP_EXPAND_PAIR
@ SWS_UOP_EXPAND_PAIR
Definition: uops.h:113
check_filter
static void check_filter(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:460
ff_sws_ops_compile
int ff_sws_ops_compile(SwsContext *ctx, const SwsOpBackend *backend, const SwsOpList *ops, SwsCompiledOp *out)
Attempt to compile a list of operations using a specific backend, or the best available backend if ba...
Definition: ops_dispatch.c:99