Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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
     * 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
 */
219
void 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
 */
228
int ff_framesync_configure(FFFrameSync *fs);
229
 
230
/**
231
 * Free all memory currently allocated.
232
 */
233
void 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
 */
244
int 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
 */
251
void ff_framesync_next(FFFrameSync *fs);
252
 
253
/**
254
 * Drop the current frame event.
255
 */
256
void 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
 */
268
int 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
 */
276
int 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
 */
285
int 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
 */
294
int ff_framesync_request_frame(FFFrameSync *fs, AVFilterLink *outlink);
295
 
296
#endif /* AVFILTER_FRAMESYNC_H */