FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/op_list_gen_template.c
Date: 2026-09-15 15:24:09
Exec Total Coverage
Lines: 48 54 88.9%
Functions: 5 5 100.0%
Branches: 14 20 70.0%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <stdbool.h>
20
21 #include "libswscale/format.h"
22 #include "libswscale/ops.h"
23 #include "libswscale/swscale.h"
24 #include "libswscale/swscale_internal.h"
25
26 #include "libavutil/error.h"
27 #include "libavutil/macros.h"
28 #include "libavutil/pixdesc.h"
29 #include "libavutil/pixfmt.h"
30
31 #define DUMMY_SIZE 16
32
33 struct EnumFmtPriv {
34 SwsContext *ctx;
35 const SwsLut3D *lut3d;
36 int (*cb)(SwsContext *ctx, void *opaque, SwsOpList *ops);
37 void *opaque;
38
39 /* for slice threading */
40 enum AVPixelFormat src_start, src_end;
41 enum AVPixelFormat dst_start, dst_end;
42 };
43
44 574592 static int enum_ops_fmt(const struct EnumFmtPriv *s,
45 enum AVPixelFormat src_fmt,
46 enum AVPixelFormat dst_fmt)
47 {
48 574592 int ret = 0;
49 574592 SwsOpList *ops = NULL;
50 SwsFormat src, dst;
51 574592 ff_fmt_from_pixfmt(src_fmt, &src);
52 574592 ff_fmt_from_pixfmt(dst_fmt, &dst);
53 574592 bool incomplete = ff_infer_colors(&src.color, &dst.color);
54 574592 src.width = src.height = DUMMY_SIZE;
55
56 static const int dst_sizes[][2] = {
57 { DUMMY_SIZE, DUMMY_SIZE },
58 { DUMMY_SIZE, DUMMY_SIZE * 2 },
59 { DUMMY_SIZE * 2, DUMMY_SIZE },
60 { DUMMY_SIZE * 2, DUMMY_SIZE * 2 },
61 };
62
63
2/2
✓ Branch 0 taken 995936 times.
✓ Branch 1 taken 140448 times.
1136384 for (int i = 0; i < FF_ARRAY_ELEMS(dst_sizes); i++) {
64 995936 dst.width = dst_sizes[i][0];
65 995936 dst.height = dst_sizes[i][1];
66
67 995936 ret = ff_sws_op_list_generate(s->ctx, &src, &dst, s->lut3d, &ops, &incomplete);
68
2/2
✓ Branch 0 taken 434144 times.
✓ Branch 1 taken 561792 times.
995936 if (ret == AVERROR(ENOTSUP))
69 434144 return 0; /* silently skip unsupported formats */
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 561792 times.
561792 else if (ret < 0)
71 return ret;
72
73 561792 ret = ff_sws_op_list_optimize(ops);
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 561792 times.
561792 if (ret < 0)
75 goto fail;
76
77 561792 ret = s->cb(s->ctx, s->opaque, ops);
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 561792 times.
561792 if (ret < 0)
79 goto fail;
80
81 561792 ff_sws_op_list_free(&ops);
82 }
83
84 140448 fail:
85 140448 ff_sws_op_list_free(&ops);
86 140448 return ret;
87 }
88
89 2144 static int enum_fmt_slice(void *priv, int jobnr, int threadnr, int nb_jobs,
90 int nb_threads)
91 {
92 2144 const struct EnumFmtPriv *s = priv;
93 2144 const enum AVPixelFormat src = s->src_start + jobnr;
94 2144 int ret = 0;
95
96
2/2
✓ Branch 0 taken 574592 times.
✓ Branch 1 taken 2144 times.
576736 for (enum AVPixelFormat dst = s->dst_start; dst <= s->dst_end; dst++) {
97 574592 ret = enum_ops_fmt(s, src, dst);
98
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 574592 times.
574592 if (ret < 0)
99 break;
100 }
101
102 2144 return ret;
103 }
104
105 8 static enum AVPixelFormat first_pix_fmt(void)
106 {
107 8 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_next(NULL);
108 8 return av_pix_fmt_desc_get_id(desc);
109 }
110
111 8 static enum AVPixelFormat last_pix_fmt(void)
112 {
113 8 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_next(NULL);
114 2136 while (1) {
115 2144 const AVPixFmtDescriptor *next = av_pix_fmt_desc_next(desc);
116
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2136 times.
2144 if (!next)
117 8 return av_pix_fmt_desc_get_id(desc);
118 2136 desc = next;
119 }
120 }
121
122 /**
123 * Helper function to enumerate over all possible (optimized) operation lists,
124 * under the current set of options in `ctx`, and run the given callback on
125 * each list.
126 *
127 * @param src_fmt If set (not AV_PIX_FMT_NONE), constrain the source format
128 * @param dst_fmt If set (not AV_PIX_FMT_NONE), constrain the destination format
129 * @param cb Callback to run on each op list. If ctx->threads != 1, this may be
130 * called from multiple threads.
131 * @return 0 on success, the return value if cb() < 0, or a negative error code
132 *
133 * @note `ops` belongs to sws_enum_op_lists(), but may be mutated by `cb`.
134 */
135 static inline
136 8 int ff_sws_enum_op_lists(SwsContext *ctx, void *opaque, const SwsLut3D *lut3d,
137 enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt,
138 int (*cb)(SwsContext *ctx, void *opaque, SwsOpList *ops))
139 {
140 8 struct EnumFmtPriv s = {
141 .ctx = ctx,
142 .cb = cb,
143 .opaque = opaque,
144 .lut3d = lut3d,
145 };
146
147 8 s.src_start = s.dst_start = first_pix_fmt();
148 8 s.src_end = s.dst_end = last_pix_fmt();
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (src_fmt != AV_PIX_FMT_NONE)
150 s.src_start = s.src_end = src_fmt;
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (dst_fmt != AV_PIX_FMT_NONE)
152 s.dst_start = s.dst_end = dst_fmt;
153
154 8 const int nb_fmts = s.src_end - s.src_start + 1;
155 8 return ff_sws_thread_exec(&s, enum_fmt_slice, ctx->threads, nb_fmts);
156 }
157