FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/tests/sws_ops_aarch64.c
Date: 2026-09-19 14:27:34
Exec Total Coverage
Lines: 222 231 96.1%
Functions: 12 12 100.0%
Branches: 99 108 91.7%

Line Branch Exec Source
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 #include <stdio.h>
22
23 #include "libavutil/avassert.h"
24 #include "libavutil/bprint.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/tree.h"
27 #include "libswscale/graph.h"
28 #include "libswscale/ops.h"
29 #include "libswscale/ops_chain.h"
30 #include "libswscale/op_list_gen_template.c"
31 #include "libswscale/ops_dispatch.h"
32
33 #include "libswscale/aarch64/ops_impl_conv.c"
34
35 #ifdef _WIN32
36 #include <io.h>
37 #include <fcntl.h>
38 #endif
39
40 /*********************************************************************/
41 51683 static uint16_t clear_to_mask(const SwsClearUOp *clear)
42 {
43 51683 uint16_t mask = 0;
44
2/2
✓ Branch 0 taken 206732 times.
✓ Branch 1 taken 51683 times.
258415 for (int i = 0; i < 4; i++) {
45
2/2
✓ Branch 0 taken 196789 times.
✓ Branch 1 taken 9943 times.
206732 if (clear->zero & SWS_COMP(i)) {
46 /* no-op */
47
2/2
✓ Branch 0 taken 23016 times.
✓ Branch 1 taken 173773 times.
196789 } else if (clear->one & SWS_COMP(i)) {
48 23016 NIBBLE_SET(mask, i, 1);
49 } else {
50 173773 NIBBLE_SET(mask, i, 0xf);
51 }
52 }
53 51683 return mask;
54 }
55
56 104349 static uint64_t move_to_mask(const SwsMoveUOp *move)
57 {
58 104349 uint64_t mask = 0;
59
2/2
✓ Branch 0 taken 325168 times.
✓ Branch 1 taken 104349 times.
429517 for (int i = 0; i < move->num_moves; i++) {
60
2/2
✓ Branch 0 taken 254106 times.
✓ Branch 1 taken 71062 times.
325168 uint8_t dst = move->dst[i] < 0 ? 0xf : move->dst[i];
61
2/2
✓ Branch 0 taken 254106 times.
✓ Branch 1 taken 71062 times.
325168 uint8_t src = move->src[i] < 0 ? 0xf : move->src[i];
62 325168 uint64_t pair = src | (dst << 4);
63 325168 mask |= pair << (i * 8);
64 }
65 104349 return mask;
66 }
67
68 46468 static uint16_t pack_to_mask(const SwsPackUOp *pack)
69 {
70 46468 uint16_t mask = 0;
71
2/2
✓ Branch 0 taken 185872 times.
✓ Branch 1 taken 46468 times.
232340 for (int i = 0; i < 4; i++)
72 185872 NIBBLE_SET(mask, i, pack->pattern[i]);
73 46468 return mask;
74 }
75
76 132642 static uint64_t linear_to_mask(const SwsLinearUOp *linear)
77 {
78 132642 uint64_t mask = 0;
79
2/2
✓ Branch 0 taken 530568 times.
✓ Branch 1 taken 132642 times.
663210 for (int i = 0; i < 4; i++) {
80
2/2
✓ Branch 0 taken 2652840 times.
✓ Branch 1 taken 530568 times.
3183408 for (int j = 0; j < 5; j++) {
81
2/2
✓ Branch 0 taken 2122272 times.
✓ Branch 1 taken 530568 times.
2652840 int jj = (j == 0) ? 4 : (j - 1);
82
2/2
✓ Branch 0 taken 8193 times.
✓ Branch 1 taken 2644647 times.
2652840 if (linear->one & SWS_MASK(i, jj))
83 8193 mask |= 1ULL << (2 * ((5 * i + j)));
84
2/2
✓ Branch 0 taken 870251 times.
✓ Branch 1 taken 1774396 times.
2644647 else if (!(linear->zero & SWS_MASK(i, jj)))
85 870251 mask |= 3ULL << (2 * ((5 * i + j)));
86 }
87 }
88 132642 return mask;
89 }
90
91 43980 static uint16_t dither_to_mask(const SwsAArch64OpImplParams *p, const SwsDitherUOp *dither)
92 {
93 43980 uint16_t mask = 0;
94
2/2
✓ Branch 0 taken 175920 times.
✓ Branch 1 taken 43980 times.
219900 for (int i = 0; i < 4; i++) {
95
2/2
✓ Branch 0 taken 115279 times.
✓ Branch 1 taken 60641 times.
175920 if (p->mask & SWS_COMP(i)) {
96 115279 NIBBLE_SET(mask, i, dither->y_offset[i]);
97 } else {
98 60641 NIBBLE_SET(mask, i, 0xf);
99 }
100 }
101 43980 return mask;
102 }
103
104 1096180 static int aarch64_op_impl_cmp(const void *a, const void *b)
105 {
106 1096180 const SwsAArch64OpImplParams *pa = (const SwsAArch64OpImplParams *) a;
107 1096180 const SwsAArch64OpImplParams *pb = (const SwsAArch64OpImplParams *) b;
108 1096180 const SwsUOpParams *para = &pa->par;
109 1096180 const SwsUOpParams *parb = &pb->par;
110
111
2/2
✓ Branch 0 taken 592320 times.
✓ Branch 1 taken 503860 times.
1096180 if (pa->uop != pb->uop)
112 592320 return (int) pa->uop - pb->uop;
113
114
7/7
✓ Branch 0 taken 52132 times.
✓ Branch 1 taken 23219 times.
✓ Branch 2 taken 7394 times.
✓ Branch 3 taken 25820 times.
✓ Branch 4 taken 66305 times.
✓ Branch 5 taken 21979 times.
✓ Branch 6 taken 307011 times.
503860 switch (pa->uop) {
115 52132 case SWS_UOP_PERMUTE:
116 case SWS_UOP_COPY: {
117 52132 uint64_t ia = move_to_mask(&para->move);
118 52132 uint64_t ib = move_to_mask(&parb->move);
119
2/2
✓ Branch 0 taken 31553 times.
✓ Branch 1 taken 20579 times.
52132 if (ia != ib)
120
2/2
✓ Branch 0 taken 12160 times.
✓ Branch 1 taken 19393 times.
31553 return (int64_t) (ia - ib) < 0 ? -1 : 1;
121 20579 break;
122 }
123 23219 case SWS_UOP_UNPACK:
124 case SWS_UOP_PACK: {
125 23219 uint16_t ia = pack_to_mask(&para->pack);
126 23219 uint16_t ib = pack_to_mask(&parb->pack);
127
2/2
✓ Branch 0 taken 15123 times.
✓ Branch 1 taken 8096 times.
23219 if (ia != ib)
128 15123 return (int) ia - ib;
129 8096 break;
130 }
131 7394 case SWS_UOP_LSHIFT:
132 case SWS_UOP_RSHIFT:
133
2/2
✓ Branch 0 taken 2715 times.
✓ Branch 1 taken 4679 times.
7394 if (para->shift.amount != parb->shift.amount)
134 2715 return (int) para->shift.amount - parb->shift.amount;
135 4679 break;
136 25820 case SWS_UOP_CLEAR: {
137 25820 uint16_t ia = clear_to_mask(&para->clear);
138 25820 uint16_t ib = clear_to_mask(&parb->clear);
139
2/2
✓ Branch 0 taken 10636 times.
✓ Branch 1 taken 15184 times.
25820 if (ia != ib)
140 10636 return (int) ia - ib;
141 15184 break;
142 }
143 66305 case SWS_UOP_LINEAR:
144 case SWS_UOP_LINEAR_FMA: {
145 66305 uint64_t ia = linear_to_mask(&para->lin);
146 66305 uint64_t ib = linear_to_mask(&parb->lin);
147
2/2
✓ Branch 0 taken 44677 times.
✓ Branch 1 taken 21628 times.
66305 if (ia != ib)
148
2/2
✓ Branch 0 taken 18454 times.
✓ Branch 1 taken 26223 times.
44677 return (int64_t) (ia - ib) < 0 ? -1 : 1;
149 21628 break;
150 }
151 21979 case SWS_UOP_DITHER: {
152 21979 uint16_t ia = dither_to_mask(pa, &para->dither);
153 21979 uint16_t ib = dither_to_mask(pb, &parb->dither);
154
2/2
✓ Branch 0 taken 13413 times.
✓ Branch 1 taken 8566 times.
21979 if (ia != ib)
155 13413 return (int) ia - ib;
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8566 times.
8566 if (para->dither.size_log2 != parb->dither.size_log2)
157 return (int) para->dither.size_log2 - parb->dither.size_log2;
158 8566 break;
159 }
160 }
161
162
2/2
✓ Branch 0 taken 66809 times.
✓ Branch 1 taken 318934 times.
385743 if (pa->block_size != pb->block_size)
163 66809 return (int) pa->block_size - pb->block_size;
164
2/2
✓ Branch 0 taken 74048 times.
✓ Branch 1 taken 244886 times.
318934 if (pa->type != pb->type)
165 74048 return (int) pa->type - pb->type;
166
2/2
✓ Branch 0 taken 90023 times.
✓ Branch 1 taken 154863 times.
244886 if (pa->mask != pb->mask)
167 90023 return (int) pa->mask - pb->mask;
168
169 154863 return 0;
170 }
171
172 /*********************************************************************/
173 /* Insert the SwsAArch64OpImplParams structure into the AVTreeNode. */
174 155276 static int aarch64_collect_op(const SwsAArch64OpImplParams *params, struct AVTreeNode **root)
175 {
176 155276 int ret = 0;
177
178 155276 struct AVTreeNode *node = av_tree_node_alloc();
179 155276 SwsAArch64OpImplParams *copy = av_memdup(params, sizeof(*params));
180
2/4
✓ Branch 0 taken 155276 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 155276 times.
155276 if (!node || !copy) {
181 ret = AVERROR(ENOMEM);
182 goto error;
183 }
184 155276 av_tree_insert(root, copy, aarch64_op_impl_cmp, &node);
185
2/2
✓ Branch 0 taken 154863 times.
✓ Branch 1 taken 413 times.
155276 if (!node)
186 413 copy = NULL;
187
188 154863 error:
189 155276 av_free(node);
190 155276 av_free(copy);
191 155276 return ret;
192 }
193
194 19519 static int collect_ops_compile(SwsContext *ctx, const SwsOpList *ops,
195 SwsCompiledOp *out)
196 {
197 19519 struct AVTreeNode **root = (struct AVTreeNode **) ctx->opaque;
198 int ret;
199
200 /* Use at most two full vregs during the widest precision section */
201
2/2
✓ Branch 1 taken 15967 times.
✓ Branch 2 taken 3552 times.
19519 int block_size = (ff_sws_op_list_max_size(ops) == 4) ? 8 : 16;
202
203
2/2
✓ Branch 0 taken 144578 times.
✓ Branch 1 taken 19519 times.
164097 for (int i = 0; i < ops->num_ops; i++) {
204 144578 SwsAArch64OpImplParams params = { 0 };
205 144578 ret = convert_to_aarch64_impl(ctx, ops, i, block_size, &params);
206
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 144446 times.
144578 if (ret == AVERROR(ENOTSUP))
207 132 continue;
208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144446 times.
144446 if (ret < 0)
209 goto end;
210 144446 ret = aarch64_collect_op(&params, root);
211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144446 times.
144446 if (ret < 0)
212 goto end;
213
2/2
✓ Branch 0 taken 10830 times.
✓ Branch 1 taken 133616 times.
144446 if (params.uop == SWS_UOP_LINEAR_FMA) {
214 /**
215 * Generate both sets of linear op functions that do use
216 * and do not use fmla (selected by SWS_BITEXACT).
217 */
218 10830 params.uop = SWS_UOP_LINEAR;
219 10830 ret = aarch64_collect_op(&params, root);
220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10830 times.
10830 if (ret < 0)
221 goto end;
222 }
223 }
224
225 19519 *out = (SwsCompiledOp) { 0 };
226 19519 ret = 0;
227
228 19519 end:
229 19519 return ret;
230 }
231
232 static const SwsOpBackend backend_collect = {
233 .name = "collect_ops",
234 .compile = collect_ops_compile,
235 };
236
237 /*********************************************************************/
238 70224 static int register_op(SwsContext *ctx, void *opaque, SwsOpList *ops)
239 {
240 /* Skip ops lists which include filtering, since this is still not
241 * supported. */
242
2/2
✓ Branch 0 taken 278146 times.
✓ Branch 1 taken 17556 times.
295702 for (int i = 0; i < ops->num_ops; i++) {
243 278146 const SwsOp *op = &ops->ops[i];
244
3/3
✓ Branch 0 taken 87780 times.
✓ Branch 1 taken 39996 times.
✓ Branch 2 taken 150370 times.
278146 switch (op->op) {
245 87780 case SWS_OP_READ:
246 case SWS_OP_WRITE:
247
2/2
✓ Branch 0 taken 12672 times.
✓ Branch 1 taken 75108 times.
87780 if (op->rw.filter.op)
248 12672 return 0;
249 75108 break;
250 39996 case SWS_OP_FILTER_H:
251 case SWS_OP_FILTER_V:
252 39996 return 0;
253 }
254 }
255
256 /* ff_sws_compile_pass() takes over ownership of `ops` */
257 17556 SwsOpList *copy = ff_sws_op_list_duplicate(ops);
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17556 times.
17556 if (!copy)
259 return AVERROR(ENOMEM);
260
261 17556 const int flags = SWS_OP_FLAG_DRY_RUN | SWS_OP_FLAG_SPLIT_MEMCPY;
262 17556 return ff_sws_compile_pass(opaque, &backend_collect, &copy, flags, NULL, NULL);
263 }
264
265 /*********************************************************************/
266 static const char op_type_names[SWS_UOP_TYPE_NB][16] = {
267 [SWS_UOP_READ_BIT ] = "read_bit",
268 [SWS_UOP_READ_NIBBLE ] = "read_nibble",
269 [SWS_UOP_READ_PACKED ] = "read_packed",
270 [SWS_UOP_READ_PLANAR ] = "read_planar",
271 [SWS_UOP_WRITE_BIT ] = "write_bit",
272 [SWS_UOP_WRITE_NIBBLE ] = "write_nibble",
273 [SWS_UOP_WRITE_PACKED ] = "write_packed",
274 [SWS_UOP_WRITE_PLANAR ] = "write_planar",
275 [SWS_UOP_SWAP_BYTES ] = "swap_bytes",
276 [SWS_UOP_PERMUTE ] = "permute",
277 [SWS_UOP_COPY ] = "copy",
278 [SWS_UOP_UNPACK ] = "unpack",
279 [SWS_UOP_PACK ] = "pack",
280 [SWS_UOP_LSHIFT ] = "lshift",
281 [SWS_UOP_RSHIFT ] = "rshift",
282 [SWS_UOP_CLEAR ] = "clear",
283 [SWS_UOP_TO_U8 ] = "to_u8",
284 [SWS_UOP_TO_U16 ] = "to_u16",
285 [SWS_UOP_TO_U32 ] = "to_u32",
286 [SWS_UOP_TO_F32 ] = "to_f32",
287 [SWS_UOP_EXPAND_PAIR ] = "expand_pair",
288 [SWS_UOP_EXPAND_QUAD ] = "expand_quad",
289 [SWS_UOP_MIN ] = "min",
290 [SWS_UOP_MAX ] = "max",
291 [SWS_UOP_SCALE ] = "scale",
292 [SWS_UOP_LINEAR ] = "linear",
293 [SWS_UOP_LINEAR_FMA ] = "linear_fma",
294 [SWS_UOP_DITHER ] = "dither",
295 };
296
297 static const char pixel_type_names[SWS_PIXEL_TYPE_NB][4] = {
298 [SWS_PIXEL_U8 ] = "u8",
299 [SWS_PIXEL_U16] = "u16",
300 [SWS_PIXEL_U32] = "u32",
301 [SWS_PIXEL_F32] = "f32",
302 };
303
304 static const char uop_types[SWS_UOP_TYPE_NB][32] = {
305 [SWS_UOP_READ_BIT ] = "SWS_UOP_READ_BIT",
306 [SWS_UOP_READ_NIBBLE ] = "SWS_UOP_READ_NIBBLE",
307 [SWS_UOP_READ_PACKED ] = "SWS_UOP_READ_PACKED",
308 [SWS_UOP_READ_PLANAR ] = "SWS_UOP_READ_PLANAR",
309 [SWS_UOP_WRITE_BIT ] = "SWS_UOP_WRITE_BIT",
310 [SWS_UOP_WRITE_NIBBLE ] = "SWS_UOP_WRITE_NIBBLE",
311 [SWS_UOP_WRITE_PACKED ] = "SWS_UOP_WRITE_PACKED",
312 [SWS_UOP_WRITE_PLANAR ] = "SWS_UOP_WRITE_PLANAR",
313 [SWS_UOP_SWAP_BYTES ] = "SWS_UOP_SWAP_BYTES",
314 [SWS_UOP_PERMUTE ] = "SWS_UOP_PERMUTE",
315 [SWS_UOP_COPY ] = "SWS_UOP_COPY",
316 [SWS_UOP_UNPACK ] = "SWS_UOP_UNPACK",
317 [SWS_UOP_PACK ] = "SWS_UOP_PACK",
318 [SWS_UOP_LSHIFT ] = "SWS_UOP_LSHIFT",
319 [SWS_UOP_RSHIFT ] = "SWS_UOP_RSHIFT",
320 [SWS_UOP_CLEAR ] = "SWS_UOP_CLEAR",
321 [SWS_UOP_TO_U8 ] = "SWS_UOP_TO_U8",
322 [SWS_UOP_TO_U16 ] = "SWS_UOP_TO_U16",
323 [SWS_UOP_TO_U32 ] = "SWS_UOP_TO_U32",
324 [SWS_UOP_TO_F32 ] = "SWS_UOP_TO_F32",
325 [SWS_UOP_EXPAND_PAIR ] = "SWS_UOP_EXPAND_PAIR",
326 [SWS_UOP_EXPAND_QUAD ] = "SWS_UOP_EXPAND_QUAD",
327 [SWS_UOP_MIN ] = "SWS_UOP_MIN",
328 [SWS_UOP_MAX ] = "SWS_UOP_MAX",
329 [SWS_UOP_SCALE ] = "SWS_UOP_SCALE",
330 [SWS_UOP_LINEAR ] = "SWS_UOP_LINEAR",
331 [SWS_UOP_LINEAR_FMA ] = "SWS_UOP_LINEAR_FMA",
332 [SWS_UOP_DITHER ] = "SWS_UOP_DITHER",
333 };
334
335 static const char pixel_types[SWS_PIXEL_TYPE_NB][32] = {
336 [SWS_PIXEL_U8 ] = "SWS_PIXEL_U8",
337 [SWS_PIXEL_U16] = "SWS_PIXEL_U16",
338 [SWS_PIXEL_U32] = "SWS_PIXEL_U32",
339 [SWS_PIXEL_F32] = "SWS_PIXEL_F32",
340 };
341
342 413 static void serialize_op(AVBPrint *bp, const SwsAArch64OpImplParams *params)
343 {
344 #define FUNC_NAME_WIDTH 45
345 #define UOP_NAME_WIDTH 21
346 #define TYPE_NAME_WIDTH 14
347
348 413 const SwsUOpParams *par = &params->par;
349
350 char func_name[FUNC_NAME_WIDTH + 2];
351 413 snprintf(func_name, sizeof(func_name), "ff_sws_%s", op_type_names[params->uop]);
352
7/7
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 43 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 169 times.
413 switch (params->uop) {
353 85 case SWS_UOP_PERMUTE:
354 case SWS_UOP_COPY:
355 85 av_strlcatf(func_name, sizeof(func_name), "_%012" PRIx64, move_to_mask(&par->move));
356 85 break;
357 30 case SWS_UOP_UNPACK:
358 case SWS_UOP_PACK:
359 30 av_strlcatf(func_name, sizeof(func_name), "_%04x", pack_to_mask(&par->pack));
360 30 break;
361 32 case SWS_UOP_LSHIFT:
362 case SWS_UOP_RSHIFT:
363 32 av_strlcatf(func_name, sizeof(func_name), "_%u", par->shift.amount);
364 32 break;
365 43 case SWS_UOP_CLEAR:
366 43 av_strlcatf(func_name, sizeof(func_name), "_%04x", clear_to_mask(&par->clear));
367 43 break;
368 32 case SWS_UOP_LINEAR:
369 case SWS_UOP_LINEAR_FMA:
370 32 av_strlcatf(func_name, sizeof(func_name), "_%010" PRIx64, linear_to_mask(&par->lin));
371 32 break;
372 22 case SWS_UOP_DITHER:
373 22 av_strlcatf(func_name, sizeof(func_name), "_%04x_%u", dither_to_mask(params, &par->dither), par->dither.size_log2);
374 22 break;
375 }
376 413 av_strlcatf(func_name, sizeof(func_name), "_%u_%s_%04x_neon,",
377 413 params->block_size, pixel_type_names[params->type], nibble_mask(params->mask));
378
379 char uop_name[UOP_NAME_WIDTH + 2];
380 413 snprintf(uop_name, sizeof(uop_name), "%s,", uop_types[params->uop]);
381
382 char type_name[TYPE_NAME_WIDTH + 2];
383 413 snprintf(type_name, sizeof(type_name), "%s,", pixel_types[params->type]);
384
385 413 av_bprintf(bp, "ENTRY(%-*s { .uop = %-*s .block_size = %2u, .type = %-*s .mask = 0x%x",
386 FUNC_NAME_WIDTH, func_name, UOP_NAME_WIDTH, uop_name,
387 413 params->block_size, TYPE_NAME_WIDTH, type_name, params->mask);
388
7/7
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 43 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 169 times.
413 switch (params->uop) {
389 85 case SWS_UOP_PERMUTE:
390 case SWS_UOP_COPY:
391 85 av_bprintf(bp, ", .par.move = { .num_moves = %d, .dst = {%d, %d, %d, %d, %d, %d}, .src = {%d, %d, %d, %d, %d, %d} }",
392 85 par->move.num_moves,
393 85 par->move.dst[0], par->move.dst[1], par->move.dst[2],
394 85 par->move.dst[3], par->move.dst[4], par->move.dst[5],
395 85 par->move.src[0], par->move.src[1], par->move.src[2],
396 85 par->move.src[3], par->move.src[4], par->move.src[5]);
397 85 break;
398 30 case SWS_UOP_UNPACK:
399 case SWS_UOP_PACK:
400 30 av_bprintf(bp, ", .par.pack = { .pattern = {%d, %d, %d, %d} }",
401 30 par->pack.pattern[0], par->pack.pattern[1],
402 30 par->pack.pattern[2], par->pack.pattern[3]);
403 30 break;
404 32 case SWS_UOP_LSHIFT:
405 case SWS_UOP_RSHIFT:
406 32 av_bprintf(bp, ", .par.shift = { .amount = %u }", par->shift.amount);
407 32 break;
408 43 case SWS_UOP_CLEAR:
409 43 av_bprintf(bp, ", .par.clear = { .one = 0x%0x, .zero = 0x%0x }", par->clear.one, par->clear.zero);
410 43 break;
411 32 case SWS_UOP_LINEAR:
412 case SWS_UOP_LINEAR_FMA:
413 32 av_bprintf(bp, ", .par.lin = { .one = 0x%x, .zero = 0x%x }", par->lin.one, par->lin.zero);
414 32 break;
415 22 case SWS_UOP_DITHER:
416 22 av_bprintf(bp, ", .par.dither = { .y_offset = {%u, %u, %u, %u}, .size_log2 = %u }",
417 22 par->dither.y_offset[0], par->dither.y_offset[1],
418 22 par->dither.y_offset[2], par->dither.y_offset[3],
419 22 par->dither.size_log2);
420 22 break;
421 }
422 413 av_bprintf(bp, " })");
423 413 }
424
425 /* Serialize SwsAArch64OpImplParams for one function. */
426 413 static int print_op(void *opaque, void *elem)
427 {
428 413 SwsAArch64OpImplParams *params = (SwsAArch64OpImplParams *) elem;
429 413 FILE *fp = (FILE *) opaque;
430
431 AVBPrint bp;
432 413 av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
433 413 serialize_op(&bp, params);
434 413 fprintf(fp, "%s\n", bp.str);
435 413 av_bprint_finalize(&bp, NULL);
436
437 413 av_free(params);
438
439 413 return 0;
440 }
441
442 /*********************************************************************/
443 1 int main(int argc, char *argv[])
444 {
445 1 struct AVTreeNode *root = NULL;
446 1 int ret = 1;
447
448 #ifdef _WIN32
449 _setmode(_fileno(stdout), _O_BINARY);
450 #endif
451
452 1 SwsContext *ctx = sws_alloc_context();
453
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ctx)
454 goto fail;
455
456 1 SwsGraph *graph = ff_sws_graph_alloc();
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!graph)
458 goto fail;
459
460 1 graph->ctx = ctx;
461 1 ctx->opaque = &root;
462
463 1 ret = ff_sws_enum_op_lists(ctx, graph, NULL, AV_PIX_FMT_NONE, AV_PIX_FMT_NONE,
464 register_op);
465
466 /**
467 * Generate a C file with all the unique function parameter entries
468 * collected by aarch64_enum_ops().
469 */
470 1 printf("/*\n");
471 1 printf(" * This file is automatically generated. Do not edit manually.\n");
472 1 printf(" * To regenerate, run: make fate-sws-ops-entries-aarch64 GEN=1\n");
473 1 printf(" */\n");
474 1 printf("\n");
475 1 av_tree_enumerate(root, stdout, NULL, print_op);
476
477 1 ff_sws_graph_free(&graph);
478
479 1 fail:
480 1 av_tree_destroy(root);
481 1 sws_free_context(&ctx);
482 1 return ret;
483 }
484