FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/graph.h
Date: 2025-06-01 09:29:47
Exec Total Coverage
Lines: 8 8 100.0%
Functions: 2 2 100.0%
Branches: 8 8 100.0%

Line Branch Exec Source
1 /*
2 * Copyright (C) 2024 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 #ifndef SWSCALE_GRAPH_H
22 #define SWSCALE_GRAPH_H
23
24 #include <stdbool.h>
25
26 #include "libavutil/slicethread.h"
27 #include "swscale.h"
28 #include "format.h"
29
30 /**
31 * Represents a view into a single field of frame data.
32 */
33 typedef struct SwsImg {
34 enum AVPixelFormat fmt;
35 uint8_t *data[4]; /* points to y=0 */
36 int linesize[4];
37 } SwsImg;
38
39 1382576 static av_always_inline av_const int ff_fmt_vshift(enum AVPixelFormat fmt, int plane)
40 {
41 1382576 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
42
4/4
✓ Branch 0 taken 926012 times.
✓ Branch 1 taken 456564 times.
✓ Branch 2 taken 296164 times.
✓ Branch 3 taken 629848 times.
1382576 return (plane == 1 || plane == 2) ? desc->log2_chroma_h : 0;
43 }
44
45 621254 static av_const inline SwsImg ff_sws_img_shift(const SwsImg *base, const int y)
46 {
47 621254 SwsImg img = *base;
48
4/4
✓ Branch 0 taken 1995236 times.
✓ Branch 1 taken 8594 times.
✓ Branch 2 taken 1382576 times.
✓ Branch 3 taken 612660 times.
2003830 for (int i = 0; i < 4 && img.data[i]; i++)
49 1382576 img.data[i] += (y >> ff_fmt_vshift(img.fmt, i)) * img.linesize[i];
50 621254 return img;
51 }
52
53 typedef struct SwsPass SwsPass;
54 typedef struct SwsGraph SwsGraph;
55
56 /**
57 * Output `h` lines of filtered data. `out` and `in` point to the
58 * start of the image buffer for this pass.
59 */
60 typedef void (*sws_filter_run_t)(const SwsImg *out, const SwsImg *in,
61 int y, int h, const SwsPass *pass);
62
63 /**
64 * Represents a single filter pass in the scaling graph. Each filter will
65 * read from some previous pass's output, and write to a buffer associated
66 * with the pass (or into the final output image).
67 */
68 struct SwsPass {
69 const SwsGraph *graph;
70
71 /**
72 * Filter main execution function. Called from multiple threads, with
73 * the granularity dictated by `slice_h`. Individual slices sent to `run`
74 * are always equal to (or smaller than, for the last slice) `slice_h`.
75 */
76 sws_filter_run_t run;
77 enum AVPixelFormat format; /* new pixel format */
78 int width, height; /* new output size */
79 int slice_h; /* filter granularity */
80 int num_slices;
81
82 /**
83 * Filter input. This pass's output will be resolved to form this pass's.
84 * input. If NULL, the original input image is used.
85 */
86 const SwsPass *input;
87
88 /**
89 * Filter output buffer. Allocated on demand and freed automatically.
90 */
91 SwsImg output;
92
93 /**
94 * Called once from the main thread before running the filter. Optional.
95 * `out` and `in` always point to the main image input/output, regardless
96 * of `input` and `output` fields.
97 */
98 void (*setup)(const SwsImg *out, const SwsImg *in, const SwsPass *pass);
99
100 /**
101 * Optional private state and associated free() function.
102 */
103 void (*free)(void *priv);
104 void *priv;
105 };
106
107 /**
108 * Filter graph, which represents a 'baked' pixel format conversion.
109 */
110 typedef struct SwsGraph {
111 SwsContext *ctx;
112 AVSliceThread *slicethread;
113 int num_threads; /* resolved at init() time */
114 bool incomplete; /* set during init() if formats had to be inferred */
115 bool noop; /* set during init() if the graph is a no-op */
116
117 /** Sorted sequence of filter passes to apply */
118 SwsPass **passes;
119 int num_passes;
120
121 /**
122 * Cached copy of the public options that were used to construct this
123 * SwsGraph. Used only to detect when the graph needs to be reinitialized.
124 */
125 SwsContext opts_copy;
126
127 /**
128 * Currently active format and processing parameters.
129 */
130 SwsFormat src, dst;
131 int field;
132
133 /** Temporary execution state inside ff_sws_graph_run */
134 struct {
135 const SwsPass *pass; /* current filter pass */
136 SwsImg input;
137 SwsImg output;
138 } exec;
139 } SwsGraph;
140
141 /**
142 * Allocate and initialize the filter graph. Returns 0 or a negative error.
143 */
144 int ff_sws_graph_create(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src,
145 int field, SwsGraph **out_graph);
146
147
148 /**
149 * Allocate and add a new pass to the filter graph.
150 *
151 * @param graph Filter graph to add the pass to.
152 * @param fmt Pixel format of the output image.
153 * @param w Width of the output image.
154 * @param h Height of the output image.
155 * @param input Previous pass to read from, or NULL for the input image.
156 * @param align Minimum slice alignment for this pass, or 0 for no threading.
157 * @param priv Private state for the filter run function.
158 * @param run Filter function to run.
159 * @return The newly created pass, or NULL on error.
160 */
161 SwsPass *ff_sws_graph_add_pass(SwsGraph *graph, enum AVPixelFormat fmt,
162 int width, int height, SwsPass *input,
163 int align, void *priv, sws_filter_run_t run);
164
165 /**
166 * Uninitialize any state associate with this filter graph and free it.
167 */
168 void ff_sws_graph_free(SwsGraph **graph);
169
170 /**
171 * Update dynamic per-frame HDR metadata without requiring a full reinit.
172 */
173 void ff_sws_graph_update_metadata(SwsGraph *graph, const SwsColor *color);
174
175 /**
176 * Wrapper around ff_sws_graph_create() that reuses the existing graph if the
177 * format is compatible. This will also update dynamic per-frame metadata.
178 * Must be called after changing any of the fields in `ctx`, or else they will
179 * have no effect.
180 */
181 int ff_sws_graph_reinit(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src,
182 int field, SwsGraph **graph);
183
184 /**
185 * Dispatch the filter graph on a single field. Internally threaded.
186 */
187 void ff_sws_graph_run(SwsGraph *graph, uint8_t *const out_data[4],
188 const int out_linesize[4],
189 const uint8_t *const in_data[4],
190 const int in_linesize[4]);
191
192 #endif /* SWSCALE_GRAPH_H */
193