FFmpeg
Loading...
Searching...
No Matches
uops.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_UOPS_H
22#define SWSCALE_UOPS_H
23
24#include <assert.h>
25#include <stdbool.h>
26#include <stdint.h>
27
28/***************************************************************************
29 * Note: This header must be usable at build time, to generate asm sources *
30 ***************************************************************************/
31
33
34typedef struct SwsContext SwsContext;
36typedef struct SwsLut3D SwsLut3D;
37typedef struct SwsOpList SwsOpList;
38
47
49
51{
52 switch (type) {
53 case SWS_PIXEL_U8: return sizeof(uint8_t);
54 case SWS_PIXEL_U16: return sizeof(uint16_t);
55 case SWS_PIXEL_U32: return sizeof(uint32_t);
56 case SWS_PIXEL_F32: return sizeof(float);
57 case SWS_PIXEL_NONE: break;
58 case SWS_PIXEL_TYPE_NB: break;
59 }
60 return 0;
61}
62
64{
65 switch (type) {
66 case SWS_PIXEL_U8:
67 case SWS_PIXEL_U16:
68 case SWS_PIXEL_U32:
69 return true;
70 case SWS_PIXEL_F32:
71 return false;
72 case SWS_PIXEL_NONE:
73 case SWS_PIXEL_TYPE_NB: break;
74 }
75 return false;
76}
77
78typedef union SwsPixel {
79 char data[4];
80
81 uint8_t u8;
82 uint16_t u16;
83 uint32_t u32;
84 float f32;
85} SwsPixel;
86
87/* Ensures (SwsPixel) {0} is properly initialized to all zeros */
88static_assert(sizeof(SwsPixel) == sizeof(char[4]), "SwsPixel size mismatch");
89
90/**
91 * Bit-mask of components. Exact meaning depends on the usage context.
92 */
93typedef uint8_t SwsCompMask;
94enum {
97#define SWS_COMP(X) (1 << (X))
98#define SWS_COMP_TEST(mask, X) (!!((mask) & SWS_COMP(X)))
99#define SWS_COMP_INV(mask) ((mask) ^ SWS_COMP_ALL)
100#define SWS_COMP_ELEMS(N) ((1 << (N)) - 1)
101#define SWS_COMP_COUNT(mask) (av_popcount((mask) & SWS_COMP_ALL))
102#define SWS_COMP_MASK(X, Y, Z, W) \
103 (((X) ? SWS_COMP(0) : 0) | \
104 ((Y) ? SWS_COMP(1) : 0) | \
105 ((Z) ? SWS_COMP(2) : 0) | \
106 ((W) ? SWS_COMP(3) : 0))
107};
108
109
110#define ff_sws_comp_mask_str(mask) ff_sws_comp_mask_print(mask, (char[5]){0})
111static inline char *ff_sws_comp_mask_print(SwsCompMask mask, char buf[5])
112{
113 char *ptr = buf;
114 for (int c = 0; c < 4; c++) {
115 if (SWS_COMP_TEST(mask, c))
116 *ptr++ = "xyzw"[c];
117 }
118 *ptr = '\0';
119 return buf;
120}
121
122typedef uint32_t SwsUOpFlags;
123typedef enum SwsUOpFlagBits {
125 SWS_UOP_FLAG_FMA = (1 << 0), /* platform supports FMA ops */
126 SWS_UOP_FLAG_PSHUFB = (1 << 1), /* platform supports pshufb equivalent */
128
129typedef enum SwsUOpType {
131
132 /* Read/write uops; mask = components to read/write */
133 SWS_UOP_READ_PLANAR, /* simple planar byte-aligned read */
134 SWS_UOP_READ_PLANAR_FH, /* planar read with horizontal filter */
135 SWS_UOP_READ_PLANAR_FV, /* planar read with vertical filter */
137 SWS_UOP_READ_PACKED, /* simple packed byte-aligned read */
138 SWS_UOP_READ_NIBBLE, /* fractional read (4 bits) from single plane */
139 SWS_UOP_READ_BIT, /* fractional read (1 bit) from single plane */
140 SWS_UOP_READ_PALETTE, /* indexed read from palette in plane 1 */
141
142 SWS_UOP_WRITE_PLANAR, /* simple planar byte-aligned write */
143 SWS_UOP_WRITE_PACKED, /* simple packed byte-aligned write */
144 SWS_UOP_WRITE_NIBBLE, /* fractional write (4 bits) to single plane */
145 SWS_UOP_WRITE_BIT, /* fractional write (1 bit) to single plane */
146
147 /* Packed shuffle / gather uops */
148 SWS_UOP_RW_SHUFFLE, /* in-place (packed) indexed shuffle/gather */
149
150 /* Data rearrangement uops; mask = needed or trivial components */
151 SWS_UOP_PERMUTE, /* permute pointers (no duplicates) */
152 SWS_UOP_COPY, /* permute data (may contain duplicates) */
153
154 /* Data conversion / manipulation uops; mask = affected components */
155 SWS_UOP_SWAP_BYTES, /* swap byte order in components */
156 SWS_UOP_EXPAND_BIT, /* expand low-order bit to all bits in type */
157 SWS_UOP_EXPAND_PAIR, /* expand bytes in pairs (16 bit) */
158 SWS_UOP_EXPAND_QUAD, /* expand bytes in quads (32 bit) */
159 SWS_UOP_TO_U8, /* cast pixel values to SWS_PIXEL_U8 */
160 SWS_UOP_TO_U16, /* cast pixel values to SWS_PIXEL_U16 */
161 SWS_UOP_TO_U32, /* cast pixel values to SWS_PIXEL_U32 */
162 SWS_UOP_TO_F32, /* cast pixel values to SWS_PIXEL_F32 */
163
164 /* Arithmetic uops */
165 SWS_UOP_SCALE, /* multiply masked components by scalar */
166 SWS_UOP_ADD, /* add vec4 to masked components */
167 SWS_UOP_MIN, /* min(x, vec4) on masked components */
168 SWS_UOP_MAX, /* max(x, vec4) on masked components */
169
170 /* Identical to corresponding SwsOpType */
171 SWS_UOP_UNPACK, /* mask = nonzero components in pack pattern */
172 SWS_UOP_PACK, /* mask = nonzero components in pack pattern */
173 SWS_UOP_LSHIFT, /* mask = components to shift */
174 SWS_UOP_RSHIFT, /* mask = components to shift */
175 SWS_UOP_CLEAR, /* mask = components to clear */
176 SWS_UOP_LINEAR, /* mask = non-trivial output rows */
177 SWS_UOP_LINEAR_FMA, /* with SWS_UOP_FLAG_FMA */
178 SWS_UOP_DITHER, /* mask = components to dither */
179 SWS_UOP_LUT_3D, /* mask = needed output components */
180
181 /* Platform-specific uops would go here */
183} SwsUOpType;
184
185typedef struct SwsShuffleUOp {
186 uint8_t clear_value; /* value to clear elements with negative indices to */
187 uint8_t read_size; /* input bytes per iteration */
188 uint8_t write_size; /* output bytes per iteration */
190
191typedef struct SwsShuffleMask {
192 int8_t mask[16]; /* shuffle index mask, or -1 to clear bytes (to `clear_value`) */
193 uint8_t pixels; /* number of pixels per iteration */
195
196typedef struct SwsFilterUOp {
197 SwsPixelType type; /* pixel type to store result as */
199
200typedef struct SwsShiftUOp {
201 uint8_t amount;
203
204typedef struct SwsMoveUOp {
205 /* The worst case number of moves (for two independent cycles) */
206 #define SWS_UOP_MOVE_MAX 6
208
209 /* This may involve a temporary register (index -1) */
210 int8_t dst[SWS_UOP_MOVE_MAX]; /* destination register index */
211 int8_t src[SWS_UOP_MOVE_MAX]; /* source register index */
212} SwsMoveUOp;
213
214typedef struct SwsPackUOp {
215 uint8_t pattern[4]; /* bit depth pattern, from MSB to LSB */
216} SwsPackUOp;
217
218typedef struct SwsClearUOp {
219 SwsCompMask one; /* mask of coefficients equal to all 1s */
220 SwsCompMask zero; /* mask of coefficients equal to all 0s */
222
223typedef struct SwsLinearUOp {
224 uint32_t one; /* mask of coefficients equal to one */
225 uint32_t zero; /* mask of coefficients equal to zero */
226
227 /* for SWS_UOP_LINEAR_FMA only */
228 uint32_t exact; /* mask of coefficients whose product is exact */
230
231#define SWS_MASK(I, J) (1 << (5 * (I) + (J)))
232#define SWS_MASK_OFF(I) SWS_MASK(I, 4)
233#define SWS_MASK_ROW(I) (0x1F << (5 * (I)))
234#define SWS_MASK_COL(J) (0x8421 << J)
235#define SWS_MASK_DIAG4 (0x41041)
236
237typedef struct SwsDitherUOp {
238 uint8_t y_offset[4];
239 uint8_t size_log2;
241
242typedef struct SwsLut3DUOp {
245
246/**
247 * Computes (1 << size_log2) + MAX(y_offset). The dither matrix attached to
248 * the SwsUOp is always pre-padded to this number of lines.
249 */
251
252typedef union SwsUOpParams {
253 SwsShuffleUOp shuffle; /* for SWS_UOP_RW_SHUFFLE */
254 SwsFilterUOp filter; /* for SWS_UOP_READ_*_FV/FH */
256 SwsMoveUOp move; /* for SWS_UOP_PERMUTE and SWS_UOP_COPY */
263
264typedef struct SwsUOp {
265 /* These fields uniquely identify the uop implementation */
270
271 /* Constant data for this uop; not part of the unique identifier */
272 union {
273 SwsFilterWeights *kernel; /* refstruct */
274 SwsPixel *ptr; /* refstruct */
277 SwsPixel mat4[4][5]; /* row major */
278 SwsShuffleMask shuffle; /* for SWS_UOP_RW_SHUFFLE */
279 const SwsLut3D *lut3d; /* for SWS_UOP_LUT_3D; refstruct */
280 void *opaque; /* reserved for internal use */
282} SwsUOp;
283
284/**
285 * Compare two SwsUOps for equality (excluding constant data).
286 */
287int ff_sws_uop_cmp(const SwsUOp *a, const SwsUOp *b);
288
289static inline int ff_sws_uop_cmp_v(const void *a, const void *b)
290{
291 return ff_sws_uop_cmp(a, b);
292}
293
294/**
295 * Generate a unique name for a SwsUOp.
296 */
297#define SWS_UOP_NAME_MAX 64
298void ff_sws_uop_name(const SwsUOp *op, char buf[SWS_UOP_NAME_MAX]);
299
300typedef struct SwsUOpList {
303
304 /* Additional metadata for implementations */
305 SwsCompMask planes_in; /* mask of planes read from */
306 SwsCompMask planes_out; /* mask of planes written to */
307 int pixel_size_max; /* size of largest pixel type seen in any uop */
308} SwsUOpList;
309
312void ff_sws_uop_list_remove_at(SwsUOpList *uops, int index, int count);
313
314/* Takes over ownership of `uop` and sets it to {0}, even on failure. */
316
317/**
318 * Called internally by ff_sws_ops_translate().
319 */
321
322/**
323 * Translate a list of operations down to micro-ops, which can be further
324 * optimized and then directly executed by backends.
325 *
326 * Return 0 or a negative error code.
327 */
330
331/**
332 * Compute a shuffle mask for `pshufb`-style ASM functions, by repeating
333 * the shuffle pattern for as many groups as will fit.
334 *
335 * @param uop An operation of type SWS_UOP_RW_SHUFFLE.
336 * @param shuffle The output shuffle index mask (or -1 to clear bytes).
337 * @param size The maximum size (in bytes) of the output shuffle mask.
338 *
339 * @return the number of groups on success, or a negative error code.
340 *
341 * @note The shuffle mask is already pre-expanded to fill up to 16 bytes,
342 * so this is only needed for larger shuffle instructions (e.g. vpermb).
343 */
344int ff_sws_shuffle_mask(const SwsUOp *uop, int8_t shuffle[], int size);
345
346#endif
static AVFormatContext * ctx
#define flags(name, subs,...)
Definition cbs_h264.c:74
static uint64_t shuffle(uint64_t in, const uint8_t *shuffle, int shuffle_len)
Definition des.c:179
int index
Definition gxfenc.c:90
int a
cl_device_type type
#define b
Definition input.c:43
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
Macro definitions for various function/variable attributes.
#define av_const
Definition attributes.h:111
static const uint16_t mask[17]
Definition lzw.c:38
const char data[16]
Definition mxf.c:149
SwsCompMask one
Definition uops.h:219
SwsCompMask zero
Definition uops.h:220
Main external API structure.
Definition swscale.h:227
uint8_t size_log2
Definition uops.h:239
uint8_t y_offset[4]
Definition uops.h:238
SwsPixelType type
Definition uops.h:197
Represents a computed filter kernel.
Definition filters.h:85
uint32_t zero
Definition uops.h:225
uint32_t one
Definition uops.h:224
uint32_t exact
Definition uops.h:228
int dynamic
Definition uops.h:243
Append a set of operations for applying a gamut/tone mapping 3D LUT to the pixels.
Definition lut3d.h:50
int8_t src[SWS_UOP_MOVE_MAX]
Definition uops.h:211
int num_moves
Definition uops.h:207
int8_t dst[SWS_UOP_MOVE_MAX]
Definition uops.h:210
Helper struct for representing a list of operations.
Definition ops.h:293
uint8_t pattern[4]
Definition uops.h:215
uint8_t amount
Definition uops.h:201
int8_t mask[16]
Definition uops.h:192
uint8_t pixels
Definition uops.h:193
uint8_t write_size
Definition uops.h:188
uint8_t read_size
Definition uops.h:187
uint8_t clear_value
Definition uops.h:186
SwsUOp * ops
Definition uops.h:301
int pixel_size_max
Definition uops.h:307
int num_ops
Definition uops.h:302
SwsCompMask planes_in
Definition uops.h:305
SwsCompMask planes_out
Definition uops.h:306
Definition uops.h:264
SwsPixel scalar
Definition uops.h:275
SwsCompMask mask
Definition uops.h:268
SwsUOpType uop
Definition uops.h:267
SwsUOpParams par
Definition uops.h:269
const SwsLut3D * lut3d
Definition uops.h:279
SwsFilterWeights * kernel
Definition uops.h:273
SwsPixel mat4[4][5]
Definition uops.h:277
SwsPixel * ptr
Definition uops.h:274
void * opaque
Definition uops.h:280
SwsPixelType type
Definition uops.h:266
SwsShuffleMask shuffle
Definition uops.h:278
SwsPixel vec4[4]
Definition uops.h:276
int size
float f32
Definition uops.h:84
uint32_t u32
Definition uops.h:83
char data[4]
Definition uops.h:79
uint8_t u8
Definition uops.h:81
uint16_t u16
Definition uops.h:82
SwsMoveUOp move
Definition uops.h:256
SwsClearUOp clear
Definition uops.h:258
SwsDitherUOp dither
Definition uops.h:260
SwsFilterUOp filter
Definition uops.h:254
SwsLut3DUOp lut3d
Definition uops.h:261
SwsShuffleUOp shuffle
Definition uops.h:253
SwsLinearUOp lin
Definition uops.h:259
SwsShiftUOp shift
Definition uops.h:255
SwsPackUOp pack
Definition uops.h:257
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...
Definition uops.c:677
@ SWS_COMP_ALL
Definition uops.h:96
@ SWS_COMP_NONE
Definition uops.h:95
uint32_t SwsUOpFlags
Definition uops.h:122
int ff_sws_dither_height(const SwsDitherUOp *dither)
Computes (1 << size_log2) + MAX(y_offset).
Definition uops.c:232
int ff_sws_uop_list_append(SwsUOpList *uops, SwsUOp *uop)
Definition uops.c:208
SwsPixelType
Definition uops.h:39
@ SWS_PIXEL_F32
Definition uops.h:44
@ SWS_PIXEL_U32
Definition uops.h:43
@ SWS_PIXEL_U16
Definition uops.h:42
@ SWS_PIXEL_TYPE_NB
Definition uops.h:45
@ SWS_PIXEL_NONE
Definition uops.h:40
@ SWS_PIXEL_U8
Definition uops.h:41
int ff_sws_uop_list_optimize(SwsContext *ctx, SwsUOpFlags flags, SwsUOpList *uops)
Called internally by ff_sws_ops_translate().
#define SWS_UOP_MOVE_MAX
Definition uops.h:206
void ff_sws_uop_name(const SwsUOp *op, char buf[SWS_UOP_NAME_MAX])
Definition uops.c:81
int ff_sws_uop_cmp(const SwsUOp *a, const SwsUOp *b)
Compare two SwsUOps for equality (excluding constant data).
Definition uops.c:31
#define SWS_COMP_TEST(mask, X)
Definition uops.h:98
SwsUOpType
Definition uops.h:129
@ SWS_UOP_TO_U8
Definition uops.h:159
@ SWS_UOP_PACK
Definition uops.h:172
@ SWS_UOP_PERMUTE
Definition uops.h:151
@ SWS_UOP_EXPAND_QUAD
Definition uops.h:158
@ SWS_UOP_READ_PLANAR
Definition uops.h:133
@ SWS_UOP_WRITE_PLANAR
Definition uops.h:142
@ SWS_UOP_READ_NIBBLE
Definition uops.h:138
@ SWS_UOP_MAX
Definition uops.h:168
@ SWS_UOP_READ_BIT
Definition uops.h:139
@ SWS_UOP_SWAP_BYTES
Definition uops.h:155
@ SWS_UOP_MIN
Definition uops.h:167
@ SWS_UOP_LINEAR
Definition uops.h:176
@ SWS_UOP_RSHIFT
Definition uops.h:174
@ SWS_UOP_COPY
Definition uops.h:152
@ SWS_UOP_WRITE_NIBBLE
Definition uops.h:144
@ SWS_UOP_INVALID
Definition uops.h:130
@ SWS_UOP_LINEAR_FMA
Definition uops.h:177
@ SWS_UOP_READ_PLANAR_FH
Definition uops.h:134
@ SWS_UOP_SCALE
Definition uops.h:165
@ SWS_UOP_WRITE_PACKED
Definition uops.h:143
@ SWS_UOP_WRITE_BIT
Definition uops.h:145
@ SWS_UOP_READ_PLANAR_FV_FMA
Definition uops.h:136
@ SWS_UOP_READ_PACKED
Definition uops.h:137
@ SWS_UOP_LUT_3D
Definition uops.h:179
@ SWS_UOP_EXPAND_PAIR
Definition uops.h:157
@ SWS_UOP_TO_U16
Definition uops.h:160
@ SWS_UOP_DITHER
Definition uops.h:178
@ SWS_UOP_ADD
Definition uops.h:166
@ SWS_UOP_TYPE_NB
Definition uops.h:182
@ SWS_UOP_CLEAR
Definition uops.h:175
@ SWS_UOP_READ_PALETTE
Definition uops.h:140
@ SWS_UOP_EXPAND_BIT
Definition uops.h:156
@ SWS_UOP_READ_PLANAR_FV
Definition uops.h:135
@ SWS_UOP_TO_U32
Definition uops.h:161
@ SWS_UOP_RW_SHUFFLE
Definition uops.h:148
@ SWS_UOP_UNPACK
Definition uops.h:171
@ SWS_UOP_TO_F32
Definition uops.h:162
@ SWS_UOP_LSHIFT
Definition uops.h:173
SwsUOpList * ff_sws_uop_list_alloc(void)
Definition uops.c:203
const char * ff_sws_pixel_type_name(SwsPixelType type)
Definition ops.c:56
static int ff_sws_uop_cmp_v(const void *a, const void *b)
Definition uops.h:289
void ff_sws_uop_list_remove_at(SwsUOpList *uops, int index, int count)
Definition uops.c:221
static char * ff_sws_comp_mask_print(SwsCompMask mask, char buf[5])
Definition uops.h:111
SwsUOpFlagBits
Definition uops.h:123
@ SWS_UOP_FLAG_FMA
Definition uops.h:125
@ SWS_UOP_FLAG_PSHUFB
Definition uops.h:126
@ SWS_UOP_FLAG_NONE
Definition uops.h:124
int ff_sws_shuffle_mask(const SwsUOp *uop, int8_t shuffle[], int size)
Compute a shuffle mask for pshufb-style ASM functions, by repeating the shuffle pattern for as many g...
#define SWS_UOP_NAME_MAX
Generate a unique name for a SwsUOp.
Definition uops.h:297
static av_const bool ff_sws_pixel_type_is_int(SwsPixelType type)
Definition uops.h:63
uint8_t SwsCompMask
Bit-mask of components.
Definition uops.h:93
static av_const int ff_sws_pixel_type_size(SwsPixelType type)
Definition uops.h:50
void ff_sws_uop_list_free(SwsUOpList **ops)
Definition uops.c:189
static const uint16_t dither[8][8]
Definition vf_gradfun.c:46
static double c[64]