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)
61 #define DECL_RW(EXT, TYPE, NAME, OP, ELEMS, PACKED, FRAC) \
62 DECL_ASM(TYPE, NAME##ELEMS##EXT, \
64 .rw = { .elems = ELEMS, .packed = PACKED, .frac = FRAC }, \
67 #define DECL_PACKED_RW(EXT, DEPTH) \
68 DECL_RW(EXT, U##DEPTH, read##DEPTH##_packed, READ, 2, true, 0) \
69 DECL_RW(EXT, U##DEPTH, read##DEPTH##_packed, READ, 3, true, 0) \
70 DECL_RW(EXT, U##DEPTH, read##DEPTH##_packed, READ, 4, true, 0) \
71 DECL_RW(EXT, U##DEPTH, write##DEPTH##_packed, WRITE, 2, true, 0) \
72 DECL_RW(EXT, U##DEPTH, write##DEPTH##_packed, WRITE, 3, true, 0) \
73 DECL_RW(EXT, U##DEPTH, write##DEPTH##_packed, WRITE, 4, true, 0) \
75 #define DECL_PACK_UNPACK(EXT, TYPE, X, Y, Z, W) \
76 DECL_ASM(TYPE, pack_##X##Y##Z##W##EXT, \
78 .pack.pattern = {X, Y, Z, W}, \
81 DECL_ASM(TYPE, unpack_##X##Y##Z##W##EXT, \
82 .op = SWS_OP_UNPACK, \
83 .pack.pattern = {X, Y, Z, W}, \
89 for (
int i = 0;
i < 16;
i++)
94 #define DECL_SWAP_BYTES(EXT, TYPE, X, Y, Z, W) \
95 DECL_ENTRY(TYPE, p##X##Y##Z##W##_swap_bytes_##TYPE##EXT, \
96 .op = SWS_OP_SWAP_BYTES, \
97 .unused = { !X, !Y, !Z, !W }, \
98 .func = ff_p##X##Y##Z##W##_shuffle##EXT, \
99 .setup = setup_swap_bytes, \
102 #define DECL_CLEAR_ALPHA(EXT, IDX) \
103 DECL_ASM(U8, clear_alpha##IDX##EXT, \
104 .op = SWS_OP_CLEAR, \
106 .unused[IDX] = true, \
109 #define DECL_CLEAR_ZERO(EXT, IDX) \
110 DECL_ASM(U8, clear_zero##IDX##EXT, \
111 .op = SWS_OP_CLEAR, \
113 .unused[IDX] = true, \
118 for (
int i = 0;
i < 4;
i++)
119 out->u32[
i] = (uint32_t)
op->c.q4[
i].num;
123 #define DECL_CLEAR(EXT, X, Y, Z, W) \
124 DECL_PATTERN(U8, clear##EXT, X, Y, Z, W, \
125 .op = SWS_OP_CLEAR, \
126 .setup = setup_clear, \
130 #define DECL_SWIZZLE(EXT, X, Y, Z, W) \
131 DECL_ASM(U8, swizzle_##X##Y##Z##W##EXT, \
132 .op = SWS_OP_SWIZZLE, \
133 .swizzle.in = {X, Y, Z, W}, \
136 #define DECL_CONVERT(EXT, FROM, TO) \
137 DECL_COMMON_PATTERNS(FROM, convert_##FROM##_##TO##EXT, \
138 .op = SWS_OP_CONVERT, \
139 .convert.to = SWS_PIXEL_##TO, \
142 #define DECL_EXPAND(EXT, FROM, TO) \
143 DECL_COMMON_PATTERNS(FROM, expand_##FROM##_##TO##EXT, \
144 .op = SWS_OP_CONVERT, \
145 .convert.to = SWS_PIXEL_##TO, \
146 .convert.expand = true, \
151 out->u16[0] =
op->c.u;
155 #define DECL_SHIFT16(EXT) \
156 DECL_COMMON_PATTERNS(U16, lshift16##EXT, \
157 .op = SWS_OP_LSHIFT, \
158 .setup = setup_shift, \
162 DECL_COMMON_PATTERNS(U16, rshift16##EXT, \
163 .op = SWS_OP_RSHIFT, \
164 .setup = setup_shift, \
168 #define DECL_MIN_MAX(EXT) \
169 DECL_COMMON_PATTERNS(F32, min##EXT, \
171 .setup = ff_sws_setup_q4, \
175 DECL_COMMON_PATTERNS(F32, max##EXT, \
177 .setup = ff_sws_setup_q4, \
181 #define DECL_SCALE(EXT) \
182 DECL_COMMON_PATTERNS(F32, scale##EXT, \
183 .op = SWS_OP_SCALE, \
184 .setup = ff_sws_setup_q, \
188 #define DECL_EXPAND_BITS(EXT, BITS) \
189 DECL_ASM(U##BITS, expand_bits##BITS##EXT, \
190 .op = SWS_OP_SCALE, \
191 .scale = Q((1 << (BITS)) - 1), \
197 if (!
op->dither.size_log2) {
203 const int size = 1 <<
op->dither.size_log2;
204 const int8_t *off =
op->dither.y_offset;
206 for (
int i = 0;
i < 4;
i++) {
208 max_offset =
FFMAX(max_offset, off[
i] & (
size - 1));
216 const int num_rows =
size + max_offset;
222 matrix[
i] = (
float)
op->dither.matrix[
i].num /
op->dither.matrix[
i].den;
227 static_assert(
sizeof(
out->ptr) <=
sizeof(int16_t[4]),
">8 byte pointers not supported");
228 assert(max_offset *
stride <= INT16_MAX);
229 int16_t *off_out = &
out->i16[4];
230 for (
int i = 0;
i < 4;
i++)
231 off_out[
i] = off[
i] >= 0 ? (off[
i] & (
size - 1)) *
stride : -1;
236 #define DECL_DITHER(DECL_MACRO, EXT, SIZE) \
237 DECL_MACRO(F32, dither##SIZE##EXT, \
238 .op = SWS_OP_DITHER, \
239 .setup = setup_dither, \
240 .free = (SIZE) ? av_free : NULL, \
241 .dither_size = SIZE, \
250 for (
int y = 0; y < 4; y++) {
251 for (
int x = 0; x < 5; x++)
252 matrix[y * 5 + x] = (
float)
op->lin.m[y][x].num /
op->lin.m[y][x].den;
258 #define DECL_LINEAR(EXT, NAME, MASK) \
259 DECL_ASM(F32, NAME##EXT, \
260 .op = SWS_OP_LINEAR, \
261 .setup = setup_linear, \
263 .linear_mask = (MASK), \
266 #define DECL_FUNCS_8(SIZE, EXT, FLAG) \
267 DECL_RW(EXT, U8, read_planar, READ, 1, false, 0) \
268 DECL_RW(EXT, U8, read_planar, READ, 2, false, 0) \
269 DECL_RW(EXT, U8, read_planar, READ, 3, false, 0) \
270 DECL_RW(EXT, U8, read_planar, READ, 4, false, 0) \
271 DECL_RW(EXT, U8, write_planar, WRITE, 1, false, 0) \
272 DECL_RW(EXT, U8, write_planar, WRITE, 2, false, 0) \
273 DECL_RW(EXT, U8, write_planar, WRITE, 3, false, 0) \
274 DECL_RW(EXT, U8, write_planar, WRITE, 4, false, 0) \
275 DECL_RW(EXT, U8, read_nibbles, READ, 1, false, 1) \
276 DECL_RW(EXT, U8, read_bits, READ, 1, false, 3) \
277 DECL_RW(EXT, U8, write_bits, WRITE, 1, false, 3) \
278 DECL_EXPAND_BITS(EXT, 8) \
279 DECL_PACKED_RW(EXT, 8) \
280 DECL_PACK_UNPACK(EXT, U8, 1, 2, 1, 0) \
281 DECL_PACK_UNPACK(EXT, U8, 3, 3, 2, 0) \
282 DECL_PACK_UNPACK(EXT, U8, 2, 3, 3, 0) \
283 void ff_p1000_shuffle##EXT(void); \
284 void ff_p1001_shuffle##EXT(void); \
285 void ff_p1110_shuffle##EXT(void); \
286 void ff_p1111_shuffle##EXT(void); \
287 DECL_SWIZZLE(EXT, 3, 0, 1, 2) \
288 DECL_SWIZZLE(EXT, 3, 0, 2, 1) \
289 DECL_SWIZZLE(EXT, 2, 1, 0, 3) \
290 DECL_SWIZZLE(EXT, 3, 2, 1, 0) \
291 DECL_SWIZZLE(EXT, 3, 1, 0, 2) \
292 DECL_SWIZZLE(EXT, 3, 2, 0, 1) \
293 DECL_SWIZZLE(EXT, 1, 2, 0, 3) \
294 DECL_SWIZZLE(EXT, 1, 0, 2, 3) \
295 DECL_SWIZZLE(EXT, 2, 0, 1, 3) \
296 DECL_SWIZZLE(EXT, 2, 3, 1, 0) \
297 DECL_SWIZZLE(EXT, 2, 1, 3, 0) \
298 DECL_SWIZZLE(EXT, 1, 2, 3, 0) \
299 DECL_SWIZZLE(EXT, 1, 3, 2, 0) \
300 DECL_SWIZZLE(EXT, 0, 2, 1, 3) \
301 DECL_SWIZZLE(EXT, 0, 2, 3, 1) \
302 DECL_SWIZZLE(EXT, 0, 3, 1, 2) \
303 DECL_SWIZZLE(EXT, 3, 1, 2, 0) \
304 DECL_SWIZZLE(EXT, 0, 3, 2, 1) \
305 DECL_SWIZZLE(EXT, 0, 0, 0, 3) \
306 DECL_SWIZZLE(EXT, 3, 0, 0, 0) \
307 DECL_SWIZZLE(EXT, 0, 0, 0, 1) \
308 DECL_SWIZZLE(EXT, 1, 0, 0, 0) \
309 DECL_CLEAR_ALPHA(EXT, 0) \
310 DECL_CLEAR_ALPHA(EXT, 1) \
311 DECL_CLEAR_ALPHA(EXT, 3) \
312 DECL_CLEAR_ZERO(EXT, 0) \
313 DECL_CLEAR_ZERO(EXT, 1) \
314 DECL_CLEAR_ZERO(EXT, 3) \
315 DECL_CLEAR(EXT, 1, 1, 1, 0) \
316 DECL_CLEAR(EXT, 0, 1, 1, 1) \
317 DECL_CLEAR(EXT, 0, 0, 1, 1) \
318 DECL_CLEAR(EXT, 1, 0, 0, 1) \
319 DECL_CLEAR(EXT, 1, 1, 0, 0) \
320 DECL_CLEAR(EXT, 0, 1, 0, 1) \
321 DECL_CLEAR(EXT, 1, 0, 1, 0) \
322 DECL_CLEAR(EXT, 1, 0, 0, 0) \
323 DECL_CLEAR(EXT, 0, 1, 0, 0) \
324 DECL_CLEAR(EXT, 0, 0, 1, 0) \
326 static const SwsOpTable ops8##EXT = { \
327 .cpu_flags = AV_CPU_FLAG_##FLAG, \
328 .block_size = SIZE, \
330 &op_read_planar1##EXT, \
331 &op_read_planar2##EXT, \
332 &op_read_planar3##EXT, \
333 &op_read_planar4##EXT, \
334 &op_write_planar1##EXT, \
335 &op_write_planar2##EXT, \
336 &op_write_planar3##EXT, \
337 &op_write_planar4##EXT, \
338 &op_read8_packed2##EXT, \
339 &op_read8_packed3##EXT, \
340 &op_read8_packed4##EXT, \
341 &op_write8_packed2##EXT, \
342 &op_write8_packed3##EXT, \
343 &op_write8_packed4##EXT, \
344 &op_read_nibbles1##EXT, \
345 &op_read_bits1##EXT, \
346 &op_write_bits1##EXT, \
347 &op_expand_bits8##EXT, \
348 &op_pack_1210##EXT, \
349 &op_pack_3320##EXT, \
350 &op_pack_2330##EXT, \
351 &op_unpack_1210##EXT, \
352 &op_unpack_3320##EXT, \
353 &op_unpack_2330##EXT, \
354 &op_swizzle_3012##EXT, \
355 &op_swizzle_3021##EXT, \
356 &op_swizzle_2103##EXT, \
357 &op_swizzle_3210##EXT, \
358 &op_swizzle_3102##EXT, \
359 &op_swizzle_3201##EXT, \
360 &op_swizzle_1203##EXT, \
361 &op_swizzle_1023##EXT, \
362 &op_swizzle_2013##EXT, \
363 &op_swizzle_2310##EXT, \
364 &op_swizzle_2130##EXT, \
365 &op_swizzle_1230##EXT, \
366 &op_swizzle_1320##EXT, \
367 &op_swizzle_0213##EXT, \
368 &op_swizzle_0231##EXT, \
369 &op_swizzle_0312##EXT, \
370 &op_swizzle_3120##EXT, \
371 &op_swizzle_0321##EXT, \
372 &op_swizzle_0003##EXT, \
373 &op_swizzle_0001##EXT, \
374 &op_swizzle_3000##EXT, \
375 &op_swizzle_1000##EXT, \
376 &op_clear_alpha0##EXT, \
377 &op_clear_alpha1##EXT, \
378 &op_clear_alpha3##EXT, \
379 &op_clear_zero0##EXT, \
380 &op_clear_zero1##EXT, \
381 &op_clear_zero3##EXT, \
382 REF_PATTERN(clear##EXT, 1, 1, 1, 0), \
383 REF_PATTERN(clear##EXT, 0, 1, 1, 1), \
384 REF_PATTERN(clear##EXT, 0, 0, 1, 1), \
385 REF_PATTERN(clear##EXT, 1, 0, 0, 1), \
386 REF_PATTERN(clear##EXT, 1, 1, 0, 0), \
387 REF_PATTERN(clear##EXT, 0, 1, 0, 1), \
388 REF_PATTERN(clear##EXT, 1, 0, 1, 0), \
389 REF_PATTERN(clear##EXT, 1, 0, 0, 0), \
390 REF_PATTERN(clear##EXT, 0, 1, 0, 0), \
391 REF_PATTERN(clear##EXT, 0, 0, 1, 0), \
396 #define DECL_FUNCS_16(SIZE, EXT, FLAG) \
397 DECL_PACKED_RW(EXT, 16) \
398 DECL_EXPAND_BITS(EXT, 16) \
399 DECL_PACK_UNPACK(EXT, U16, 4, 4, 4, 0) \
400 DECL_PACK_UNPACK(EXT, U16, 5, 5, 5, 0) \
401 DECL_PACK_UNPACK(EXT, U16, 5, 6, 5, 0) \
402 DECL_SWAP_BYTES(EXT, U16, 1, 0, 0, 0) \
403 DECL_SWAP_BYTES(EXT, U16, 1, 0, 0, 1) \
404 DECL_SWAP_BYTES(EXT, U16, 1, 1, 1, 0) \
405 DECL_SWAP_BYTES(EXT, U16, 1, 1, 1, 1) \
407 DECL_CONVERT(EXT, U8, U16) \
408 DECL_CONVERT(EXT, U16, U8) \
409 DECL_EXPAND(EXT, U8, U16) \
411 static const SwsOpTable ops16##EXT = { \
412 .cpu_flags = AV_CPU_FLAG_##FLAG, \
413 .block_size = SIZE, \
415 &op_read16_packed2##EXT, \
416 &op_read16_packed3##EXT, \
417 &op_read16_packed4##EXT, \
418 &op_write16_packed2##EXT, \
419 &op_write16_packed3##EXT, \
420 &op_write16_packed4##EXT, \
421 &op_pack_4440##EXT, \
422 &op_pack_5550##EXT, \
423 &op_pack_5650##EXT, \
424 &op_unpack_4440##EXT, \
425 &op_unpack_5550##EXT, \
426 &op_unpack_5650##EXT, \
427 &op_expand_bits16##EXT, \
428 REF_COMMON_PATTERNS(swap_bytes_U16##EXT), \
429 REF_COMMON_PATTERNS(convert_U8_U16##EXT), \
430 REF_COMMON_PATTERNS(convert_U16_U8##EXT), \
431 REF_COMMON_PATTERNS(expand_U8_U16##EXT), \
432 REF_COMMON_PATTERNS(lshift16##EXT), \
433 REF_COMMON_PATTERNS(rshift16##EXT), \
438 #define DECL_FUNCS_32(SIZE, EXT, FLAG) \
439 DECL_PACKED_RW(_m2##EXT, 32) \
440 DECL_PACK_UNPACK(_m2##EXT, U32, 10, 10, 10, 2) \
441 DECL_PACK_UNPACK(_m2##EXT, U32, 2, 10, 10, 10) \
442 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 0, 0, 0) \
443 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 0, 0, 1) \
444 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 1, 1, 0) \
445 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 1, 1, 1) \
446 DECL_CONVERT(EXT, U8, U32) \
447 DECL_CONVERT(EXT, U32, U8) \
448 DECL_CONVERT(EXT, U16, U32) \
449 DECL_CONVERT(EXT, U32, U16) \
450 DECL_CONVERT(EXT, U8, F32) \
451 DECL_CONVERT(EXT, F32, U8) \
452 DECL_CONVERT(EXT, U16, F32) \
453 DECL_CONVERT(EXT, F32, U16) \
454 DECL_EXPAND(EXT, U8, U32) \
457 DECL_DITHER(DECL_COMMON_PATTERNS, EXT, 0) \
458 DECL_DITHER(DECL_ASM, EXT, 1) \
459 DECL_DITHER(DECL_ASM, EXT, 2) \
460 DECL_DITHER(DECL_ASM, EXT, 3) \
461 DECL_DITHER(DECL_ASM, EXT, 4) \
462 DECL_DITHER(DECL_ASM, EXT, 5) \
463 DECL_DITHER(DECL_ASM, EXT, 6) \
464 DECL_DITHER(DECL_ASM, EXT, 7) \
465 DECL_DITHER(DECL_ASM, EXT, 8) \
466 DECL_LINEAR(EXT, luma, SWS_MASK_LUMA) \
467 DECL_LINEAR(EXT, alpha, SWS_MASK_ALPHA) \
468 DECL_LINEAR(EXT, lumalpha, SWS_MASK_LUMA | SWS_MASK_ALPHA) \
469 DECL_LINEAR(EXT, dot3, 0x7) \
470 DECL_LINEAR(EXT, row0, SWS_MASK_ROW(0)) \
471 DECL_LINEAR(EXT, row0a, SWS_MASK_ROW(0) | SWS_MASK_ALPHA) \
472 DECL_LINEAR(EXT, diag3, SWS_MASK_DIAG3) \
473 DECL_LINEAR(EXT, diag4, SWS_MASK_DIAG4) \
474 DECL_LINEAR(EXT, diagoff3, SWS_MASK_DIAG3 | SWS_MASK_OFF3) \
475 DECL_LINEAR(EXT, matrix3, SWS_MASK_MAT3) \
476 DECL_LINEAR(EXT, affine3, SWS_MASK_MAT3 | SWS_MASK_OFF3) \
477 DECL_LINEAR(EXT, affine3a, SWS_MASK_MAT3 | SWS_MASK_OFF3 | SWS_MASK_ALPHA) \
478 DECL_LINEAR(EXT, matrix4, SWS_MASK_MAT4) \
479 DECL_LINEAR(EXT, affine4, SWS_MASK_MAT4 | SWS_MASK_OFF4) \
481 static const SwsOpTable ops32##EXT = { \
482 .cpu_flags = AV_CPU_FLAG_##FLAG, \
483 .block_size = SIZE, \
485 &op_read32_packed2_m2##EXT, \
486 &op_read32_packed3_m2##EXT, \
487 &op_read32_packed4_m2##EXT, \
488 &op_write32_packed2_m2##EXT, \
489 &op_write32_packed3_m2##EXT, \
490 &op_write32_packed4_m2##EXT, \
491 &op_pack_1010102_m2##EXT, \
492 &op_pack_2101010_m2##EXT, \
493 &op_unpack_1010102_m2##EXT, \
494 &op_unpack_2101010_m2##EXT, \
495 REF_COMMON_PATTERNS(swap_bytes_U32_m2##EXT), \
496 REF_COMMON_PATTERNS(convert_U8_U32##EXT), \
497 REF_COMMON_PATTERNS(convert_U32_U8##EXT), \
498 REF_COMMON_PATTERNS(convert_U16_U32##EXT), \
499 REF_COMMON_PATTERNS(convert_U32_U16##EXT), \
500 REF_COMMON_PATTERNS(convert_U8_F32##EXT), \
501 REF_COMMON_PATTERNS(convert_F32_U8##EXT), \
502 REF_COMMON_PATTERNS(convert_U16_F32##EXT), \
503 REF_COMMON_PATTERNS(convert_F32_U16##EXT), \
504 REF_COMMON_PATTERNS(expand_U8_U32##EXT), \
505 REF_COMMON_PATTERNS(min##EXT), \
506 REF_COMMON_PATTERNS(max##EXT), \
507 REF_COMMON_PATTERNS(scale##EXT), \
508 REF_COMMON_PATTERNS(dither0##EXT), \
566 return !(
op->rw.elems > 1 &&
op->rw.packed) && !
op->rw.frac;
591 const int num_lanes = mmsize / 16;
594 const int read_size = in_total <= 4 ? 4 :
602 .block_size = pixels * num_lanes,
603 .over_read = read_size - in_total,
604 .over_write = mmsize - out_total,
613 #define ASSIGN_SHUFFLE_FUNC(IN, OUT, EXT) \
615 SWS_DECL_FUNC(ff_packed_shuffle##IN##_##OUT##_##EXT); \
616 if (in_total == IN && out_total == OUT) \
617 out->func = ff_packed_shuffle##IN##_##OUT##_##EXT; \
643 static_assert(
sizeof(uint32_t) ==
sizeof(
int),
"int size mismatch");
651 for (
int i = 0;
i < 4;
i++) {
652 if (!
op->c.q4[
i].den)
655 case 1:
c.u32 = 0x1010101
U * priv.
u8[
i];
break;
656 case 2:
c.u32 = (uint32_t)priv.
u16[
i] << 16 | priv.
u16[
i];
break;
657 case 4:
c.u32 = priv.
u32[
i];
break;
660 op->c.q4[
i].num =
c.i;
697 out->over_read =
sizeof(uint32_t);
699 out->over_write =
sizeof(uint32_t);
712 int op_block_size =
out->block_size;
723 op_block_size, chain);
730 #define ASSIGN_PROCESS_FUNC(NAME) \
732 SWS_DECL_FUNC(NAME); \
733 void NAME##_return(void); \
734 ret = ff_sws_op_chain_append(chain, NAME##_return, \
735 NULL, &(SwsOpPriv) {0}); \
739 const int read_planes =
read ? (
read->rw.packed ? 1 :
read->rw.elems) : 0;
741 switch (
FFMAX(read_planes, write_planes)) {
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)
static int setup_linear(const SwsOp *op, SwsOpPriv *out)
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
int ff_sws_pixel_type_size(SwsPixelType type)
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Writing a table generator This documentation is preliminary Parts of the API are not good and should be changed Basic concepts A table generator consists of two *_tablegen c and *_tablegen h The h file will provide the variable declarations and initialization code for the tables
#define AV_CPU_FLAG_AVX512
AVX-512 functions: requires OS support even if YMM/ZMM registers aren't used.
static int setup_dither(const SwsOp *op, SwsOpPriv *out)
#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 AVFormatContext * ctx
#define AV_CPU_FLAG_SSE4
Penryn SSE4.1 functions.
Compiled "chain" of operations, which can be dispatched efficiently.
int ff_sws_op_compile_tables(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.
Rational number (pair of numerator and denominator).
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)
void ff_sws_op_chain_free_cb(void *ptr)
static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out)
void(* free[SWS_MAX_OPS+1])(void *)
static int setup_swap_bytes(const SwsOp *op, SwsOpPriv *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...
int ff_sws_setup_q4(const SwsOp *op, SwsOpPriv *out)
#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)
#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...
static int setup_shift(const SwsOp *op, SwsOpPriv *out)
static int setup_clear(const SwsOp *op, SwsOpPriv *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.
Copyright (C) 2025 Niklas Haas.
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.