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));
47 #define UOP_NAME(OP, ABBR) [OP] = { #OP, ABBR }
114 #define Q2PIXEL(val) pixel_from_q64(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;
154 for (
int i = 0;
i < 4;
i++)
159 for (
int i = 0;
i < 4;
i++) {
180 for (
int i = 0;
i < 4;
i++) {
193 for (
int i = 0;
i < 4;
i++) {
197 for (
int j = 0; j < 5; j++) {
210 for (
int i = 0;
i < 4;
i++) {
226 AVBPrint *bp =
ref->data.opaque;
230 av_bprintf(bp,
", .type = %-13s, .uop = %-24s, .mask = 0x%x",
246 av_bprintf(bp,
", .par.swizzle.in = {%d, %d, %d, %d}",
252 av_bprintf(bp,
", .par.move.dst = {%d, %d, %d, %d, %d, %d}",
255 av_bprintf(bp,
", .par.move.src = {%d, %d, %d, %d, %d, %d}",
261 av_bprintf(bp,
", .par.pack.pattern = {%d, %d, %d, %d}",
266 av_bprintf(bp,
", .par.clear.one = 0x%x, .par.clear.zero = 0x%x",
271 av_bprintf(bp,
", .par.lin.one = 0x%x, .par.lin.zero = 0x%x",
277 av_bprintf(bp,
", .par.dither = { .y_offset = {%u, %u, %u, %u}, .size_log2 = %u }",
292 AVBPrint *bp =
ref->data.opaque;
295 av_bprintf(bp,
" \\\n MACRO(__VA_ARGS__, %-40s, %-13s, %-24s, 0x%x",
389 sizeof(*uop), (uint8_t *) uop))
402 for (
int i = 0;
i < 4;
i++)
404 return (1 <<
dither->size_log2) + max_offset;
422 volatile float prod =
a *
b;
423 volatile float result =
b ? prod /
b : 0.0f;
434 else if (!minq.
den || !maxq.
den)
459 const uint64_t max_val = UINT64_MAX >> (64 -
bits);
473 op->rw.elems > 2,
op->rw.elems > 3),
477 if (!
op->rw.filter.op)
481 if (
op->rw.filter.op) {
498 if (
op->rw.frac || !is_read)
501 }
else if (
op->rw.frac == 3) {
503 }
else if (
op->rw.frac == 1) {
516 for (
size_t i = 0;
i <
size;
i++) {
534 for (
int i = 0;
i < 4;
i++) {
535 if (
op->swizzle.in[
i] ==
i)
541 for (
int i = 0;
i < 4;
i++) {
547 int idx[4 + 1] = { 0, 1, 2, 3, -1 };
557 const int cur = idx[
dst];
561 if (idx[
src] ==
op->swizzle.in[
dst]) {
603 .par.swizzle.in = {0, 1, 2, 3},
608 for (
int i = 0;
i < 4;
i++) {
611 const int src =
op->swizzle.in[
i];
620 for (
int i = 0;
i < 4;
i++) {
627 for (
int j = 0; j < 4; j++) {
642 for (
int i = 0;
i < 4;
i++) {
658 .par.dither.size_log2 =
op->dither.size_log2,
661 if (
op->dither.size_log2 == 0) {
665 for (
int i = 0;
i < 4;
i++) {
675 const int size = 1 <<
op->dither.size_log2;
676 for (
int i = 0;
i < 4;
i++) {
679 const uint8_t off =
op->dither.y_offset[
i] & (
size - 1);
713 for (
int i = 0;
i < 4;
i++) {
716 bool nonzero = (
op->lin.m[
i][4].num != 0);
717 for (
int j = 0; j < 5; j++) {
723 else if (j < 4 && k.
num == k.
den)
788 if (
op->convert.expand) {
790 switch (
op->convert.to) {
795 switch (
op->convert.to) {
807 for (
int i = 0;
i < 4 &&
op->pack.pattern[
i];
i++) {
820 uop.
mask &=
op->clear.mask;
821 for (
int i = 0;
i < 4;
i++) {
845 for (
int i = 0;
i < 4;
i++) {
880 memset(&
key->data, 0,
sizeof(
key->data));
964 if (
a->type !=
b->type)
965 return (
int)
b->type -
a->type;
966 if (
a->uop !=
b->uop)
967 return (
int)
b->uop -
a->uop;
982 AVBPrint bprint, *
const bp = &bprint;
1017 for (
int elems = 1; elems <= 4; elems++) {
1018 for (
int rw = 0; rw < 2; rw++) {
1032 #define BPRINT_STR(str) av_bprint_append_data(bp, str, strlen(str))
1035 " * This file is automatically generated. Do not edit manually.\n"
1036 " * To regenerate, run: make fate-sws-uops-macros GEN=1\n"
1039 "#ifndef SWSCALE_UOPS_MACROS_H\n"
1040 "#define SWSCALE_UOPS_MACROS_H\n"
1043 " * Boilerplate helper macros, for template-based backends. These will be\n"
1044 " * instantiated like this, with parameters in struct order:\n"
1045 " * MACRO(__VA_ARGS__, NAME, UOP, TYPE, MASK, [PARAMS,])\n"
1046 " * The _STRUCT variants pass all arguments in C struct syntax, while the\n"
1047 " * plain variants give them as separate C values (e.g. for use in calls)\n"
1049 "#define SWS_GLUE3(x, y, z) x ## _ ## y ## _ ## z\n"
1050 "#define SWS_FOR(TYPE, UOP, MACRO, ...) \\\n"
1051 " SWS_GLUE3(SWS_FOR, TYPE, UOP)(MACRO, __VA_ARGS__)\n"
1052 "#define SWS_FOR_STRUCT(TYPE, UOP, MACRO, ...) \\\n"
1053 " SWS_GLUE3(SWS_FOR_STRUCT, TYPE, UOP)(MACRO, __VA_ARGS__)\n"
1059 const char *macro =
uop_names[
key.uop].full +
sizeof(
"SWS_UOP_") - 1;
1070 BPRINT_STR(
"\n#endif /* SWSCALE_UOPS_MACROS_H */");
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
static const struct @587 pixel_types[SWS_PIXEL_TYPE_NB]
SwsOpList * ff_sws_op_list_duplicate(const SwsOpList *ops)
Returns a duplicate of ops, or NULL on OOM.
@ SWS_RW_PLANAR
Note: 1-component reads are either SWS_RW_PLANAR or SWS_RW_PACKED, depending on the underlying interp...
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
SwsCompMask ff_sws_comp_mask_q4(const AVRational64 q[4])
#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.
@ SWS_FILTER_SCALE
14-bit coefficients are picked to fit comfortably within int16_t for efficient SIMD processing (e....
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 const struct @586 uop_names[SWS_UOP_TYPE_NB]
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)
#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)
@ SWS_OP_FLAG_SPLIT_MEMCPY
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)
64-bit Rational number (pair of numerator and denominator).
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...
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...
static bool is_expand_bit(SwsPixelType type, AVRational64 factor)
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)
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)
static SwsPixel pixel_from_q64(SwsPixelType type, AVRational64 val)
#define ff_sws_comp_mask_str(mask)