FFmpeg
ops_impl.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2026 Ramiro Polla
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 /**
22  * This file is used both by sws_ops_aarch64 to generate ops_entries.c and
23  * by the standalone build-time tool that generates the static assembly
24  * functions (aarch64/ops_asmgen). Therefore, it must not depend on internal
25  * FFmpeg libraries.
26  */
27 
28 #include <inttypes.h>
29 #include <stdarg.h>
30 #include <stdbool.h>
31 #include <stdio.h>
32 
33 #include "libavutil/attributes.h"
34 
35 /**
36  * NOTE: ops_asmgen contains header redefinitions to provide av_assert0
37  * while not depending on internal FFmpeg libraries.
38  */
39 #include "libavutil/avassert.h"
40 
41 #include "ops_impl.h"
42 
43 /*********************************************************************/
44 static const char pixel_types[AARCH64_PIXEL_TYPE_NB][32] = {
45  [AARCH64_PIXEL_U8 ] = "AARCH64_PIXEL_U8",
46  [AARCH64_PIXEL_U16] = "AARCH64_PIXEL_U16",
47  [AARCH64_PIXEL_U32] = "AARCH64_PIXEL_U32",
48  [AARCH64_PIXEL_F32] = "AARCH64_PIXEL_F32",
49 };
50 
51 static const char *aarch64_pixel_type(SwsAArch64PixelType fmt)
52 {
53  if (fmt >= AARCH64_PIXEL_TYPE_NB) {
54  av_assert0(!"Invalid pixel type!");
55  return NULL;
56  }
57  return pixel_types[fmt];
58 }
59 
60 static const char pixel_type_names[AARCH64_PIXEL_TYPE_NB][4] = {
61  [AARCH64_PIXEL_U8 ] = "u8",
62  [AARCH64_PIXEL_U16] = "u16",
63  [AARCH64_PIXEL_U32] = "u32",
64  [AARCH64_PIXEL_F32] = "f32",
65 };
66 
68 {
69  if (fmt >= AARCH64_PIXEL_TYPE_NB) {
70  av_assert0(!"Invalid pixel type!");
71  return NULL;
72  }
73  return pixel_type_names[fmt];
74 }
75 
76 /*********************************************************************/
77 static const char op_types[AARCH64_SWS_OP_TYPE_NB][32] = {
78  [AARCH64_SWS_OP_NONE ] = "AARCH64_SWS_OP_NONE",
79  [AARCH64_SWS_OP_READ_BIT ] = "AARCH64_SWS_OP_READ_BIT",
80  [AARCH64_SWS_OP_READ_NIBBLE ] = "AARCH64_SWS_OP_READ_NIBBLE",
81  [AARCH64_SWS_OP_READ_PACKED ] = "AARCH64_SWS_OP_READ_PACKED",
82  [AARCH64_SWS_OP_READ_PLANAR ] = "AARCH64_SWS_OP_READ_PLANAR",
83  [AARCH64_SWS_OP_WRITE_BIT ] = "AARCH64_SWS_OP_WRITE_BIT",
84  [AARCH64_SWS_OP_WRITE_NIBBLE ] = "AARCH64_SWS_OP_WRITE_NIBBLE",
85  [AARCH64_SWS_OP_WRITE_PACKED ] = "AARCH64_SWS_OP_WRITE_PACKED",
86  [AARCH64_SWS_OP_WRITE_PLANAR ] = "AARCH64_SWS_OP_WRITE_PLANAR",
87  [AARCH64_SWS_OP_SWAP_BYTES ] = "AARCH64_SWS_OP_SWAP_BYTES",
88  [AARCH64_SWS_OP_SWIZZLE ] = "AARCH64_SWS_OP_SWIZZLE",
89  [AARCH64_SWS_OP_UNPACK ] = "AARCH64_SWS_OP_UNPACK",
90  [AARCH64_SWS_OP_PACK ] = "AARCH64_SWS_OP_PACK",
91  [AARCH64_SWS_OP_LSHIFT ] = "AARCH64_SWS_OP_LSHIFT",
92  [AARCH64_SWS_OP_RSHIFT ] = "AARCH64_SWS_OP_RSHIFT",
93  [AARCH64_SWS_OP_CLEAR ] = "AARCH64_SWS_OP_CLEAR",
94  [AARCH64_SWS_OP_CONVERT ] = "AARCH64_SWS_OP_CONVERT",
95  [AARCH64_SWS_OP_EXPAND ] = "AARCH64_SWS_OP_EXPAND",
96  [AARCH64_SWS_OP_MIN ] = "AARCH64_SWS_OP_MIN",
97  [AARCH64_SWS_OP_MAX ] = "AARCH64_SWS_OP_MAX",
98  [AARCH64_SWS_OP_SCALE ] = "AARCH64_SWS_OP_SCALE",
99  [AARCH64_SWS_OP_LINEAR ] = "AARCH64_SWS_OP_LINEAR",
100  [AARCH64_SWS_OP_DITHER ] = "AARCH64_SWS_OP_DITHER",
101 };
102 
104 {
106  av_assert0(!"Invalid op type!");
107  return NULL;
108  }
109  return op_types[op];
110 }
111 
112 static const char op_type_names[AARCH64_SWS_OP_TYPE_NB][16] = {
113  [AARCH64_SWS_OP_NONE ] = "none",
114  [AARCH64_SWS_OP_READ_BIT ] = "read_bit",
115  [AARCH64_SWS_OP_READ_NIBBLE ] = "read_nibble",
116  [AARCH64_SWS_OP_READ_PACKED ] = "read_packed",
117  [AARCH64_SWS_OP_READ_PLANAR ] = "read_planar",
118  [AARCH64_SWS_OP_WRITE_BIT ] = "write_bit",
119  [AARCH64_SWS_OP_WRITE_NIBBLE ] = "write_nibble",
120  [AARCH64_SWS_OP_WRITE_PACKED ] = "write_packed",
121  [AARCH64_SWS_OP_WRITE_PLANAR ] = "write_planar",
122  [AARCH64_SWS_OP_SWAP_BYTES ] = "swap_bytes",
123  [AARCH64_SWS_OP_SWIZZLE ] = "swizzle",
124  [AARCH64_SWS_OP_UNPACK ] = "unpack",
125  [AARCH64_SWS_OP_PACK ] = "pack",
126  [AARCH64_SWS_OP_LSHIFT ] = "lshift",
127  [AARCH64_SWS_OP_RSHIFT ] = "rshift",
128  [AARCH64_SWS_OP_CLEAR ] = "clear",
129  [AARCH64_SWS_OP_CONVERT ] = "convert",
130  [AARCH64_SWS_OP_EXPAND ] = "expand",
131  [AARCH64_SWS_OP_MIN ] = "min",
132  [AARCH64_SWS_OP_MAX ] = "max",
133  [AARCH64_SWS_OP_SCALE ] = "scale",
134  [AARCH64_SWS_OP_LINEAR ] = "linear",
135  [AARCH64_SWS_OP_DITHER ] = "dither",
136 };
137 
139 {
141  av_assert0(!"Invalid op type!");
142  return NULL;
143  }
144  return op_type_names[op];
145 }
146 
147 /*********************************************************************/
148 /*
149  * Helper string concatenation function that does not depend on the
150  * FFmpeg libraries, so it may be used standalone.
151  */
153 static void buf_appendf(char **pbuf, size_t *prem, const char *fmt, ...)
154 {
155  char *buf = *pbuf;
156  size_t rem = *prem;
157  if (!rem)
158  return;
159 
160  va_list ap;
161  va_start(ap, fmt);
162  int n = vsnprintf(buf, rem, fmt, ap);
163  va_end(ap);
164 
165  if (n > 0) {
166  if (n < rem) {
167  buf += n;
168  rem -= n;
169  } else {
170  buf += rem - 1;
171  rem = 0;
172  }
173  *pbuf = buf;
174  *prem = rem;
175  }
176 }
177 
178 /*********************************************************************/
179 /**
180  * The following structure is used to describe one field from
181  * SwsAArch64OpImplParams. This will be used to serialize the parameter
182  * structure, generate function names and lookup strings, and compare
183  * two sets of parameters.
184  */
185 
186 typedef struct ParamField {
187  const char *name;
188  size_t offset;
189  size_t size;
190  void (*print_str)(char **pbuf, size_t *prem, void *p);
191  void (*print_val)(char **pbuf, size_t *prem, void *p);
192  int (*cmp_val)(void *pa, void *pb);
193 } ParamField;
194 
195 #define PARAM_FIELD(name) #name, offsetof(SwsAArch64OpImplParams, name), sizeof(((SwsAArch64OpImplParams *) 0)->name)
196 
197 static void print_op_name(char **pbuf, size_t *prem, void *p)
198 {
200  buf_appendf(pbuf, prem, "_%s", aarch64_op_type_name(op));
201 }
202 
203 static void print_op_val(char **pbuf, size_t *prem, void *p)
204 {
206  buf_appendf(pbuf, prem, "%s", aarch64_op_type(op));
207 }
208 
209 static int cmp_op(void *pa, void *pb)
210 {
211  int64_t ia = (int64_t) *((SwsAArch64OpType *) pa);
212  int64_t ib = (int64_t) *((SwsAArch64OpType *) pb);
213  int64_t diff = ia - ib;
214  if (diff)
215  return diff < 0 ? -1 : 1;
216  return 0;
217 }
218 
219 static void print_pixel_name(char **pbuf, size_t *prem, void *p)
220 {
222  buf_appendf(pbuf, prem, "_%s", aarch64_pixel_type_name(type));
223 }
224 
225 static void print_pixel_val(char **pbuf, size_t *prem, void *p)
226 {
228  buf_appendf(pbuf, prem, "%s", aarch64_pixel_type(type));
229 }
230 
231 static int cmp_pixel(void *pa, void *pb)
232 {
233  int64_t ia = (int64_t) *((SwsAArch64PixelType *) pa);
234  int64_t ib = (int64_t) *((SwsAArch64PixelType *) pb);
235  int64_t diff = ia - ib;
236  if (diff)
237  return diff < 0 ? -1 : 1;
238  return 0;
239 }
240 
241 static void print_u8_name(char **pbuf, size_t *prem, void *p)
242 {
243  uint8_t val = *(uint8_t *) p;
244  buf_appendf(pbuf, prem, "_%u", val);
245 }
246 
247 static void print_u8_val(char **pbuf, size_t *prem, void *p)
248 {
249  uint8_t val = *(uint8_t *) p;
250  buf_appendf(pbuf, prem, "%u", val);
251 }
252 
253 static int cmp_u8(void *pa, void *pb)
254 {
255  int64_t ia = (int64_t) *((uint8_t *) pa);
256  int64_t ib = (int64_t) *((uint8_t *) pb);
257  int64_t diff = ia - ib;
258  if (diff)
259  return diff < 0 ? -1 : 1;
260  return 0;
261 }
262 
263 static void print_u16_name(char **pbuf, size_t *prem, void *p)
264 {
265  uint16_t val = *(uint16_t *) p;
266  buf_appendf(pbuf, prem, "_%04x", val);
267 }
268 
269 static void print_u16_val(char **pbuf, size_t *prem, void *p)
270 {
271  uint16_t val = *(uint16_t *) p;
272  buf_appendf(pbuf, prem, "0x%04x", val);
273 }
274 
275 static int cmp_u16(void *pa, void *pb)
276 {
277  int64_t ia = (int64_t) *((uint16_t *) pa);
278  int64_t ib = (int64_t) *((uint16_t *) pb);
279  int64_t diff = ia - ib;
280  if (diff)
281  return diff < 0 ? -1 : 1;
282  return 0;
283 }
284 
285 static void print_u40_name(char **pbuf, size_t *prem, void *p)
286 {
287  uint64_t val = *(uint64_t *) p;
288  buf_appendf(pbuf, prem, "_%010" PRIx64, val);
289 }
290 
291 static void print_u40_val(char **pbuf, size_t *prem, void *p)
292 {
293  uint64_t val = *(uint64_t *) p;
294  buf_appendf(pbuf, prem, "0x%010" PRIx64 "ULL", val);
295 }
296 
297 static int cmp_u40(void *pa, void *pb)
298 {
299  int64_t ia = (int64_t) *((uint64_t *) pa);
300  int64_t ib = (int64_t) *((uint64_t *) pb);
301  int64_t diff = ia - ib;
302  if (diff)
303  return diff < 0 ? -1 : 1;
304  return 0;
305 }
306 
307 /*********************************************************************/
320 
321 /* Fields needed to uniquely identify each SwsAArch64OpType. */
322 #define MAX_LEVELS 8
346 };
AARCH64_SWS_OP_MIN
@ AARCH64_SWS_OP_MIN
Definition: ops_impl.h:57
field_dither_y_offset
static const ParamField field_dither_y_offset
Definition: ops_impl.c:318
pixel_type_names
static const char pixel_type_names[AARCH64_PIXEL_TYPE_NB][4]
Definition: ops_impl.c:60
ParamField
The following structure is used to describe one field from SwsAArch64OpImplParams.
Definition: ops_impl.c:186
cmp_u40
static int cmp_u40(void *pa, void *pb)
Definition: ops_impl.c:297
field_linear_fmla
static const ParamField field_linear_fmla
Definition: ops_impl.c:317
int64_t
long long int64_t
Definition: coverity.c:34
op_types
static const char op_types[AARCH64_SWS_OP_TYPE_NB][32]
Definition: ops_impl.c:77
print_u8_name
static void print_u8_name(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:241
ops_impl.h
mask
int mask
Definition: mediacodecdec_common.c:154
linear
static int linear(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:135
cmp_op
static int cmp_op(void *pa, void *pb)
Definition: ops_impl.c:209
pixel_types
static const char pixel_types[AARCH64_PIXEL_TYPE_NB][32]
This file is used both by sws_ops_aarch64 to generate ops_entries.c and by the standalone build-time ...
Definition: ops_impl.c:44
AARCH64_SWS_OP_SWIZZLE
@ AARCH64_SWS_OP_SWIZZLE
Definition: ops_impl.h:49
field_to_type
static const ParamField field_to_type
Definition: ops_impl.c:315
av_printf_format
av_printf_format(3, 4)
Definition: ops_impl.c:152
AARCH64_PIXEL_TYPE_NB
@ AARCH64_PIXEL_TYPE_NB
Definition: ops_impl.h:34
ParamField::print_val
void(* print_val)(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:191
cmp_pixel
static int cmp_pixel(void *pa, void *pb)
Definition: ops_impl.c:231
AARCH64_SWS_OP_CLEAR
@ AARCH64_SWS_OP_CLEAR
Definition: ops_impl.h:54
AARCH64_SWS_OP_NONE
@ AARCH64_SWS_OP_NONE
Definition: ops_impl.h:39
aarch64_op_type_name
static const char * aarch64_op_type_name(SwsAArch64OpType op)
Definition: ops_impl.c:138
field_mask
static const ParamField field_mask
Definition: ops_impl.c:309
AARCH64_SWS_OP_READ_NIBBLE
@ AARCH64_SWS_OP_READ_NIBBLE
Definition: ops_impl.h:41
AARCH64_SWS_OP_PACK
@ AARCH64_SWS_OP_PACK
Definition: ops_impl.h:51
AARCH64_SWS_OP_SWAP_BYTES
@ AARCH64_SWS_OP_SWAP_BYTES
Definition: ops_impl.h:48
AARCH64_SWS_OP_READ_BIT
@ AARCH64_SWS_OP_READ_BIT
Definition: ops_impl.h:40
AARCH64_SWS_OP_MAX
@ AARCH64_SWS_OP_MAX
Definition: ops_impl.h:58
MAX_LEVELS
#define MAX_LEVELS
Definition: ops_impl.c:322
field_shift
static const ParamField field_shift
Definition: ops_impl.c:312
val
static double val(void *priv, double ch)
Definition: aeval.c:77
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
aarch64_pixel_type_name
static const char * aarch64_pixel_type_name(SwsAArch64PixelType fmt)
Definition: ops_impl.c:67
avassert.h
field_type
static const ParamField field_type
Definition: ops_impl.c:310
AARCH64_SWS_OP_WRITE_NIBBLE
@ AARCH64_SWS_OP_WRITE_NIBBLE
Definition: ops_impl.h:45
AARCH64_SWS_OP_DITHER
@ AARCH64_SWS_OP_DITHER
Definition: ops_impl.h:61
AARCH64_SWS_OP_RSHIFT
@ AARCH64_SWS_OP_RSHIFT
Definition: ops_impl.h:53
dither
static const uint16_t dither[8][8]
Definition: vf_gradfun.c:46
print_pixel_val
static void print_pixel_val(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:225
AARCH64_SWS_OP_LINEAR
@ AARCH64_SWS_OP_LINEAR
Definition: ops_impl.h:60
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
cmp_u8
static int cmp_u8(void *pa, void *pb)
Definition: ops_impl.c:253
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
print_u8_val
static void print_u8_val(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:247
AARCH64_SWS_OP_CONVERT
@ AARCH64_SWS_OP_CONVERT
Definition: ops_impl.h:55
print_op_val
static void print_op_val(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:203
op_fields
static const ParamField * op_fields[AARCH64_SWS_OP_TYPE_NB][MAX_LEVELS]
Definition: ops_impl.c:323
AARCH64_PIXEL_F32
@ AARCH64_PIXEL_F32
Definition: ops_impl.h:33
print_op_name
static void print_op_name(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:197
field_op
static const ParamField field_op
Definition: ops_impl.c:308
AARCH64_SWS_OP_SCALE
@ AARCH64_SWS_OP_SCALE
Definition: ops_impl.h:59
NULL
#define NULL
Definition: coverity.c:32
print_u16_val
static void print_u16_val(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:269
ParamField::cmp_val
int(* cmp_val)(void *pa, void *pb)
Definition: ops_impl.c:192
ParamField::print_str
void(* print_str)(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:190
AARCH64_SWS_OP_READ_PACKED
@ AARCH64_SWS_OP_READ_PACKED
Definition: ops_impl.h:42
attributes.h
field_dither_size_log2
static const ParamField field_dither_size_log2
Definition: ops_impl.c:319
print_u40_name
static void print_u40_name(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:285
AARCH64_SWS_OP_WRITE_PLANAR
@ AARCH64_SWS_OP_WRITE_PLANAR
Definition: ops_impl.h:47
AARCH64_SWS_OP_LSHIFT
@ AARCH64_SWS_OP_LSHIFT
Definition: ops_impl.h:52
shift
static int shift(int a, int b)
Definition: bonk.c:261
field_linear_mask
static const ParamField field_linear_mask
Definition: ops_impl.c:316
AARCH64_SWS_OP_TYPE_NB
@ AARCH64_SWS_OP_TYPE_NB
Definition: ops_impl.h:62
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:166
AARCH64_SWS_OP_WRITE_BIT
@ AARCH64_SWS_OP_WRITE_BIT
Definition: ops_impl.h:44
AARCH64_SWS_OP_READ_PLANAR
@ AARCH64_SWS_OP_READ_PLANAR
Definition: ops_impl.h:43
AARCH64_SWS_OP_EXPAND
@ AARCH64_SWS_OP_EXPAND
Definition: ops_impl.h:56
print_u16_name
static void print_u16_name(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:263
AARCH64_SWS_OP_UNPACK
@ AARCH64_SWS_OP_UNPACK
Definition: ops_impl.h:50
field_block_size
static const ParamField field_block_size
Definition: ops_impl.c:311
PARAM_FIELD
#define PARAM_FIELD(name)
Definition: ops_impl.c:195
ParamField::name
const char * name
Definition: ops_impl.c:187
vsnprintf
#define vsnprintf
Definition: snprintf.h:36
print_pixel_name
static void print_pixel_name(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:219
op_type_names
static const char op_type_names[AARCH64_SWS_OP_TYPE_NB][16]
Definition: ops_impl.c:112
AARCH64_PIXEL_U8
@ AARCH64_PIXEL_U8
Definition: ops_impl.h:30
print_u40_val
static void print_u40_val(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:291
field_swizzle
static const ParamField field_swizzle
Definition: ops_impl.c:313
AARCH64_PIXEL_U32
@ AARCH64_PIXEL_U32
Definition: ops_impl.h:32
field_pack
static const ParamField field_pack
Definition: ops_impl.c:314
SwsAArch64OpType
SwsAArch64OpType
Definition: ops_impl.h:38
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
ParamField::size
size_t size
Definition: ops_impl.c:189
cmp_u16
static int cmp_u16(void *pa, void *pb)
Definition: ops_impl.c:275
AARCH64_SWS_OP_WRITE_PACKED
@ AARCH64_SWS_OP_WRITE_PACKED
Definition: ops_impl.h:46
ParamField::offset
size_t offset
Definition: ops_impl.c:188
ib
#define ib(width, name)
Definition: cbs_h264.c:65
AARCH64_PIXEL_U16
@ AARCH64_PIXEL_U16
Definition: ops_impl.h:31
aarch64_op_type
static const char * aarch64_op_type(SwsAArch64OpType op)
Definition: ops_impl.c:103
SwsAArch64PixelType
SwsAArch64PixelType
Definition: ops_impl.h:29
aarch64_pixel_type
static const char * aarch64_pixel_type(SwsAArch64PixelType fmt)
Definition: ops_impl.c:51