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