OSDN Git Service

Merge commit '7ff018c1cb43a5fe5ee2049d325cdd785852067a'
[android-x86/external-ffmpeg.git] / libavfilter / framesync.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_FRAMESYNC_H
22 #define AVFILTER_FRAMESYNC_H
23
24 #include "bufferqueue.h"
25
26 /*
27  * TODO
28  * Callback-based API similar to dualinput.
29  * Export convenient options.
30  */
31
32 /**
33  * This API is intended as a helper for filters that have several video
34  * input and need to combine them somehow. If the inputs have different or
35  * variable frame rate, getting the input frames to match requires a rather
36  * complex logic and a few user-tunable options.
37  *
38  * In this API, when a set of synchronized input frames is ready to be
39  * procesed is called a frame event. Frame event can be generated in
40  * response to input frames on any or all inputs and the handling of
41  * situations where some stream extend beyond the beginning or the end of
42  * others can be configured.
43  *
44  * The basic working of this API is the following:
45  *
46  * - When a frame is available on any input, add it using
47  *   ff_framesync_add_frame().
48  *
49  * - When a frame event is ready to be processed (i.e. after adding a frame
50  *   or when requested on input):
51  *   - call ff_framesync_next();
52  *   - if fs->frame_ready is true, process the frames;
53  *   - call ff_framesync_drop().
54  */
55
56 /**
57  * Stream extrapolation mode
58  *
59  * Describe how the frames of a stream are extrapolated before the first one
60  * and after EOF to keep sync with possibly longer other streams.
61  */
62 enum FFFrameSyncExtMode {
63
64     /**
65      * Completely stop all streams with this one.
66      */
67     EXT_STOP,
68
69     /**
70      * Ignore this stream and continue processing the other ones.
71      */
72     EXT_NULL,
73
74     /**
75      * Extend the frame to infinity.
76      */
77     EXT_INFINITY,
78 };
79
80 /**
81  * Input stream structure
82  */
83 typedef struct FFFrameSyncIn {
84
85     /**
86      * Queue of incoming AVFrame, and NULL to mark EOF
87      */
88     struct FFBufQueue queue;
89
90     /**
91      * Extrapolation mode for timestamps before the first frame
92      */
93     enum FFFrameSyncExtMode before;
94
95     /**
96      * Extrapolation mode for timestamps after the last frame
97      */
98     enum FFFrameSyncExtMode after;
99
100     /**
101      * Time base for the incoming frames
102      */
103     AVRational time_base;
104
105     /**
106      * Current frame, may be NULL before the first one or after EOF
107      */
108     AVFrame *frame;
109
110     /**
111      * Next frame, for internal use
112      */
113     AVFrame *frame_next;
114
115     /**
116      * PTS of the current frame
117      */
118     int64_t pts;
119
120     /**
121      * PTS of the next frame, for internal use
122      */
123     int64_t pts_next;
124
125     /**
126      * Boolean flagging the next frame, for internal use
127      */
128     uint8_t have_next;
129
130     /**
131      * State: before first, in stream or after EOF, for internal use
132      */
133     uint8_t state;
134
135     /**
136      * Synchronization level: frames on input at the highest sync level will
137      * generate output frame events.
138      *
139      * For example, if inputs #0 and #1 have sync level 2 and input #2 has
140      * sync level 1, then a frame on either input #0 or #1 will generate a
141      * frame event, but not a frame on input #2 until both inputs #0 and #1
142      * have reached EOF.
143      *
144      * If sync is 0, no frame event will be generated.
145      */
146     unsigned sync;
147
148 } FFFrameSyncIn;
149
150 /**
151  * Frame sync structure.
152  */
153 typedef struct FFFrameSync {
154     const AVClass *class;
155     void *parent;
156
157     /**
158      * Number of input streams
159      */
160     unsigned nb_in;
161
162     /**
163      * Time base for the output events
164      */
165     AVRational time_base;
166
167     /**
168      * Timestamp of the current event
169      */
170     int64_t pts;
171
172     /**
173      * Callback called when a frame event is ready
174      */
175     int (*on_event)(struct FFFrameSync *fs);
176
177     /**
178      * Opaque pointer, not used by the API
179      */
180     void *opaque;
181
182     /**
183      * Index of the input that requires a request
184      */
185     unsigned in_request;
186
187     /**
188      * Synchronization level: only inputs with the same sync level are sync
189      * sources.
190      */
191     unsigned sync_level;
192
193     /**
194      * Flag indicating that a frame event is ready
195      */
196     uint8_t frame_ready;
197
198     /**
199      * Flag indicating that output has reached EOF.
200      */
201     uint8_t eof;
202
203     /**
204      * Pointer to array of inputs.
205      */
206     FFFrameSyncIn *in;
207
208 } FFFrameSync;
209
210 /**
211  * Initialize a frame sync structure.
212  *
213  * The entire structure is expected to be already set to 0.
214  *
215  * @param  fs      frame sync structure to initialize
216  * @param  parent  parent object, used for logging
217  * @param  nb_in   number of inputs
218  * @return  >= 0 for success or a negative error code
219  */
220 int ff_framesync_init(FFFrameSync *fs, void *parent, unsigned nb_in);
221
222 /**
223  * Configure a frame sync structure.
224  *
225  * Must be called after all options are set but before all use.
226  *
227  * @return  >= 0 for success or a negative error code
228  */
229 int ff_framesync_configure(FFFrameSync *fs);
230
231 /**
232  * Free all memory currently allocated.
233  */
234 void ff_framesync_uninit(FFFrameSync *fs);
235
236 /**
237  * Add a frame to an input
238  *
239  * Typically called from the filter_frame() method.
240  *
241  * @param fs     frame sync structure
242  * @param in     index of the input
243  * @param frame  input frame, or NULL for EOF
244  */
245 int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame);
246
247 /**
248  * Prepare the next frame event.
249  *
250  * The status of the operation can be found in fs->frame_ready and fs->eof.
251  */
252 void ff_framesync_next(FFFrameSync *fs);
253
254 /**
255  * Drop the current frame event.
256  */
257 void ff_framesync_drop(FFFrameSync *fs);
258
259 /**
260  * Get the current frame in an input.
261  *
262  * @param fs      frame sync structure
263  * @param in      index of the input
264  * @param rframe  used to return the current frame (or NULL)
265  * @param get     if not zero, the calling code needs to get ownership of
266  *                the returned frame; the current frame will either be
267  *                duplicated or removed from the framesync structure
268  */
269 int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
270                            unsigned get);
271
272 /**
273  * Process one or several frame using the on_event callback.
274  *
275  * @return  number of frames processed or negative error code
276  */
277 int ff_framesync_process_frame(FFFrameSync *fs, unsigned all);
278
279
280 /**
281  * Accept a frame on a filter input.
282  *
283  * This function can be the complete implementation of all filter_frame
284  * methods of a filter using framesync.
285  */
286 int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink,
287                               AVFrame *in);
288
289 /**
290  * Request a frame on the filter output.
291  *
292  * This function can be the complete implementation of all filter_frame
293  * methods of a filter using framesync if it has only one output.
294  */
295 int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink);
296
297 #endif /* AVFILTER_FRAMESYNC_H */