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 */ 297