FFmpeg coverage


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