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 static_assert(
sizeof(
SwsOpPriv) >=
sizeof(
float[2][2]),
"2x2 dither matrix too large");
191 const int size = 1 <<
op->dither.size_log2;
200 matrix[
i] = (
float)
op->dither.matrix[
i].num /
op->dither.matrix[
i].den;
205 #define DECL_DITHER(EXT, SIZE) \
206 DECL_COMMON_PATTERNS(F32, dither##SIZE##EXT, \
207 .op = SWS_OP_DITHER, \
208 .setup = setup_dither, \
209 .free = SIZE > 2 ? av_free : NULL, \
210 .dither_size = SIZE, \
219 for (
int y = 0; y < 4; y++) {
220 for (
int x = 0; x < 5; x++)
221 matrix[y * 5 + x] = (
float)
op->lin.m[y][x].num /
op->lin.m[y][x].den;
227 #define DECL_LINEAR(EXT, NAME, MASK) \
228 DECL_ASM(F32, NAME##EXT, \
229 .op = SWS_OP_LINEAR, \
230 .setup = setup_linear, \
232 .linear_mask = (MASK), \
235 #define DECL_FUNCS_8(SIZE, EXT, FLAG) \
236 DECL_RW(EXT, U8, read_planar, READ, 1, false, 0) \
237 DECL_RW(EXT, U8, read_planar, READ, 2, false, 0) \
238 DECL_RW(EXT, U8, read_planar, READ, 3, false, 0) \
239 DECL_RW(EXT, U8, read_planar, READ, 4, false, 0) \
240 DECL_RW(EXT, U8, write_planar, WRITE, 1, false, 0) \
241 DECL_RW(EXT, U8, write_planar, WRITE, 2, false, 0) \
242 DECL_RW(EXT, U8, write_planar, WRITE, 3, false, 0) \
243 DECL_RW(EXT, U8, write_planar, WRITE, 4, false, 0) \
244 DECL_RW(EXT, U8, read_nibbles, READ, 1, false, 1) \
245 DECL_RW(EXT, U8, read_bits, READ, 1, false, 3) \
246 DECL_RW(EXT, U8, write_bits, WRITE, 1, false, 3) \
247 DECL_PACKED_RW(EXT, 8) \
248 DECL_PACK_UNPACK(EXT, U8, 1, 2, 1, 0) \
249 DECL_PACK_UNPACK(EXT, U8, 3, 3, 2, 0) \
250 DECL_PACK_UNPACK(EXT, U8, 2, 3, 3, 0) \
251 void ff_p1000_shuffle##EXT(void); \
252 void ff_p1001_shuffle##EXT(void); \
253 void ff_p1110_shuffle##EXT(void); \
254 void ff_p1111_shuffle##EXT(void); \
255 DECL_SWIZZLE(EXT, 3, 0, 1, 2) \
256 DECL_SWIZZLE(EXT, 3, 0, 2, 1) \
257 DECL_SWIZZLE(EXT, 2, 1, 0, 3) \
258 DECL_SWIZZLE(EXT, 3, 2, 1, 0) \
259 DECL_SWIZZLE(EXT, 3, 1, 0, 2) \
260 DECL_SWIZZLE(EXT, 3, 2, 0, 1) \
261 DECL_SWIZZLE(EXT, 1, 2, 0, 3) \
262 DECL_SWIZZLE(EXT, 1, 0, 2, 3) \
263 DECL_SWIZZLE(EXT, 2, 0, 1, 3) \
264 DECL_SWIZZLE(EXT, 2, 3, 1, 0) \
265 DECL_SWIZZLE(EXT, 2, 1, 3, 0) \
266 DECL_SWIZZLE(EXT, 1, 2, 3, 0) \
267 DECL_SWIZZLE(EXT, 1, 3, 2, 0) \
268 DECL_SWIZZLE(EXT, 0, 2, 1, 3) \
269 DECL_SWIZZLE(EXT, 0, 2, 3, 1) \
270 DECL_SWIZZLE(EXT, 0, 3, 1, 2) \
271 DECL_SWIZZLE(EXT, 3, 1, 2, 0) \
272 DECL_SWIZZLE(EXT, 0, 3, 2, 1) \
273 DECL_SWIZZLE(EXT, 0, 0, 0, 3) \
274 DECL_SWIZZLE(EXT, 3, 0, 0, 0) \
275 DECL_SWIZZLE(EXT, 0, 0, 0, 1) \
276 DECL_SWIZZLE(EXT, 1, 0, 0, 0) \
277 DECL_CLEAR_ALPHA(EXT, 0) \
278 DECL_CLEAR_ALPHA(EXT, 1) \
279 DECL_CLEAR_ALPHA(EXT, 3) \
280 DECL_CLEAR_ZERO(EXT, 0) \
281 DECL_CLEAR_ZERO(EXT, 1) \
282 DECL_CLEAR_ZERO(EXT, 3) \
283 DECL_CLEAR(EXT, 1, 1, 1, 0) \
284 DECL_CLEAR(EXT, 0, 1, 1, 1) \
285 DECL_CLEAR(EXT, 0, 0, 1, 1) \
286 DECL_CLEAR(EXT, 1, 0, 0, 1) \
287 DECL_CLEAR(EXT, 1, 1, 0, 0) \
288 DECL_CLEAR(EXT, 0, 1, 0, 1) \
289 DECL_CLEAR(EXT, 1, 0, 1, 0) \
290 DECL_CLEAR(EXT, 1, 0, 0, 0) \
291 DECL_CLEAR(EXT, 0, 1, 0, 0) \
292 DECL_CLEAR(EXT, 0, 0, 1, 0) \
294 static const SwsOpTable ops8##EXT = { \
295 .cpu_flags = AV_CPU_FLAG_##FLAG, \
296 .block_size = SIZE, \
298 &op_read_planar1##EXT, \
299 &op_read_planar2##EXT, \
300 &op_read_planar3##EXT, \
301 &op_read_planar4##EXT, \
302 &op_write_planar1##EXT, \
303 &op_write_planar2##EXT, \
304 &op_write_planar3##EXT, \
305 &op_write_planar4##EXT, \
306 &op_read8_packed2##EXT, \
307 &op_read8_packed3##EXT, \
308 &op_read8_packed4##EXT, \
309 &op_write8_packed2##EXT, \
310 &op_write8_packed3##EXT, \
311 &op_write8_packed4##EXT, \
312 &op_read_nibbles1##EXT, \
313 &op_read_bits1##EXT, \
314 &op_write_bits1##EXT, \
315 &op_pack_1210##EXT, \
316 &op_pack_3320##EXT, \
317 &op_pack_2330##EXT, \
318 &op_unpack_1210##EXT, \
319 &op_unpack_3320##EXT, \
320 &op_unpack_2330##EXT, \
321 &op_swizzle_3012##EXT, \
322 &op_swizzle_3021##EXT, \
323 &op_swizzle_2103##EXT, \
324 &op_swizzle_3210##EXT, \
325 &op_swizzle_3102##EXT, \
326 &op_swizzle_3201##EXT, \
327 &op_swizzle_1203##EXT, \
328 &op_swizzle_1023##EXT, \
329 &op_swizzle_2013##EXT, \
330 &op_swizzle_2310##EXT, \
331 &op_swizzle_2130##EXT, \
332 &op_swizzle_1230##EXT, \
333 &op_swizzle_1320##EXT, \
334 &op_swizzle_0213##EXT, \
335 &op_swizzle_0231##EXT, \
336 &op_swizzle_0312##EXT, \
337 &op_swizzle_3120##EXT, \
338 &op_swizzle_0321##EXT, \
339 &op_swizzle_0003##EXT, \
340 &op_swizzle_0001##EXT, \
341 &op_swizzle_3000##EXT, \
342 &op_swizzle_1000##EXT, \
343 &op_clear_alpha0##EXT, \
344 &op_clear_alpha1##EXT, \
345 &op_clear_alpha3##EXT, \
346 &op_clear_zero0##EXT, \
347 &op_clear_zero1##EXT, \
348 &op_clear_zero3##EXT, \
349 REF_PATTERN(clear##EXT, 1, 1, 1, 0), \
350 REF_PATTERN(clear##EXT, 0, 1, 1, 1), \
351 REF_PATTERN(clear##EXT, 0, 0, 1, 1), \
352 REF_PATTERN(clear##EXT, 1, 0, 0, 1), \
353 REF_PATTERN(clear##EXT, 1, 1, 0, 0), \
354 REF_PATTERN(clear##EXT, 0, 1, 0, 1), \
355 REF_PATTERN(clear##EXT, 1, 0, 1, 0), \
356 REF_PATTERN(clear##EXT, 1, 0, 0, 0), \
357 REF_PATTERN(clear##EXT, 0, 1, 0, 0), \
358 REF_PATTERN(clear##EXT, 0, 0, 1, 0), \
363 #define DECL_FUNCS_16(SIZE, EXT, FLAG) \
364 DECL_PACKED_RW(EXT, 16) \
365 DECL_PACK_UNPACK(EXT, U16, 4, 4, 4, 0) \
366 DECL_PACK_UNPACK(EXT, U16, 5, 5, 5, 0) \
367 DECL_PACK_UNPACK(EXT, U16, 5, 6, 5, 0) \
368 DECL_SWAP_BYTES(EXT, U16, 1, 0, 0, 0) \
369 DECL_SWAP_BYTES(EXT, U16, 1, 0, 0, 1) \
370 DECL_SWAP_BYTES(EXT, U16, 1, 1, 1, 0) \
371 DECL_SWAP_BYTES(EXT, U16, 1, 1, 1, 1) \
373 DECL_CONVERT(EXT, U8, U16) \
374 DECL_CONVERT(EXT, U16, U8) \
375 DECL_EXPAND(EXT, U8, U16) \
377 static const SwsOpTable ops16##EXT = { \
378 .cpu_flags = AV_CPU_FLAG_##FLAG, \
379 .block_size = SIZE, \
381 &op_read16_packed2##EXT, \
382 &op_read16_packed3##EXT, \
383 &op_read16_packed4##EXT, \
384 &op_write16_packed2##EXT, \
385 &op_write16_packed3##EXT, \
386 &op_write16_packed4##EXT, \
387 &op_pack_4440##EXT, \
388 &op_pack_5550##EXT, \
389 &op_pack_5650##EXT, \
390 &op_unpack_4440##EXT, \
391 &op_unpack_5550##EXT, \
392 &op_unpack_5650##EXT, \
393 REF_COMMON_PATTERNS(swap_bytes_U16##EXT), \
394 REF_COMMON_PATTERNS(convert_U8_U16##EXT), \
395 REF_COMMON_PATTERNS(convert_U16_U8##EXT), \
396 REF_COMMON_PATTERNS(expand_U8_U16##EXT), \
397 REF_COMMON_PATTERNS(lshift16##EXT), \
398 REF_COMMON_PATTERNS(rshift16##EXT), \
403 #define DECL_FUNCS_32(SIZE, EXT, FLAG) \
404 DECL_PACKED_RW(_m2##EXT, 32) \
405 DECL_PACK_UNPACK(_m2##EXT, U32, 10, 10, 10, 2) \
406 DECL_PACK_UNPACK(_m2##EXT, U32, 2, 10, 10, 10) \
407 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 0, 0, 0) \
408 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 0, 0, 1) \
409 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 1, 1, 0) \
410 DECL_SWAP_BYTES(_m2##EXT, U32, 1, 1, 1, 1) \
411 DECL_CONVERT(EXT, U8, U32) \
412 DECL_CONVERT(EXT, U32, U8) \
413 DECL_CONVERT(EXT, U16, U32) \
414 DECL_CONVERT(EXT, U32, U16) \
415 DECL_CONVERT(EXT, U8, F32) \
416 DECL_CONVERT(EXT, F32, U8) \
417 DECL_CONVERT(EXT, U16, F32) \
418 DECL_CONVERT(EXT, F32, U16) \
419 DECL_EXPAND(EXT, U8, U32) \
422 DECL_DITHER(EXT, 0) \
423 DECL_DITHER(EXT, 1) \
424 DECL_DITHER(EXT, 2) \
425 DECL_DITHER(EXT, 3) \
426 DECL_DITHER(EXT, 4) \
427 DECL_DITHER(EXT, 5) \
428 DECL_DITHER(EXT, 6) \
429 DECL_DITHER(EXT, 7) \
430 DECL_DITHER(EXT, 8) \
431 DECL_LINEAR(EXT, luma, SWS_MASK_LUMA) \
432 DECL_LINEAR(EXT, alpha, SWS_MASK_ALPHA) \
433 DECL_LINEAR(EXT, lumalpha, SWS_MASK_LUMA | SWS_MASK_ALPHA) \
434 DECL_LINEAR(EXT, dot3, 0x7) \
435 DECL_LINEAR(EXT, row0, SWS_MASK_ROW(0)) \
436 DECL_LINEAR(EXT, row0a, SWS_MASK_ROW(0) | SWS_MASK_ALPHA) \
437 DECL_LINEAR(EXT, diag3, SWS_MASK_DIAG3) \
438 DECL_LINEAR(EXT, diag4, SWS_MASK_DIAG4) \
439 DECL_LINEAR(EXT, diagoff3, SWS_MASK_DIAG3 | SWS_MASK_OFF3) \
440 DECL_LINEAR(EXT, matrix3, SWS_MASK_MAT3) \
441 DECL_LINEAR(EXT, affine3, SWS_MASK_MAT3 | SWS_MASK_OFF3) \
442 DECL_LINEAR(EXT, affine3a, SWS_MASK_MAT3 | SWS_MASK_OFF3 | SWS_MASK_ALPHA) \
443 DECL_LINEAR(EXT, matrix4, SWS_MASK_MAT4) \
444 DECL_LINEAR(EXT, affine4, SWS_MASK_MAT4 | SWS_MASK_OFF4) \
446 static const SwsOpTable ops32##EXT = { \
447 .cpu_flags = AV_CPU_FLAG_##FLAG, \
448 .block_size = SIZE, \
450 &op_read32_packed2_m2##EXT, \
451 &op_read32_packed3_m2##EXT, \
452 &op_read32_packed4_m2##EXT, \
453 &op_write32_packed2_m2##EXT, \
454 &op_write32_packed3_m2##EXT, \
455 &op_write32_packed4_m2##EXT, \
456 &op_pack_1010102_m2##EXT, \
457 &op_pack_2101010_m2##EXT, \
458 &op_unpack_1010102_m2##EXT, \
459 &op_unpack_2101010_m2##EXT, \
460 REF_COMMON_PATTERNS(swap_bytes_U32_m2##EXT), \
461 REF_COMMON_PATTERNS(convert_U8_U32##EXT), \
462 REF_COMMON_PATTERNS(convert_U32_U8##EXT), \
463 REF_COMMON_PATTERNS(convert_U16_U32##EXT), \
464 REF_COMMON_PATTERNS(convert_U32_U16##EXT), \
465 REF_COMMON_PATTERNS(convert_U8_F32##EXT), \
466 REF_COMMON_PATTERNS(convert_F32_U8##EXT), \
467 REF_COMMON_PATTERNS(convert_U16_F32##EXT), \
468 REF_COMMON_PATTERNS(convert_F32_U16##EXT), \
469 REF_COMMON_PATTERNS(expand_U8_U32##EXT), \
470 REF_COMMON_PATTERNS(min##EXT), \
471 REF_COMMON_PATTERNS(max##EXT), \
472 REF_COMMON_PATTERNS(scale##EXT), \
473 REF_COMMON_PATTERNS(dither0##EXT), \
474 REF_COMMON_PATTERNS(dither1##EXT), \
475 REF_COMMON_PATTERNS(dither2##EXT), \
476 REF_COMMON_PATTERNS(dither3##EXT), \
477 REF_COMMON_PATTERNS(dither4##EXT), \
478 REF_COMMON_PATTERNS(dither5##EXT), \
479 REF_COMMON_PATTERNS(dither6##EXT), \
480 REF_COMMON_PATTERNS(dither7##EXT), \
481 REF_COMMON_PATTERNS(dither8##EXT), \
531 return !
op->rw.packed && !
op->rw.frac;
556 const int num_lanes = mmsize / 16;
559 const int read_size = in_total <= 4 ? 4 :
566 .block_size = pixels * num_lanes,
567 .over_read = read_size - in_total,
568 .over_write = mmsize - out_total,
577 #define ASSIGN_SHUFFLE_FUNC(IN, OUT, EXT) \
579 SWS_DECL_FUNC(ff_packed_shuffle##IN##_##OUT##_##EXT); \
580 if (in_total == IN && out_total == OUT) \
581 out->func = ff_packed_shuffle##IN##_##OUT##_##EXT; \
607 static_assert(
sizeof(uint32_t) ==
sizeof(
int),
"int size mismatch");
615 for (
int i = 0;
i < 4;
i++) {
616 if (!
op->c.q4[
i].den)
619 case 1:
c.u32 = 0x1010101 * priv.
u8[
i];
break;
620 case 2:
c.u32 = priv.
u16[
i] << 16 | priv.
u16[
i];
break;
621 case 4:
c.u32 = priv.
u32[
i];
break;
624 op->c.q4[
i].num =
c.i;
659 if (
read.rw.packed &&
read.rw.elems == 3)
660 out->over_read =
sizeof(uint32_t);
662 out->over_write =
sizeof(uint32_t);
675 int op_block_size =
out->block_size;
686 op_block_size, chain);
693 #define ASSIGN_PROCESS_FUNC(NAME) \
695 SWS_DECL_FUNC(NAME); \
696 void NAME##_return(void); \
697 ret = ff_sws_op_chain_append(chain, NAME##_return, \
698 NULL, (SwsOpPriv) {0}); \
702 const int read_planes =
read.rw.packed ? 1 :
read.rw.elems;
704 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.
#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.
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 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 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.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
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)
void ff_sws_op_chain_free(SwsOpChain *chain)
#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.