FFmpeg
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
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/avstring.h"
23 #include "libavutil/bswap.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/rational.h"
26 #include "libavutil/refstruct.h"
27 
28 #include "ops.h"
29 #include "ops_internal.h"
30 
31 extern const SwsOpBackend backend_c;
32 extern const SwsOpBackend backend_murder;
33 extern const SwsOpBackend backend_x86;
34 extern const SwsOpBackend backend_vulkan;
35 
36 const SwsOpBackend * const ff_sws_op_backends[] = {
38 #if ARCH_X86_64 && HAVE_X86ASM
39  &backend_x86,
40 #endif
41  &backend_c,
42 #if CONFIG_VULKAN
44 #endif
45  NULL
46 };
47 
49 {
50  switch (type) {
51  case SWS_PIXEL_U8: return "u8";
52  case SWS_PIXEL_U16: return "u16";
53  case SWS_PIXEL_U32: return "u32";
54  case SWS_PIXEL_F32: return "f32";
55  case SWS_PIXEL_NONE: return "none";
56  case SWS_PIXEL_TYPE_NB: break;
57  }
58 
59  av_unreachable("Invalid pixel type!");
60  return "ERR";
61 }
62 
64 {
65  switch (type) {
66  case SWS_PIXEL_U8: return sizeof(uint8_t);
67  case SWS_PIXEL_U16: return sizeof(uint16_t);
68  case SWS_PIXEL_U32: return sizeof(uint32_t);
69  case SWS_PIXEL_F32: return sizeof(float);
70  case SWS_PIXEL_NONE: break;
71  case SWS_PIXEL_TYPE_NB: break;
72  }
73 
74  av_unreachable("Invalid pixel type!");
75  return 0;
76 }
77 
79 {
80  switch (type) {
81  case SWS_PIXEL_U8:
82  case SWS_PIXEL_U16:
83  case SWS_PIXEL_U32:
84  return true;
85  case SWS_PIXEL_F32:
86  return false;
87  case SWS_PIXEL_NONE:
88  case SWS_PIXEL_TYPE_NB: break;
89  }
90 
91  av_unreachable("Invalid pixel type!");
92  return false;
93 }
94 
95 /* biased towards `a` */
97 {
98  return av_cmp_q(a, b) == 1 ? b : a;
99 }
100 
102 {
103  return av_cmp_q(a, b) == -1 ? b : a;
104 }
105 
107 {
108  uint64_t mask[4];
109  int shift[4];
110 
111  switch (op->op) {
112  case SWS_OP_READ:
113  case SWS_OP_WRITE:
114  return;
115  case SWS_OP_UNPACK: {
118  unsigned val = x[0].num;
119  for (int i = 0; i < 4; i++)
120  x[i] = Q((val >> shift[i]) & mask[i]);
121  return;
122  }
123  case SWS_OP_PACK: {
126  unsigned val = 0;
127  for (int i = 0; i < 4; i++)
128  val |= (x[i].num & mask[i]) << shift[i];
129  x[0] = Q(val);
130  return;
131  }
132  case SWS_OP_SWAP_BYTES:
134  switch (ff_sws_pixel_type_size(op->type)) {
135  case 2:
136  for (int i = 0; i < 4; i++)
137  x[i].num = av_bswap16(x[i].num);
138  break;
139  case 4:
140  for (int i = 0; i < 4; i++)
141  x[i].num = av_bswap32(x[i].num);
142  break;
143  }
144  return;
145  case SWS_OP_CLEAR:
146  for (int i = 0; i < 4; i++) {
147  if (op->c.q4[i].den)
148  x[i] = op->c.q4[i];
149  }
150  return;
151  case SWS_OP_LSHIFT: {
153  AVRational mult = Q(1 << op->c.u);
154  for (int i = 0; i < 4; i++)
155  x[i] = x[i].den ? av_mul_q(x[i], mult) : x[i];
156  return;
157  }
158  case SWS_OP_RSHIFT: {
160  for (int i = 0; i < 4; i++)
161  x[i] = x[i].den ? Q((x[i].num / x[i].den) >> op->c.u) : x[i];
162  return;
163  }
164  case SWS_OP_SWIZZLE: {
165  const AVRational orig[4] = { x[0], x[1], x[2], x[3] };
166  for (int i = 0; i < 4; i++)
167  x[i] = orig[op->swizzle.in[i]];
168  return;
169  }
170  case SWS_OP_CONVERT:
171  if (ff_sws_pixel_type_is_int(op->convert.to)) {
172  const AVRational scale = ff_sws_pixel_expand(op->type, op->convert.to);
173  for (int i = 0; i < 4; i++) {
174  x[i] = x[i].den ? Q(x[i].num / x[i].den) : x[i];
175  if (op->convert.expand)
176  x[i] = av_mul_q(x[i], scale);
177  }
178  }
179  return;
180  case SWS_OP_DITHER:
182  for (int i = 0; i < 4; i++) {
183  if (op->dither.y_offset[i] >= 0 && x[i].den)
184  x[i] = av_add_q(x[i], av_make_q(1, 2));
185  }
186  return;
187  case SWS_OP_MIN:
188  for (int i = 0; i < 4; i++)
189  x[i] = av_min_q(x[i], op->c.q4[i]);
190  return;
191  case SWS_OP_MAX:
192  for (int i = 0; i < 4; i++)
193  x[i] = av_max_q(x[i], op->c.q4[i]);
194  return;
195  case SWS_OP_LINEAR: {
197  const AVRational orig[4] = { x[0], x[1], x[2], x[3] };
198  for (int i = 0; i < 4; i++) {
199  AVRational sum = op->lin.m[i][4];
200  for (int j = 0; j < 4; j++)
201  sum = av_add_q(sum, av_mul_q(orig[j], op->lin.m[i][j]));
202  x[i] = sum;
203  }
204  return;
205  }
206  case SWS_OP_SCALE:
207  for (int i = 0; i < 4; i++)
208  x[i] = x[i].den ? av_mul_q(x[i], op->c.q) : x[i];
209  return;
210  }
211 
212  av_unreachable("Invalid operation type!");
213 }
214 
215 /* merge_comp_flags() forms a monoid with flags_identity as the null element */
216 static const unsigned flags_identity = SWS_COMP_ZERO | SWS_COMP_EXACT;
217 static unsigned merge_comp_flags(unsigned a, unsigned b)
218 {
219  const unsigned flags_or = SWS_COMP_GARBAGE;
220  const unsigned flags_and = SWS_COMP_ZERO | SWS_COMP_EXACT;
221  return ((a & b) & flags_and) | ((a | b) & flags_or);
222 }
223 
224 /* Linearly propagate flags per component */
225 static void propagate_flags(SwsOp *op, const SwsComps *prev)
226 {
227  for (int i = 0; i < 4; i++)
228  op->comps.flags[i] = prev->flags[i];
229 }
230 
231 /* Clear undefined values in dst with src */
233 {
234  for (int i = 0; i < 4; i++) {
235  if (dst[i].den == 0)
236  dst[i] = src[i];
237  }
238 }
239 
240 /* Infer + propagate known information about components */
242 {
243  SwsComps next = { .unused = {true, true, true, true} };
244  SwsComps prev = { .flags = {
246  }};
247 
248  /* Forwards pass, propagates knowledge about the incoming pixel values */
249  for (int n = 0; n < ops->num_ops; n++) {
250  SwsOp *op = &ops->ops[n];
251 
252  switch (op->op) {
253  case SWS_OP_READ:
254  case SWS_OP_LINEAR:
255  case SWS_OP_SWAP_BYTES:
256  case SWS_OP_UNPACK:
257  break; /* special cases, handled below */
258  default:
259  memcpy(op->comps.min, prev.min, sizeof(prev.min));
260  memcpy(op->comps.max, prev.max, sizeof(prev.max));
261  ff_sws_apply_op_q(op, op->comps.min);
262  ff_sws_apply_op_q(op, op->comps.max);
263  break;
264  }
265 
266  switch (op->op) {
267  case SWS_OP_READ:
268  /* Active components are taken from the user-provided values,
269  * other components are explicitly stripped */
270  for (int i = 0; i < op->rw.elems; i++) {
271  const int idx = op->rw.packed ? i : ops->order_src.in[i];
272  op->comps.flags[i] = ops->comps_src.flags[idx];
273  op->comps.min[i] = ops->comps_src.min[idx];
274  op->comps.max[i] = ops->comps_src.max[idx];
275  }
276  for (int i = op->rw.elems; i < 4; i++) {
277  op->comps.flags[i] = prev.flags[i];
278  op->comps.min[i] = prev.min[i];
279  op->comps.max[i] = prev.max[i];
280  }
281  break;
282  case SWS_OP_SWAP_BYTES:
283  for (int i = 0; i < 4; i++) {
284  op->comps.flags[i] = prev.flags[i] ^ SWS_COMP_SWAPPED;
285  op->comps.min[i] = prev.min[i];
286  op->comps.max[i] = prev.max[i];
287  }
288  break;
289  case SWS_OP_WRITE:
290  for (int i = 0; i < op->rw.elems; i++)
291  av_assert1(!(prev.flags[i] & SWS_COMP_GARBAGE));
292  /* fall through */
293  case SWS_OP_LSHIFT:
294  case SWS_OP_RSHIFT:
295  propagate_flags(op, &prev);
296  break;
297  case SWS_OP_MIN:
298  propagate_flags(op, &prev);
299  clear_undefined_values(op->comps.max, op->c.q4);
300  break;
301  case SWS_OP_MAX:
302  propagate_flags(op, &prev);
303  clear_undefined_values(op->comps.min, op->c.q4);
304  break;
305  case SWS_OP_DITHER:
306  /* Strip zero flag because of the nonzero dithering offset */
307  for (int i = 0; i < 4; i++)
308  op->comps.flags[i] = prev.flags[i] & ~SWS_COMP_ZERO;
309  break;
310  case SWS_OP_UNPACK:
311  for (int i = 0; i < 4; i++) {
312  const int pattern = op->pack.pattern[i];
313  if (pattern) {
314  av_assert1(pattern < 32);
315  op->comps.flags[i] = prev.flags[0];
316  op->comps.min[i] = Q(0);
317  op->comps.max[i] = Q((1ULL << pattern) - 1);
318  } else
319  op->comps.flags[i] = SWS_COMP_GARBAGE;
320  }
321  break;
322  case SWS_OP_PACK: {
323  unsigned flags = flags_identity;
324  for (int i = 0; i < 4; i++) {
325  if (op->pack.pattern[i])
326  flags = merge_comp_flags(flags, prev.flags[i]);
327  if (i > 0) /* clear remaining comps for sanity */
328  op->comps.flags[i] = SWS_COMP_GARBAGE;
329  }
330  op->comps.flags[0] = flags;
331  break;
332  }
333  case SWS_OP_CLEAR:
334  for (int i = 0; i < 4; i++) {
335  if (op->c.q4[i].den) {
336  op->comps.flags[i] = 0;
337  if (op->c.q4[i].num == 0)
338  op->comps.flags[i] |= SWS_COMP_ZERO;
339  if (op->c.q4[i].den == 1)
340  op->comps.flags[i] |= SWS_COMP_EXACT;
341  } else {
342  op->comps.flags[i] = prev.flags[i];
343  }
344  }
345  break;
346  case SWS_OP_SWIZZLE:
347  for (int i = 0; i < 4; i++)
348  op->comps.flags[i] = prev.flags[op->swizzle.in[i]];
349  break;
350  case SWS_OP_CONVERT:
351  for (int i = 0; i < 4; i++) {
352  op->comps.flags[i] = prev.flags[i];
353  if (ff_sws_pixel_type_is_int(op->convert.to))
354  op->comps.flags[i] |= SWS_COMP_EXACT;
355  }
356  break;
357  case SWS_OP_LINEAR:
358  for (int i = 0; i < 4; i++) {
359  unsigned flags = flags_identity;
360  AVRational min = Q(0), max = Q(0);
361  for (int j = 0; j < 4; j++) {
362  const AVRational k = op->lin.m[i][j];
363  AVRational mink = av_mul_q(prev.min[j], k);
364  AVRational maxk = av_mul_q(prev.max[j], k);
365  if (k.num) {
366  flags = merge_comp_flags(flags, prev.flags[j]);
367  if (k.den != 1) /* fractional coefficient */
368  flags &= ~SWS_COMP_EXACT;
369  if (k.num < 0)
370  FFSWAP(AVRational, mink, maxk);
371  min = av_add_q(min, mink);
372  max = av_add_q(max, maxk);
373  }
374  }
375  if (op->lin.m[i][4].num) { /* nonzero offset */
376  flags &= ~SWS_COMP_ZERO;
377  if (op->lin.m[i][4].den != 1) /* fractional offset */
378  flags &= ~SWS_COMP_EXACT;
379  min = av_add_q(min, op->lin.m[i][4]);
380  max = av_add_q(max, op->lin.m[i][4]);
381  }
382  op->comps.flags[i] = flags;
383  op->comps.min[i] = min;
384  op->comps.max[i] = max;
385  }
386  break;
387  case SWS_OP_SCALE:
388  for (int i = 0; i < 4; i++) {
389  op->comps.flags[i] = prev.flags[i];
390  if (op->c.q.den != 1) /* fractional scale */
391  op->comps.flags[i] &= ~SWS_COMP_EXACT;
392  if (op->c.q.num < 0)
393  FFSWAP(AVRational, op->comps.min[i], op->comps.max[i]);
394  }
395  break;
396 
397  case SWS_OP_INVALID:
398  case SWS_OP_TYPE_NB:
399  av_unreachable("Invalid operation type!");
400  }
401 
402  prev = op->comps;
403  }
404 
405  /* Backwards pass, solves for component dependencies */
406  for (int n = ops->num_ops - 1; n >= 0; n--) {
407  SwsOp *op = &ops->ops[n];
408 
409  switch (op->op) {
410  case SWS_OP_READ:
411  case SWS_OP_WRITE:
412  for (int i = 0; i < op->rw.elems; i++)
413  op->comps.unused[i] = op->op == SWS_OP_READ;
414  for (int i = op->rw.elems; i < 4; i++)
415  op->comps.unused[i] = next.unused[i];
416  break;
417  case SWS_OP_SWAP_BYTES:
418  case SWS_OP_LSHIFT:
419  case SWS_OP_RSHIFT:
420  case SWS_OP_CONVERT:
421  case SWS_OP_DITHER:
422  case SWS_OP_MIN:
423  case SWS_OP_MAX:
424  case SWS_OP_SCALE:
425  for (int i = 0; i < 4; i++)
426  op->comps.unused[i] = next.unused[i];
427  break;
428  case SWS_OP_UNPACK: {
429  bool unused = true;
430  for (int i = 0; i < 4; i++) {
431  if (op->pack.pattern[i])
432  unused &= next.unused[i];
433  op->comps.unused[i] = i > 0;
434  }
435  op->comps.unused[0] = unused;
436  break;
437  }
438  case SWS_OP_PACK:
439  for (int i = 0; i < 4; i++) {
440  if (op->pack.pattern[i])
441  op->comps.unused[i] = next.unused[0];
442  else
443  op->comps.unused[i] = true;
444  }
445  break;
446  case SWS_OP_CLEAR:
447  for (int i = 0; i < 4; i++) {
448  if (op->c.q4[i].den)
449  op->comps.unused[i] = true;
450  else
451  op->comps.unused[i] = next.unused[i];
452  }
453  break;
454  case SWS_OP_SWIZZLE: {
455  bool unused[4] = { true, true, true, true };
456  for (int i = 0; i < 4; i++)
457  unused[op->swizzle.in[i]] &= next.unused[i];
458  for (int i = 0; i < 4; i++)
459  op->comps.unused[i] = unused[i];
460  break;
461  }
462  case SWS_OP_LINEAR:
463  for (int j = 0; j < 4; j++) {
464  bool unused = true;
465  for (int i = 0; i < 4; i++) {
466  if (op->lin.m[i][j].num)
467  unused &= next.unused[i];
468  }
469  op->comps.unused[j] = unused;
470  }
471  break;
472  }
473 
474  next = op->comps;
475  }
476 }
477 
478 static void op_uninit(SwsOp *op)
479 {
480  switch (op->op) {
481  case SWS_OP_DITHER:
482  av_refstruct_unref(&op->dither.matrix);
483  break;
484  }
485 
486  *op = (SwsOp) {0};
487 }
488 
490 {
491  SwsOpList *ops = av_mallocz(sizeof(SwsOpList));
492  if (!ops)
493  return NULL;
494 
495  ops->order_src = ops->order_dst = SWS_SWIZZLE(0, 1, 2, 3);
496  ff_fmt_clear(&ops->src);
497  ff_fmt_clear(&ops->dst);
498  return ops;
499 }
500 
502 {
503  SwsOpList *ops = *p_ops;
504  if (!ops)
505  return;
506 
507  for (int i = 0; i < ops->num_ops; i++)
508  op_uninit(&ops->ops[i]);
509 
510  av_freep(&ops->ops);
511  av_free(ops);
512  *p_ops = NULL;
513 }
514 
516 {
517  SwsOpList *copy = av_malloc(sizeof(*copy));
518  if (!copy)
519  return NULL;
520 
521  int num = ops->num_ops;
522  if (num)
523  num = 1 << av_ceil_log2(num);
524 
525  *copy = *ops;
526  copy->ops = av_memdup(ops->ops, num * sizeof(ops->ops[0]));
527  if (!copy->ops) {
528  av_free(copy);
529  return NULL;
530  }
531 
532  for (int i = 0; i < ops->num_ops; i++) {
533  const SwsOp *op = &ops->ops[i];
534  switch (op->op) {
535  case SWS_OP_DITHER:
536  av_refstruct_ref(copy->ops[i].dither.matrix);
537  break;
538  }
539  }
540 
541  return copy;
542 }
543 
545 {
546  if (!ops->num_ops)
547  return NULL;
548 
549  const SwsOp *read = &ops->ops[0];
550  return read->op == SWS_OP_READ ? read : NULL;
551 }
552 
554 {
555  if (!ops->num_ops)
556  return NULL;
557 
558  const SwsOp *write = &ops->ops[ops->num_ops - 1];
559  return write->op == SWS_OP_WRITE ? write : NULL;
560 }
561 
562 void ff_sws_op_list_remove_at(SwsOpList *ops, int index, int count)
563 {
564  const int end = ops->num_ops - count;
565  av_assert2(index >= 0 && count >= 0 && index + count <= ops->num_ops);
566  op_uninit(&ops->ops[index]);
567  for (int i = index; i < end; i++)
568  ops->ops[i] = ops->ops[i + count];
569  ops->num_ops = end;
570 }
571 
573 {
574  void *ret = av_dynarray2_add((void **) &ops->ops, &ops->num_ops, sizeof(*op), NULL);
575  if (!ret) {
576  op_uninit(op);
577  return AVERROR(ENOMEM);
578  }
579 
580  for (int i = ops->num_ops - 1; i > index; i--)
581  ops->ops[i] = ops->ops[i - 1];
582  ops->ops[index] = *op;
583  return 0;
584 }
585 
587 {
588  return ff_sws_op_list_insert_at(ops, ops->num_ops, op);
589 }
590 
592 {
593  if (!ops->num_ops)
594  return true;
595 
596  const SwsOp *read = ff_sws_op_list_input(ops);
597  const SwsOp *write = ff_sws_op_list_output(ops);
598  if (!read || !write || ops->num_ops > 2 ||
599  read->type != write->type ||
600  read->rw.packed != write->rw.packed ||
601  read->rw.elems != write->rw.elems ||
602  read->rw.frac != write->rw.frac)
603  return false;
604 
605  /**
606  * Note that this check is unlikely to ever be hit in practice, since it
607  * would imply the existence of planar formats with different plane orders
608  * between them, e.g. rgbap <-> gbrap, which doesn't currently exist.
609  * However, the check is cheap and lets me sleep at night.
610  */
611  const int num_planes = read->rw.packed ? 1 : read->rw.elems;
612  for (int i = 0; i < num_planes; i++) {
613  if (ops->order_src.in[i] != ops->order_dst.in[i])
614  return false;
615  }
616 
617  return true;
618 }
619 
621 {
622  int max_size = 0;
623  for (int i = 0; i < ops->num_ops; i++) {
624  const int size = ff_sws_pixel_type_size(ops->ops[i].type);
625  max_size = FFMAX(max_size, size);
626  }
627 
628  return max_size;
629 }
630 
632 {
633  uint32_t mask = 0;
634  for (int i = 0; i < 4; i++) {
635  for (int j = 0; j < 5; j++) {
636  if (av_cmp_q(c.m[i][j], Q(i == j)))
637  mask |= SWS_MASK(i, j);
638  }
639  }
640  return mask;
641 }
642 
643 static const char *describe_lin_mask(uint32_t mask)
644 {
645  /* Try to be fairly descriptive without assuming too much */
646  static const struct {
647  char name[24];
648  uint32_t mask;
649  } patterns[] = {
650  { "noop", 0 },
651  { "luma", SWS_MASK_LUMA },
652  { "alpha", SWS_MASK_ALPHA },
653  { "luma+alpha", SWS_MASK_LUMA | SWS_MASK_ALPHA },
654  { "dot3", 0x7 },
655  { "dot4", 0xF },
656  { "row0", SWS_MASK_ROW(0) },
657  { "row0+alpha", SWS_MASK_ROW(0) | SWS_MASK_ALPHA },
658  { "col0", SWS_MASK_COL(0) },
659  { "col0+off3", SWS_MASK_COL(0) | SWS_MASK_OFF3 },
660  { "off3", SWS_MASK_OFF3 },
661  { "off3+alpha", SWS_MASK_OFF3 | SWS_MASK_ALPHA },
662  { "diag3", SWS_MASK_DIAG3 },
663  { "diag4", SWS_MASK_DIAG4 },
664  { "diag3+alpha", SWS_MASK_DIAG3 | SWS_MASK_ALPHA },
665  { "diag3+off3", SWS_MASK_DIAG3 | SWS_MASK_OFF3 },
666  { "diag3+off3+alpha", SWS_MASK_DIAG3 | SWS_MASK_OFF3 | SWS_MASK_ALPHA },
667  { "diag4+off4", SWS_MASK_DIAG4 | SWS_MASK_OFF4 },
668  { "matrix3", SWS_MASK_MAT3 },
669  { "matrix3+off3", SWS_MASK_MAT3 | SWS_MASK_OFF3 },
670  { "matrix3+off3+alpha", SWS_MASK_MAT3 | SWS_MASK_OFF3 | SWS_MASK_ALPHA },
671  { "matrix4", SWS_MASK_MAT4 },
672  { "matrix4+off4", SWS_MASK_MAT4 | SWS_MASK_OFF4 },
673  };
674 
675  for (int i = 0; i < FF_ARRAY_ELEMS(patterns); i++) {
676  if (!(mask & ~patterns[i].mask))
677  return patterns[i].name;
678  }
679 
680  av_unreachable("Invalid linear mask!");
681  return "ERR";
682 }
683 
684 static char describe_comp_flags(unsigned flags)
685 {
686  if (flags & SWS_COMP_GARBAGE)
687  return 'X';
688  else if (flags & SWS_COMP_ZERO)
689  return '0';
690  else if (flags & SWS_COMP_SWAPPED)
691  return 'z';
692  else if (flags & SWS_COMP_EXACT)
693  return '+';
694  else
695  return '.';
696 }
697 
698 static const char *describe_order(SwsSwizzleOp order, int planes, char buf[32])
699 {
700  if (order.mask == SWS_SWIZZLE(0, 1, 2, 3).mask)
701  return "";
702 
703  av_strlcpy(buf, ", via {", 32);
704  for (int i = 0; i < planes; i++)
705  av_strlcatf(buf, 32, "%s%d", i ? ", " : "", order.in[i]);
706  av_strlcat(buf, "}", 32);
707  return buf;
708 }
709 
710 static const char *print_q(const AVRational q, char buf[], int buf_len)
711 {
712  if (!q.den) {
713  return q.num > 0 ? "inf" : q.num < 0 ? "-inf" : "nan";
714  } else if (q.den == 1) {
715  snprintf(buf, buf_len, "%d", q.num);
716  return buf;
717  } else if (abs(q.num) > 1000 || abs(q.den) > 1000) {
718  snprintf(buf, buf_len, "%f", av_q2d(q));
719  return buf;
720  } else {
721  snprintf(buf, buf_len, "%d/%d", q.num, q.den);
722  return buf;
723  }
724 }
725 
726 #define PRINTQ(q) print_q(q, (char[32]){0}, sizeof(char[32]))
727 
728 void ff_sws_op_list_print(void *log, int lev, int lev_extra,
729  const SwsOpList *ops)
730 {
731  if (!ops->num_ops) {
732  av_log(log, lev, " (empty)\n");
733  return;
734  }
735 
736  for (int i = 0; i < ops->num_ops; i++) {
737  const SwsOp *op = &ops->ops[i];
738  const SwsOp *next = i + 1 < ops->num_ops ? &ops->ops[i + 1] : op;
739  char buf[32];
740 
741  av_log(log, lev, " [%3s %c%c%c%c -> %c%c%c%c] ",
742  ff_sws_pixel_type_name(op->type),
743  op->comps.unused[0] ? 'X' : '.',
744  op->comps.unused[1] ? 'X' : '.',
745  op->comps.unused[2] ? 'X' : '.',
746  op->comps.unused[3] ? 'X' : '.',
747  next->comps.unused[0] ? 'X' : describe_comp_flags(op->comps.flags[0]),
748  next->comps.unused[1] ? 'X' : describe_comp_flags(op->comps.flags[1]),
749  next->comps.unused[2] ? 'X' : describe_comp_flags(op->comps.flags[2]),
750  next->comps.unused[3] ? 'X' : describe_comp_flags(op->comps.flags[3]));
751 
752  switch (op->op) {
753  case SWS_OP_INVALID:
754  av_log(log, lev, "SWS_OP_INVALID\n");
755  break;
756  case SWS_OP_READ:
757  case SWS_OP_WRITE:
758  av_log(log, lev, "%-20s: %d elem(s) %s >> %d%s\n",
759  op->op == SWS_OP_READ ? "SWS_OP_READ"
760  : "SWS_OP_WRITE",
761  op->rw.elems, op->rw.packed ? "packed" : "planar",
762  op->rw.frac,
763  describe_order(op->op == SWS_OP_READ ? ops->order_src
764  : ops->order_dst,
765  op->rw.packed ? 1 : op->rw.elems, buf));
766  break;
767  case SWS_OP_SWAP_BYTES:
768  av_log(log, lev, "SWS_OP_SWAP_BYTES\n");
769  break;
770  case SWS_OP_LSHIFT:
771  av_log(log, lev, "%-20s: << %u\n", "SWS_OP_LSHIFT", op->c.u);
772  break;
773  case SWS_OP_RSHIFT:
774  av_log(log, lev, "%-20s: >> %u\n", "SWS_OP_RSHIFT", op->c.u);
775  break;
776  case SWS_OP_PACK:
777  case SWS_OP_UNPACK:
778  av_log(log, lev, "%-20s: {%d %d %d %d}\n",
779  op->op == SWS_OP_PACK ? "SWS_OP_PACK"
780  : "SWS_OP_UNPACK",
781  op->pack.pattern[0], op->pack.pattern[1],
782  op->pack.pattern[2], op->pack.pattern[3]);
783  break;
784  case SWS_OP_CLEAR:
785  av_log(log, lev, "%-20s: {%s %s %s %s}\n", "SWS_OP_CLEAR",
786  op->c.q4[0].den ? PRINTQ(op->c.q4[0]) : "_",
787  op->c.q4[1].den ? PRINTQ(op->c.q4[1]) : "_",
788  op->c.q4[2].den ? PRINTQ(op->c.q4[2]) : "_",
789  op->c.q4[3].den ? PRINTQ(op->c.q4[3]) : "_");
790  break;
791  case SWS_OP_SWIZZLE:
792  av_log(log, lev, "%-20s: %d%d%d%d\n", "SWS_OP_SWIZZLE",
793  op->swizzle.x, op->swizzle.y, op->swizzle.z, op->swizzle.w);
794  break;
795  case SWS_OP_CONVERT:
796  av_log(log, lev, "%-20s: %s -> %s%s\n", "SWS_OP_CONVERT",
797  ff_sws_pixel_type_name(op->type),
798  ff_sws_pixel_type_name(op->convert.to),
799  op->convert.expand ? " (expand)" : "");
800  break;
801  case SWS_OP_DITHER:
802  av_log(log, lev, "%-20s: %dx%d matrix + {%d %d %d %d}\n", "SWS_OP_DITHER",
803  1 << op->dither.size_log2, 1 << op->dither.size_log2,
804  op->dither.y_offset[0], op->dither.y_offset[1],
805  op->dither.y_offset[2], op->dither.y_offset[3]);
806  break;
807  case SWS_OP_MIN:
808  av_log(log, lev, "%-20s: x <= {%s %s %s %s}\n", "SWS_OP_MIN",
809  op->c.q4[0].den ? PRINTQ(op->c.q4[0]) : "_",
810  op->c.q4[1].den ? PRINTQ(op->c.q4[1]) : "_",
811  op->c.q4[2].den ? PRINTQ(op->c.q4[2]) : "_",
812  op->c.q4[3].den ? PRINTQ(op->c.q4[3]) : "_");
813  break;
814  case SWS_OP_MAX:
815  av_log(log, lev, "%-20s: {%s %s %s %s} <= x\n", "SWS_OP_MAX",
816  op->c.q4[0].den ? PRINTQ(op->c.q4[0]) : "_",
817  op->c.q4[1].den ? PRINTQ(op->c.q4[1]) : "_",
818  op->c.q4[2].den ? PRINTQ(op->c.q4[2]) : "_",
819  op->c.q4[3].den ? PRINTQ(op->c.q4[3]) : "_");
820  break;
821  case SWS_OP_LINEAR:
822  av_log(log, lev, "%-20s: %s [[%s %s %s %s %s] "
823  "[%s %s %s %s %s] "
824  "[%s %s %s %s %s] "
825  "[%s %s %s %s %s]]\n",
826  "SWS_OP_LINEAR", describe_lin_mask(op->lin.mask),
827  PRINTQ(op->lin.m[0][0]), PRINTQ(op->lin.m[0][1]), PRINTQ(op->lin.m[0][2]), PRINTQ(op->lin.m[0][3]), PRINTQ(op->lin.m[0][4]),
828  PRINTQ(op->lin.m[1][0]), PRINTQ(op->lin.m[1][1]), PRINTQ(op->lin.m[1][2]), PRINTQ(op->lin.m[1][3]), PRINTQ(op->lin.m[1][4]),
829  PRINTQ(op->lin.m[2][0]), PRINTQ(op->lin.m[2][1]), PRINTQ(op->lin.m[2][2]), PRINTQ(op->lin.m[2][3]), PRINTQ(op->lin.m[2][4]),
830  PRINTQ(op->lin.m[3][0]), PRINTQ(op->lin.m[3][1]), PRINTQ(op->lin.m[3][2]), PRINTQ(op->lin.m[3][3]), PRINTQ(op->lin.m[3][4]));
831  break;
832  case SWS_OP_SCALE:
833  av_log(log, lev, "%-20s: * %s\n", "SWS_OP_SCALE",
834  PRINTQ(op->c.q));
835  break;
836  case SWS_OP_TYPE_NB:
837  break;
838  }
839 
840  if (op->comps.min[0].den || op->comps.min[1].den ||
841  op->comps.min[2].den || op->comps.min[3].den ||
842  op->comps.max[0].den || op->comps.max[1].den ||
843  op->comps.max[2].den || op->comps.max[3].den)
844  {
845  av_log(log, lev_extra, " min: {%s, %s, %s, %s}, max: {%s, %s, %s, %s}\n",
846  next->comps.unused[0] ? "_" : PRINTQ(op->comps.min[0]),
847  next->comps.unused[1] ? "_" : PRINTQ(op->comps.min[1]),
848  next->comps.unused[2] ? "_" : PRINTQ(op->comps.min[2]),
849  next->comps.unused[3] ? "_" : PRINTQ(op->comps.min[3]),
850  next->comps.unused[0] ? "_" : PRINTQ(op->comps.max[0]),
851  next->comps.unused[1] ? "_" : PRINTQ(op->comps.max[1]),
852  next->comps.unused[2] ? "_" : PRINTQ(op->comps.max[2]),
853  next->comps.unused[3] ? "_" : PRINTQ(op->comps.max[3]));
854  }
855 
856  }
857 
858  av_log(log, lev, " (X = unused, z = byteswapped, + = exact, 0 = zero)\n");
859 }
SWS_OP_READ
@ SWS_OP_READ
Definition: ops.h:47
flags
const SwsFlags flags[]
Definition: swscale.c:61
SWS_PIXEL_U16
@ SWS_PIXEL_U16
Definition: ops.h:33
ff_sws_op_list_free
void ff_sws_op_list_free(SwsOpList **p_ops)
Definition: ops.c:501
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
SwsComps::flags
unsigned flags[4]
Definition: ops.h:90
SWS_OP_SWIZZLE
@ SWS_OP_SWIZZLE
Definition: ops.h:50
ff_sws_op_list_alloc
SwsOpList * ff_sws_op_list_alloc(void)
Definition: ops.c:489
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
SWS_OP_LSHIFT
@ SWS_OP_LSHIFT
Definition: ops.h:55
SWS_OP_UNPACK
@ SWS_OP_UNPACK
Definition: ops.h:53
ff_sws_op_list_duplicate
SwsOpList * ff_sws_op_list_duplicate(const SwsOpList *ops)
Returns a duplicate of ops, or NULL on OOM.
Definition: ops.c:515
SwsSwizzleOp::mask
uint32_t mask
Definition: ops.h:126
av_min_q
static AVRational av_min_q(AVRational a, AVRational b)
Definition: ops.c:96
SwsOpList::comps_src
SwsComps comps_src
Source component metadata associated with pixel values from each corresponding component (in plane/me...
Definition: ops.h:241
ff_sws_op_list_input
const SwsOp * ff_sws_op_list_input(const SwsOpList *ops)
Returns the input operation for a given op list, or NULL if there is none (e.g.
Definition: ops.c:544
SWS_COMP_ZERO
@ SWS_COMP_ZERO
Definition: ops.h:75
SWS_OP_CLEAR
@ SWS_OP_CLEAR
Definition: ops.h:59
ff_sws_linear_mask
uint32_t ff_sws_linear_mask(const SwsLinearOp c)
Definition: ops.c:631
ff_sws_op_list_max_size
int ff_sws_op_list_max_size(const SwsOpList *ops)
Returns the size of the largest pixel type used in ops.
Definition: ops.c:620
backend_x86
const SwsOpBackend backend_x86
Definition: ops.c:765
SwsComps::unused
bool unused[4]
Definition: ops.h:91
rational.h
ff_sws_op_list_append
int ff_sws_op_list_append(SwsOpList *ops, SwsOp *op)
These will take over ownership of op and set it to {0}, even on failure.
Definition: ops.c:586
normalize.log
log
Definition: normalize.py:21
mask
int mask
Definition: mediacodecdec_common.c:154
SwsOp::rw
SwsReadWriteOp rw
Definition: ops.h:191
backend_vulkan
const SwsOpBackend backend_vulkan
Definition: ops.c:338
ops.h
SWS_MASK_MAT3
@ SWS_MASK_MAT3
Definition: ops.h:174
SWS_OP_DITHER
@ SWS_OP_DITHER
Definition: ops.h:67
av_dynarray2_add
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
Definition: mem.c:343
b
#define b
Definition: input.c:42
max
#define max(a, b)
Definition: cuda_runtime.h:33
SWS_PIXEL_U32
@ SWS_PIXEL_U32
Definition: ops.h:34
SWS_OP_TYPE_NB
@ SWS_OP_TYPE_NB
Definition: ops.h:69
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
ff_sws_pixel_type_size
int ff_sws_pixel_type_size(SwsPixelType type)
Definition: ops.c:63
describe_comp_flags
static char describe_comp_flags(unsigned flags)
Definition: ops.c:684
clear_undefined_values
static void clear_undefined_values(AVRational dst[4], const AVRational src[4])
Definition: ops.c:232
SWS_MASK_ROW
#define SWS_MASK_ROW(I)
Definition: ops.h:164
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
SwsPixelType
SwsPixelType
Copyright (C) 2025 Niklas Haas.
Definition: ops.h:30
SwsComps::max
AVRational max[4]
Definition: ops.h:95
ff_sws_op_list_print
void ff_sws_op_list_print(void *log, int lev, int lev_extra, const SwsOpList *ops)
Print out the contents of an operation list.
Definition: ops.c:728
SWS_PIXEL_F32
@ SWS_PIXEL_F32
Definition: ops.h:35
ff_sws_op_backends
const SwsOpBackend *const ff_sws_op_backends[]
Definition: ops.c:36
av_ceil_log2
#define av_ceil_log2
Definition: common.h:97
SwsOpList::num_ops
int num_ops
Definition: ops.h:224
SWS_MASK_COL
#define SWS_MASK_COL(J)
Definition: ops.h:165
flags_identity
static const unsigned flags_identity
Definition: ops.c:216
SWS_PIXEL_U8
@ SWS_PIXEL_U8
Definition: ops.h:32
SwsSwizzleOp
Definition: ops.h:120
ff_sws_pixel_type_is_int
bool ff_sws_pixel_type_is_int(SwsPixelType type)
Definition: ops.c:78
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
AVRational::num
int num
Numerator.
Definition: rational.h:59
refstruct.h
SwsOp::op
SwsOpType op
Definition: ops.h:187
Q
#define Q(q)
SWS_MASK_LUMA
@ SWS_MASK_LUMA
Definition: ops.h:169
mult
static int16_t mult(Float11 *f1, Float11 *f2)
Definition: g726.c:60
SWS_OP_SCALE
@ SWS_OP_SCALE
Definition: ops.h:63
avassert.h
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
float
float
Definition: af_crystalizer.c:122
SWS_SWIZZLE
#define SWS_SWIZZLE(X, Y, Z, W)
Definition: ops.h:132
SwsComps::min
AVRational min[4]
Definition: ops.h:95
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
SWS_MASK_OFF4
@ SWS_MASK_OFF4
Definition: ops.h:179
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
backend_c
const SwsOpBackend backend_c
Copyright (C) 2025 Niklas Haas.
Definition: ops_backend.c:104
SWS_OP_MIN
@ SWS_OP_MIN
Definition: ops.h:61
ff_sws_pixel_expand
static AVRational ff_sws_pixel_expand(SwsPixelType from, SwsPixelType to)
Definition: ops_internal.h:31
SWS_MASK_DIAG3
@ SWS_MASK_DIAG3
Definition: ops.h:172
SWS_OP_LINEAR
@ SWS_OP_LINEAR
Definition: ops.h:66
ff_sws_op_list_output
const SwsOp * ff_sws_op_list_output(const SwsOpList *ops)
Returns the output operation for a given op list, or NULL if there is none.
Definition: ops.c:553
PRINTQ
#define PRINTQ(q)
Definition: ops.c:726
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
describe_order
static const char * describe_order(SwsSwizzleOp order, int planes, char buf[32])
Definition: ops.c:698
SwsOpBackend
Definition: ops_internal.h:55
SWS_OP_PACK
@ SWS_OP_PACK
Definition: ops.h:54
merge_comp_flags
static unsigned merge_comp_flags(unsigned a, unsigned b)
Definition: ops.c:217
ff_sws_op_list_is_noop
bool ff_sws_op_list_is_noop(const SwsOpList *ops)
Returns whether an op list represents a true no-op operation, i.e.
Definition: ops.c:591
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_unreachable
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition: avassert.h:116
SwsReadWriteOp::frac
uint8_t frac
Definition: ops.h:100
SWS_MASK_ALPHA
@ SWS_MASK_ALPHA
Definition: ops.h:170
SWS_COMP_GARBAGE
@ SWS_COMP_GARBAGE
Definition: ops.h:73
planes
static const struct @562 planes[]
abs
#define abs(x)
Definition: cuda_runtime.h:35
ff_sws_op_list_remove_at
void ff_sws_op_list_remove_at(SwsOpList *ops, int index, int count)
Definition: ops.c:562
print_q
static const char * print_q(const AVRational q, char buf[], int buf_len)
Definition: ops.c:710
SWS_MASK
#define SWS_MASK(I, J)
Definition: ops.h:162
SWS_PIXEL_NONE
@ SWS_PIXEL_NONE
Definition: ops.h:31
index
int index
Definition: gxfenc.c:90
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
ff_sws_apply_op_q
void ff_sws_apply_op_q(const SwsOp *op, AVRational x[4])
Apply an operation to an AVRational.
Definition: ops.c:106
SwsOpList::order_dst
SwsSwizzleOp order_dst
Definition: ops.h:230
SWS_MASK_DIAG4
@ SWS_MASK_DIAG4
Definition: ops.h:178
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
shift
static int shift(int a, int b)
Definition: bonk.c:261
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_bswap32
#define av_bswap32
Definition: bswap.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
SwsOp::type
SwsPixelType type
Definition: ops.h:188
ff_sws_op_list_insert_at
int ff_sws_op_list_insert_at(SwsOpList *ops, int index, SwsOp *op)
Definition: ops.c:572
size
int size
Definition: twinvq_data.h:10344
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
SWS_OP_RSHIFT
@ SWS_OP_RSHIFT
Definition: ops.h:56
SwsOpList::src
SwsFormat src
Definition: ops.h:227
SWS_OP_INVALID
@ SWS_OP_INVALID
Definition: ops.h:44
ff_sws_op_list_update_comps
void ff_sws_op_list_update_comps(SwsOpList *ops)
Infer + propagate known information about components.
Definition: ops.c:241
SWS_OP_WRITE
@ SWS_OP_WRITE
Definition: ops.h:48
av_refstruct_ref
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition: refstruct.c:140
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
op_uninit
static void op_uninit(SwsOp *op)
Definition: ops.c:478
SwsOp::comps
SwsComps comps
Metadata about the operation's input/output components.
Definition: ops.h:206
SwsLinearOp
Definition: ops.h:145
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
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
av_max_q
static AVRational av_max_q(AVRational a, AVRational b)
Definition: ops.c:101
SwsOpList::ops
SwsOp * ops
Definition: ops.h:223
SwsOpList::order_src
SwsSwizzleOp order_src
Definition: ops.h:230
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:58
ops_internal.h
lev
static LevelCodes lev[4+3+3]
Definition: clearvideo.c:80
SwsOp
Definition: ops.h:186
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
ret
ret
Definition: filter_design.txt:187
bswap.h
backend_murder
const SwsOpBackend backend_murder
Definition: ops_memcpy.c:130
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
av_malloc
void * av_malloc(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:98
SwsOpList::dst
SwsFormat dst
Definition: ops.h:227
SWS_OP_MAX
@ SWS_OP_MAX
Definition: ops.h:62
SWS_PIXEL_TYPE_NB
@ SWS_PIXEL_TYPE_NB
Definition: ops.h:36
SwsComps
Definition: ops.h:89
AVRational::den
int den
Denominator.
Definition: rational.h:60
SWS_COMP_SWAPPED
@ SWS_COMP_SWAPPED
Definition: ops.h:76
SwsReadWriteOp::packed
bool packed
Definition: ops.h:101
ff_sws_pixel_type_name
const char * ff_sws_pixel_type_name(SwsPixelType type)
Definition: ops.c:48
SWS_OP_SWAP_BYTES
@ SWS_OP_SWAP_BYTES
Definition: ops.h:49
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
SWS_COMP_EXACT
@ SWS_COMP_EXACT
Definition: ops.h:74
SWS_MASK_MAT4
@ SWS_MASK_MAT4
Definition: ops.h:180
describe_lin_mask
static const char * describe_lin_mask(uint32_t mask)
Definition: ops.c:643
SwsReadWriteOp::elems
uint8_t elems
Definition: ops.h:99
mem.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:278
av_add_q
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition: rational.c:93
ff_sws_pack_op_decode
static void ff_sws_pack_op_decode(const SwsOp *op, uint64_t mask[4], int shift[4])
Definition: ops_internal.h:43
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
SwsSwizzleOp::in
uint8_t in[4]
Definition: ops.h:127
SWS_OP_CONVERT
@ SWS_OP_CONVERT
Definition: ops.h:60
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
propagate_flags
static void propagate_flags(SwsOp *op, const SwsComps *prev)
Definition: ops.c:225
SWS_MASK_OFF3
@ SWS_MASK_OFF3
Definition: ops.h:173
avstring.h
SwsOpList
Helper struct for representing a list of operations.
Definition: ops.h:222
av_bswap16
#define av_bswap16
Definition: bswap.h:28
snprintf
#define snprintf
Definition: snprintf.h:34
src
#define src
Definition: vp8dsp.c:248
read
static uint32_t BS_FUNC() read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
Definition: bitstream_template.h:239
ff_fmt_clear
static void ff_fmt_clear(SwsFormat *fmt)
Definition: format.h:89
min
float min
Definition: vorbis_enc_data.h:429