FFmpeg
ops.h
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2025 Niklas Haas
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #ifndef SWSCALE_OPS_H
22 #define SWSCALE_OPS_H
23 
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <stdalign.h>
27 
28 #include "graph.h"
29 
30 typedef enum SwsPixelType {
37 } SwsPixelType;
38 
42 
43 typedef enum SwsOpType {
45 
46  /* Defined for all types; but implemented for integers only */
47  SWS_OP_READ, /* gather raw pixels from planes */
48  SWS_OP_WRITE, /* write raw pixels to planes */
49  SWS_OP_SWAP_BYTES, /* swap byte order (for differing endianness) */
50  SWS_OP_SWIZZLE, /* rearrange channel order, or duplicate channels */
51 
52  /* Bit manipulation operations. Defined for integers only. */
53  SWS_OP_UNPACK, /* split tightly packed data into components */
54  SWS_OP_PACK, /* compress components into tightly packed data */
55  SWS_OP_LSHIFT, /* logical left shift of raw pixel values by (u8) */
56  SWS_OP_RSHIFT, /* right shift of raw pixel values by (u8) */
57 
58  /* Generic arithmetic. Defined and implemented for all types */
59  SWS_OP_CLEAR, /* clear pixel values */
60  SWS_OP_CONVERT, /* convert (cast) between formats */
61  SWS_OP_MIN, /* numeric minimum (q4) */
62  SWS_OP_MAX, /* numeric maximum (q4) */
63  SWS_OP_SCALE, /* multiplication by scalar (q) */
64 
65  /* Floating-point only arithmetic operations. */
66  SWS_OP_LINEAR, /* generalized linear affine transform */
67  SWS_OP_DITHER, /* add dithering noise */
68 
70 } SwsOpType;
71 
73  SWS_COMP_GARBAGE = 1 << 0, /* contents are undefined / garbage data */
74  SWS_COMP_EXACT = 1 << 1, /* value is an exact integer */
75  SWS_COMP_ZERO = 1 << 2, /* known to be a constant zero */
76 };
77 
78 typedef union SwsConst {
79  /* Generic constant value */
82  unsigned u;
83 } SwsConst;
84 
85 static_assert(sizeof(SwsConst) == sizeof(AVRational) * 4,
86  "First field of SwsConst should span the entire union");
87 
88 typedef struct SwsComps {
89  unsigned flags[4]; /* knowledge about (output) component contents */
90  bool unused[4]; /* which input components are definitely unused */
91 
92  /* Keeps track of the known possible value range, or {0, 0} for undefined
93  * or (unknown range) floating point inputs */
94  AVRational min[4], max[4];
95 } SwsComps;
96 
97 typedef struct SwsReadWriteOp {
98  uint8_t elems; /* number of elements (of type `op.type`) to read/write */
99  uint8_t frac; /* fractional pixel step factor (log2) */
100  bool packed; /* read multiple elements from a single plane */
101 
102  /** Examples:
103  * rgba = 4x u8 packed
104  * yuv444p = 3x u8
105  * rgb565 = 1x u16 <- use SWS_OP_UNPACK to unpack
106  * monow = 1x u8 (frac 3)
107  * rgb4 = 1x u8 (frac 1)
108  */
110 
111 typedef struct SwsPackOp {
112  uint8_t pattern[4]; /* bit depth pattern, from MSB to LSB */
113 } SwsPackOp;
114 
115 typedef struct SwsSwizzleOp {
116  /**
117  * Input component for each output component:
118  * Out[x] := In[swizzle.in[x]]
119  */
120  union {
121  uint32_t mask;
122  uint8_t in[4];
123  struct { uint8_t x, y, z, w; };
124  };
125 } SwsSwizzleOp;
126 
127 #define SWS_SWIZZLE(X,Y,Z,W) ((SwsSwizzleOp) { .in = {X, Y, Z, W} })
128 
129 typedef struct SwsConvertOp {
130  SwsPixelType to; /* type of pixel to convert to */
131  bool expand; /* if true, integers are expanded to the full range */
132 } SwsConvertOp;
133 
134 typedef struct SwsDitherOp {
135  AVRational *matrix; /* tightly packed dither matrix (refstruct) */
136  int size_log2; /* size (in bits) of the dither matrix */
137  uint8_t y_offset[4]; /* row offset for each component */
138 } SwsDitherOp;
139 
140 typedef struct SwsLinearOp {
141  /**
142  * Generalized 5x5 affine transformation:
143  * [ Out.x ] = [ A B C D E ]
144  * [ Out.y ] = [ F G H I J ] * [ x y z w 1 ]
145  * [ Out.z ] = [ K L M N O ]
146  * [ Out.w ] = [ P Q R S T ]
147  *
148  * The mask keeps track of which components differ from an identity matrix.
149  * There may be more efficient implementations of particular subsets, for
150  * example the common subset of {A, E, G, J, M, O} can be implemented with
151  * just three fused multiply-add operations.
152  */
153  AVRational m[4][5];
154  uint32_t mask; /* m[i][j] <-> 1 << (5 * i + j) */
155 } SwsLinearOp;
156 
157 #define SWS_MASK(I, J) (1 << (5 * (I) + (J)))
158 #define SWS_MASK_OFF(I) SWS_MASK(I, 4)
159 #define SWS_MASK_ROW(I) (0x1F << (5 * (I)))
160 #define SWS_MASK_COL(J) (0x8421 << J)
161 
162 enum {
163  SWS_MASK_ALL = (1 << 20) - 1,
166 
167  SWS_MASK_DIAG3 = SWS_MASK(0, 0) | SWS_MASK(1, 1) | SWS_MASK(2, 2),
169  SWS_MASK_MAT3 = SWS_MASK(0, 0) | SWS_MASK(0, 1) | SWS_MASK(0, 2) |
170  SWS_MASK(1, 0) | SWS_MASK(1, 1) | SWS_MASK(1, 2) |
171  SWS_MASK(2, 0) | SWS_MASK(2, 1) | SWS_MASK(2, 2),
172 
176 };
177 
178 /* Helper function to compute the correct mask */
180 
181 typedef struct SwsOp {
182  SwsOpType op; /* operation to perform */
183  SwsPixelType type; /* pixel type to operate on */
184  union {
192  };
193 
194  /* For use internal use inside ff_sws_*() functions */
196 } SwsOp;
197 
198 /**
199  * Frees any allocations associated with an SwsOp and sets it to {0}.
200  */
201 void ff_sws_op_uninit(SwsOp *op);
202 
203 /**
204  * Apply an operation to an AVRational. No-op for read/write operations.
205  */
206 void ff_sws_apply_op_q(const SwsOp *op, AVRational x[4]);
207 
208 /**
209  * Helper struct for representing a list of operations.
210  */
211 typedef struct SwsOpList {
213  int num_ops;
214 
215  /* Metadata associated with this operation list */
216  SwsFormat src, dst; /* if set; may inform the optimizer about e.g value ranges */
217 } SwsOpList;
218 
220 void ff_sws_op_list_free(SwsOpList **ops);
221 
222 /**
223  * Returns a duplicate of `ops`, or NULL on OOM.
224  */
226 
227 /**
228  * Returns the size of the largest pixel type used in `ops`.
229  */
230 int ff_sws_op_list_max_size(const SwsOpList *ops);
231 
232 /**
233  * These will take over ownership of `op` and set it to {0}, even on failure.
234  */
237 
238 void ff_sws_op_list_remove_at(SwsOpList *ops, int index, int count);
239 
240 /**
241  * Print out the contents of an operation list.
242  */
243 void ff_sws_op_list_print(void *log_ctx, int log_level, const SwsOpList *ops);
244 
245 /**
246  * Infer + propagate known information about components. Called automatically
247  * when needed by the optimizer and compiler.
248  */
250 
251 /**
252  * Fuse compatible and eliminate redundant operations, as well as replacing
253  * some operations with more efficient alternatives.
254  */
256 
258  /* Automatically optimize the operations when compiling */
260 };
261 
262 /**
263  * Resolves an operation list to a graph pass. The first and last operations
264  * must be a read/write respectively. `flags` is a list of SwsOpCompileFlags.
265  *
266  * Note: `ops` may be modified by this function.
267  */
270 
271 #endif
SWS_OP_READ
@ SWS_OP_READ
Definition: ops.h:47
flags
const SwsFlags flags[]
Definition: swscale.c:61
SWS_PIXEL_U16
@ SWS_PIXEL_U16
Definition: ops.h:33
SwsComps::flags
unsigned flags[4]
Definition: ops.h:89
SWS_OP_SWIZZLE
@ SWS_OP_SWIZZLE
Definition: ops.h:50
SwsPass
Represents a single filter pass in the scaling graph.
Definition: graph.h:68
SWS_OP_LSHIFT
@ SWS_OP_LSHIFT
Definition: ops.h:55
SWS_OP_UNPACK
@ SWS_OP_UNPACK
Definition: ops.h:53
SwsSwizzleOp::mask
uint32_t mask
Definition: ops.h:121
SWS_MASK_DIAG3
@ SWS_MASK_DIAG3
Definition: ops.h:167
SwsConst
Definition: ops.h:78
SWS_COMP_ZERO
@ SWS_COMP_ZERO
Definition: ops.h:75
SWS_OP_CLEAR
@ SWS_OP_CLEAR
Definition: ops.h:59
SwsOp::swizzle
SwsSwizzleOp swizzle
Definition: ops.h:188
SwsLinearOp::m
AVRational m[4][5]
Generalized 5x5 affine transformation: [ Out.x ] = [ A B C D E ] [ Out.y ] = [ F G H I J ] * [ x y z ...
Definition: ops.h:153
SwsSwizzleOp::z
uint8_t z
Definition: ops.h:123
SwsComps::unused
bool unused[4]
Definition: ops.h:90
SwsOp::convert
SwsConvertOp convert
Definition: ops.h:189
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
SwsOp::rw
SwsReadWriteOp rw
Definition: ops.h:186
SWS_MASK_OFF3
@ SWS_MASK_OFF3
Definition: ops.h:168
SWS_OP_DITHER
@ SWS_OP_DITHER
Definition: ops.h:67
ff_sws_op_list_max_size
int ff_sws_op_list_max_size(const SwsOpList *ops)
Returns the size of the largest pixel type used in ops.
Definition: ops.c:308
av_const
#define av_const
Definition: attributes.h:100
SWS_MASK_LUMA
@ SWS_MASK_LUMA
Definition: ops.h:164
SWS_MASK_ALPHA
@ SWS_MASK_ALPHA
Definition: ops.h:165
ff_sws_pixel_type_size
int ff_sws_pixel_type_size(SwsPixelType type) av_const
Definition: ops.c:64
SWS_PIXEL_U32
@ SWS_PIXEL_U32
Definition: ops.h:34
SWS_OP_TYPE_NB
@ SWS_OP_TYPE_NB
Definition: ops.h:69
SwsPixelType
SwsPixelType
Copyright (C) 2025 Niklas Haas.
Definition: ops.h:30
SwsComps::max
AVRational max[4]
Definition: ops.h:94
SwsSwizzleOp::w
uint8_t w
Definition: ops.h:123
SWS_PIXEL_F32
@ SWS_PIXEL_F32
Definition: ops.h:35
SWS_MASK_OFF4
@ SWS_MASK_OFF4
Definition: ops.h:174
SwsOpList::num_ops
int num_ops
Definition: ops.h:213
SwsCompFlags
SwsCompFlags
Definition: ops.h:72
SwsDitherOp
Definition: ops.h:134
ff_sws_op_uninit
void ff_sws_op_uninit(SwsOp *op)
Frees any allocations associated with an SwsOp and sets it to {0}.
SwsOp::c
SwsConst c
Definition: ops.h:191
ff_sws_op_list_alloc
SwsOpList * ff_sws_op_list_alloc(void)
Definition: ops.c:225
SWS_PIXEL_U8
@ SWS_PIXEL_U8
Definition: ops.h:32
SwsReadWriteOp
Definition: ops.h:97
SwsSwizzleOp
Definition: ops.h:115
type
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
Definition: writing_filters.txt:86
SwsLinearOp::mask
uint32_t mask
Definition: ops.h:154
SwsOp::op
SwsOpType op
Definition: ops.h:182
SwsOpCompileFlags
SwsOpCompileFlags
Definition: ops.h:257
SWS_OP_SCALE
@ SWS_OP_SCALE
Definition: ops.h:63
ff_sws_op_list_append
int ff_sws_op_list_append(SwsOpList *ops, SwsOp *op)
These will take over ownership of op and set it to {0}, even on failure.
Definition: ops.c:303
SwsDitherOp::y_offset
uint8_t y_offset[4]
Definition: ops.h:137
ff_sws_op_list_insert_at
int ff_sws_op_list_insert_at(SwsOpList *ops, int index, SwsOp *op)
Definition: ops.c:289
SwsComps::min
AVRational min[4]
Definition: ops.h:94
op
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.
Definition: anm.c:76
SWS_OP_MIN
@ SWS_OP_MIN
Definition: ops.h:61
SWS_OP_LINEAR
@ SWS_OP_LINEAR
Definition: ops.h:66
SWS_OP_PACK
@ SWS_OP_PACK
Definition: ops.h:54
SwsOp::dither
SwsDitherOp dither
Definition: ops.h:190
SWS_MASK_DIAG4
@ SWS_MASK_DIAG4
Definition: ops.h:173
ff_sws_op_list_duplicate
SwsOpList * ff_sws_op_list_duplicate(const SwsOpList *ops)
Returns a duplicate of ops, or NULL on OOM.
Definition: ops.c:250
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
SwsReadWriteOp::frac
uint8_t frac
Definition: ops.h:99
ff_sws_pixel_type_is_int
bool ff_sws_pixel_type_is_int(SwsPixelType type) av_const
Definition: ops.c:79
SWS_COMP_GARBAGE
@ SWS_COMP_GARBAGE
Definition: ops.h:73
SwsConvertOp::to
SwsPixelType to
Definition: ops.h:130
SwsOpType
SwsOpType
Definition: ops.h:43
SWS_MASK
#define SWS_MASK(I, J)
Definition: ops.h:157
SWS_PIXEL_NONE
@ SWS_PIXEL_NONE
Definition: ops.h:31
index
int index
Definition: gxfenc.c:90
SwsConvertOp::expand
bool expand
Definition: ops.h:131
SwsPackOp::pattern
uint8_t pattern[4]
Definition: ops.h:112
SwsConst::q
AVRational q
Definition: ops.h:81
ff_sws_op_list_free
void ff_sws_op_list_free(SwsOpList **ops)
Definition: ops.c:236
SwsDitherOp::size_log2
int size_log2
Definition: ops.h:136
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
SWS_MASK_ALL
@ SWS_MASK_ALL
Definition: ops.h:163
SwsOp::type
SwsPixelType type
Definition: ops.h:183
SwsDitherOp::matrix
AVRational * matrix
Definition: ops.h:135
SWS_OP_RSHIFT
@ SWS_OP_RSHIFT
Definition: ops.h:56
SwsOp::lin
SwsLinearOp lin
Definition: ops.h:185
SwsOpList::src
SwsFormat src
Definition: ops.h:216
SWS_OP_INVALID
@ SWS_OP_INVALID
Definition: ops.h:44
SwsFormat
Definition: format.h:77
SWS_OP_WRITE
@ SWS_OP_WRITE
Definition: ops.h:48
SwsOp::comps
SwsComps comps
Definition: ops.h:195
SWS_OP_FLAG_OPTIMIZE
@ SWS_OP_FLAG_OPTIMIZE
Definition: ops.h:259
SwsLinearOp
Definition: ops.h:140
input
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
Definition: filter_design.txt:172
ff_sws_op_list_update_comps
void ff_sws_op_list_update_comps(SwsOpList *ops)
Infer + propagate known information about components.
Definition: ops_optimizer.c:159
ff_sws_op_list_optimize
int ff_sws_op_list_optimize(SwsOpList *ops)
Fuse compatible and eliminate redundant operations, as well as replacing some operations with more ef...
Definition: ops_optimizer.c:496
SwsOpList::ops
SwsOp * ops
Definition: ops.h:212
SwsPackOp
Definition: ops.h:111
graph.h
SwsConst::q4
AVRational q4[4]
Definition: ops.h:80
SwsOp
Definition: ops.h:181
ff_sws_apply_op_q
void ff_sws_apply_op_q(const SwsOp *op, AVRational x[4])
Apply an operation to an AVRational.
Definition: ops.c:107
SWS_MASK_MAT4
@ SWS_MASK_MAT4
Definition: ops.h:175
SwsOpList::dst
SwsFormat dst
Definition: ops.h:216
SWS_OP_MAX
@ SWS_OP_MAX
Definition: ops.h:62
SWS_MASK_MAT3
@ SWS_MASK_MAT3
Definition: ops.h:169
SWS_PIXEL_TYPE_NB
@ SWS_PIXEL_TYPE_NB
Definition: ops.h:36
SwsComps
Definition: ops.h:88
ff_sws_compile_pass
int ff_sws_compile_pass(SwsGraph *graph, SwsOpList *ops, int flags, SwsFormat dst, SwsPass *input, SwsPass **output)
Resolves an operation list to a graph pass.
SwsConst::u
unsigned u
Definition: ops.h:82
SWS_MASK_OFF
#define SWS_MASK_OFF(I)
Definition: ops.h:158
SwsReadWriteOp::packed
bool packed
Definition: ops.h:100
SwsSwizzleOp::y
uint8_t y
Definition: ops.h:123
SWS_OP_SWAP_BYTES
@ SWS_OP_SWAP_BYTES
Definition: ops.h:49
SwsSwizzleOp::x
uint8_t x
Definition: ops.h:123
SWS_COMP_EXACT
@ SWS_COMP_EXACT
Definition: ops.h:74
ff_sws_op_list_print
void ff_sws_op_list_print(void *log_ctx, int log_level, const SwsOpList *ops)
Print out the contents of an operation list.
Definition: ops.c:402
SwsReadWriteOp::elems
uint8_t elems
Definition: ops.h:98
ff_sws_pixel_type_name
const char * ff_sws_pixel_type_name(SwsPixelType type)
Definition: ops.c:49
SwsGraph
Filter graph, which represents a 'baked' pixel format conversion.
Definition: graph.h:108
SwsSwizzleOp::in
uint8_t in[4]
Definition: ops.h:122
SWS_OP_CONVERT
@ SWS_OP_CONVERT
Definition: ops.h:60
ff_sws_op_list_remove_at
void ff_sws_op_list_remove_at(SwsOpList *ops, int index, int count)
Definition: ops.c:279
SwsConvertOp
Definition: ops.h:129
SwsOpList
Helper struct for representing a list of operations.
Definition: ops.h:211
SwsOp::pack
SwsPackOp pack
Definition: ops.h:187
ff_sws_linear_mask
uint32_t ff_sws_linear_mask(SwsLinearOp)
Definition: ops.c:319