FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/tests/sws_ops.c
Date: 2026-10-06 20:08:58
Exec Total Coverage
Lines: 57 91 62.6%
Functions: 4 4 100.0%
Branches: 18 46 39.1%

Line Branch Exec Source
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 #include "libavutil/mem.h"
22 #include "libavutil/pixdesc.h"
23 #include "libswscale/ops.h"
24 #include "libswscale/ops_dispatch.h"
25 #include "libswscale/ops_internal.h"
26 #include "libswscale/op_list_gen_template.c"
27 #include "libswscale/format.h"
28
29 #ifdef _WIN32
30 #include <io.h>
31 #include <fcntl.h>
32 #endif
33
34 static int pass_idx;
35
36 199806 static int print_ops(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out)
37 {
38 199806 SwsUOpList *uops = ff_sws_uop_list_alloc();
39
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199806 times.
199806 if (!uops)
40 ✗ return AVERROR(ENOMEM);
41
42 199806 const SwsUOpFlags flags = SWS_UOP_FLAG_EXPAND_BIT
43 | SWS_UOP_FLAG_READ_PALETTE
44 | SWS_UOP_FLAG_ADD;
45 199806 int ret = ff_sws_ops_translate(ctx, ops, flags, uops);
46
2/2
✓ Branch 0 taken 59496 times.
✓ Branch 1 taken 140310 times.
199806 if (ret == AVERROR(ENOTSUP))
47 59496 goto fail;
48
49
2/2
✓ Branch 0 taken 68078 times.
✓ Branch 1 taken 72232 times.
140310 if (pass_idx > 0)
50 68078 av_log(NULL, AV_LOG_INFO, " Sub-pass #%d:\n", pass_idx);
51
52 140310 ff_sws_op_list_print(NULL, AV_LOG_INFO, AV_LOG_INFO, ops);
53
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140310 times.
140310 if (ret < 0) {
54 ✗ av_log(NULL, AV_LOG_ERROR, "Error translating ops: %s\n", av_err2str(ret));
55 ✗ goto fail;
56 }
57
58 140310 av_log(NULL, AV_LOG_INFO, " translated micro-ops:\n");
59
2/2
✓ Branch 0 taken 681871 times.
✓ Branch 1 taken 140310 times.
822181 for (int i = 0; i < uops->num_ops; i++) {
60 char name[SWS_UOP_NAME_MAX];
61 681871 ff_sws_uop_name(&uops->ops[i], name);
62 681871 av_log(NULL, AV_LOG_INFO, " %s\n", name);
63 }
64
65 140310 *out = (SwsCompiledOp) {0}; /* dummy value, will be immediately freed */
66 140310 pass_idx++;
67 140310 ret = 0;
68
69 199806 fail:
70 199806 ff_sws_uop_list_free(&uops);
71 199806 return ret;
72 }
73
74 /* Dummy backend that just prints all seen op lists */
75 static const SwsOpBackend backend_print = {
76 .name = "print_ops",
77 .compile = print_ops,
78 };
79
80 72360 static int print_passes(SwsContext *ctx, void *graph, SwsOpList *ops)
81 {
82 72360 av_log(NULL, AV_LOG_INFO, "%s %dx%d -> %s %dx%d:\n",
83 av_get_pix_fmt_name(ops->src.format),
84 ops->src.width, ops->src.height,
85 av_get_pix_fmt_name(ops->dst.format),
86 ops->dst.width, ops->dst.height);
87
88
2/2
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 72232 times.
72360 if (ff_sws_op_list_is_noop(ops)) {
89 128 av_log(NULL, AV_LOG_INFO, " (no-op)\n");
90 128 return 0;
91 }
92
93 /* ff_sws_compile_pass() takes over ownership of `ops` */
94 72232 SwsOpList *copy = ff_sws_op_list_duplicate(ops);
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72232 times.
72232 if (!copy)
96 ✗ return AVERROR(ENOMEM);
97
98 72232 pass_idx = 0;
99 72232 const int flags = SWS_OP_FLAG_DRY_RUN | SWS_OP_FLAG_SPLIT_MEMCPY;
100 72232 return ff_sws_compile_pass(graph, &backend_print, &copy, flags, NULL, NULL);
101 }
102 4966213 static void log_stdout(void *avcl, int level, const char *fmt, va_list vl)
103 {
104
2/2
✓ Branch 0 taken 2142107 times.
✓ Branch 1 taken 2824106 times.
4966213 if (level != AV_LOG_INFO) {
105 2142107 av_log_default_callback(avcl, level, fmt, vl);
106
1/2
✓ Branch 1 taken 2824106 times.
✗ Branch 2 not taken.
2824106 } else if (av_log_get_level() >= AV_LOG_INFO) {
107 2824106 vfprintf(stdout, fmt, vl);
108 }
109 4966213 }
110
111 1 int main(int argc, char **argv)
112 {
113 1 enum AVPixelFormat src_fmt = AV_PIX_FMT_NONE;
114 1 enum AVPixelFormat dst_fmt = AV_PIX_FMT_NONE;
115 1 SwsContext *ctx = NULL;
116 1 SwsGraph *graph = NULL;
117 1 int ret = 1;
118
119 #ifdef _WIN32
120 _setmode(_fileno(stdout), _O_BINARY);
121 #endif
122
123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 for (int i = 1; i < argc; i++) {
124 ✗ if (!strcmp(argv[i], "-help") || !strcmp(argv[i], "--help")) {
125 ✗ fprintf(stderr,
126 "sws_ops [options...]\n"
127 " -help\n"
128 " This text\n"
129 " -dst <pixfmt>\n"
130 " Only test the specified destination pixel format\n"
131 " -src <pixfmt>\n"
132 " Only test the specified source pixel format\n"
133 " -v <level>\n"
134 " Enable log verbosity at given level\n"
135 );
136 ✗ return 0;
137 }
138 ✗ if (!strcmp(argv[i], "-src")) {
139 ✗ if (i + 1 >= argc)
140 ✗ goto bad_option;
141 ✗ src_fmt = av_get_pix_fmt(argv[i + 1]);
142 ✗ if (src_fmt == AV_PIX_FMT_NONE) {
143 ✗ fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
144 ✗ return AVERROR(EINVAL);
145 }
146 ✗ i++;
147 ✗ } else if (!strcmp(argv[i], "-dst")) {
148 ✗ if (i + 1 >= argc)
149 ✗ goto bad_option;
150 ✗ dst_fmt = av_get_pix_fmt(argv[i + 1]);
151 ✗ if (dst_fmt == AV_PIX_FMT_NONE) {
152 ✗ fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
153 ✗ return AVERROR(EINVAL);
154 }
155 ✗ i++;
156 ✗ } else if (!strcmp(argv[i], "-v")) {
157 ✗ if (i + 1 >= argc)
158 ✗ goto bad_option;
159 ✗ av_log_set_level(atoi(argv[i + 1]));
160 ✗ i++;
161 } else {
162 ✗ bad_option:
163 ✗ fprintf(stderr, "bad option or argument missing (%s) see -help\n", argv[i]);
164 ✗ return AVERROR(EINVAL);
165 }
166 }
167
168 /* Allocate dummy graph and context for ff_sws_compile_pass() */
169 1 graph = ff_sws_graph_alloc();
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!graph)
171 ✗ goto fail;
172 1 graph->ctx = ctx = sws_alloc_context();
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ctx)
174 ✗ goto fail;
175 1 ctx->scaler = SWS_SCALE_BILINEAR; /* reduce filter generation overhead */
176
177 1 av_log_set_callback(log_stdout);
178
179 1 ret = ff_sws_enum_op_lists(ctx, graph, NULL, src_fmt, dst_fmt, print_passes);
180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
181 ✗ goto fail;
182
183 1 ret = 0;
184 1 fail:
185 1 sws_free_context(&ctx);
186 1 ff_sws_graph_free(&graph);
187 1 return ret;
188 }
189