Go to the documentation of this file.
26 #include "../ops_chain.h"
28 #define DECL_ENTRY(TYPE, NAME, ...) \
29 static const SwsOpEntry op_##NAME = { \
30 .type = SWS_PIXEL_##TYPE, \
34 #define DECL_ASM(TYPE, NAME, ...) \
35 void ff_##NAME(void); \
36 DECL_ENTRY(TYPE, NAME, \
40 #define DECL_PATTERN(TYPE, NAME, X, Y, Z, W, ...) \
41 DECL_ASM(TYPE, p##X##Y##Z##W##_##NAME, \
42 .unused = { !X, !Y, !Z, !W }, \
46 #define REF_PATTERN(NAME, X, Y, Z, W) \
47 &op_p##X##Y##Z##W##_##NAME
49 #define DECL_COMMON_PATTERNS(TYPE, NAME, ...) \
50 DECL_PATTERN(TYPE, NAME, 1, 0, 0, 0, __VA_ARGS__); \
51 DECL_PATTERN(TYPE, NAME, 1, 0, 0, 1, __VA_ARGS__); \
52 DECL_PATTERN(TYPE, NAME, 1, 1, 1, 0, __VA_ARGS__); \
53 DECL_PATTERN(TYPE, NAME, 1, 1, 1, 1, __VA_ARGS__) \
55 #define REF_COMMON_PATTERNS(NAME) \
56 REF_PATTERN(NAME, 1, 0, 0, 0), \
57 REF_PATTERN(NAME, 1, 0, 0, 1), \
58 REF_PATTERN(NAME, 1, 1, 1, 0), \
59 REF_PATTERN(NAME, 1, 1, 1, 1)
66 if (
op->rw.packed &&
op->rw.elems == 3) {
76 #define DECL_RW(EXT, TYPE, NAME, OP, ELEMS, PACKED, FRAC) \
77 DECL_ASM(TYPE, NAME##ELEMS##EXT, \
79 .rw = { .elems = ELEMS, .packed = PACKED, .frac = FRAC }, \
83 #define DECL_PACKED_RW(EXT, DEPTH) \
84 DECL_RW(EXT, U##DEPTH, read##DEPTH##_packed, READ, 2, true, 0) \
85 DECL_RW(EXT, U##DEPTH, read##DEPTH##_packed, READ, 3, true, 0) \
86 DECL_RW(EXT, U##DEPTH, read##DEPTH##_packed, READ, 4, true, 0) \
87 DECL_RW(EXT, U##DEPTH, write##DEPTH##_packed, WRITE, 2, true, 0) \
88 DECL_RW(EXT, U##DEPTH, write##DEPTH##_packed, WRITE, 3, true, 0) \
89 DECL_RW(EXT, U##DEPTH, write##DEPTH##_packed, WRITE, 4, true, 0) \
91 #define DECL_PACK_UNPACK(EXT, TYPE, X, Y, Z, W) \
92 DECL_ASM(TYPE, pack_##X##Y##Z##W##EXT, \
94 .pack.pattern = {X, Y, Z, W}, \
97 DECL_ASM(TYPE, unpack_##X##Y##Z##W##EXT, \
98 .op = SWS_OP_UNPACK, \
99 .pack.pattern = {X, Y, Z, W}, \
105 for (
int i = 0;
i < 16;
i++)
110 #define DECL_SWAP_BYTES(EXT, TYPE, X, Y, Z, W) \
111 DECL_ENTRY(TYPE, p##X##Y##Z##W##_swap_bytes_##TYPE##EXT, \
112 .op = SWS_OP_SWAP_BYTES, \
113 .unused = { !X, !Y, !Z, !W }, \
114 .func = ff_p##X##Y##Z##W##_shuffle##EXT, \
115 .setup = setup_swap_bytes, \
118 #define DECL_CLEAR_ALPHA(EXT, IDX) \
119 DECL_ASM(U8, clear_alpha##IDX##EXT, \
120 .op = SWS_OP_CLEAR, \
122 .unused[IDX] = true, \
125 #define DECL_CLEAR_ZERO(EXT, IDX) \
126 DECL_ASM(U8, clear_zero##IDX##EXT, \
127 .op = SWS_OP_CLEAR, \
129 .unused[IDX] = true, \
135 for (
int i = 0;
i < 4;
i++)
136 out->priv.u32[
i] = (uint32_t)
op->c.q4[
i].num;
140 #define DECL_CLEAR(EXT, X, Y, Z, W) \
141 DECL_PATTERN(U8, clear##EXT, X, Y, Z, W, \
142 .op = SWS_OP_CLEAR, \
143 .setup = setup_clear, \
147 #define DECL_SWIZZLE(EXT, X, Y, Z, W) \
148 DECL_ASM(U8, swizzle_##X##Y##Z##W##EXT, \
149 .op = SWS_OP_SWIZZLE, \
150 .swizzle.in = {X, Y, Z, W}, \
153 #define DECL_CONVERT(EXT, FROM, TO) \
154 DECL_COMMON_PATTERNS(FROM, convert_##FROM##_##TO##EXT, \
155 .op = SWS_OP_CONVERT, \
156 .convert.to = SWS_PIXEL_##TO, \
159 #define DECL_EXPAND(EXT, FROM, TO) \
160 DECL_COMMON_PATTERNS(FROM, expand_##FROM##_##TO##EXT, \
161 .op = SWS_OP_CONVERT, \
162 .convert.to = SWS_PIXEL_##TO, \
163 .convert.expand = true, \
168 out->priv.u16[0] = params->
op->
c.
u;
172 #define DECL_SHIFT16(EXT) \
173 DECL_COMMON_PATTERNS(U16, lshift16##EXT, \
174 .op = SWS_OP_LSHIFT, \
175 .setup = setup_shift, \
179 DECL_COMMON_PATTERNS(U16, rshift16##EXT, \
180 .op = SWS_OP_RSHIFT, \
181 .setup = setup_shift, \
185 #define DECL_MIN_MAX(EXT) \
186 DECL_COMMON_PATTERNS(F32, min##EXT, \
188 .setup = ff_sws_setup_q4, \
192 DECL_COMMON_PATTERNS(F32, max##EXT, \
194 .setup = ff_sws_setup_q4, \
198 #define DECL_SCALE(EXT) \
199 DECL_COMMON_PATTERNS(F32, scale##EXT, \
200 .op = SWS_OP_SCALE, \
201 .setup = ff_sws_setup_q, \
205 #define DECL_EXPAND_BITS(EXT, BITS) \
206 DECL_ASM(U##BITS, expand_bits##BITS##EXT, \
207 .op = SWS_OP_SCALE, \
208 .scale = { .num = ((1 << (BITS)) - 1), .den = 1 }, \
215 if (!
op->dither.size_log2) {
221 const int size = 1 <<
op->dither.size_log2;
222 const int8_t *off =
op->dither.y_offset;
224 for (
int i = 0;
i < 4;
i++) {
226 max_offset =
FFMAX(max_offset, off[
i] & (
size - 1));
234 const int num_rows =
size + max_offset;
241 matrix[
i] = (
float)
op->dither.matrix[
i].num /
op->dither.matrix[
i].den;
246 static_assert(
sizeof(
out->priv.ptr) <=
sizeof(int16_t[4]),
247 ">8 byte pointers not supported");
248 assert(max_offset *
stride <= INT16_MAX);
249 int16_t *off_out = &
out->priv.i16[4];
250 for (
int i = 0;
i < 4;
i++)
251 off_out[
i] = off[
i] >= 0 ? (off[
i] & (
size - 1)) *
stride : -1;
256 #define DECL_DITHER(DECL_MACRO, EXT, SIZE) \
257 DECL_MACRO(F32, dither##SIZE##EXT, \
258 .op = SWS_OP_DITHER, \
259 .setup = setup_dither, \
260 .dither_size = SIZE, \
272 for (
int y = 0; y < 4; y++) {
273 for (
int x = 0; x < 5; x++)
274 matrix[y * 5 + x] = (
float)
op->lin.m[y][x].num /
op->lin.m[y][x].den;
280 #define DECL_LINEAR(EXT, NAME, MASK) \
281 DECL_ASM(F32, NAME##EXT, \
282 .op = SWS_OP_LINEAR, \
283 .setup = setup_linear, \
284 .linear_mask = (MASK), \
287 #define DECL_FUNCS_8(SIZE, EXT, FLAG) \
288 DECL_RW(EXT, U8, read_planar, READ, 1, false, 0) \
289 DECL_RW(EXT, U8, read_planar, READ, 2, false, 0) \
290 DECL_RW(EXT, U8, read_planar, READ, 3, false, 0) \
291 DECL_RW(EXT, U8, read_planar, READ, 4, false, 0) \
292 DECL_RW(EXT, U8, write_planar, WRITE, 1, false, 0) \
293 DECL_RW(EXT, U8, write_planar, WRITE, 2, false, 0) \
294 DECL_RW(EXT, U8, write_planar, WRITE, 3, false, 0) \
295 DECL_RW(EXT, U8, write_planar, WRITE, 4, false, 0) \
296 DECL_RW(EXT, U8, read_nibbles, READ, 1, false, 1) \
297 DECL_RW(EXT, U8, read_bits, READ, 1, false, 3) \
298 DECL_RW(EXT, U8, write_bits, WRITE, 1, false, 3) \
299 DECL_EXPAND_BITS(EXT, 8) \
300 DECL_PACKED_RW(EXT, 8) \
301 DECL_PACK_UNPACK(EXT, U8, 1, 2, 1, 0) \
302 DECL_PACK_UNPACK(EXT, U8, 3, 3, 2, 0) \
303 DECL_PACK_UNPACK(EXT, U8, 2, 3, 3, 0) \
304 void ff_p1000_shuffle##EXT(void); \
305 void ff_p1001_shuffle##EXT(void); \
306 void ff_p1110_shuffle##EXT(void); \
307 void ff_p1111_shuffle##EXT(void); \
308 DECL_SWIZZLE(EXT, 3, 0, 1, 2) \
309 DECL_SWIZZLE(EXT, 3, 0, 2, 1) \
310 DECL_SWIZZLE(EXT, 2, 1, 0, 3) \
311 DECL_SWIZZLE(EXT, 3, 2, 1, 0) \
312 DECL_SWIZZLE(EXT, 3, 1, 0, 2) \
313 DECL_SWIZZLE(EXT, 3, 2, 0, 1) \
314 DECL_SWIZZLE(EXT, 1, 2, 0, 3) \
315 DECL_SWIZZLE(EXT, 1, 0, 2, 3) \
316 DECL_SWIZZLE(EXT, 2, 0, 1, 3) \
317 DECL_SWIZZLE(EXT, 2, 3, 1, 0) \
318 DECL_SWIZZLE(EXT, 2, 1, 3, 0) \
319 DECL_SWIZZLE(EXT, 1, 2, 3, 0) \
320 DECL_SWIZZLE(EXT, 1, 3, 2, 0) \
321 DECL_SWIZZLE(EXT, 0, 2, 1, 3) \
322 DECL_SWIZZLE(EXT, 0, 2, 3, 1) \
323 DECL_SWIZZLE(EXT, 0, 3, 1, 2) \
324 DECL_SWIZZLE(EXT, 3, 1, 2, 0) \
325 DECL_SWIZZLE(EXT, 0, 3, 2, 1) \
326 DECL_SWIZZLE(EXT, 0, 0, 0, 3) \
327 DECL_SWIZZLE(EXT, 3, 0, 0, 0) \
328 DECL_SWIZZLE(EXT, 0, 0, 0, 1) \
329 DECL_SWIZZLE(EXT, 1, 0, 0, 0) \
330 DECL_CLEAR_ALPHA(EXT, 0) \
331 DECL_CLEAR_ALPHA(EXT, 1) \
332 DECL_CLEAR_ALPHA(EXT, 3) \
333 DECL_CLEAR_ZERO(EXT, 0) \
334 DECL_CLEAR_ZERO(EXT, 1) \
335 DECL_CLEAR_ZERO(EXT, 3) \
336 DECL_CLEAR(EXT, 1, 1, 1, 0) \
337 DECL_CLEAR(EXT, 0, 1, 1, 1) \
338 DECL_CLEAR(EXT, 0, 0, 1, 1) \
339 DECL_CLEAR(EXT, 1, 0, 0, 1) \
340 DECL_CLEAR(EXT, 1, 1, 0, 0) \
341 DECL_CLEAR(EXT, 0, 1, 0, 1) \
342 DECL_CLEAR(EXT, 1, 0, 1, 0) \
343 DECL_CLEAR(EXT, 1, 0, 0, 0) \
344 DECL_CLEAR(EXT, 0, 1, 0, 0) \
345 DECL_CLEAR(EXT, 0, 0, 1, 0) \
347 static const SwsOpTable ops8##EXT = { \
348 .cpu_flags = AV_CPU_FLAG_##FLAG, \
349 .block_size = SIZE, \
351 &op_read_planar1##EXT, \
352 &op_read_planar2##EXT, \
353 &op_read_planar3##EXT, \
354 &op_read_planar4##EXT, \
355 &op_write_planar1##EXT, \
356 &op_write_planar2##EXT, \
357 &op_write_planar3##EXT, \
358 &op_write_planar4##EXT, \
359 &op_read8_packed2##EXT, \
360 &op_read8_packed3##EXT, \
361 &op_read8_packed4##EXT, \
362 &op_write8_packed2##EXT, \
363 &op_write8_packed3##EXT, \
364 &op_write8_packed4##EXT, \
365 &op_read_nibbles1##EXT, \
366 &op_read_bits1##EXT, \
367 &op_write_bits1##EXT, \
368 &op_expand_bits8##EXT, \
369 &op_pack_1210##EXT, \
370 &op_pack_3320##EXT, \
371 &op_pack_2330##EXT, \
372 &op_unpack_1210##EXT, \
373 &op_unpack_3320##EXT, \
374 &op_unpack_2330##EXT, \
375 &op_swizzle_3012##EXT, \
376 &op_swizzle_3021##EXT, \
377 &op_swizzle_2103##EXT, \
378 &op_swizzle_3210##EXT, \
379 &op_swizzle_3102##EXT, \
380 &op_swizzle_3201##EXT, \
381 &op_swizzle_1203##EXT, \
382 &op_swizzle_1023##EXT, \
383 &op_swizzle_2013##EXT, \
384 &op_swizzle_2310##EXT, \
385 &op_swizzle_2130##EXT, \
386 &op_swizzle_1230##EXT, \
387 &op_swizzle_1320##EXT, \
388 &op_swizzle_0213##EXT, \
389 &op_swizzle_0231##EXT, \
390 &op_swizzle_0312##EXT, \
391 &op_swizzle_3120##EXT, \
392 &op_swizzle_0321##EXT, \
393 &op_swizzle_0003##EXT, \
394 &op_swizzle_0001##EXT, \
395 &op_swizzle_3000##EXT, \
396 &op_swizzle_1000##EXT, \
397 &op_clear_alpha0##EXT, \
398 &op_clear_alpha1##EXT, \
399 &op_clear_alpha3##EXT, \
400 &op_clear_zero0##EXT, \
401 &op_clear_zero1##EXT, \
402 &op_clear_zero3##EXT, \
403 REF_PATTERN(clear##EXT, 1, 1, 1, 0), \
404 REF_PATTERN(clear##EXT, 0, 1, 1, 1), \
405 REF_PATTERN(clear##EXT, 0, 0, 1, 1), \
406 REF_PATTERN(clear##EXT, 1, 0, 0, 1), \
407 REF_PATTERN(clear##EXT, 1, 1, 0, 0), \
408 REF_PATTERN(clear##EXT, 0, 1, 0, 1), \
409 REF_PATTERN(clear##EXT, 1, 0, 1, 0), \
410 REF_PATTERN(clear##EXT, 1, 0, 0, 0), \
411 REF_PATTERN(clear##EXT, 0, 1, 0, 0), \
412 REF_PATTERN(clear##EXT, 0, 0, 1, 0), \
417 #define DECL_FUNCS_16(SIZE, EXT, FLAG) \
418 DECL_PACKED_RW(EXT, 16) \
419 DECL_EXPAND_BITS(EXT, 16) \
420 DECL_PACK_UNPACK(EXT, U16, 4, 4, 4, 0) \
421 DECL_PACK_UNPACK(EXT, U16, 5, 5, 5, 0) \
422 DECL_PACK_UNPACK(EXT, U16, 5, 6, 5, 0) \
423 DECL_SWAP_BYTES(EXT, U16, 1, 0, 0, 0) \
424 DECL_SWAP_BYTES(EXT, U16, 1, 0, 0, 1) \
425 DECL_SWAP_BYTES(EXT, U16, 1, 1, 1, 0) \
426 DECL_SWAP_BYTES(EXT, U16, 1, 1, 1, 1) \
428 DECL_CONVERT(EXT, U8, U16) \
429 DECL_CONVERT(EXT, U16, U8) \
430 DECL_EXPAND(EXT, U8, U16) \
432 static const SwsOpTable ops16##EXT = { \
433 .cpu_flags = AV_CPU_FLAG_##FLAG, \
434 .block_size = SIZE, \
436 &op_read16_packed2##EXT, \
437 &op_read16_packed3##EXT, \
438 &op_read16_packed4##EXT, \
439 &op_write16_packed2##EXT, \
440 &op_write16_packed3##EXT, \
441 &op_write16_packed4##EXT, \
442 &op_pack_4440##EXT, \
443 &op_pack_5550##EXT, \
444 &op_pack_5650##EXT, \
445 &op_unpack_4440##EXT, \
446 &op_unpack_5550##EXT, \
447 &op_unpack_5650##EXT, \
448 &op_expand_bits16##EXT, \
449 REF_COMMON_PATTERNS(swap_bytes_U16##EXT), \
450 REF_COMMON_PATTERNS(convert_U8_U16##EXT), \
451 REF_COMMON_PATTERNS(convert_U16_U8##EXT), \
452 REF_COMMON_PATTERNS(expand_U8_U16##EXT), \
453 REF_COMMON_PATTERNS(lshift16##EXT), \
454 REF_COMMON_PATTERNS(rshift16##EXT), \
459 #define DECL_FUNCS_32(SIZE, EXT, FLAG) \
460 DECL_PACKED_RW(_m2##EXT, 32) \
461 DECL_PACK_UNPACK(_m2##EXT, U32, 10, 10, 10, 2) \
462 DECL_PACK_UNPACK(_m2##EXT, U32, 2, 10, 10, 10) \
463 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 0, 0, 0) \
464 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 0, 0, 1) \
465 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 1, 1, 0) \
466 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 1, 1, 1) \
467 DECL_CONVERT(EXT, U8, U32) \
468 DECL_CONVERT(EXT, U32, U8) \
469 DECL_CONVERT(EXT, U16, U32) \
470 DECL_CONVERT(EXT, U32, U16) \
471 DECL_CONVERT(EXT, U8, F32) \
472 DECL_CONVERT(EXT, F32, U8) \
473 DECL_CONVERT(EXT, U16, F32) \
474 DECL_CONVERT(EXT, F32, U16) \
475 DECL_EXPAND(EXT, U8, U32) \
478 DECL_DITHER(DECL_COMMON_PATTERNS, EXT, 0) \
479 DECL_DITHER(DECL_ASM, EXT, 1) \
480 DECL_DITHER(DECL_ASM, EXT, 2) \
481 DECL_DITHER(DECL_ASM, EXT, 3) \
482 DECL_DITHER(DECL_ASM, EXT, 4) \
483 DECL_DITHER(DECL_ASM, EXT, 5) \
484 DECL_DITHER(DECL_ASM, EXT, 6) \
485 DECL_DITHER(DECL_ASM, EXT, 7) \
486 DECL_DITHER(DECL_ASM, EXT, 8) \
487 DECL_LINEAR(EXT, luma, SWS_MASK_LUMA) \
488 DECL_LINEAR(EXT, alpha, SWS_MASK_ALPHA) \
489 DECL_LINEAR(EXT, lumalpha, SWS_MASK_LUMA | SWS_MASK_ALPHA) \
490 DECL_LINEAR(EXT, dot3, 0x7) \
491 DECL_LINEAR(EXT, row0, SWS_MASK_ROW(0)) \
492 DECL_LINEAR(EXT, row0a, SWS_MASK_ROW(0) | SWS_MASK_ALPHA) \
493 DECL_LINEAR(EXT, diag3, SWS_MASK_DIAG3) \
494 DECL_LINEAR(EXT, diag4, SWS_MASK_DIAG4) \
495 DECL_LINEAR(EXT, diagoff3, SWS_MASK_DIAG3 | SWS_MASK_OFF3) \
496 DECL_LINEAR(EXT, matrix3, SWS_MASK_MAT3) \
497 DECL_LINEAR(EXT, affine3, SWS_MASK_MAT3 | SWS_MASK_OFF3) \
498 DECL_LINEAR(EXT, affine3a, SWS_MASK_MAT3 | SWS_MASK_OFF3 | SWS_MASK_ALPHA) \
499 DECL_LINEAR(EXT, matrix4, SWS_MASK_MAT4) \
500 DECL_LINEAR(EXT, affine4, SWS_MASK_MAT4 | SWS_MASK_OFF4) \
502 static const SwsOpTable ops32##EXT = { \
503 .cpu_flags = AV_CPU_FLAG_##FLAG, \
504 .block_size = SIZE, \
506 &op_read32_packed2_m2##EXT, \
507 &op_read32_packed3_m2##EXT, \
508 &op_read32_packed4_m2##EXT, \
509 &op_write32_packed2_m2##EXT, \
510 &op_write32_packed3_m2##EXT, \
511 &op_write32_packed4_m2##EXT, \
512 &op_pack_1010102_m2##EXT, \
513 &op_pack_2101010_m2##EXT, \
514 &op_unpack_1010102_m2##EXT, \
515 &op_unpack_2101010_m2##EXT, \
516 REF_COMMON_PATTERNS(swap_bytes_U32_m2##EXT), \
517 REF_COMMON_PATTERNS(convert_U8_U32##EXT), \
518 REF_COMMON_PATTERNS(convert_U32_U8##EXT), \
519 REF_COMMON_PATTERNS(convert_U16_U32##EXT), \
520 REF_COMMON_PATTERNS(convert_U32_U16##EXT), \
521 REF_COMMON_PATTERNS(convert_U8_F32##EXT), \
522 REF_COMMON_PATTERNS(convert_F32_U8##EXT), \
523 REF_COMMON_PATTERNS(convert_U16_F32##EXT), \
524 REF_COMMON_PATTERNS(convert_F32_U16##EXT), \
525 REF_COMMON_PATTERNS(expand_U8_U32##EXT), \
526 REF_COMMON_PATTERNS(min##EXT), \
527 REF_COMMON_PATTERNS(max##EXT), \
528 REF_COMMON_PATTERNS(scale##EXT), \
529 REF_COMMON_PATTERNS(dither0##EXT), \
597 return !(
op->rw.elems > 1 &&
op->rw.packed) && !
op->rw.frac;
622 const int num_lanes = mmsize / 16;
625 const int read_size = in_total <= 4 ? 4 :
633 .block_size = pixels * num_lanes,
634 .over_read = read_size - in_total,
635 .over_write = mmsize - out_total,
644 #define ASSIGN_SHUFFLE_FUNC(IN, OUT, EXT) \
646 SWS_DECL_FUNC(ff_packed_shuffle##IN##_##OUT##_##EXT); \
647 if (in_total == IN && out_total == OUT) \
648 out->func = ff_packed_shuffle##IN##_##OUT##_##EXT; \
674 static_assert(
sizeof(uint32_t) ==
sizeof(
int),
"int size mismatch");
683 for (
int i = 0;
i < 4;
i++) {
684 if (!
op->c.q4[
i].den)
687 case 1:
c.u32 = 0x1010101
U * res.
priv.
u8[
i];
break;
692 op->c.q4[
i].num =
c.i;
726 int op_block_size =
out->block_size;
737 &rest, op_block_size, chain);
749 #define ASSIGN_PROCESS_FUNC(NAME) \
751 SWS_DECL_FUNC(NAME); \
752 void NAME##_return(void); \
753 ret = ff_sws_op_chain_append(chain, NAME##_return, \
754 NULL, &(SwsOpPriv) {0}); \
760 const int read_planes =
read ? (
read->rw.packed ? 1 :
read->rw.elems) : 0;
762 switch (
FFMAX(read_planes, write_planes)) {
Copyright (C) 2025 Niklas Haas.
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
#define ASSIGN_PROCESS_FUNC(NAME)
static av_const int get_mmsize(const int cpu_flags)
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.
int ff_sws_op_list_max_size(const SwsOpList *ops)
Returns the size of the largest pixel type used in ops.
const SwsOpBackend backend_x86
static void normalize_clear(SwsOp *op)
static void read_bytes(const uint8_t *src, float *dst, int src_stride, int dst_stride, int width, int height, float scale)
#define DECL_FUNCS_32(SIZE, EXT, FLAG)
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
static atomic_int cpu_flags
static int setup_linear(const SwsImplParams *params, SwsImplResult *out)
int ff_sws_pixel_type_size(SwsPixelType type)
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
static int setup_dither(const SwsImplParams *params, SwsImplResult *out)
void ff_sws_op_list_print(void *log, int lev, int lev_extra, const SwsOpList *ops)
Print out the contents of an operation list.
#define AV_CPU_FLAG_AVX512
AVX-512 functions: requires OS support even if YMM/ZMM registers aren't used.
void(* free[SWS_MAX_OPS+1])(SwsOpPriv *)
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define FF_ARRAY_ELEMS(a)
SwsOpChain * ff_sws_op_chain_alloc(void)
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.
static int setup_clear(const SwsImplParams *params, SwsImplResult *out)
static AVFormatContext * ctx
#define AV_CPU_FLAG_SSE4
Penryn SSE4.1 functions.
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.
Compiled "chain" of operations, which can be dispatched efficiently.
Rational number (pair of numerator and denominator).
static const SwsOpTable *const tables[]
static int setup_rw(const SwsImplParams *params, SwsImplResult *out)
static int solve_shuffle(const SwsOpList *ops, int mmsize, SwsCompiledOp *out)
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
#define AV_CPU_FLAG_AVX2
AVX2 functions: requires OS support even if YMM registers aren't used.
#define i(width, name, range_min, range_max)
static int setup_swap_bytes(const SwsImplParams *params, SwsImplResult *out)
int ff_sws_op_compile_tables(SwsContext *ctx, const SwsOpTable *const tables[], int num_tables, SwsOpList *ops, const int block_size, SwsOpChain *chain)
"Compile" a single op by looking it up in a list of fixed size op tables.
int ff_sws_setup_q4(const SwsImplParams *params, SwsImplResult *out)
void ff_sws_op_chain_free_cb(void *ptr)
static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out)
static void ff_sws_op_chain_free(SwsOpChain *chain)
static bool op_is_type_invariant(const SwsOp *op)
Returns true if the operation's implementation only depends on the block size, and not the underlying...
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
static void write_bytes(const float *src, uint8_t *dst, int src_stride, int dst_stride, int width, int height, int depth, float scale)
static void ff_op_priv_free(SwsOpPriv *priv)
static int setup_shift(const SwsImplParams *params, SwsImplResult *out)
#define ASSIGN_SHUFFLE_FUNC(IN, OUT, EXT)
int ff_sws_solve_shuffle(const SwsOpList *ops, uint8_t shuffle[], int size, uint8_t clear_val, int *read_bytes, int *write_bytes)
"Solve" an op list into a fixed shuffle mask, with an optional ability to also directly clear the out...
#define DECL_FUNCS_16(SIZE, EXT, FLAG)
Helper struct for representing a list of operations.
#define DECL_FUNCS_8(SIZE, EXT, FLAG)
Main external API structure.
static uint64_t shuffle(uint64_t in, const uint8_t *shuffle, int shuffle_len)
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.