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  if (op->rw.mode == SWS_RW_PALETTE)
60  return 8; /* index size */
61 
62  int elems = 0;
63  switch (op->rw.mode) {
64  case SWS_RW_PLANAR: elems = 1; break;
65  case SWS_RW_PACKED: elems = op->rw.elems; break;
66  }
67 
68  const int size = ff_sws_pixel_type_size(op->type);
69  const int bits = 8 >> op->rw.frac;
70  av_assert1(bits >= 1);
71  return elems * size * bits;
72 }
73 
74 static float rndf(void)
75 {
76  union { uint32_t u; float f; } x;
77  do {
78  x.u = rnd();
79  } while (!isnormal(x.f));
80  return x.f;
81 }
82 
83 static void fill32f(float *line, int num, unsigned range)
84 {
85  const float scale = (float) range / UINT32_MAX;
86  for (int i = 0; i < num; i++)
87  line[i] = range ? scale * rnd() : rndf();
88 }
89 
90 static void fill32(uint32_t *line, int num, unsigned range)
91 {
92  for (int i = 0; i < num; i++)
93  line[i] = (range && range < UINT_MAX) ? rnd() % (range + 1) : rnd();
94 }
95 
96 static void fill16(uint16_t *line, int num, unsigned range)
97 {
98  if (!range) {
99  fill32((uint32_t *) line, AV_CEIL_RSHIFT(num, 1), 0);
100  } else {
101  for (int i = 0; i < num; i++)
102  line[i] = rnd() % (range + 1);
103  }
104 }
105 
106 static void fill8(uint8_t *line, int num, unsigned range)
107 {
108  if (!range) {
109  fill32((uint32_t *) line, AV_CEIL_RSHIFT(num, 2), 0);
110  } else {
111  for (int i = 0; i < num; i++)
112  line[i] = rnd() % (range + 1);
113  }
114 }
115 
116 static void set_range(AVRational *rangeq, unsigned range, unsigned range_def)
117 {
118  if (!range)
119  range = range_def;
120  if (range && range <= INT_MAX)
121  *rangeq = (AVRational) { range, 1 };
122 }
123 
124 static void check_compiled(const char *name,
125  const SwsOp *read_op, const SwsOp *write_op,
126  const int ranges[NB_PLANES],
127  const SwsCompiledOp *comp_ref,
128  const SwsCompiledOp *comp_new)
129 {
130  /**
131  * We can't use `check_func()` alone because the actual function pointer
132  * may be a wrapper or entry point shared by multiple implementations.
133  * Solve it by hashing in the active CPU flags as well.
134  */
135  uintptr_t id = (uintptr_t) comp_new->func;
136  id ^= (id << 6) + (id >> 2) + 0x9e3779b97f4a7c15 + comp_new->cpu_flags;
137  if (!check_key(id, "%s", name))
138  return;
139 
140  declare_func(void, const SwsOpExec *, const void *, int bx, int y, int bx_end, int y_end);
141 
142  static DECLARE_ALIGNED_64(char, src0)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
143  static DECLARE_ALIGNED_64(char, src1)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
144  static DECLARE_ALIGNED_64(char, dst0)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
145  static DECLARE_ALIGNED_64(char, dst1)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])];
146 
147  av_assert0(PIXELS % comp_new->block_size == 0);
148  for (int p = 0; p < NB_PLANES; p++) {
149  void *plane = src0[p];
150  switch (read_op->type) {
151  case U8:
152  fill8(plane, sizeof(src0[p]) / sizeof(uint8_t), ranges[p]);
153  break;
154  case U16:
155  fill16(plane, sizeof(src0[p]) / sizeof(uint16_t), ranges[p]);
156  break;
157  case U32:
158  fill32(plane, sizeof(src0[p]) / sizeof(uint32_t), ranges[p]);
159  break;
160  case F32:
161  fill32f(plane, sizeof(src0[p]) / sizeof(uint32_t), ranges[p]);
162  break;
163  }
164  }
165 
166  memcpy(src1, src0, sizeof(src0));
167  memset(dst0, 0, sizeof(dst0));
168  memset(dst1, 0, sizeof(dst1));
169 
170  const int read_size = PIXELS * rw_pixel_bits(read_op) >> 3;
171  const int write_size = PIXELS * rw_pixel_bits(write_op) >> 3;
172 
173  SwsOpExec exec = {0};
174  exec.width = PIXELS;
175  exec.height = exec.slice_h = LINES;
176  for (int i = 0; i < NB_PLANES; i++) {
177  exec.in_stride[i] = sizeof(src0[i][0]);
178  exec.out_stride[i] = sizeof(dst0[i][0]);
179  exec.in_bump[i] = exec.in_stride[i] - read_size;
180  exec.out_bump[i] = exec.out_stride[i] - write_size;
181  }
182 
183  if (read_op->rw.mode == SWS_RW_PALETTE) {
184  static_assert(sizeof(src0[1]) >= sizeof(uint32_t[256]), "palette plane too small");
185  exec.in_bump[1] = exec.in_stride[1] = 0;
186  }
187 
188  int32_t in_bump_y[LINES];
189  if (read_op->rw.filter.op == SWS_OP_FILTER_V) {
190  const int *offsets = read_op->rw.filter.kernel->offsets;
191  for (int y = 0; y < LINES - 1; y++)
192  in_bump_y[y] = offsets[y + 1] - offsets[y] - 1;
193  in_bump_y[LINES - 1] = 0;
194  exec.in_bump_y = in_bump_y;
195  }
196 
197  int32_t in_offset_x[PIXELS];
198  if (read_op->rw.filter.op == SWS_OP_FILTER_H) {
199  const int *offsets = read_op->rw.filter.kernel->offsets;
200  const int rw_bits = rw_pixel_bits(read_op);
201  for (int x = 0; x < PIXELS; x++)
202  in_offset_x[x] = offsets[x] * rw_bits >> 3;
203  exec.in_offset_x = in_offset_x;
204  }
205 
206  for (int i = 0; i < NB_PLANES; i++) {
207  exec.in[i] = (void *) src0[i];
208  exec.out[i] = (void *) dst0[i];
209  exec.block_size_in[i] = comp_ref->block_size * rw_pixel_bits(read_op) >> 3;
210  exec.block_size_out[i] = comp_ref->block_size * rw_pixel_bits(write_op) >> 3;
211  }
212  checkasm_call(comp_ref->func, &exec, comp_ref->priv, 0, 0, PIXELS / comp_ref->block_size, LINES);
213 
214  for (int i = 0; i < NB_PLANES; i++) {
215  exec.in[i] = (void *) src1[i];
216  exec.out[i] = (void *) dst1[i];
217  exec.block_size_in[i] = comp_new->block_size * rw_pixel_bits(read_op) >> 3;
218  exec.block_size_out[i] = comp_new->block_size * rw_pixel_bits(write_op) >> 3;
219  }
220  checkasm_call_checked(comp_new->func, &exec, comp_new->priv, 0, 0, PIXELS / comp_new->block_size, LINES);
221 
222  for (int i = 0; i < NB_PLANES; i++) {
223  const char *desc = FMT("%s[%d]", name, i);
224  const int stride = sizeof(dst0[i][0]);
225 
226  switch (write_op->type) {
227  case U8:
228  checkasm_check(uint8_t, (void *) dst0[i], stride,
229  (void *) dst1[i], stride,
230  write_size, LINES, desc);
231  break;
232  case U16:
233  checkasm_check(uint16_t, (void *) dst0[i], stride,
234  (void *) dst1[i], stride,
235  write_size >> 1, LINES, desc);
236  break;
237  case U32:
238  checkasm_check(uint32_t, (void *) dst0[i], stride,
239  (void *) dst1[i], stride,
240  write_size >> 2, LINES, desc);
241  break;
242  case F32:
243  checkasm_check(float_ulp, (void *) dst0[i], stride,
244  (void *) dst1[i], stride,
245  write_size >> 2, LINES, desc, 0);
246  break;
247  }
248 
249  if (write_op->rw.mode == SWS_RW_PACKED)
250  break;
251  }
252 
253  bench(comp_new->func, &exec, comp_new->priv, 0, 0, PIXELS / comp_new->block_size, LINES);
254 }
255 
256 static void check_ops(const char *name, const unsigned ranges[NB_PLANES],
257  const SwsOp *ops)
258 {
260  if (!ctx)
261  return;
263 
264  static const unsigned def_ranges[4] = {0};
265  if (!ranges)
266  ranges = def_ranges;
267 
268  const SwsOp *read_op, *write_op;
269  SwsOpList oplist = {
270  .ops = (SwsOp *) ops,
271  .plane_src = {0, 1, 2, 3},
272  .plane_dst = {0, 1, 2, 3},
273  };
274 
275  read_op = &ops[0];
276  for (oplist.num_ops = 0; ops[oplist.num_ops].op; oplist.num_ops++)
277  write_op = &ops[oplist.num_ops];
278 
279  for (int p = 0; p < NB_PLANES; p++) {
280  switch (read_op->type) {
281  case U8:
282  set_range(&oplist.comps_src.max[p], ranges[p], UINT8_MAX);
283  oplist.comps_src.min[p] = (AVRational) { 0, 1 };
284  break;
285  case U16:
286  set_range(&oplist.comps_src.max[p], ranges[p], UINT16_MAX);
287  oplist.comps_src.min[p] = (AVRational) { 0, 1 };
288  break;
289  case U32:
290  set_range(&oplist.comps_src.max[p], ranges[p], UINT32_MAX);
291  oplist.comps_src.min[p] = (AVRational) { 0, 1 };
292  break;
293  case F32:
294  if (ranges[p] && ranges[p] <= INT_MAX) {
295  oplist.comps_src.max[p] = (AVRational) { ranges[p], 1 };
296  oplist.comps_src.min[p] = (AVRational) { 0, 1 };
297  }
298  break;
299  }
300  }
301 
302  static const SwsOpBackend *backend_ref;
303  if (!backend_ref) {
304  for (int n = 0; ff_sws_op_backends[n]; n++) {
305  if (!strcmp(ff_sws_op_backends[n]->name, "c")) {
306  backend_ref = ff_sws_op_backends[n];
307  break;
308  }
309  }
310  av_assert0(backend_ref);
311  }
312 
313  /* Always compile `ops` using the C backend as a reference */
314  SwsCompiledOp comp_ref = {0};
315  int ret = ff_sws_ops_compile(ctx, backend_ref, &oplist, &comp_ref);
316  if (ret < 0) {
317  av_assert0(ret != AVERROR(ENOTSUP));
318  fail();
319  goto done;
320  }
321 
322  /* Check with the C backend to establish a reference */
323  check_compiled(name, read_op, write_op, ranges, &comp_ref, &comp_ref);
324 
325  /* Iterate over every other backend, and test it against the C reference */
326  for (int n = 0; ff_sws_op_backends[n]; n++) {
327  const SwsOpBackend *backend = ff_sws_op_backends[n];
328  if (backend->hw_format != AV_PIX_FMT_NONE || backend == backend_ref)
329  continue;
330 
331  SwsCompiledOp comp_new = {0};
332  int ret = ff_sws_ops_compile(ctx, backend, &oplist, &comp_new);
333  if (ret == AVERROR(ENOTSUP)) {
334  continue;
335  } else if (ret < 0) {
336  fail();
337  goto done;
338  }
339 
340  /* Distinguish backends from each other even with same CPU flags */
342  check_compiled(name, read_op, write_op, ranges, &comp_ref, &comp_new);
343  ff_sws_compiled_op_unref(&comp_new);
344  }
345 
346 done:
347  ff_sws_compiled_op_unref(&comp_ref);
349 }
350 
351 #define CHECK_RANGES(NAME, RANGES, N_IN, N_OUT, IN, OUT, ...) \
352  do { \
353  check_ops(NAME, RANGES, (SwsOp[]) { \
354  { \
355  .op = SWS_OP_READ, \
356  .type = IN, \
357  .rw.elems = N_IN, \
358  }, \
359  __VA_ARGS__, \
360  { \
361  .op = SWS_OP_WRITE, \
362  .type = OUT, \
363  .rw.elems = N_OUT, \
364  }, {0} \
365  }); \
366  } while (0)
367 
368 #define MK_RANGES(R) ((const unsigned[]) { R, R, R, R })
369 #define CHECK_RANGE(NAME, RANGE, N_IN, N_OUT, IN, OUT, ...) \
370  CHECK_RANGES(NAME, MK_RANGES(RANGE), N_IN, N_OUT, IN, OUT, __VA_ARGS__)
371 
372 #define CHECK(NAME, N_IN, N_OUT, IN, OUT, ...) \
373  CHECK_RANGE(NAME, 0, N_IN, N_OUT, IN, OUT, __VA_ARGS__)
374 
375 static inline int mask_num(const SwsCompMask mask)
376 {
377  switch (mask) {
378  case SWS_COMP_ELEMS(1): return 1;
379  case SWS_COMP_ELEMS(2): return 2;
380  case SWS_COMP_ELEMS(3): return 3;
381  case SWS_COMP_ELEMS(4): return 4;
382  default: return 0;
383  }
384 }
385 
386 #define CHECK_MASK(NAME, MASK, RANGES, IN, OUT, ...) \
387 do { \
388  const SwsCompMask mask = (MASK); \
389  const int num = mask_num(mask); \
390  if (!num) \
391  break; /* can't test these with current infrastructure */ \
392  CHECK_RANGES(NAME, RANGES, 4, num, IN, OUT, __VA_ARGS__); \
393 } while (0)
394 
396 {
397  const unsigned num = rnd();
398  if (ff_sws_pixel_type_is_int(t)) {
399  const int bits = ff_sws_pixel_type_size(t) * 8;
400  const unsigned mask = UINT_MAX >> (32 - bits);
401  return (AVRational) { num & mask, 1 };
402  } else {
403  const unsigned den = rnd();
404  return (AVRational) { num, den ? den : 1 };
405  }
406 }
407 
408 static void check_read(const char *name, const SwsUOp *uop)
409 {
411  switch (uop->uop) {
412  case SWS_UOP_READ_PACKED:
413  case SWS_UOP_READ_BIT:
414  case SWS_UOP_READ_NIBBLE: mode = SWS_RW_PACKED; break;
415  case SWS_UOP_READ_PLANAR: mode = SWS_RW_PLANAR; break;
417  default: return;
418  }
419 
420  const int num = mask_num(uop->mask);
421  check_ops(name, NULL, (SwsOp[]) {
422  {
423  .op = SWS_OP_READ,
424  .type = uop->type,
425  .rw.elems = num,
426  .rw.mode = mode,
427  .rw.frac = uop->uop == SWS_UOP_READ_BIT ? 3 :
428  uop->uop == SWS_UOP_READ_NIBBLE ? 1 : 0,
429  }, {
430  .op = SWS_OP_WRITE,
431  .type = uop->type,
432  .rw.elems = num,
433  }, {0}
434  });
435 }
436 
437 static void check_write(const char *name, const SwsUOp *uop)
438 {
440  switch (uop->uop) {
441  case SWS_UOP_WRITE_BIT:
443  case SWS_UOP_WRITE_PACKED: mode = SWS_RW_PACKED; break;
444  case SWS_UOP_WRITE_PLANAR: mode = SWS_RW_PLANAR; break;
445  default: return;
446  }
447 
448  const int frac = uop->uop == SWS_UOP_WRITE_BIT ? 3 :
449  uop->uop == SWS_UOP_WRITE_NIBBLE ? 1 : 0;
450  const int num = mask_num(uop->mask);
451  const int bits = 8 >> frac;
452  const unsigned range = (1 << bits) - 1;
453 
455  {
456  .op = SWS_OP_READ,
457  .type = uop->type,
458  .rw.elems = num,
459  }, {
460  .op = SWS_OP_WRITE,
461  .type = uop->type,
462  .rw.elems = num,
463  .rw.mode = mode,
464  .rw.frac = frac,
465  }, {0}
466  });
467 }
468 
469 static void check_filter(const char *name, const SwsUOp *uop)
470 {
471  const int num = mask_num(uop->mask);
472  const bool is_vert = uop->uop == SWS_UOP_READ_PLANAR_FV;
473 
474  SwsFilterParams par = {
476  .dst_size = is_vert ? LINES : PIXELS,
477  };
478 
479  const SwsScaler scalers[] = {
482  };
483 
484  for (int s = 0; s < FF_ARRAY_ELEMS(scalers); s++) {
485  par.scaler = scalers[s];
486 
487  for (par.src_size = 1; par.src_size <= par.dst_size; par.src_size <<= 1) {
489  if (ff_sws_filter_generate(NULL, &par, &filter) < 0) {
490  fail();
491  return;
492  }
493 
494  char desc[256];
495  snprintf(desc, sizeof(desc), "%s_%s_%d", name, filter->name, par.src_size);
496  check_ops(desc, NULL, (SwsOp[]) {
497  {
498  .op = SWS_OP_READ,
499  .type = uop->type,
500  .rw.elems = num,
501  .rw.filter = {
502  .op = is_vert ? SWS_OP_FILTER_V : SWS_OP_FILTER_H,
503  .kernel = filter,
504  .type = SWS_PIXEL_F32,
505  },
506  }, {
507  .op = SWS_OP_WRITE,
508  .type = SWS_PIXEL_F32,
509  .rw.elems = num,
510  }, {0}
511  });
512 
514  }
515  }
516 }
517 
518 static void check_cast(const char *name, const SwsUOp *uop)
519 {
521  switch (uop->uop) {
522  case SWS_UOP_TO_U8: dst = SWS_PIXEL_U8; break;
523  case SWS_UOP_TO_U16: dst = SWS_PIXEL_U16; break;
524  case SWS_UOP_TO_U32: dst = SWS_PIXEL_U32; break;
525  case SWS_UOP_TO_F32: dst = SWS_PIXEL_F32; break;
526  default: return;
527  }
528 
529  const int isize = ff_sws_pixel_type_size(uop->type);
530  const int osize = ff_sws_pixel_type_size(dst);
531  unsigned range = UINT32_MAX >> (32 - osize * 8);
532  if (isize < osize || !ff_sws_pixel_type_is_int(dst))
533  range = 0;
534 
535  CHECK_MASK(name, uop->mask, MK_RANGES(range), uop->type, dst, {
536  .op = SWS_OP_CONVERT,
537  .type = uop->type,
538  .convert.to = dst,
539  });
540 }
541 
542 static void check_expand_bit(const char *name, const SwsUOp *uop)
543 {
544  AVRational factor = { .den = 1 };
545  switch (uop->type) {
546  case SWS_PIXEL_U8: factor.num = UINT8_MAX; break;
547  case SWS_PIXEL_U16: factor.num = UINT16_MAX; break;
548  case SWS_PIXEL_U32: factor.num = UINT32_MAX; break;
549  default: return;
550  }
551 
552  CHECK_MASK(name, uop->mask, MK_RANGES(1), uop->type, uop->type, {
553  .op = SWS_OP_SCALE,
554  .type = uop->type,
555  .scale.factor = factor,
556  });
557 }
558 
559 static void check_expand(const char *name, const SwsUOp *uop)
560 {
562  switch (uop->uop) {
563  case SWS_UOP_EXPAND_PAIR: dst = SWS_PIXEL_U16; break;
564  case SWS_UOP_EXPAND_QUAD: dst = SWS_PIXEL_U32; break;
565  }
566 
567  av_assert0(uop->type == SWS_PIXEL_U8);
568  CHECK_MASK(name, uop->mask, NULL, uop->type, dst, {
569  .op = SWS_OP_CONVERT,
570  .type = uop->type,
571  .convert = {
572  .to = dst,
573  .expand = true,
574  },
575  });
576 }
577 
578 static void check_swizzle(const char *name, const SwsUOp *uop)
579 {
580  const SwsSwizzleUOp *swiz = &uop->par.swizzle;
581  CHECK_MASK(name, uop->mask, NULL, uop->type, uop->type, {
582  .op = SWS_OP_SWIZZLE,
583  .type = uop->type,
584  .swizzle.in = { swiz->in[0], swiz->in[1], swiz->in[2], swiz->in[3] },
585  });
586 }
587 
588 static void check_scale(const char *name, const SwsUOp *uop)
589 {
590  unsigned range = 0;
592 
593  if (ff_sws_pixel_type_is_int(uop->type)) {
594  /* Ensure the result won't exceed the value range */
595  const int bits = ff_sws_pixel_type_size(uop->type) * 8;
596  const unsigned max = UINT32_MAX >> (32 - bits);
597  scale = (AVRational) { rnd() & (max >> 1), 1 };
598  range = max / (scale.num ? scale.num : 1);
599  } else {
600  scale = rndq(uop->type);
601  }
602 
603  CHECK_MASK(name, uop->mask, MK_RANGES(range), uop->type, uop->type, {
604  .op = SWS_OP_SCALE,
605  .type = uop->type,
606  .scale.factor = scale,
607  });
608 }
609 
610 static void check_clamp(const char *name, const SwsUOp *uop)
611 {
612  const SwsPixelType t = uop->type;
613  CHECK_MASK(name, uop->mask, NULL, t, t, {
614  .op = uop->uop == SWS_UOP_MIN ? SWS_OP_MIN : SWS_OP_MAX,
615  .type = t,
616  .clamp.limit = { rndq(t), rndq(t), rndq(t), rndq(t) },
617  });
618 }
619 
620 static void check_swap_bytes(const char *name, const SwsUOp *uop)
621 {
622  CHECK_MASK(name, uop->mask, NULL, uop->type, uop->type, {
623  .op = SWS_OP_SWAP_BYTES,
624  .type = uop->type,
625  });
626 }
627 
628 static void check_unpack(const char *name, const SwsUOp *uop)
629 {
630  const uint8_t *pat = uop->par.pack.pattern;
631  const int num = pat[3] ? 4 : 3;
632  const int total = pat[0] + pat[1] + pat[2] + pat[3];
633  const unsigned range = UINT32_MAX >> (32 - total);
634 
635  CHECK_RANGE(name, range, 1, num, uop->type, uop->type, {
636  .op = SWS_OP_UNPACK,
637  .type = uop->type,
638  .pack.pattern = { pat[0], pat[1], pat[2], pat[3] },
639  });
640 }
641 
642 static void check_pack(const char *name, const SwsUOp *uop)
643 {
644  const uint8_t *pat = uop->par.pack.pattern;
645  const unsigned ranges[4] = {
646  (1 << pat[0]) - 1, (1 << pat[1]) - 1,
647  (1 << pat[2]) - 1, (1 << pat[3]) - 1,
648  };
649 
650  CHECK_RANGES(name, ranges, 4, 1, uop->type, uop->type, {
651  .op = SWS_OP_PACK,
652  .type = uop->type,
653  .pack.pattern = { pat[0], pat[1], pat[2], pat[3] },
654  });
655 }
656 
657 static void check_shift(const char *name, const SwsUOp *uop)
658 {
659  CHECK_MASK(name, uop->mask, NULL, uop->type, uop->type, {
660  .op = uop->uop == SWS_UOP_LSHIFT ? SWS_OP_LSHIFT : SWS_OP_RSHIFT,
661  .type = uop->type,
662  .shift.amount = uop->par.shift.amount,
663  });
664 }
665 
666 static void check_clear(const char *name, const SwsUOp *uop)
667 {
668  const SwsPixelType type = uop->type;
669  const int bits = ff_sws_pixel_type_size(type) * 8;
670  const unsigned range = UINT32_MAX >> (32 - bits);
671  const AVRational one = (AVRational) { (int) range, 1};
672  const AVRational zero = (AVRational) { 0, 1};
673  const AVRational val = { (rand() & 0x7F) | 1, 1 };
674 
675  SwsClearOp clear = { .mask = uop->mask };
676  for (int i = 0; i < 4; i++) {
677  if (SWS_COMP_TEST(uop->par.clear.one, i))
678  clear.value[i] = one;
679  else if (SWS_COMP_TEST(uop->par.clear.zero, i))
680  clear.value[i] = zero;
681  else
682  clear.value[i] = val;
683  }
684 
685  CHECK(name, 4, 4, type, type, {
686  .op = SWS_OP_CLEAR,
687  .type = type,
688  .clear = clear,
689  });
690 }
691 
692 static void check_linear(const char *name, const SwsUOp *uop)
693 {
694  const SwsPixelType type = uop->type;
696 
697  SwsLinearOp lin;
698  for (int i = 0; i < 4; i++) {
699  for (int j = 0; j < 5; j++) {
700  if (uop->par.lin.one & SWS_MASK(i, j))
701  lin.m[i][j] = (AVRational) { 1, 1 };
702  else if (uop->par.lin.zero & SWS_MASK(i, j))
703  lin.m[i][j] = (AVRational) { 0, 1 };
704  else
705  lin.m[i][j] = rndq(type);
706  }
707  }
708 
709  lin.mask = ff_sws_linear_mask(&lin);
710  CHECK(name, 4, 4, type, type, {
711  .op = SWS_OP_LINEAR,
712  .type = type,
713  .lin = lin,
714  });
715 }
716 
717 static void check_dither(const char *name, const SwsUOp *uop)
718 {
719  const SwsPixelType type = uop->type;
721 
722  SwsDitherOp dither = { .size_log2 = uop->par.dither.size_log2 };
723  const int size = 1 << dither.size_log2;
724  const uint8_t *y_offset = uop->par.dither.y_offset;
725  for (int i = 0; i < 4; i++)
726  dither.y_offset[i] = SWS_COMP_TEST(uop->mask, i) ? y_offset[i] : -1;
727 
728  dither.matrix = av_refstruct_allocz(size * size * sizeof(*dither.matrix));
729  if (!dither.matrix) {
730  fail();
731  return;
732  }
733 
734  for (int i = 0; i < size * size; i++)
735  dither.matrix[i] = rndq(type);
736 
737  CHECK(name, 4, 4, type, type, {
738  .op = SWS_OP_DITHER,
739  .type = type,
740  .dither = dither,
741  });
742 
743  av_refstruct_unref(&dither.matrix);
744 }
745 
746 static void check_add(const char *name, const SwsUOp *uop)
747 {
748  /* SwsOp has no concept of SWS_OP_ADD; this is only used for
749  * SWS_OP_DITHER with a 1x1 dither matrix; so translate the uop */
750  check_dither(name, &(SwsUOp) {
751  .uop = SWS_UOP_DITHER,
752  .type = uop->type,
753  .mask = uop->mask,
754  .par.dither.size_log2 = 0,
755  });
756 }
757 
758 #define CHECK_FUNCTION(CHECK, NAME, ...) \
759  CHECK(#NAME, &(SwsUOp) { __VA_ARGS__ });
760 
761 #define CHECK_FOR(UOP, CHECK) \
762  SWS_FOR_STRUCT(U8, UOP, CHECK_FUNCTION, CHECK) \
763  SWS_FOR_STRUCT(U16, UOP, CHECK_FUNCTION, CHECK) \
764  SWS_FOR_STRUCT(U32, UOP, CHECK_FUNCTION, CHECK) \
765  SWS_FOR_STRUCT(F32, UOP, CHECK_FUNCTION, CHECK) \
766  report(#UOP)
767 
769 {
770  CHECK_FOR(READ_PLANAR, check_read);
771  CHECK_FOR(READ_PLANAR_FH, check_filter);
772  CHECK_FOR(READ_PLANAR_FV, check_filter);
773  CHECK_FOR(READ_PACKED, check_read);
774  CHECK_FOR(READ_NIBBLE, check_read);
775  CHECK_FOR(READ_BIT, check_read);
776  CHECK_FOR(READ_PALETTE, check_read);
777  CHECK_FOR(WRITE_PLANAR, check_write);
778  CHECK_FOR(WRITE_PACKED, check_write);
779  CHECK_FOR(WRITE_NIBBLE, check_write);
780  CHECK_FOR(WRITE_BIT, check_write);
781  CHECK_FOR(PERMUTE, check_swizzle);
783  CHECK_FOR(EXPAND_BIT, check_expand_bit);
784  CHECK_FOR(EXPAND_PAIR, check_expand);
785  CHECK_FOR(EXPAND_QUAD, check_expand);
786  CHECK_FOR(SWAP_BYTES, check_swap_bytes);
787  CHECK_FOR(TO_U8, check_cast);
788  CHECK_FOR(TO_U16, check_cast);
789  CHECK_FOR(TO_U32, check_cast);
790  CHECK_FOR(TO_F32, check_cast);
795  CHECK_FOR(UNPACK, check_unpack);
796  CHECK_FOR(PACK, check_pack);
797  CHECK_FOR(LSHIFT, check_shift);
801  CHECK_FOR(DITHER, check_dither);
802 }
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:375
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:159
SwsClearOp
Definition: ops.h:157
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:692
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:302
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:169
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:195
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:642
SwsSwizzleUOp
Definition: uops.h:149
mask
int mask
Definition: mediacodecdec_common.c:154
SwsOp::rw
SwsReadWriteOp rw
Definition: ops.h:233
mode
Definition: swscale.c:71
check_shift
static void check_shift(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:657
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:85
checkasm_check_sw_ops
void checkasm_check_sw_ops(void)
Definition: sw_ops.c:768
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:628
SwsFilterWeights::offsets
int * offsets
The computed source pixel positions for each row of the filter.
Definition: filters.h:105
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:194
SwsLinearUOp::one
uint32_t one
Definition: uops.h:173
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:74
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:369
SwsComps::max
AVRational max[4]
Definition: ops.h:84
SwsClearOp::mask
SwsCompMask mask
Definition: ops.h:158
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:117
SwsOpList::num_ops
int num_ops
Definition: ops.h:285
SwsFilterParams::dst_size
int dst_size
Definition: filters.h:58
SwsDitherOp
Definition: ops.h:175
SwsUOpParams::pack
SwsPackUOp pack
Definition: uops.h:196
checkasm.h
check_dither
static void check_dither(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:717
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:196
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:761
CHECK_MASK
#define CHECK_MASK(NAME, MASK, RANGES, IN, OUT,...)
Definition: sw_ops.c:386
SwsOp::op
SwsOpType op
Definition: ops.h:229
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:103
SWS_UOP_READ_PALETTE
@ SWS_UOP_READ_PALETTE
Definition: uops.h:99
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:205
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:101
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:119
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:90
MK_RANGES
#define MK_RANGES(R)
Definition: sw_ops.c:368
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:125
fill16
static void fill16(uint16_t *line, int num, unsigned range)
Definition: sw_ops.c:96
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:122
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:518
SwsClearUOp::one
SwsCompMask one
Definition: uops.h:168
U16
@ U16
Definition: sw_ops.c:42
check_swizzle
static void check_swizzle(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:578
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:588
SWS_MASK
#define SWS_MASK(I, J)
Definition: ops.h:199
check_write
static void check_write(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:437
SwsPixelType
SwsPixelType
Definition: uops.h:38
SwsUOp::par
SwsUOpParams par
Definition: uops.h:207
SWS_UOP_TO_U32
@ SWS_UOP_TO_U32
Definition: uops.h:118
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:202
SWS_UOP_WRITE_BIT
@ SWS_UOP_WRITE_BIT
Definition: uops.h:104
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:230
SwsLinearUOp::zero
uint32_t zero
Definition: uops.h:174
SwsUOp::mask
SwsCompMask mask
Definition: uops.h:206
SwsDitherUOp::size_log2
uint8_t size_log2
Definition: uops.h:182
ff_sws_linear_mask
uint32_t ff_sws_linear_mask(const SwsLinearOp *c)
Definition: ops.c:773
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:182
zero
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:121
SwsReadWriteOp::op
SwsOpType op
Definition: ops.h:124
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:83
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:610
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:116
SWS_UOP_READ_PLANAR
@ SWS_UOP_READ_PLANAR
Definition: uops.h:92
SwsOpList::ops
SwsOp * ops
Definition: ops.h:284
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:559
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:542
SwsFilterParams::scaler_params
double scaler_params[SWS_NUM_SCALER_PARAMS]
Definition: filters.h:50
SwsReadWriteMode
SwsReadWriteMode
Definition: ops.h:87
SwsOp
Definition: ops.h:228
SwsOpExec::width
int32_t width
Definition: ops_dispatch.h:55
SwsUOpParams::lin
SwsLinearUOp lin
Definition: uops.h:198
SwsCompiledOp::priv
void * priv
Definition: ops_dispatch.h:127
SwsPackUOp::pattern
uint8_t pattern[4]
Definition: uops.h:164
SwsUOp::type
SwsPixelType type
Definition: uops.h:204
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.
SWS_RW_PALETTE
@ SWS_RW_PALETTE
Definition: ops.h:99
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:124
PIXELS
@ PIXELS
Definition: sw_ops.c:36
check_add
static void check_add(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:746
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:181
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:620
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:666
SWS_UOP_DITHER
@ SWS_UOP_DITHER
Definition: uops.h:135
SWS_UOP_WRITE_PACKED
@ SWS_UOP_WRITE_PACKED
Definition: uops.h:102
rndq
static AVRational rndq(SwsPixelType t)
Definition: sw_ops.c:395
desc
const char * desc
Definition: libsvtav1.c:83
SwsUOpParams::dither
SwsDitherUOp dither
Definition: uops.h:199
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:115
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:408
fill8
static void fill8(uint8_t *line, int num, unsigned range)
Definition: sw_ops.c:106
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:116
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:256
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:112
SwsOpList
Helper struct for representing a list of operations.
Definition: ops.h:283
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:372
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:197
CHECK_RANGES
#define CHECK_RANGES(NAME, RANGES, N_IN, N_OUT, IN, OUT,...)
Definition: sw_ops.c:351
SwsOpExec::out_bump
ptrdiff_t out_bump[4]
Definition: ops_dispatch.h:52
SWS_UOP_EXPAND_PAIR
@ SWS_UOP_EXPAND_PAIR
Definition: uops.h:114
check_filter
static void check_filter(const char *name, const SwsUOp *uop)
Definition: sw_ops.c:469
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:100