/src/ffmpeg/libavcodec/bsf/packetsync.h
Line | Count | 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 License |
6 | | * 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 |
12 | | * GNU Lesser General Public License for more details. |
13 | | * |
14 | | * You should have received a copy of the GNU Lesser General Public License |
15 | | * along with FFmpeg; if not, write to the Free Software Foundation, Inc., |
16 | | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | | */ |
18 | | |
19 | | #ifndef AVCODEC_BSF_PACKETSYNC_H |
20 | | #define AVCODEC_BSF_PACKETSYNC_H |
21 | | |
22 | | #include <stdint.h> |
23 | | |
24 | | #include "libavutil/log.h" |
25 | | |
26 | | #include "libavcodec/bsf.h" |
27 | | #include "libavcodec/packet.h" |
28 | | |
29 | | enum EOFAction { |
30 | | EOF_ACTION_ENDALL, |
31 | | EOF_ACTION_PASS |
32 | | }; |
33 | | |
34 | | /** |
35 | | * This API is intended as a helper for filters that have several video |
36 | | * input and need to combine them somehow. If the inputs have different or |
37 | | * variable frame rate, getting the input packets to match requires a rather |
38 | | * complex logic and a few user-tunable options. |
39 | | * |
40 | | * In this API, when a set of synchronized input packets is ready to be |
41 | | * processed is called a packet event. packet event can be generated in |
42 | | * response to input packets on any or all inputs and the handling of |
43 | | * situations where some stream extend beyond the beginning or the end of |
44 | | * others can be configured. |
45 | | * |
46 | | * The basic working of this API is the following: set the on_event |
47 | | * callback, then call ff_packetsync_activate() from the filter's activate |
48 | | * callback. |
49 | | */ |
50 | | |
51 | | /** |
52 | | * Stream extrapolation mode |
53 | | * |
54 | | * Describe how the packets of a stream are extrapolated before the first one |
55 | | * and after EOF to keep sync with possibly longer other streams. |
56 | | */ |
57 | | enum FFPacketSyncExtMode { |
58 | | |
59 | | /** |
60 | | * Completely stop all streams with this one. |
61 | | */ |
62 | | EXT_STOP, |
63 | | |
64 | | /** |
65 | | * Ignore this stream and continue processing the other ones. |
66 | | */ |
67 | | EXT_NULL, |
68 | | }; |
69 | | |
70 | | /** |
71 | | * Timestamp synchronization mode |
72 | | * |
73 | | * Describe how the packets of a stream are synchronized based on timestamp |
74 | | * distance. |
75 | | */ |
76 | | enum FFPacketTSSyncMode { |
77 | | |
78 | | /** |
79 | | * Sync to packets from secondary input with the nearest, lower or equal |
80 | | * timestamp to the packet event one. |
81 | | */ |
82 | | TS_DEFAULT, |
83 | | |
84 | | /** |
85 | | * Sync to packets from secondary input with the absolute nearest timestamp |
86 | | * to the packet event one. |
87 | | */ |
88 | | TS_NEAREST, |
89 | | }; |
90 | | |
91 | | /** |
92 | | * Input stream structure |
93 | | */ |
94 | | typedef struct FFPacketSyncIn { |
95 | | |
96 | | /** |
97 | | * Extrapolation mode for timestamps before the first packet |
98 | | */ |
99 | | enum FFPacketSyncExtMode before; |
100 | | |
101 | | /** |
102 | | * Extrapolation mode for timestamps after the last packet |
103 | | */ |
104 | | enum FFPacketSyncExtMode after; |
105 | | |
106 | | /** |
107 | | * Time base for the incoming packets |
108 | | */ |
109 | | AVRational time_base; |
110 | | |
111 | | /** |
112 | | * Current packet, may be NULL before the first one or after EOF |
113 | | */ |
114 | | AVPacket *pkt; |
115 | | |
116 | | /** |
117 | | * Next packet, for internal use |
118 | | */ |
119 | | AVPacket *pkt_next; |
120 | | |
121 | | /** |
122 | | * PTS of the current packet |
123 | | */ |
124 | | int64_t pts; |
125 | | |
126 | | /** |
127 | | * PTS of the next packet, for internal use |
128 | | */ |
129 | | int64_t pts_next; |
130 | | |
131 | | /** |
132 | | * Boolean flagging the next packet, for internal use |
133 | | */ |
134 | | uint8_t have_next; |
135 | | |
136 | | /** |
137 | | * State: before first, in stream or after EOF, for internal use |
138 | | */ |
139 | | uint8_t state; |
140 | | |
141 | | /** |
142 | | * Synchronization level: packets on input at the highest sync level will |
143 | | * generate output packet events. |
144 | | * |
145 | | * For example, if inputs #0 and #1 have sync level 2 and input #2 has |
146 | | * sync level 1, then a packet on either input #0 or #1 will generate a |
147 | | * packet event, but not a packet on input #2 until both inputs #0 and #1 |
148 | | * have reached EOF. |
149 | | * |
150 | | * If sync is 0, no packet event will be generated. |
151 | | */ |
152 | | unsigned sync; |
153 | | |
154 | | enum FFPacketTSSyncMode ts_mode; |
155 | | } FFPacketSyncIn; |
156 | | |
157 | | /** |
158 | | * Packet sync structure. |
159 | | */ |
160 | | typedef struct FFPacketSync { |
161 | | const AVClass *class; |
162 | | |
163 | | /** |
164 | | * Parent filter context. |
165 | | */ |
166 | | AVBitStreamFilterContext *parent; |
167 | | |
168 | | /** |
169 | | * Number of input streams |
170 | | */ |
171 | | unsigned nb_in; |
172 | | |
173 | | /** |
174 | | * Time base for the output events |
175 | | */ |
176 | | AVRational time_base; |
177 | | |
178 | | /** |
179 | | * Timestamp of the current event |
180 | | */ |
181 | | int64_t pts; |
182 | | |
183 | | /** |
184 | | * Callback called when a packet event is ready |
185 | | */ |
186 | | int (*on_event)(struct FFPacketSync *fs); |
187 | | |
188 | | /** |
189 | | * Opaque pointer, not used by the API |
190 | | */ |
191 | | void *opaque; |
192 | | |
193 | | /** |
194 | | * Index of the input that requires a request |
195 | | */ |
196 | | unsigned in_request; |
197 | | |
198 | | /** |
199 | | * Synchronization level: only inputs with the same sync level are sync |
200 | | * sources. |
201 | | */ |
202 | | unsigned sync_level; |
203 | | |
204 | | /** |
205 | | * Flag indicating that a packet event is ready |
206 | | */ |
207 | | uint8_t pkt_ready; |
208 | | |
209 | | /** |
210 | | * Flag indicating that output has reached EOF. |
211 | | */ |
212 | | uint8_t eof; |
213 | | |
214 | | /** |
215 | | * Pointer to array of inputs. |
216 | | */ |
217 | | FFPacketSyncIn *in; |
218 | | |
219 | | int opt_eof_action; |
220 | | int opt_ts_sync_mode; |
221 | | |
222 | | } FFPacketSync; |
223 | | |
224 | | /** |
225 | | * Pre-initialize a packet sync structure. |
226 | | * |
227 | | * It sets the class pointer and inits the options to their default values. |
228 | | * The entire structure is expected to be already set to 0. |
229 | | * This step is optional, but necessary to use the options. |
230 | | */ |
231 | | void ff_packetsync_preinit(FFPacketSync *fs); |
232 | | |
233 | | /** |
234 | | * Initialize a packet sync structure. |
235 | | * |
236 | | * The entire structure is expected to be already set to 0 or preinited. |
237 | | * |
238 | | * @param fs packet sync structure to initialize |
239 | | * @param parent parent AVBitStreamFilterContext object |
240 | | * @param nb_in number of inputs |
241 | | * @return >= 0 for success or a negative error code |
242 | | */ |
243 | | int ff_packetsync_init(FFPacketSync *fs, AVBitStreamFilterContext *parent, unsigned nb_in); |
244 | | |
245 | | /** |
246 | | * Configure a packet sync structure. |
247 | | * |
248 | | * Must be called after all options are set but before all use. |
249 | | * |
250 | | * @return >= 0 for success or a negative error code |
251 | | */ |
252 | | int ff_packetsync_configure(FFPacketSync *fs); |
253 | | |
254 | | /** |
255 | | * Free all memory currently allocated. |
256 | | */ |
257 | | void ff_packetsync_uninit(FFPacketSync *fs); |
258 | | |
259 | | /** |
260 | | * Get the current packet in an input. |
261 | | * |
262 | | * @param fs packet sync structure |
263 | | * @param in index of the input |
264 | | * @param rpacket used to return the current packet (or NULL) |
265 | | * @param get if not zero, the calling code needs to get ownership of |
266 | | * the returned packet; the current packet will either be |
267 | | * duplicated or removed from the packetsync structure |
268 | | */ |
269 | | int ff_packetsync_get_packet(FFPacketSync *fs, unsigned in, AVPacket **rpacket, |
270 | | unsigned get); |
271 | | |
272 | | /** |
273 | | * Examine the packets in the filter's input and try to produce output. |
274 | | * |
275 | | * This function can be the complete implementation of the activate |
276 | | * method of a filter using packetsync. |
277 | | */ |
278 | | int ff_packetsync_activate(FFPacketSync *fs); |
279 | | |
280 | | /** |
281 | | * Initialize a packet sync structure for dualinput. |
282 | | * |
283 | | * Compared to generic packetsync, dualinput assumes the first input is the |
284 | | * main one and the filtering is performed on it. The first input will be |
285 | | * the only one with sync set and generic timeline support will just pass it |
286 | | * unchanged when disabled. |
287 | | * |
288 | | * Equivalent to ff_packetsync_init(fs, parent, 2) then setting the time |
289 | | * base, sync and ext modes on the inputs. |
290 | | */ |
291 | | int ff_packetsync_init_dualinput(FFPacketSync *fs, AVBitStreamFilterContext *parent); |
292 | | |
293 | | /** |
294 | | * @param f0 used to return the main packet |
295 | | * @param f1 used to return the second packet, or NULL if disabled |
296 | | * @return >=0 for success or AVERROR code |
297 | | * @note The packet returned in f0 belongs to the caller (get = 1 in |
298 | | * ff_packetsync_get_packet()) while the packet returned in f1 is still owned |
299 | | * by the packetsync structure. |
300 | | */ |
301 | | int ff_packetsync_dualinput_get(FFPacketSync *fs, AVPacket **f0, AVPacket **f1); |
302 | | |
303 | | /** |
304 | | * Same as ff_packetsync_dualinput_get(), but make sure that f0 is writable. |
305 | | */ |
306 | | int ff_packetsync_dualinput_get_writable(FFPacketSync *fs, AVPacket **f0, AVPacket **f1); |
307 | | |
308 | | const AVClass *ff_packetsync_child_class_iterate(void **iter); |
309 | | extern const AVClass ff_packetsync_class; |
310 | | |
311 | | #define PACKETSYNC_DEFINE_PURE_CLASS(name, desc, func_prefix, options) \ |
312 | | static const AVClass name##_class = { \ |
313 | | .class_name = desc, \ |
314 | | .item_name = av_default_item_name, \ |
315 | | .option = options, \ |
316 | | .version = LIBAVUTIL_VERSION_INT, \ |
317 | | .category = AV_CLASS_CATEGORY_BITSTREAM_FILTER, \ |
318 | | .child_class_iterate = ff_packetsync_child_class_iterate, \ |
319 | | .child_next = func_prefix##_child_next, \ |
320 | | } |
321 | | |
322 | | /* A filter that uses the *_child_next-function from this macro |
323 | | * is required to initialize the FFPacketSync structure in AVBitStreamFilter.preinit |
324 | | * via the *_packetsync_preinit function defined alongside it. */ |
325 | | #define PACKETSYNC_AUXILIARY_FUNCS(func_prefix, context, field) \ |
326 | 0 | static int func_prefix##_packetsync_preinit(AVBitStreamFilterContext *ctx) \ |
327 | 0 | { \ |
328 | 0 | context *s = ctx->priv_data; \ |
329 | 0 | ff_packetsync_preinit(&s->field); \ |
330 | 0 | return 0; \ |
331 | 0 | } \ |
332 | 0 | static void *func_prefix##_child_next(void *obj, void *prev) \ |
333 | 0 | { \ |
334 | 0 | context *s = obj; \ |
335 | 0 | return prev ? NULL : &s->field; \ |
336 | 0 | } |
337 | | |
338 | | #define PACKETSYNC_DEFINE_CLASS_EXT(name, context, field, options) \ |
339 | | PACKETSYNC_AUXILIARY_FUNCS(name, context, field) \ |
340 | | PACKETSYNC_DEFINE_PURE_CLASS(name, #name, name, options) |
341 | | |
342 | | #define PACKETSYNC_DEFINE_CLASS(name, context, field) \ |
343 | | PACKETSYNC_DEFINE_CLASS_EXT(name, context, field, name##_options) |
344 | | |
345 | | #endif /* AVCODEC_BSF_PACKETSYNC_H */ |