Go to the documentation of this file.
34 if (
a->type !=
b->type)
35 return (
int)
a->type -
b->type;
37 return (
int)
a->uop -
b->uop;
38 if (
a->mask !=
b->mask)
39 return (
int)
a->mask -
b->mask;
40 return memcmp(&
a->par, &
b->par,
sizeof(
a->par));
48 #define UOP_NAME(OP, ABBR) [SWS_UOP_##OP] = { "SWS_UOP_" #OP, ABBR, #OP }
50 UOP_NAME(READ_PLANAR,
"read_planar"),
51 UOP_NAME(READ_PLANAR_FH,
"read_planar_fh"),
52 UOP_NAME(READ_PLANAR_FV,
"read_planar_fv"),
53 UOP_NAME(READ_PLANAR_FV_FMA,
"read_planar_fv_fma"),
54 UOP_NAME(READ_PACKED,
"read_packed"),
55 UOP_NAME(READ_NIBBLE,
"read_nibble"),
57 UOP_NAME(WRITE_PLANAR,
"write_planar"),
58 UOP_NAME(WRITE_PACKED,
"write_packed"),
59 UOP_NAME(WRITE_NIBBLE,
"write_nibble"),
66 UOP_NAME(EXPAND_PAIR,
"expand_pair"),
67 UOP_NAME(EXPAND_QUAD,
"expand_quad"),
114 #define Q2PIXEL(val) pixel_from_q(op->type, val)
119 case 1:
return val.u8 == UINT8_MAX;
120 case 2:
return val.u16 == UINT16_MAX;
121 case 4:
return val.u32 == UINT32_MAX;
140 for (
int i = 0;
i < 4;
i++) {
160 for (
int i = 0;
i < 4;
i++) {
181 for (
int i = 0;
i < 4;
i++) {
194 for (
int i = 0;
i < 4;
i++) {
198 for (
int j = 0; j < 5; j++) {
211 for (
int i = 0;
i < 4;
i++) {
227 AVBPrint *bp =
ref->data.opaque;
231 av_bprintf(bp,
", .type = %-13s, .uop = %-24s, .mask = 0x%x",
247 av_bprintf(bp,
", .par.swizzle.in = {%d, %d, %d, %d}",
253 av_bprintf(bp,
", .par.move.dst = {%d, %d, %d, %d, %d, %d}",
256 av_bprintf(bp,
", .par.move.src = {%d, %d, %d, %d, %d, %d}",
262 av_bprintf(bp,
", .par.pack.pattern = {%d, %d, %d, %d}",
267 av_bprintf(bp,
", .par.clear.one = 0x%x, .par.clear.zero = 0x%x",
272 av_bprintf(bp,
", .par.lin.one = 0x%x, .par.lin.zero = 0x%x",
278 av_bprintf(bp,
", .par.dither = { .y_offset = {%u, %u, %u, %u}, .size_log2 = %u }",
293 AVBPrint *bp =
ref->data.opaque;
296 av_bprintf(bp,
" \\\n MACRO(__VA_ARGS__, %-40s, %-13s, %-24s, 0x%x",
390 sizeof(*uop), (uint8_t *) uop))
403 for (
int i = 0;
i < 4;
i++)
405 return (1 <<
dither->size_log2) + max_offset;
423 volatile float prod =
a *
b;
424 volatile float result =
b ? prod /
b : 0.0f;
435 else if (!minq.
den || !maxq.
den)
460 const uint64_t max_val = UINT64_MAX >> (64 -
bits);
474 op->rw.elems > 2,
op->rw.elems > 3),
494 }
else if (
op->rw.packed &&
op->rw.elems > 1) {
498 }
else if (
op->rw.frac == 3) {
500 }
else if (
op->rw.frac == 1) {
513 for (
size_t i = 0;
i <
size;
i++) {
531 for (
int i = 0;
i < 4;
i++) {
532 if (
op->swizzle.in[
i] ==
i)
538 for (
int i = 0;
i < 4;
i++) {
544 int idx[4 + 1] = { 0, 1, 2, 3, -1 };
554 const int cur = idx[
dst];
558 if (idx[
src] ==
op->swizzle.in[
dst]) {
601 .par.swizzle.in = {0, 1, 2, 3},
605 for (
int i = 0;
i < 4;
i++) {
608 const int src =
op->swizzle.in[
i];
617 for (
int i = 0;
i < 4;
i++) {
624 for (
int j = 0; j < 4; j++) {
638 for (
int i = 0;
i < 4;
i++) {
651 .par.dither.size_log2 =
op->dither.size_log2,
654 if (
op->dither.size_log2 == 0) {
658 for (
int i = 0;
i < 4;
i++) {
668 const int size = 1 <<
op->dither.size_log2;
669 for (
int i = 0;
i < 4;
i++) {
672 const uint8_t off =
op->dither.y_offset[
i] & (
size - 1);
706 for (
int i = 0;
i < 4;
i++) {
709 for (
int j = 0; j < 5; j++) {
778 if (
op->convert.expand) {
780 switch (
op->convert.to) {
785 switch (
op->convert.to) {
797 for (
int i = 0;
i < 4 &&
op->pack.pattern[
i];
i++) {
810 uop.
mask &=
op->clear.mask;
811 for (
int i = 0;
i < 4;
i++) {
835 for (
int i = 0;
i < 4;
i++) {
868 memset(&
key->data, 0,
sizeof(
key->data));
951 if (
a->type !=
b->type)
952 return (
int)
b->type -
a->type;
953 if (
a->uop !=
b->uop)
954 return (
int)
b->uop -
a->uop;
969 AVBPrint bprint, *
const bp = &bprint;
1004 for (
int elems = 1; elems <= 4; elems++) {
1005 for (
int rw = 0; rw < 2; rw++) {
1019 #define BPRINT_STR(str) av_bprint_append_data(bp, str, strlen(str))
1022 " * This file is automatically generated. Do not edit manually.\n"
1023 " * To regenerate, run: make fate-sws-uops-macros GEN=1\n"
1026 "#ifndef SWSCALE_UOPS_MACROS_H\n"
1027 "#define SWSCALE_UOPS_MACROS_H\n"
1030 " * Boilerplate helper macros, for template-based backends. These will be\n"
1031 " * instantiated like this, with parameters in struct order:\n"
1032 " * MACRO(__VA_ARGS__, NAME, UOP, TYPE, MASK, [PARAMS,])\n"
1033 " * The _STRUCT variants pass all arguments in C struct syntax, while the\n"
1034 " * plain variants give them as separate C values (e.g. for use in calls)\n"
1036 "#define SWS_GLUE3(x, y, z) x ## _ ## y ## _ ## z\n"
1037 "#define SWS_FOR(TYPE, UOP, MACRO, ...) \\\n"
1038 " SWS_GLUE3(SWS_FOR, TYPE, UOP)(MACRO, __VA_ARGS__)\n"
1039 "#define SWS_FOR_STRUCT(TYPE, UOP, MACRO, ...) \\\n"
1040 " SWS_GLUE3(SWS_FOR_STRUCT, TYPE, UOP)(MACRO, __VA_ARGS__)\n"
1057 BPRINT_STR(
"\n#endif /* SWSCALE_UOPS_MACROS_H */");
static SwsPixel pixel_from_q(SwsPixelType type, AVRational val)
static const int factor[16]
#define AV_BPRINT_SIZE_UNLIMITED
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
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
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
SwsOpList * ff_sws_op_list_duplicate(const SwsOpList *ops)
Returns a duplicate of ops, or NULL on OOM.
static int free_uop_key(void *opaque, void *key)
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
SwsComps comps_src
Source component metadata associated with pixel values from each corresponding component (in plane/me...
static int ff_sws_uop_cmp_v(const void *a, const void *b)
void * av_tree_insert(AVTreeNode **tp, void *key, int(*cmp)(const void *key, const void *b), AVTreeNode **next)
Insert or remove an element.
@ SWS_SCALE_BILINEAR
bilinear filtering
#define u(width, name, range_min, range_max)
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.
static int translate_rw_op(SwsContext *ctx, SwsUOpList *ops, SwsUOpFlags flags, const SwsOp *op)
int ff_sws_uop_cmp(const SwsUOp *a, const SwsUOp *b)
Copyright (C) 2026 Niklas Haas.
#define SWS_COMP_MASK(X, Y, Z, W)
struct AVTreeNode * av_tree_node_alloc(void)
Allocate an AVTreeNode.
#define SWS_UOP_NAME_MAX
Generate a unique name for a SwsUOp.
int ff_sws_pixel_type_size(SwsPixelType type)
void av_tree_enumerate(AVTreeNode *t, void *opaque, int(*cmp)(void *opaque, void *elem), int(*enu)(void *opaque, void *elem))
Apply enu(opaque, &elem) to all the elements in the tree in a given range.
static bool check_filter_fma(SwsContext *ctx, SwsUOpFlags flags, const SwsOp *op)
SwsGraph * ff_sws_graph_alloc(void)
Allocate an empty SwsGraph.
SwsCompMask ff_sws_comp_mask_needed(const SwsOp *op)
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
static int enum_type(void *opaque, void *elem)
#define SWS_COMP_TEST(mask, X)
void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size)
Init a print buffer using a pre-existing buffer.
static int translate_move(SwsUOpList *ops, const SwsOp *op)
#define UOP_NAME(OP, ABBR)
bool ff_sws_pixel_type_is_int(SwsPixelType type)
static double val(void *priv, double ch)
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
#define SWS_COMP_ELEMS(N)
static void * av_refstruct_allocz(size_t size)
Equivalent to av_refstruct_alloc_ext(size, 0, NULL, NULL)
#define FF_ARRAY_ELEMS(a)
static const SwsUOpFlags uop_flags[]
#define SWS_OP_NEEDED(op, idx)
SwsFilterWeights * kernel
static const uint16_t dither[8][8]
int flags
Flags modifying the (de)muxer behaviour.
static const SwsOpBackend backend_uops
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_assert0(cond)
assert() equivalent, that is always enabled.
static AVFormatContext * ctx
uint8_t SwsCompMask
Bit-mask of components.
static int count_idx(const int *arr, size_t size, int val)
static int register_flags(SwsContext *ctx, const SwsOpList *ops, SwsUOpFlags flags)
and forward the result(frame or status change) to the corresponding input. If nothing is possible
static const SwsFlags flags[]
static int translate_swizzle(SwsUOpList *ops, SwsUOpFlags flags, const SwsOp *op)
Rational number (pair of numerator and denominator).
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
int8_t dst[SWS_UOP_MOVE_MAX]
static int generate_entry_struct(void *opaque, void *key)
static int translate_dither_op(SwsUOpList *ops, const SwsOp *op)
void av_tree_destroy(AVTreeNode *t)
static bool pixel_is_1s(SwsPixelType type, SwsPixel val)
static bool exact_prod(SwsPixelType type, SwsPixel coef, const SwsComps *comps, int idx)
void ff_sws_graph_free(SwsGraph **pgraph)
Uninitialize any state associate with this filter graph and free it.
static void uop_uninit(SwsUOp *uop)
static void copy(const float *p1, float *p2, const int length)
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
@ SWS_UOP_READ_PLANAR_FV_FMA
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
#define i(width, name, range_min, range_max)
static const struct @583 pixel_types[SWS_PIXEL_TYPE_NB]
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
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
SwsComps comps
Metadata about the operation's input/output components.
static int register_uop(struct AVTreeNode **root, const SwsUOp *uop)
int ff_sws_uops_macros_gen(char **out_str)
Generate a set of boilerplate C preprocessor macros for describing and programmatically iterating ove...
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
SwsUOpList * ff_sws_uop_list_alloc(void)
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
SwsCompMask ff_sws_comp_mask_q4(const AVRational q[4])
static const struct @582 uop_names[SWS_UOP_TYPE_NB]
static bool is_expand_bit(SwsPixelType type, AVRational factor)
static int register_all_uops(SwsContext *ctx, void *graph, SwsOpList *ops)
static bool exact_product_f32(float a, float b)
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is needed
int ff_sws_enum_op_lists(SwsContext *ctx, void *opaque, enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt, int(*cb)(SwsContext *ctx, void *opaque, SwsOpList *ops))
Helper function to enumerate over all possible (optimized) operation lists, under the current set of ...
static SwsPixelType pixel_type_to_int(const SwsPixelType type)
int ff_sws_ops_translate(SwsContext *ctx, const SwsOpList *ops, SwsUOpFlags flags, SwsUOpList *uops)
Translate a list of operations down to micro-ops, which can be further optimized and then directly ex...
void ff_sws_uop_list_free(SwsUOpList **p_ops)
void av_bprintf(AVBPrint *buf, const char *fmt,...)
const char * ff_sws_pixel_type_name(SwsPixelType type)
void ff_sws_uop_name(const SwsUOp *op, char buf[SWS_UOP_NAME_MAX])
static int ref[MAX_W *MAX_W]
int ff_sws_uop_list_append(SwsUOpList *uops, SwsUOp *uop)
int ff_sws_compile_pass(SwsGraph *graph, const SwsOpBackend *backend, SwsOpList **pops, int flags, SwsPass *input, SwsPass **output)
Resolves an operation list to a graph pass.
static int generate_entry_args(void *opaque, void *key)
@ SWS_FILTER_SCALE
14-bit coefficients are picked to fit comfortably within int16_t for efficient SIMD processing (e....
Filter graph, which represents a 'baked' pixel format conversion.
void sws_free_context(SwsContext **ctx)
Free the context and everything associated with it, and write NULL to the provided pointer.
int8_t src[SWS_UOP_MOVE_MAX]
static int translate_linear_op(SwsContext *ctx, SwsUOpList *ops, SwsUOpFlags flags, const SwsOp *op, const SwsComps *input)
int ff_sws_dither_height(const SwsDitherUOp *dither)
Computes (1 << size_log2) + MAX(y_offset).
static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags, const SwsOp *op, const SwsComps *input)
@ SWS_ACCURATE_RND
Force bit-exact output.
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Helper struct for representing a list of operations.
Main external API structure.
static int register_uops(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out)