]> git.sesse.net Git - ffmpeg/blob - libavfilter/framesync2.h
avfilter/vf_mcdeint: free the AVCodecContext struct properly
[ffmpeg] / libavfilter / framesync2.h
1 /*
2  * Copyright (c) 2013 Nicolas George
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 License
8  * 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
14  * GNU Lesser General Public License for more details.
15  *
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
19  */
20
21 #ifndef AVFILTER_FRAMESYNC2_H
22 #define AVFILTER_FRAMESYNC2_H
23
24 #include "bufferqueue.h"
25
26 /*
27  * TODO
28  * Export convenient options.
29  */
30
31 /**
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.
36  *
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.
42  *
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
45  * callback.
46  */
47
48 /**
49  * Stream extrapolation mode
50  *
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.
53  */
54 enum FFFrameSyncExtMode {
55
56     /**
57      * Completely stop all streams with this one.
58      */
59     EXT_STOP,
60
61     /**
62      * Ignore this stream and continue processing the other ones.
63      */
64     EXT_NULL,
65
66     /**
67      * Extend the frame to infinity.
68      */
69     EXT_INFINITY,
70 };
71
72 /**
73  * Input stream structure
74  */
75 typedef struct FFFrameSyncIn {
76
77     /**
78      * Extrapolation mode for timestamps before the first frame
79      */
80     enum FFFrameSyncExtMode before;
81
82     /**
83      * Extrapolation mode for timestamps after the last frame
84      */
85     enum FFFrameSyncExtMode after;
86
87     /**
88      * Time base for the incoming frames
89      */
90     AVRational time_base;
91
92     /**
93      * Current frame, may be NULL before the first one or after EOF
94      */
95     AVFrame *frame;
96
97     /**
98      * Next frame, for internal use
99      */
100     AVFrame *frame_next;
101
102     /**
103      * PTS of the current frame
104      */
105     int64_t pts;
106
107     /**
108      * PTS of the next frame, for internal use
109      */
110     int64_t pts_next;
111
112     /**
113      * Boolean flagging the next frame, for internal use
114      */
115     uint8_t have_next;
116
117     /**
118      * State: before first, in stream or after EOF, for internal use
119      */
120     uint8_t state;
121
122     /**
123      * Synchronization level: frames on input at the highest sync level will
124      * generate output frame events.
125      *
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
129      * have reached EOF.
130      *
131      * If sync is 0, no frame event will be generated.
132      */
133     unsigned sync;
134
135 } FFFrameSyncIn;
136
137 /**
138  * Frame sync structure.
139  */
140 typedef struct FFFrameSync {
141     const AVClass *class;
142
143     /**
144      * Parent filter context.
145      */
146     AVFilterContext *parent;
147
148     /**
149      * Number of input streams
150      */
151     unsigned nb_in;
152
153     /**
154      * Time base for the output events
155      */
156     AVRational time_base;
157
158     /**
159      * Timestamp of the current event
160      */
161     int64_t pts;
162
163     /**
164      * Callback called when a frame event is ready
165      */
166     int (*on_event)(struct FFFrameSync *fs);
167
168     /**
169      * Opaque pointer, not used by the API
170      */
171     void *opaque;
172
173     /**
174      * Index of the input that requires a request
175      */
176     unsigned in_request;
177
178     /**
179      * Synchronization level: only inputs with the same sync level are sync
180      * sources.
181      */
182     unsigned sync_level;
183
184     /**
185      * Flag indicating that a frame event is ready
186      */
187     uint8_t frame_ready;
188
189     /**
190      * Flag indicating that output has reached EOF.
191      */
192     uint8_t eof;
193
194     /**
195      * Pointer to array of inputs.
196      */
197     FFFrameSyncIn *in;
198
199     int opt_repeatlast;
200     int opt_shortest;
201     int opt_eof_action;
202
203 } FFFrameSync;
204
205 /**
206  * Get the class for the framesync2 object.
207  */
208 const AVClass *framesync2_get_class(void);
209
210 /**
211  * Pre-initialize a frame sync structure.
212  *
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.
216  */
217 void ff_framesync2_preinit(FFFrameSync *fs);
218
219 /**
220  * Initialize a frame sync structure.
221  *
222  * The entire structure is expected to be already set to 0 or preinited.
223  *
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
228  */
229 int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in);
230
231 /**
232  * Configure a frame sync structure.
233  *
234  * Must be called after all options are set but before all use.
235  *
236  * @return  >= 0 for success or a negative error code
237  */
238 int ff_framesync2_configure(FFFrameSync *fs);
239
240 /**
241  * Free all memory currently allocated.
242  */
243 void ff_framesync2_uninit(FFFrameSync *fs);
244
245 /**
246  * Get the current frame in an input.
247  *
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
254  */
255 int ff_framesync2_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
256                             unsigned get);
257
258 /**
259  * Examine the frames in the filter's input and try to produce output.
260  *
261  * This function can be the complete implementation of the activate
262  * method of a filter using framesync2.
263  */
264 int ff_framesync2_activate(FFFrameSync *fs);
265
266 /**
267  * Initialize a frame sync structure for dualinput.
268  *
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.
273  *
274  * Equivalent to ff_framesync2_init(fs, parent, 2) then setting the time
275  * base, sync and ext modes on the inputs.
276  */
277 int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent);
278
279 /**
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
283  */
284 int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1);
285
286 /**
287  * Same as ff_framesync2_dualinput_get(), but make sure that f0 is writable.
288  */
289 int ff_framesync2_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1);
290
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); \
295     return 0; \
296 } \
297 static const AVClass *name##_child_class_next(const AVClass *prev) { \
298     return prev ? NULL : framesync2_get_class(); \
299 } \
300 static void *name##_child_next(void *obj, void *prev) { \
301     context *s = obj; \
302     s->fs.class = framesync2_get_class(); /* FIXME */ \
303     return prev ? NULL : &s->field; \
304 } \
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, \
313 }
314
315 #endif /* AVFILTER_FRAMESYNC2_H */