Imported Debian version 2.4.3~trusty1
[deb_ffmpeg.git] / ffmpeg / libavfilter / framesync.h
CommitLineData
2ba45a60
DM
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 */
62enum 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 */
83typedef 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 */
153typedef 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 * Array of inputs; all inputs must be in consecutive memory
205 */
206 FFFrameSyncIn in[1]; /* must be the last field */
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 */
219void ff_framesync_init(FFFrameSync *fs, void *parent, unsigned nb_in);
220
221/**
222 * Configure a frame sync structure.
223 *
224 * Must be called after all options are set but before all use.
225 *
226 * @return >= 0 for success or a negative error code
227 */
228int ff_framesync_configure(FFFrameSync *fs);
229
230/**
231 * Free all memory currently allocated.
232 */
233void ff_framesync_uninit(FFFrameSync *fs);
234
235/**
236 * Add a frame to an input
237 *
238 * Typically called from the filter_frame() method.
239 *
240 * @param fs frame sync structure
241 * @param in index of the input
242 * @param frame input frame, or NULL for EOF
243 */
244int ff_framesync_add_frame(FFFrameSync *fs, unsigned in, AVFrame *frame);
245
246/**
247 * Prepare the next frame event.
248 *
249 * The status of the operation can be found in fs->frame_ready and fs->eof.
250 */
251void ff_framesync_next(FFFrameSync *fs);
252
253/**
254 * Drop the current frame event.
255 */
256void ff_framesync_drop(FFFrameSync *fs);
257
258/**
259 * Get the current frame in an input.
260 *
261 * @param fs frame sync structure
262 * @param in index of the input
263 * @param rframe used to return the current frame (or NULL)
264 * @param get if not zero, the calling code needs to get ownership of
265 * the returned frame; the current frame will either be
266 * duplicated or removed from the framesync structure
267 */
268int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
269 unsigned get);
270
271/**
272 * Process one or several frame using the on_event callback.
273 *
274 * @return number of frames processed or negative error code
275 */
276int ff_framesync_process_frame(FFFrameSync *fs, unsigned all);
277
278
279/**
280 * Accept a frame on a filter input.
281 *
282 * This function can be the complete implementation of all filter_frame
283 * methods of a filter using framesync.
284 */
285int ff_framesync_filter_frame(FFFrameSync *fs, AVFilterLink *inlink,
286 AVFrame *in);
287
288/**
289 * Request a frame on the filter output.
290 *
291 * This function can be the complete implementation of all filter_frame
292 * methods of a filter using framesync if it has only one output.
293 */
294int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink);
295
296#endif /* AVFILTER_FRAMESYNC_H */