FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libswscale/graph.h
Date: 2026-07-19 06:51:48
Exec Total Coverage
Lines: 3 3 100.0%
Functions: 1 1 100.0%
Branches: 4 4 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 "libavutil/buffer.h"
28
29 #include "swscale.h"
30 #include "format.h"
31
32 1582359 static av_always_inline av_const int ff_fmt_vshift(enum AVPixelFormat fmt, int plane)
33 {
34 1582359 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
35
4/4
✓ Branch 0 taken 1070538 times.
✓ Branch 1 taken 511821 times.
✓ Branch 2 taken 348330 times.
✓ Branch 3 taken 722208 times.
1582359 return (plane == 1 || plane == 2) ? desc->log2_chroma_h : 0;
36 }
37
38 typedef struct SwsPass SwsPass;
39 typedef struct SwsGraph SwsGraph;
40
41 /**
42 * Output `h` lines of filtered data. `out` and `in` point to the
43 * start of the image buffer for this pass.
44 */
45 typedef void (*SwsPassFunc)(const SwsFrame *out, const SwsFrame *in,
46 int y, int h, const SwsPass *pass);
47
48 /**
49 * Function to run from the main thread before processing any lines.
50 */
51 typedef int (*SwsPassSetup)(const SwsFrame *out, const SwsFrame *in,
52 const SwsPass *pass);
53
54 /**
55 * Represents an output buffer for a filter pass. During filter graph
56 * construction, these merely hold the metadata. Allocation of the underlying
57 * storage is deferred until after all filter passes are settled.
58 */
59 typedef struct SwsPassBuffer {
60 SwsFrame frame;
61
62 int width, height; /* dimensions of this buffer */
63 AVFrame *avframe; /* backing storage for `frame` */
64
65 /* Optional allocation hints for optimal performance */
66 int width_align; /* Align width to multiple of this */
67 int width_pad; /* Extra padding pixels */
68 } SwsPassBuffer;
69
70 /**
71 * Represents a single filter pass in the scaling graph. Each filter will
72 * read from some previous pass's output, and write to a buffer associated
73 * with the pass (or into the final output image).
74 */
75 struct SwsPass {
76 const SwsGraph *graph;
77
78 /**
79 * Filter main execution function. Called from multiple threads, with
80 * the granularity dictated by `slice_h`. Individual slices sent to `run`
81 * are always equal to (or smaller than, for the last slice) `slice_h`.
82 */
83 SwsPassFunc run;
84 SwsBackend backend; /* backend this pass is using, or 0 */
85 enum AVPixelFormat format; /* new pixel format */
86 int lines; /* pass dispatch size */
87 int slice_h; /* filter granularity */
88 int num_slices;
89
90 /**
91 * Filter input. This pass's output will be resolved to form this pass's.
92 * input. If NULL, the original input image is used.
93 */
94 SwsPass *input;
95
96 /**
97 * Filter output buffer. This struct is always allocated.
98 */
99 SwsPassBuffer *output; /* refstruct */
100
101 /**
102 * Called once from the main thread before running the filter. Optional.
103 * Returns 0 or a negative error code.
104 */
105 SwsPassSetup setup;
106
107 /**
108 * Optional private state and associated free() function.
109 */
110 void (*free)(void *priv);
111 void *priv;
112 };
113
114 /**
115 * Align `width` to the optimal size for `pass`.
116 */
117 int ff_sws_pass_aligned_width(const SwsPass *pass, int width);
118
119 /**
120 * Filter graph, which represents a 'baked' pixel format conversion.
121 */
122 typedef struct SwsGraph {
123 SwsContext *ctx;
124 AVSliceThread *slicethread;
125 int num_threads; /* resolved at init() time */
126 bool incomplete; /* set during init() if formats had to be inferred */
127 bool noop; /* set during init() if the graph is a no-op */
128 SwsBackend backend; /* backends this graph is using, set during init() */
129
130 AVBufferRef *hw_frames_ref;
131
132 /** Sorted sequence of filter passes to apply */
133 SwsPass **passes;
134 int num_passes;
135
136 /**
137 * Cached copy of the public options that were used to construct this
138 * SwsGraph. Used only to detect when the graph needs to be reinitialized.
139 */
140 SwsContext opts_copy;
141
142 /**
143 * Currently active format and processing parameters.
144 */
145 SwsFormat src, dst;
146
147 /**
148 * Temporary execution state inside ff_sws_graph_run(); used to pass
149 * data to worker threads.
150 */
151 struct {
152 const SwsPass *pass; /* current filter pass */
153 const SwsFrame *input; /* current filter pass input/output */
154 const SwsFrame *output;
155 } exec;
156 } SwsGraph;
157
158 /**
159 * Allocate an empty SwsGraph. Returns NULL on failure.
160 */
161 SwsGraph *ff_sws_graph_alloc(void);
162
163 /**
164 * Initialize the filter graph for a given pair of formats. Returns 0 or a
165 * negative error.
166 */
167 int ff_sws_graph_init(SwsGraph *graph, SwsContext *ctx, const SwsFormat *dst,
168 const SwsFormat *src);
169
170
171 /**
172 * Allocate and add a new pass to the filter graph. Takes over ownership of
173 * `priv`, even on failure.
174 *
175 * @param graph Filter graph to add the pass to.
176 * @param fmt Pixel format of the output image.
177 * @param w Width of the output image.
178 * @param h Height of the output image.
179 * @param input Previous pass to read from, or NULL for the input image.
180 * @param lines Override the number of lines processed for this pass. (Optional)
181 * @param align Minimum slice alignment for this pass, or 0 for no threading.
182 * @param run Filter function to run.
183 * @param setup Optional setup function to run from the main thread.
184 * @param priv Private state for the filter run function.
185 * @param free Function to free the private state.
186 * @param out_pass The newly added pass will be written here on success.
187 * @return 0 or a negative error code
188 */
189 int ff_sws_graph_add_pass(SwsGraph *graph, enum AVPixelFormat fmt,
190 int width, int height, SwsPass *input,
191 int lines, int align,
192 SwsPassFunc run, SwsPassSetup setup,
193 void *priv, void (*free)(void *priv),
194 SwsPass **out_pass);
195
196 /**
197 * Link the output buffers to a different pass, rather than allocating
198 * new image buffers. This allows reusing the same buffer for multiple passes,
199 * e.g. in the case of in-place passes or partial passes that modify different
200 * planes.
201 *
202 * Any existing buffer on `dst` will be ignored/unref'd.
203 **/
204 void ff_sws_pass_link_output(SwsPass *dst, const SwsPass *src);
205
206 /**
207 * Remove all passes added since the given index.
208 */
209 void ff_sws_graph_rollback(SwsGraph *graph, int since_idx);
210
211 /**
212 * Uninitialize any state associate with this filter graph and free it.
213 */
214 void ff_sws_graph_free(SwsGraph **graph);
215
216 /**
217 * Update dynamic per-frame HDR metadata without requiring a full reinit.
218 */
219 void ff_sws_graph_update_metadata(SwsGraph *graph, const SwsColor *color);
220
221 /**
222 * Wrapper around ff_sws_graph_init() that reuses the existing graph if the
223 * format is compatible. This will also update dynamic per-frame metadata.
224 *
225 * Must also be called after changing any of the fields in `ctx`, or else they
226 * will have no effect.
227 */
228 int ff_sws_graph_reinit(SwsGraph *graph, SwsContext *ctx, const SwsFormat *dst,
229 const SwsFormat *src);
230
231 /**
232 * Dispatch the filter graph on a single field of the given frames. Internally
233 * threaded.
234 */
235 int ff_sws_graph_run(SwsGraph *graph, const AVFrame *dst, const AVFrame *src);
236
237 #endif /* SWSCALE_GRAPH_H */
238