2 * Copyright (c) 2013 Nicolas George
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
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
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef AVFILTER_FRAMESYNC2_H
22 #define AVFILTER_FRAMESYNC2_H
24 #include "bufferqueue.h"
28 * Export convenient options.
32 * This API is intended as a helper for filters that have several video
33 * input and need to combine them somehow. If the inputs have different or
34 * variable frame rate, getting the input frames to match requires a rather
35 * complex logic and a few user-tunable options.
37 * In this API, when a set of synchronized input frames is ready to be
38 * procesed is called a frame event. Frame event can be generated in
39 * response to input frames on any or all inputs and the handling of
40 * situations where some stream extend beyond the beginning or the end of
41 * others can be configured.
43 * The basic working of this API is the following: set the on_event
44 * callback, then call ff_framesync2_activate() from the filter's activate
49 * Stream extrapolation mode
51 * Describe how the frames of a stream are extrapolated before the first one
52 * and after EOF to keep sync with possibly longer other streams.
54 enum FFFrameSyncExtMode {
57 * Completely stop all streams with this one.
62 * Ignore this stream and continue processing the other ones.
67 * Extend the frame to infinity.
73 * Input stream structure
75 typedef struct FFFrameSyncIn {
78 * Extrapolation mode for timestamps before the first frame
80 enum FFFrameSyncExtMode before;
83 * Extrapolation mode for timestamps after the last frame
85 enum FFFrameSyncExtMode after;
88 * Time base for the incoming frames
93 * Current frame, may be NULL before the first one or after EOF
98 * Next frame, for internal use
103 * PTS of the current frame
108 * PTS of the next frame, for internal use
113 * Boolean flagging the next frame, for internal use
118 * State: before first, in stream or after EOF, for internal use
123 * Synchronization level: frames on input at the highest sync level will
124 * generate output frame events.
126 * For example, if inputs #0 and #1 have sync level 2 and input #2 has
127 * sync level 1, then a frame on either input #0 or #1 will generate a
128 * frame event, but not a frame on input #2 until both inputs #0 and #1
131 * If sync is 0, no frame event will be generated.
138 * Frame sync structure.
140 typedef struct FFFrameSync {
141 const AVClass *class;
144 * Parent filter context.
146 AVFilterContext *parent;
149 * Number of input streams
154 * Time base for the output events
156 AVRational time_base;
159 * Timestamp of the current event
164 * Callback called when a frame event is ready
166 int (*on_event)(struct FFFrameSync *fs);
169 * Opaque pointer, not used by the API
174 * Index of the input that requires a request
179 * Synchronization level: only inputs with the same sync level are sync
185 * Flag indicating that a frame event is ready
190 * Flag indicating that output has reached EOF.
195 * Pointer to array of inputs.
206 * Get the class for the framesync2 object.
208 const AVClass *framesync2_get_class(void);
211 * Pre-initialize a frame sync structure.
213 * It sets the class pointer and inits the options to their default values.
214 * The entire structure is expected to be already set to 0.
215 * This step is optional, but necessary to use the options.
217 void ff_framesync2_preinit(FFFrameSync *fs);
220 * Initialize a frame sync structure.
222 * The entire structure is expected to be already set to 0 or preinited.
224 * @param fs frame sync structure to initialize
225 * @param parent parent AVFilterContext object
226 * @param nb_in number of inputs
227 * @return >= 0 for success or a negative error code
229 int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in);
232 * Configure a frame sync structure.
234 * Must be called after all options are set but before all use.
236 * @return >= 0 for success or a negative error code
238 int ff_framesync2_configure(FFFrameSync *fs);
241 * Free all memory currently allocated.
243 void ff_framesync2_uninit(FFFrameSync *fs);
246 * Get the current frame in an input.
248 * @param fs frame sync structure
249 * @param in index of the input
250 * @param rframe used to return the current frame (or NULL)
251 * @param get if not zero, the calling code needs to get ownership of
252 * the returned frame; the current frame will either be
253 * duplicated or removed from the framesync structure
255 int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
259 * Examine the frames in the filter's input and try to produce output.
261 * This function can be the complete implementation of the activate
262 * method of a filter using framesync2.
264 int ff_framesync2_activate(FFFrameSync *fs);
267 * Initialize a frame sync structure for dualinput.
269 * Compared to generic framesync, dualinput assumes the first input is the
270 * main one and the filtering is performed on it. The first input will be
271 * the only one with sync set and generic timeline support will just pass it
272 * unchanged when disabled.
274 * Equivalent to ff_framesync2_init(fs, parent, 2) then setting the time
275 * base, sync and ext modes on the inputs.
277 int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent);
280 * @param f0 used to return the main frame
281 * @param f1 used to return the second frame, or NULL if disabled
282 * @return >=0 for success or AVERROR code
284 int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1);
287 * Same as ff_framesync2_dualinput_get(), but make sure that f0 is writable.
289 int ff_framesync2_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1);
291 #define FRAMESYNC_DEFINE_CLASS(name, context, field) \
292 static int name##_framesync_preinit(AVFilterContext *ctx) { \
293 context *s = ctx->priv; \
294 ff_framesync2_preinit(&s->field); \
297 static const AVClass *name##_child_class_next(const AVClass *prev) { \
298 return prev ? NULL : framesync2_get_class(); \
300 static void *name##_child_next(void *obj, void *prev) { \
302 s->fs.class = framesync2_get_class(); /* FIXME */ \
303 return prev ? NULL : &s->field; \
305 static const AVClass name##_class = { \
306 .class_name = #name, \
307 .item_name = av_default_item_name, \
308 .option = name##_options, \
309 .version = LIBAVUTIL_VERSION_INT, \
310 .category = AV_CLASS_CATEGORY_FILTER, \
311 .child_class_next = name##_child_class_next, \
312 .child_next = name##_child_next, \
315 #endif /* AVFILTER_FRAMESYNC2_H */