FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/tests/sws_ops_aarch64.c
Date: 2026-10-19 01:23:10
Exec Total Coverage
Lines: 228 238 95.8%
Functions: 12 12 100.0%
Branches: 101 112 90.2%

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 50590 static uint16_t clear_to_mask(const SwsClearUOp *clear)
42 {
43 50590 uint16_t mask = 0;
44
2/2
✓ Branch 0 taken 202360 times.
✓ Branch 1 taken 50590 times.
252950 for (int i = 0; i < 4; i++) {
45
2/2
✓ Branch 0 taken 192619 times.
✓ Branch 1 taken 9741 times.
202360 if (clear->zero & SWS_COMP(i)) {
46 /* no-op */
47
2/2
✓ Branch 0 taken 23096 times.
✓ Branch 1 taken 169523 times.
192619 } else if (clear->one & SWS_COMP(i)) {
48 23096 NIBBLE_SET(mask, i, 1);
49 } else {
50 169523 NIBBLE_SET(mask, i, 0xf);
51 }
52 }
53 50590 return mask;
54 }
55
56 102956 static uint64_t move_to_mask(const SwsMoveUOp *move)
57 {
58 102956 uint64_t mask = 0;
59
2/2
✓ Branch 0 taken 313234 times.
✓ Branch 1 taken 102956 times.
416190 for (int i = 0; i < move->num_moves; i++) {
60
2/2
✓ Branch 0 taken 244950 times.
✓ Branch 1 taken 68284 times.
313234 uint8_t dst = move->dst[i] < 0 ? 0xf : move->dst[i];
61
2/2
✓ Branch 0 taken 244950 times.
✓ Branch 1 taken 68284 times.
313234 uint8_t src = move->src[i] < 0 ? 0xf : move->src[i];
62 313234 uint64_t pair = src | (dst << 4);
63 313234 mask |= pair << (i * 8);
64 }
65 102956 return mask;
66 }
67
68 39762 static uint16_t pack_to_mask(const SwsPackUOp *pack)
69 {
70 39762 uint16_t mask = 0;
71
2/2
✓ Branch 0 taken 159048 times.
✓ Branch 1 taken 39762 times.
198810 for (int i = 0; i < 4; i++)
72 159048 NIBBLE_SET(mask, i, pack->pattern[i]);
73 39762 return mask;
74 }
75
76 140031 static uint64_t linear_to_mask(const SwsLinearUOp *linear)
77 {
78 140031 uint64_t mask = 0;
79
2/2
✓ Branch 0 taken 560124 times.
✓ Branch 1 taken 140031 times.
700155 for (int i = 0; i < 4; i++) {
80
2/2
✓ Branch 0 taken 2800620 times.
✓ Branch 1 taken 560124 times.
3360744 for (int j = 0; j < 5; j++) {
81
2/2
✓ Branch 0 taken 2240496 times.
✓ Branch 1 taken 560124 times.
2800620 int jj = (j == 0) ? 4 : (j - 1);
82
2/2
✓ Branch 0 taken 8112 times.
✓ Branch 1 taken 2792508 times.
2800620 if (linear->one & SWS_MASK(i, jj))
83 8112 mask |= 1ULL << (2 * ((5 * i + j)));
84
2/2
✓ Branch 0 taken 966650 times.
✓ Branch 1 taken 1825858 times.
2792508 else if (!(linear->zero & SWS_MASK(i, jj)))
85 966650 mask |= 3ULL << (2 * ((5 * i + j)));
86 }
87 }
88 140031 return mask;
89 }
90
91 71846 static uint16_t dither_to_mask(const SwsAArch64OpImplParams *p, const SwsDitherUOp *dither)
92 {
93 71846 uint16_t mask = 0;
94
2/2
✓ Branch 0 taken 287384 times.
✓ Branch 1 taken 71846 times.
359230 for (int i = 0; i < 4; i++) {
95
2/2
✓ Branch 0 taken 189484 times.
✓ Branch 1 taken 97900 times.
287384 if (p->mask & SWS_COMP(i)) {
96 189484 NIBBLE_SET(mask, i, dither->y_offset[i]);
97 } else {
98 97900 NIBBLE_SET(mask, i, 0xf);
99 }
100 }
101 71846 return mask;
102 }
103
104 1105891 static int aarch64_op_impl_cmp(const void *a, const void *b)
105 {
106 1105891 const SwsAArch64OpImplParams *pa = (const SwsAArch64OpImplParams *) a;
107 1105891 const SwsAArch64OpImplParams *pb = (const SwsAArch64OpImplParams *) b;
108 1105891 const SwsUOpParams *para = &pa->par;
109 1105891 const SwsUOpParams *parb = &pb->par;
110
111
2/2
✓ Branch 0 taken 602077 times.
✓ Branch 1 taken 503814 times.
1105891 if (pa->uop != pb->uop)
112 602077 return (int) pa->uop - pb->uop;
113
114
7/7
✓ Branch 0 taken 51435 times.
✓ Branch 1 taken 19866 times.
✓ Branch 2 taken 8180 times.
✓ Branch 3 taken 25270 times.
✓ Branch 4 taken 69994 times.
✓ Branch 5 taken 35912 times.
✓ Branch 6 taken 293157 times.
503814 switch (pa->uop) {
115 51435 case SWS_UOP_PERMUTE:
116 case SWS_UOP_COPY: {
117 51435 uint64_t ia = move_to_mask(&para->move);
118 51435 uint64_t ib = move_to_mask(&parb->move);
119
2/2
✓ Branch 0 taken 30650 times.
✓ Branch 1 taken 20785 times.
51435 if (ia != ib)
120
2/2
✓ Branch 0 taken 12502 times.
✓ Branch 1 taken 18148 times.
30650 return (int64_t) (ia - ib) < 0 ? -1 : 1;
121 20785 break;
122 }
123 19866 case SWS_UOP_UNPACK:
124 case SWS_UOP_PACK: {
125 19866 uint16_t ia = pack_to_mask(&para->pack);
126 19866 uint16_t ib = pack_to_mask(&parb->pack);
127
2/2
✓ Branch 0 taken 11490 times.
✓ Branch 1 taken 8376 times.
19866 if (ia != ib)
128 11490 return (int) ia - ib;
129 8376 break;
130 }
131 8180 case SWS_UOP_LSHIFT:
132 case SWS_UOP_RSHIFT:
133
2/2
✓ Branch 0 taken 3132 times.
✓ Branch 1 taken 5048 times.
8180 if (para->shift.amount != parb->shift.amount)
134 3132 return (int) para->shift.amount - parb->shift.amount;
135 5048 break;
136 25270 case SWS_UOP_CLEAR: {
137 25270 uint16_t ia = clear_to_mask(&para->clear);
138 25270 uint16_t ib = clear_to_mask(&parb->clear);
139
2/2
✓ Branch 0 taken 9922 times.
✓ Branch 1 taken 15348 times.
25270 if (ia != ib)
140 9922 return (int) ia - ib;
141 15348 break;
142 }
143 69994 case SWS_UOP_LINEAR:
144 case SWS_UOP_LINEAR_FMA: {
145 69994 uint64_t ia = linear_to_mask(&para->lin);
146 69994 uint64_t ib = linear_to_mask(&parb->lin);
147
2/2
✓ Branch 0 taken 48072 times.
✓ Branch 1 taken 21922 times.
69994 if (ia != ib)
148
2/2
✓ Branch 0 taken 18704 times.
✓ Branch 1 taken 29368 times.
48072 return (int64_t) (ia - ib) < 0 ? -1 : 1;
149 21922 break;
150 }
151 35912 case SWS_UOP_DITHER: {
152 35912 uint16_t ia = dither_to_mask(pa, &para->dither);
153 35912 uint16_t ib = dither_to_mask(pb, &parb->dither);
154
2/2
✓ Branch 0 taken 27406 times.
✓ Branch 1 taken 8506 times.
35912 if (ia != ib)
155 27406 return (int) ia - ib;
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8506 times.
8506 if (para->dither.size_log2 != parb->dither.size_log2)
157 ✗ return (int) para->dither.size_log2 - parb->dither.size_log2;
158 8506 break;
159 }
160 }
161
162
2/2
✓ Branch 0 taken 67781 times.
✓ Branch 1 taken 305361 times.
373142 if (pa->block_size != pb->block_size)
163 67781 return (int) pa->block_size - pb->block_size;
164
2/2
✓ Branch 0 taken 64424 times.
✓ Branch 1 taken 240937 times.
305361 if (pa->type != pb->type)
165 64424 return (int) pa->type - pb->type;
166
2/2
✓ Branch 0 taken 87827 times.
✓ Branch 1 taken 153110 times.
240937 if (pa->mask != pb->mask)
167 87827 return (int) pa->mask - pb->mask;
168
169 153110 return 0;
170 }
171
172 /*********************************************************************/
173 /* Insert the SwsAArch64OpImplParams structure into the AVTreeNode. */
174 153544 static int aarch64_collect_op(const SwsAArch64OpImplParams *params, struct AVTreeNode **root)
175 {
176 153544 int ret = 0;
177
178 153544 struct AVTreeNode *node = av_tree_node_alloc();
179 153544 SwsAArch64OpImplParams *copy = av_memdup(params, sizeof(*params));
180
2/4
✓ Branch 0 taken 153544 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 153544 times.
153544 if (!node || !copy) {
181 ✗ ret = AVERROR(ENOMEM);
182 ✗ goto error;
183 }
184 153544 av_tree_insert(root, copy, aarch64_op_impl_cmp, &node);
185
2/2
✓ Branch 0 taken 153110 times.
✓ Branch 1 taken 434 times.
153544 if (!node)
186 434 copy = NULL;
187
188 153110 error:
189 153544 av_free(node);
190 153544 av_free(copy);
191 153544 return ret;
192 }
193
194 19523 static int collect_ops_compile(SwsContext *ctx, const SwsOpList *ops,
195 SwsCompiledOp *out)
196 {
197 19523 struct AVTreeNode **root = (struct AVTreeNode **) ctx->opaque;
198 int ret;
199
200 19523 SwsUOpList *uops = ff_sws_uop_list_alloc();
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19523 times.
19523 if (!uops)
202 ✗ return AVERROR(ENOMEM);
203
204 19523 const SwsUOpFlags flags = (ctx->flags & SWS_BITEXACT) ? 0 : SWS_UOP_FLAG_FMA;
205 19523 ret = ff_sws_ops_translate(ctx, ops, flags, uops);
206
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 19391 times.
19523 if (ret == AVERROR(ENOTSUP)) {
207 132 ret = 0;
208 132 goto end;
209 }
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19391 times.
19391 if (ret < 0)
211 ✗ goto end;
212
213 /* Use at most two full vregs during the widest precision section */
214
2/2
✓ Branch 0 taken 15482 times.
✓ Branch 1 taken 3909 times.
19391 int block_size = (uops->pixel_size_max == 4) ? 8 : 16;
215
216
2/2
✓ Branch 0 taken 143193 times.
✓ Branch 1 taken 19391 times.
162584 for (int i = 0; i < uops->num_ops; i++) {
217 143193 SwsAArch64OpImplParams params = { 0 };
218 143193 convert_to_aarch64_impl(&uops->ops[i], block_size, &params);
219 143193 ret = aarch64_collect_op(&params, root);
220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143193 times.
143193 if (ret < 0)
221 ✗ goto end;
222
3/4
✓ Branch 0 taken 10351 times.
✓ Branch 1 taken 132842 times.
✓ Branch 2 taken 10351 times.
✗ Branch 3 not taken.
143193 if (params.uop == SWS_UOP_LINEAR_FMA && params.type == SWS_PIXEL_F32) {
223 /**
224 * Generate both sets of linear op functions that do use
225 * and do not use fmla (selected by SWS_BITEXACT).
226 */
227 10351 params.uop = SWS_UOP_LINEAR;
228 10351 ret = aarch64_collect_op(&params, root);
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10351 times.
10351 if (ret < 0)
230 ✗ goto end;
231 }
232 }
233
234 19391 *out = (SwsCompiledOp) { 0 };
235 19391 ret = 0;
236
237 19523 end:
238 19523 ff_sws_uop_list_free(&uops);
239 19523 return ret;
240 }
241
242 static const SwsOpBackend backend_collect = {
243 .name = "collect_ops",
244 .compile = collect_ops_compile,
245 };
246
247 /*********************************************************************/
248 70240 static int register_op(SwsContext *ctx, void *opaque, SwsOpList *ops)
249 {
250 /* Skip ops lists which include filtering, since this is still not
251 * supported. */
252
2/2
✓ Branch 0 taken 277904 times.
✓ Branch 1 taken 17560 times.
295464 for (int i = 0; i < ops->num_ops; i++) {
253 277904 const SwsOp *op = &ops->ops[i];
254
3/3
✓ Branch 0 taken 87800 times.
✓ Branch 1 taken 40008 times.
✓ Branch 2 taken 150096 times.
277904 switch (op->op) {
255 87800 case SWS_OP_READ:
256 case SWS_OP_WRITE:
257
2/2
✓ Branch 0 taken 12672 times.
✓ Branch 1 taken 75128 times.
87800 if (op->rw.filter.op)
258 12672 return 0;
259 75128 break;
260 40008 case SWS_OP_FILTER_H:
261 case SWS_OP_FILTER_V:
262 40008 return 0;
263 }
264 }
265
266 /* ff_sws_compile_pass() takes over ownership of `ops` */
267 17560 SwsOpList *copy = ff_sws_op_list_duplicate(ops);
268
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17560 times.
17560 if (!copy)
269 ✗ return AVERROR(ENOMEM);
270
271 17560 const int flags = SWS_OP_FLAG_DRY_RUN | SWS_OP_FLAG_SPLIT_MEMCPY;
272 17560 return ff_sws_compile_pass(opaque, &backend_collect, &copy, flags, NULL, NULL);
273 }
274
275 /*********************************************************************/
276 static const char op_type_names[SWS_UOP_TYPE_NB][16] = {
277 [SWS_UOP_READ_BIT ] = "read_bit",
278 [SWS_UOP_READ_NIBBLE ] = "read_nibble",
279 [SWS_UOP_READ_PACKED ] = "read_packed",
280 [SWS_UOP_READ_PLANAR ] = "read_planar",
281 [SWS_UOP_WRITE_BIT ] = "write_bit",
282 [SWS_UOP_WRITE_NIBBLE ] = "write_nibble",
283 [SWS_UOP_WRITE_PACKED ] = "write_packed",
284 [SWS_UOP_WRITE_PLANAR ] = "write_planar",
285 [SWS_UOP_SWAP_BYTES ] = "swap_bytes",
286 [SWS_UOP_PERMUTE ] = "permute",
287 [SWS_UOP_COPY ] = "copy",
288 [SWS_UOP_UNPACK ] = "unpack",
289 [SWS_UOP_PACK ] = "pack",
290 [SWS_UOP_LSHIFT ] = "lshift",
291 [SWS_UOP_RSHIFT ] = "rshift",
292 [SWS_UOP_CLEAR ] = "clear",
293 [SWS_UOP_TO_U8 ] = "to_u8",
294 [SWS_UOP_TO_U16 ] = "to_u16",
295 [SWS_UOP_TO_U32 ] = "to_u32",
296 [SWS_UOP_TO_F32 ] = "to_f32",
297 [SWS_UOP_EXPAND_PAIR ] = "expand_pair",
298 [SWS_UOP_EXPAND_QUAD ] = "expand_quad",
299 [SWS_UOP_MIN ] = "min",
300 [SWS_UOP_MAX ] = "max",
301 [SWS_UOP_SCALE ] = "scale",
302 [SWS_UOP_LINEAR ] = "linear",
303 [SWS_UOP_LINEAR_FMA ] = "linear_fma",
304 [SWS_UOP_DITHER ] = "dither",
305 };
306
307 static const char pixel_type_names[SWS_PIXEL_TYPE_NB][4] = {
308 [SWS_PIXEL_U8 ] = "u8",
309 [SWS_PIXEL_U16] = "u16",
310 [SWS_PIXEL_U32] = "u32",
311 [SWS_PIXEL_F32] = "f32",
312 };
313
314 static const char uop_types[SWS_UOP_TYPE_NB][32] = {
315 [SWS_UOP_READ_BIT ] = "SWS_UOP_READ_BIT",
316 [SWS_UOP_READ_NIBBLE ] = "SWS_UOP_READ_NIBBLE",
317 [SWS_UOP_READ_PACKED ] = "SWS_UOP_READ_PACKED",
318 [SWS_UOP_READ_PLANAR ] = "SWS_UOP_READ_PLANAR",
319 [SWS_UOP_WRITE_BIT ] = "SWS_UOP_WRITE_BIT",
320 [SWS_UOP_WRITE_NIBBLE ] = "SWS_UOP_WRITE_NIBBLE",
321 [SWS_UOP_WRITE_PACKED ] = "SWS_UOP_WRITE_PACKED",
322 [SWS_UOP_WRITE_PLANAR ] = "SWS_UOP_WRITE_PLANAR",
323 [SWS_UOP_SWAP_BYTES ] = "SWS_UOP_SWAP_BYTES",
324 [SWS_UOP_PERMUTE ] = "SWS_UOP_PERMUTE",
325 [SWS_UOP_COPY ] = "SWS_UOP_COPY",
326 [SWS_UOP_UNPACK ] = "SWS_UOP_UNPACK",
327 [SWS_UOP_PACK ] = "SWS_UOP_PACK",
328 [SWS_UOP_LSHIFT ] = "SWS_UOP_LSHIFT",
329 [SWS_UOP_RSHIFT ] = "SWS_UOP_RSHIFT",
330 [SWS_UOP_CLEAR ] = "SWS_UOP_CLEAR",
331 [SWS_UOP_TO_U8 ] = "SWS_UOP_TO_U8",
332 [SWS_UOP_TO_U16 ] = "SWS_UOP_TO_U16",
333 [SWS_UOP_TO_U32 ] = "SWS_UOP_TO_U32",
334 [SWS_UOP_TO_F32 ] = "SWS_UOP_TO_F32",
335 [SWS_UOP_EXPAND_PAIR ] = "SWS_UOP_EXPAND_PAIR",
336 [SWS_UOP_EXPAND_QUAD ] = "SWS_UOP_EXPAND_QUAD",
337 [SWS_UOP_MIN ] = "SWS_UOP_MIN",
338 [SWS_UOP_MAX ] = "SWS_UOP_MAX",
339 [SWS_UOP_SCALE ] = "SWS_UOP_SCALE",
340 [SWS_UOP_LINEAR ] = "SWS_UOP_LINEAR",
341 [SWS_UOP_LINEAR_FMA ] = "SWS_UOP_LINEAR_FMA",
342 [SWS_UOP_DITHER ] = "SWS_UOP_DITHER",
343 };
344
345 static const char pixel_types[SWS_PIXEL_TYPE_NB][32] = {
346 [SWS_PIXEL_U8 ] = "SWS_PIXEL_U8",
347 [SWS_PIXEL_U16] = "SWS_PIXEL_U16",
348 [SWS_PIXEL_U32] = "SWS_PIXEL_U32",
349 [SWS_PIXEL_F32] = "SWS_PIXEL_F32",
350 };
351
352 434 static void serialize_op(AVBPrint *bp, const SwsAArch64OpImplParams *params)
353 {
354 #define FUNC_NAME_WIDTH 45
355 #define UOP_NAME_WIDTH 21
356 #define TYPE_NAME_WIDTH 14
357
358 434 const SwsUOpParams *par = &params->par;
359
360 char func_name[FUNC_NAME_WIDTH + 2];
361 434 snprintf(func_name, sizeof(func_name), "ff_sws_%s", op_type_names[params->uop]);
362
7/7
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 50 times.
✓ Branch 4 taken 43 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 171 times.
434 switch (params->uop) {
363 86 case SWS_UOP_PERMUTE:
364 case SWS_UOP_COPY:
365 86 av_strlcatf(func_name, sizeof(func_name), "_%012" PRIx64, move_to_mask(&par->move));
366 86 break;
367 30 case SWS_UOP_UNPACK:
368 case SWS_UOP_PACK:
369 30 av_strlcatf(func_name, sizeof(func_name), "_%04x", pack_to_mask(&par->pack));
370 30 break;
371 32 case SWS_UOP_LSHIFT:
372 case SWS_UOP_RSHIFT:
373 32 av_strlcatf(func_name, sizeof(func_name), "_%u", par->shift.amount);
374 32 break;
375 50 case SWS_UOP_CLEAR:
376 50 av_strlcatf(func_name, sizeof(func_name), "_%04x", clear_to_mask(&par->clear));
377 50 break;
378 43 case SWS_UOP_LINEAR:
379 case SWS_UOP_LINEAR_FMA:
380 43 av_strlcatf(func_name, sizeof(func_name), "_%010" PRIx64, linear_to_mask(&par->lin));
381 43 break;
382 22 case SWS_UOP_DITHER:
383 22 av_strlcatf(func_name, sizeof(func_name), "_%04x_%u", dither_to_mask(params, &par->dither), par->dither.size_log2);
384 22 break;
385 }
386 434 av_strlcatf(func_name, sizeof(func_name), "_%u_%s_%04x_neon,",
387 434 params->block_size, pixel_type_names[params->type], nibble_mask(params->mask));
388
389 char uop_name[UOP_NAME_WIDTH + 2];
390 434 snprintf(uop_name, sizeof(uop_name), "%s,", uop_types[params->uop]);
391
392 char type_name[TYPE_NAME_WIDTH + 2];
393 434 snprintf(type_name, sizeof(type_name), "%s,", pixel_types[params->type]);
394
395 434 av_bprintf(bp, "ENTRY(%-*s { .uop = %-*s .block_size = %2u, .type = %-*s .mask = 0x%x",
396 FUNC_NAME_WIDTH, func_name, UOP_NAME_WIDTH, uop_name,
397 434 params->block_size, TYPE_NAME_WIDTH, type_name, params->mask);
398
7/7
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 50 times.
✓ Branch 4 taken 43 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 171 times.
434 switch (params->uop) {
399 86 case SWS_UOP_PERMUTE:
400 case SWS_UOP_COPY:
401 86 av_bprintf(bp, ", .par.move = { .num_moves = %d, .dst = {%d, %d, %d, %d, %d, %d}, .src = {%d, %d, %d, %d, %d, %d} }",
402 86 par->move.num_moves,
403 86 par->move.dst[0], par->move.dst[1], par->move.dst[2],
404 86 par->move.dst[3], par->move.dst[4], par->move.dst[5],
405 86 par->move.src[0], par->move.src[1], par->move.src[2],
406 86 par->move.src[3], par->move.src[4], par->move.src[5]);
407 86 break;
408 30 case SWS_UOP_UNPACK:
409 case SWS_UOP_PACK:
410 30 av_bprintf(bp, ", .par.pack = { .pattern = {%d, %d, %d, %d} }",
411 30 par->pack.pattern[0], par->pack.pattern[1],
412 30 par->pack.pattern[2], par->pack.pattern[3]);
413 30 break;
414 32 case SWS_UOP_LSHIFT:
415 case SWS_UOP_RSHIFT:
416 32 av_bprintf(bp, ", .par.shift = { .amount = %u }", par->shift.amount);
417 32 break;
418 50 case SWS_UOP_CLEAR:
419 50 av_bprintf(bp, ", .par.clear = { .one = 0x%0x, .zero = 0x%0x }", par->clear.one, par->clear.zero);
420 50 break;
421 43 case SWS_UOP_LINEAR:
422 case SWS_UOP_LINEAR_FMA:
423 43 av_bprintf(bp, ", .par.lin = { .one = 0x%x, .zero = 0x%x }", par->lin.one, par->lin.zero);
424 43 break;
425 22 case SWS_UOP_DITHER:
426 22 av_bprintf(bp, ", .par.dither = { .y_offset = {%u, %u, %u, %u}, .size_log2 = %u }",
427 22 par->dither.y_offset[0], par->dither.y_offset[1],
428 22 par->dither.y_offset[2], par->dither.y_offset[3],
429 22 par->dither.size_log2);
430 22 break;
431 }
432 434 av_bprintf(bp, " })");
433 434 }
434
435 /* Serialize SwsAArch64OpImplParams for one function. */
436 434 static int print_op(void *opaque, void *elem)
437 {
438 434 SwsAArch64OpImplParams *params = (SwsAArch64OpImplParams *) elem;
439 434 FILE *fp = (FILE *) opaque;
440
441 AVBPrint bp;
442 434 av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
443 434 serialize_op(&bp, params);
444 434 fprintf(fp, "%s\n", bp.str);
445 434 av_bprint_finalize(&bp, NULL);
446
447 434 av_free(params);
448
449 434 return 0;
450 }
451
452 /*********************************************************************/
453 1 int main(int argc, char *argv[])
454 {
455 1 struct AVTreeNode *root = NULL;
456 1 int ret = 1;
457
458 #ifdef _WIN32
459 _setmode(_fileno(stdout), _O_BINARY);
460 #endif
461
462 1 SwsContext *ctx = sws_alloc_context();
463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ctx)
464 ✗ goto fail;
465
466 1 SwsGraph *graph = ff_sws_graph_alloc();
467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!graph)
468 ✗ goto fail;
469
470 1 graph->ctx = ctx;
471 1 ctx->opaque = &root;
472
473 1 ret = ff_sws_enum_op_lists(ctx, graph, NULL, AV_PIX_FMT_NONE, AV_PIX_FMT_NONE,
474 register_op);
475
476 /**
477 * Generate a C file with all the unique function parameter entries
478 * collected by aarch64_enum_ops().
479 */
480 1 printf("/*\n");
481 1 printf(" * This file is automatically generated. Do not edit manually.\n");
482 1 printf(" * To regenerate, run: make fate-sws-ops-entries-aarch64 GEN=1\n");
483 1 printf(" */\n");
484 1 printf("\n");
485 1 av_tree_enumerate(root, stdout, NULL, print_op);
486
487 1 ff_sws_graph_free(&graph);
488
489 1 fail:
490 1 av_tree_destroy(root);
491 1 sws_free_context(&ctx);
492 1 return ret;
493 }
494