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