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_PROCESS ] = "AARCH64_SWS_OP_PROCESS",
80  [AARCH64_SWS_OP_PROCESS_RETURN] = "AARCH64_SWS_OP_PROCESS_RETURN",
81  [AARCH64_SWS_OP_READ_BIT ] = "AARCH64_SWS_OP_READ_BIT",
82  [AARCH64_SWS_OP_READ_NIBBLE ] = "AARCH64_SWS_OP_READ_NIBBLE",
83  [AARCH64_SWS_OP_READ_PACKED ] = "AARCH64_SWS_OP_READ_PACKED",
84  [AARCH64_SWS_OP_READ_PLANAR ] = "AARCH64_SWS_OP_READ_PLANAR",
85  [AARCH64_SWS_OP_WRITE_BIT ] = "AARCH64_SWS_OP_WRITE_BIT",
86  [AARCH64_SWS_OP_WRITE_NIBBLE ] = "AARCH64_SWS_OP_WRITE_NIBBLE",
87  [AARCH64_SWS_OP_WRITE_PACKED ] = "AARCH64_SWS_OP_WRITE_PACKED",
88  [AARCH64_SWS_OP_WRITE_PLANAR ] = "AARCH64_SWS_OP_WRITE_PLANAR",
89  [AARCH64_SWS_OP_SWAP_BYTES ] = "AARCH64_SWS_OP_SWAP_BYTES",
90  [AARCH64_SWS_OP_SWIZZLE ] = "AARCH64_SWS_OP_SWIZZLE",
91  [AARCH64_SWS_OP_UNPACK ] = "AARCH64_SWS_OP_UNPACK",
92  [AARCH64_SWS_OP_PACK ] = "AARCH64_SWS_OP_PACK",
93  [AARCH64_SWS_OP_LSHIFT ] = "AARCH64_SWS_OP_LSHIFT",
94  [AARCH64_SWS_OP_RSHIFT ] = "AARCH64_SWS_OP_RSHIFT",
95  [AARCH64_SWS_OP_CLEAR ] = "AARCH64_SWS_OP_CLEAR",
96  [AARCH64_SWS_OP_CONVERT ] = "AARCH64_SWS_OP_CONVERT",
97  [AARCH64_SWS_OP_EXPAND ] = "AARCH64_SWS_OP_EXPAND",
98  [AARCH64_SWS_OP_MIN ] = "AARCH64_SWS_OP_MIN",
99  [AARCH64_SWS_OP_MAX ] = "AARCH64_SWS_OP_MAX",
100  [AARCH64_SWS_OP_SCALE ] = "AARCH64_SWS_OP_SCALE",
101  [AARCH64_SWS_OP_LINEAR ] = "AARCH64_SWS_OP_LINEAR",
102  [AARCH64_SWS_OP_DITHER ] = "AARCH64_SWS_OP_DITHER",
103 };
104 
106 {
108  av_assert0(!"Invalid op type!");
109  return NULL;
110  }
111  return op_types[op];
112 }
113 
114 static const char op_type_names[AARCH64_SWS_OP_TYPE_NB][16] = {
115  [AARCH64_SWS_OP_NONE ] = "none",
116  [AARCH64_SWS_OP_PROCESS ] = "process",
117  [AARCH64_SWS_OP_PROCESS_RETURN] = "process_return",
118  [AARCH64_SWS_OP_READ_BIT ] = "read_bit",
119  [AARCH64_SWS_OP_READ_NIBBLE ] = "read_nibble",
120  [AARCH64_SWS_OP_READ_PACKED ] = "read_packed",
121  [AARCH64_SWS_OP_READ_PLANAR ] = "read_planar",
122  [AARCH64_SWS_OP_WRITE_BIT ] = "write_bit",
123  [AARCH64_SWS_OP_WRITE_NIBBLE ] = "write_nibble",
124  [AARCH64_SWS_OP_WRITE_PACKED ] = "write_packed",
125  [AARCH64_SWS_OP_WRITE_PLANAR ] = "write_planar",
126  [AARCH64_SWS_OP_SWAP_BYTES ] = "swap_bytes",
127  [AARCH64_SWS_OP_SWIZZLE ] = "swizzle",
128  [AARCH64_SWS_OP_UNPACK ] = "unpack",
129  [AARCH64_SWS_OP_PACK ] = "pack",
130  [AARCH64_SWS_OP_LSHIFT ] = "lshift",
131  [AARCH64_SWS_OP_RSHIFT ] = "rshift",
132  [AARCH64_SWS_OP_CLEAR ] = "clear",
133  [AARCH64_SWS_OP_CONVERT ] = "convert",
134  [AARCH64_SWS_OP_EXPAND ] = "expand",
135  [AARCH64_SWS_OP_MIN ] = "min",
136  [AARCH64_SWS_OP_MAX ] = "max",
137  [AARCH64_SWS_OP_SCALE ] = "scale",
138  [AARCH64_SWS_OP_LINEAR ] = "linear",
139  [AARCH64_SWS_OP_DITHER ] = "dither",
140 };
141 
143 {
145  av_assert0(!"Invalid op type!");
146  return NULL;
147  }
148  return op_type_names[op];
149 }
150 
151 /*********************************************************************/
152 /*
153  * Helper string concatenation function that does not depend on the
154  * FFmpeg libraries, so it may be used standalone.
155  */
157 static void buf_appendf(char **pbuf, size_t *prem, const char *fmt, ...)
158 {
159  char *buf = *pbuf;
160  size_t rem = *prem;
161  if (!rem)
162  return;
163 
164  va_list ap;
165  va_start(ap, fmt);
166  int n = vsnprintf(buf, rem, fmt, ap);
167  va_end(ap);
168 
169  if (n > 0) {
170  if (n < rem) {
171  buf += n;
172  rem -= n;
173  } else {
174  buf += rem - 1;
175  rem = 0;
176  }
177  *pbuf = buf;
178  *prem = rem;
179  }
180 }
181 
182 /*********************************************************************/
183 /**
184  * The following structure is used to describe one field from
185  * SwsAArch64OpImplParams. This will be used to serialize the parameter
186  * structure, generate function names and lookup strings, and compare
187  * two sets of parameters.
188  */
189 
190 typedef struct ParamField {
191  const char *name;
192  size_t offset;
193  size_t size;
194  void (*print_str)(char **pbuf, size_t *prem, void *p);
195  void (*print_val)(char **pbuf, size_t *prem, void *p);
196  int (*cmp_val)(void *pa, void *pb);
197 } ParamField;
198 
199 #define PARAM_FIELD(name) #name, offsetof(SwsAArch64OpImplParams, name), sizeof(((SwsAArch64OpImplParams *) 0)->name)
200 
201 static void print_op_name(char **pbuf, size_t *prem, void *p)
202 {
204  buf_appendf(pbuf, prem, "_%s", aarch64_op_type_name(op));
205 }
206 
207 static void print_op_val(char **pbuf, size_t *prem, void *p)
208 {
210  buf_appendf(pbuf, prem, "%s", aarch64_op_type(op));
211 }
212 
213 static int cmp_op(void *pa, void *pb)
214 {
215  int64_t ia = (int64_t) *((SwsAArch64OpType *) pa);
216  int64_t ib = (int64_t) *((SwsAArch64OpType *) pb);
217  int64_t diff = ia - ib;
218  if (diff)
219  return diff < 0 ? -1 : 1;
220  return 0;
221 }
222 
223 static void print_pixel_name(char **pbuf, size_t *prem, void *p)
224 {
226  buf_appendf(pbuf, prem, "_%s", aarch64_pixel_type_name(type));
227 }
228 
229 static void print_pixel_val(char **pbuf, size_t *prem, void *p)
230 {
232  buf_appendf(pbuf, prem, "%s", aarch64_pixel_type(type));
233 }
234 
235 static int cmp_pixel(void *pa, void *pb)
236 {
237  int64_t ia = (int64_t) *((SwsAArch64PixelType *) pa);
238  int64_t ib = (int64_t) *((SwsAArch64PixelType *) pb);
239  int64_t diff = ia - ib;
240  if (diff)
241  return diff < 0 ? -1 : 1;
242  return 0;
243 }
244 
245 static void print_u8_name(char **pbuf, size_t *prem, void *p)
246 {
247  uint8_t val = *(uint8_t *) p;
248  buf_appendf(pbuf, prem, "_%u", val);
249 }
250 
251 static void print_u8_val(char **pbuf, size_t *prem, void *p)
252 {
253  uint8_t val = *(uint8_t *) p;
254  buf_appendf(pbuf, prem, "%u", val);
255 }
256 
257 static int cmp_u8(void *pa, void *pb)
258 {
259  int64_t ia = (int64_t) *((uint8_t *) pa);
260  int64_t ib = (int64_t) *((uint8_t *) pb);
261  int64_t diff = ia - ib;
262  if (diff)
263  return diff < 0 ? -1 : 1;
264  return 0;
265 }
266 
267 static void print_u16_name(char **pbuf, size_t *prem, void *p)
268 {
269  uint16_t val = *(uint16_t *) p;
270  buf_appendf(pbuf, prem, "_%04x", val);
271 }
272 
273 static void print_u16_val(char **pbuf, size_t *prem, void *p)
274 {
275  uint16_t val = *(uint16_t *) p;
276  buf_appendf(pbuf, prem, "0x%04x", val);
277 }
278 
279 static int cmp_u16(void *pa, void *pb)
280 {
281  int64_t ia = (int64_t) *((uint16_t *) pa);
282  int64_t ib = (int64_t) *((uint16_t *) pb);
283  int64_t diff = ia - ib;
284  if (diff)
285  return diff < 0 ? -1 : 1;
286  return 0;
287 }
288 
289 static void print_u40_name(char **pbuf, size_t *prem, void *p)
290 {
291  uint64_t val = *(uint64_t *) p;
292  buf_appendf(pbuf, prem, "_%010" PRIx64, val);
293 }
294 
295 static void print_u40_val(char **pbuf, size_t *prem, void *p)
296 {
297  uint64_t val = *(uint64_t *) p;
298  buf_appendf(pbuf, prem, "0x%010" PRIx64 "ULL", val);
299 }
300 
301 static int cmp_u40(void *pa, void *pb)
302 {
303  int64_t ia = (int64_t) *((uint64_t *) pa);
304  int64_t ib = (int64_t) *((uint64_t *) pb);
305  int64_t diff = ia - ib;
306  if (diff)
307  return diff < 0 ? -1 : 1;
308  return 0;
309 }
310 
311 /*********************************************************************/
324 
325 /* Fields needed to uniquely identify each SwsAArch64OpType. */
326 #define MAX_LEVELS 8
352 };
AARCH64_SWS_OP_MIN
@ AARCH64_SWS_OP_MIN
Definition: ops_impl.h:59
field_dither_y_offset
static const ParamField field_dither_y_offset
Definition: ops_impl.c:322
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:190
cmp_u40
static int cmp_u40(void *pa, void *pb)
Definition: ops_impl.c:301
field_linear_fmla
static const ParamField field_linear_fmla
Definition: ops_impl.c:321
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:245
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:213
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:51
field_to_type
static const ParamField field_to_type
Definition: ops_impl.c:319
av_printf_format
av_printf_format(3, 4)
Definition: ops_impl.c:156
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:195
cmp_pixel
static int cmp_pixel(void *pa, void *pb)
Definition: ops_impl.c:235
AARCH64_SWS_OP_CLEAR
@ AARCH64_SWS_OP_CLEAR
Definition: ops_impl.h:56
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:142
field_mask
static const ParamField field_mask
Definition: ops_impl.c:313
AARCH64_SWS_OP_READ_NIBBLE
@ AARCH64_SWS_OP_READ_NIBBLE
Definition: ops_impl.h:43
AARCH64_SWS_OP_PACK
@ AARCH64_SWS_OP_PACK
Definition: ops_impl.h:53
AARCH64_SWS_OP_SWAP_BYTES
@ AARCH64_SWS_OP_SWAP_BYTES
Definition: ops_impl.h:50
AARCH64_SWS_OP_READ_BIT
@ AARCH64_SWS_OP_READ_BIT
Definition: ops_impl.h:42
AARCH64_SWS_OP_MAX
@ AARCH64_SWS_OP_MAX
Definition: ops_impl.h:60
MAX_LEVELS
#define MAX_LEVELS
Definition: ops_impl.c:326
field_shift
static const ParamField field_shift
Definition: ops_impl.c:316
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:314
AARCH64_SWS_OP_WRITE_NIBBLE
@ AARCH64_SWS_OP_WRITE_NIBBLE
Definition: ops_impl.h:47
AARCH64_SWS_OP_DITHER
@ AARCH64_SWS_OP_DITHER
Definition: ops_impl.h:63
AARCH64_SWS_OP_RSHIFT
@ AARCH64_SWS_OP_RSHIFT
Definition: ops_impl.h:55
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:229
AARCH64_SWS_OP_LINEAR
@ AARCH64_SWS_OP_LINEAR
Definition: ops_impl.h:62
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:257
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:251
AARCH64_SWS_OP_CONVERT
@ AARCH64_SWS_OP_CONVERT
Definition: ops_impl.h:57
print_op_val
static void print_op_val(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:207
AARCH64_SWS_OP_PROCESS
@ AARCH64_SWS_OP_PROCESS
Definition: ops_impl.h:40
op_fields
static const ParamField * op_fields[AARCH64_SWS_OP_TYPE_NB][MAX_LEVELS]
Definition: ops_impl.c:327
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:201
field_op
static const ParamField field_op
Definition: ops_impl.c:312
AARCH64_SWS_OP_SCALE
@ AARCH64_SWS_OP_SCALE
Definition: ops_impl.h:61
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:273
ParamField::cmp_val
int(* cmp_val)(void *pa, void *pb)
Definition: ops_impl.c:196
ParamField::print_str
void(* print_str)(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:194
AARCH64_SWS_OP_READ_PACKED
@ AARCH64_SWS_OP_READ_PACKED
Definition: ops_impl.h:44
field_dither_size_log2
static const ParamField field_dither_size_log2
Definition: ops_impl.c:323
print_u40_name
static void print_u40_name(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:289
AARCH64_SWS_OP_WRITE_PLANAR
@ AARCH64_SWS_OP_WRITE_PLANAR
Definition: ops_impl.h:49
AARCH64_SWS_OP_LSHIFT
@ AARCH64_SWS_OP_LSHIFT
Definition: ops_impl.h:54
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:320
AARCH64_SWS_OP_TYPE_NB
@ AARCH64_SWS_OP_TYPE_NB
Definition: ops_impl.h:64
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
attributes.h
AARCH64_SWS_OP_WRITE_BIT
@ AARCH64_SWS_OP_WRITE_BIT
Definition: ops_impl.h:46
AARCH64_SWS_OP_READ_PLANAR
@ AARCH64_SWS_OP_READ_PLANAR
Definition: ops_impl.h:45
AARCH64_SWS_OP_EXPAND
@ AARCH64_SWS_OP_EXPAND
Definition: ops_impl.h:58
print_u16_name
static void print_u16_name(char **pbuf, size_t *prem, void *p)
Definition: ops_impl.c:267
AARCH64_SWS_OP_UNPACK
@ AARCH64_SWS_OP_UNPACK
Definition: ops_impl.h:52
field_block_size
static const ParamField field_block_size
Definition: ops_impl.c:315
PARAM_FIELD
#define PARAM_FIELD(name)
Definition: ops_impl.c:199
ParamField::name
const char * name
Definition: ops_impl.c:191
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:223
op_type_names
static const char op_type_names[AARCH64_SWS_OP_TYPE_NB][16]
Definition: ops_impl.c:114
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:295
field_swizzle
static const ParamField field_swizzle
Definition: ops_impl.c:317
AARCH64_PIXEL_U32
@ AARCH64_PIXEL_U32
Definition: ops_impl.h:32
field_pack
static const ParamField field_pack
Definition: ops_impl.c:318
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:193
cmp_u16
static int cmp_u16(void *pa, void *pb)
Definition: ops_impl.c:279
AARCH64_SWS_OP_WRITE_PACKED
@ AARCH64_SWS_OP_WRITE_PACKED
Definition: ops_impl.h:48
ParamField::offset
size_t offset
Definition: ops_impl.c:192
AARCH64_SWS_OP_PROCESS_RETURN
@ AARCH64_SWS_OP_PROCESS_RETURN
Definition: ops_impl.h:41
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:105
SwsAArch64PixelType
SwsAArch64PixelType
Definition: ops_impl.h:29
aarch64_pixel_type
static const char * aarch64_pixel_type(SwsAArch64PixelType fmt)
Definition: ops_impl.c:51