/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 "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 | | static av_always_inline av_const int ff_fmt_vshift(enum AVPixelFormat fmt, int plane) |
40 | 0 | { |
41 | 0 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); |
42 | 0 | return (plane == 1 || plane == 2) ? desc->log2_chroma_h : 0; |
43 | 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 |
44 | | |
45 | | static av_const inline SwsImg ff_sws_img_shift(const SwsImg *base, const int y) |
46 | 0 | { |
47 | 0 | SwsImg img = *base; |
48 | 0 | for (int i = 0; i < 4 && img.data[i]; i++) |
49 | 0 | img.data[i] += (y >> ff_fmt_vshift(img.fmt, i)) * img.linesize[i]; |
50 | 0 | return img; |
51 | 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 |
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 | | */ |
96 | | void (*setup)(const SwsImg *out, const SwsImg *in, const SwsPass *pass); |
97 | | |
98 | | /** |
99 | | * Optional private state and associated free() function. |
100 | | */ |
101 | | void (*free)(void *priv); |
102 | | void *priv; |
103 | | }; |
104 | | |
105 | | /** |
106 | | * Filter graph, which represents a 'baked' pixel format conversion. |
107 | | */ |
108 | | typedef struct SwsGraph { |
109 | | SwsContext *ctx; |
110 | | AVSliceThread *slicethread; |
111 | | int num_threads; /* resolved at init() time */ |
112 | | bool incomplete; /* set during init() if formats had to be inferred */ |
113 | | bool noop; /* set during init() if the graph is a no-op */ |
114 | | |
115 | | /** Sorted sequence of filter passes to apply */ |
116 | | SwsPass **passes; |
117 | | int num_passes; |
118 | | |
119 | | /** |
120 | | * Cached copy of the public options that were used to construct this |
121 | | * SwsGraph. Used only to detect when the graph needs to be reinitialized. |
122 | | */ |
123 | | SwsContext opts_copy; |
124 | | |
125 | | /** |
126 | | * Currently active format and processing parameters. |
127 | | */ |
128 | | SwsFormat src, dst; |
129 | | int field; |
130 | | |
131 | | /** Temporary execution state inside ff_sws_graph_run */ |
132 | | struct { |
133 | | const SwsPass *pass; /* current filter pass */ |
134 | | SwsImg input; |
135 | | SwsImg output; |
136 | | } exec; |
137 | | } SwsGraph; |
138 | | |
139 | | /** |
140 | | * Allocate and initialize the filter graph. Returns 0 or a negative error. |
141 | | */ |
142 | | int ff_sws_graph_create(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src, |
143 | | int field, SwsGraph **out_graph); |
144 | | |
145 | | |
146 | | /** |
147 | | * Allocate and add a new pass to the filter graph. |
148 | | * |
149 | | * @param graph Filter graph to add the pass to. |
150 | | * @param fmt Pixel format of the output image. |
151 | | * @param w Width of the output image. |
152 | | * @param h Height of the output image. |
153 | | * @param input Previous pass to read from, or NULL for the input image. |
154 | | * @param align Minimum slice alignment for this pass, or 0 for no threading. |
155 | | * @param priv Private state for the filter run function. |
156 | | * @param run Filter function to run. |
157 | | * @return The newly created pass, or NULL on error. |
158 | | */ |
159 | | SwsPass *ff_sws_graph_add_pass(SwsGraph *graph, enum AVPixelFormat fmt, |
160 | | int width, int height, SwsPass *input, |
161 | | int align, void *priv, sws_filter_run_t run); |
162 | | |
163 | | /** |
164 | | * Uninitialize any state associate with this filter graph and free it. |
165 | | */ |
166 | | void ff_sws_graph_free(SwsGraph **graph); |
167 | | |
168 | | /** |
169 | | * Update dynamic per-frame HDR metadata without requiring a full reinit. |
170 | | */ |
171 | | void ff_sws_graph_update_metadata(SwsGraph *graph, const SwsColor *color); |
172 | | |
173 | | /** |
174 | | * Wrapper around ff_sws_graph_create() that reuses the existing graph if the |
175 | | * format is compatible. This will also update dynamic per-frame metadata. |
176 | | * Must be called after changing any of the fields in `ctx`, or else they will |
177 | | * have no effect. |
178 | | */ |
179 | | int ff_sws_graph_reinit(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src, |
180 | | int field, SwsGraph **graph); |
181 | | |
182 | | /** |
183 | | * Dispatch the filter graph on a single field. Internally threaded. |
184 | | */ |
185 | | void ff_sws_graph_run(SwsGraph *graph, uint8_t *const out_data[4], |
186 | | const int out_linesize[4], |
187 | | const uint8_t *const in_data[4], |
188 | | const int in_linesize[4]); |
189 | | |
190 | | #endif /* SWSCALE_GRAPH_H */ |