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 enum EOFAction { 27 EOF_ACTION_REPEAT, 28 EOF_ACTION_ENDALL, 29 EOF_ACTION_PASS 30 }; 31 32 /* 33 * TODO 34 * Export convenient options. 35 */ 36 37 /** 38 * This API is intended as a helper for filters that have several video 39 * input and need to combine them somehow. If the inputs have different or 40 * variable frame rate, getting the input frames to match requires a rather 41 * complex logic and a few user-tunable options. 42 * 43 * In this API, when a set of synchronized input frames is ready to be 44 * procesed is called a frame event. Frame event can be generated in 45 * response to input frames on any or all inputs and the handling of 46 * situations where some stream extend beyond the beginning or the end of 47 * others can be configured. 48 * 49 * The basic working of this API is the following: set the on_event 50 * callback, then call ff_framesync_activate() from the filter's activate 51 * callback. 52 */ 53 54 /** 55 * Stream extrapolation mode 56 * 57 * Describe how the frames of a stream are extrapolated before the first one 58 * and after EOF to keep sync with possibly longer other streams. 59 */ 60 enum FFFrameSyncExtMode { 61 62 /** 63 * Completely stop all streams with this one. 64 */ 65 EXT_STOP, 66 67 /** 68 * Ignore this stream and continue processing the other ones. 69 */ 70 EXT_NULL, 71 72 /** 73 * Extend the frame to infinity. 74 */ 75 EXT_INFINITY, 76 }; 77 78 /** 79 * Input stream structure 80 */ 81 typedef struct FFFrameSyncIn { 82 83 /** 84 * Extrapolation mode for timestamps before the first frame 85 */ 86 enum FFFrameSyncExtMode before; 87 88 /** 89 * Extrapolation mode for timestamps after the last frame 90 */ 91 enum FFFrameSyncExtMode after; 92 93 /** 94 * Time base for the incoming frames 95 */ 96 AVRational time_base; 97 98 /** 99 * Current frame, may be NULL before the first one or after EOF 100 */ 101 AVFrame *frame; 102 103 /** 104 * Next frame, for internal use 105 */ 106 AVFrame *frame_next; 107 108 /** 109 * PTS of the current frame 110 */ 111 int64_t pts; 112 113 /** 114 * PTS of the next frame, for internal use 115 */ 116 int64_t pts_next; 117 118 /** 119 * Boolean flagging the next frame, for internal use 120 */ 121 uint8_t have_next; 122 123 /** 124 * State: before first, in stream or after EOF, for internal use 125 */ 126 uint8_t state; 127 128 /** 129 * Synchronization level: frames on input at the highest sync level will 130 * generate output frame events. 131 * 132 * For example, if inputs #0 and #1 have sync level 2 and input #2 has 133 * sync level 1, then a frame on either input #0 or #1 will generate a 134 * frame event, but not a frame on input #2 until both inputs #0 and #1 135 * have reached EOF. 136 * 137 * If sync is 0, no frame event will be generated. 138 */ 139 unsigned sync; 140 141 } FFFrameSyncIn; 142 143 /** 144 * Frame sync structure. 145 */ 146 typedef struct FFFrameSync { 147 const AVClass *class; 148 149 /** 150 * Parent filter context. 151 */ 152 AVFilterContext *parent; 153 154 /** 155 * Number of input streams 156 */ 157 unsigned nb_in; 158 159 /** 160 * Time base for the output events 161 */ 162 AVRational time_base; 163 164 /** 165 * Timestamp of the current event 166 */ 167 int64_t pts; 168 169 /** 170 * Callback called when a frame event is ready 171 */ 172 int (*on_event)(struct FFFrameSync *fs); 173 174 /** 175 * Opaque pointer, not used by the API 176 */ 177 void *opaque; 178 179 /** 180 * Index of the input that requires a request 181 */ 182 unsigned in_request; 183 184 /** 185 * Synchronization level: only inputs with the same sync level are sync 186 * sources. 187 */ 188 unsigned sync_level; 189 190 /** 191 * Flag indicating that a frame event is ready 192 */ 193 uint8_t frame_ready; 194 195 /** 196 * Flag indicating that output has reached EOF. 197 */ 198 uint8_t eof; 199 200 /** 201 * Pointer to array of inputs. 202 */ 203 FFFrameSyncIn *in; 204 205 int opt_repeatlast; 206 int opt_shortest; 207 int opt_eof_action; 208 209 } FFFrameSync; 210 211 /** 212 * Pre-initialize a frame sync structure. 213 * 214 * It sets the class pointer and inits the options to their default values. 215 * The entire structure is expected to be already set to 0. 216 * This step is optional, but necessary to use the options. 217 */ 218 void ff_framesync_preinit(FFFrameSync *fs); 219 220 /** 221 * Initialize a frame sync structure. 222 * 223 * The entire structure is expected to be already set to 0 or preinited. 224 * 225 * @param fs frame sync structure to initialize 226 * @param parent parent AVFilterContext object 227 * @param nb_in number of inputs 228 * @return >= 0 for success or a negative error code 229 */ 230 int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in); 231 232 /** 233 * Configure a frame sync structure. 234 * 235 * Must be called after all options are set but before all use. 236 * 237 * @return >= 0 for success or a negative error code 238 */ 239 int ff_framesync_configure(FFFrameSync *fs); 240 241 /** 242 * Free all memory currently allocated. 243 */ 244 void ff_framesync_uninit(FFFrameSync *fs); 245 246 /** 247 * Get the current frame in an input. 248 * 249 * @param fs frame sync structure 250 * @param in index of the input 251 * @param rframe used to return the current frame (or NULL) 252 * @param get if not zero, the calling code needs to get ownership of 253 * the returned frame; the current frame will either be 254 * duplicated or removed from the framesync structure 255 */ 256 int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, 257 unsigned get); 258 259 /** 260 * Examine the frames in the filter's input and try to produce output. 261 * 262 * This function can be the complete implementation of the activate 263 * method of a filter using framesync. 264 */ 265 int ff_framesync_activate(FFFrameSync *fs); 266 267 /** 268 * Initialize a frame sync structure for dualinput. 269 * 270 * Compared to generic framesync, dualinput assumes the first input is the 271 * main one and the filtering is performed on it. The first input will be 272 * the only one with sync set and generic timeline support will just pass it 273 * unchanged when disabled. 274 * 275 * Equivalent to ff_framesync_init(fs, parent, 2) then setting the time 276 * base, sync and ext modes on the inputs. 277 */ 278 int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent); 279 280 /** 281 * @param f0 used to return the main frame 282 * @param f1 used to return the second frame, or NULL if disabled 283 * @return >=0 for success or AVERROR code 284 * @note The frame returned in f0 belongs to the caller (get = 1 in 285 * ff_framesync_get_frame()) while the frame returned in f1 is still owned 286 * by the framesync structure. 287 */ 288 int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); 289 290 /** 291 * Same as ff_framesync_dualinput_get(), but make sure that f0 is writable. 292 */ 293 int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); 294 295 const AVClass *ff_framesync_child_class_iterate(void **iter); 296 297 #define FRAMESYNC_DEFINE_PURE_CLASS(name, desc, func_prefix, options) \ 298 static const AVClass name##_class = { \ 299 .class_name = desc, \ 300 .item_name = av_default_item_name, \ 301 .option = options, \ 302 .version = LIBAVUTIL_VERSION_INT, \ 303 .category = AV_CLASS_CATEGORY_FILTER, \ 304 .child_class_iterate = ff_framesync_child_class_iterate, \ 305 .child_next = func_prefix##_child_next, \ 306 } 307 308 /* A filter that uses the *_child_next-function from this macro 309 * is required to initialize the FFFrameSync structure in AVFilter.preinit 310 * via the *_framesync_preinit function defined alongside it. */ 311 #define FRAMESYNC_AUXILIARY_FUNCS(func_prefix, context, field) \ 312 static int func_prefix##_framesync_preinit(AVFilterContext *ctx) \ 313 { \ 314 context *s = ctx->priv; \ 315 ff_framesync_preinit(&s->field); \ 316 return 0; \ 317 } \ 318 static void *func_prefix##_child_next(void *obj, void *prev) \ 319 { \ 320 context *s = obj; \ 321 return prev ? NULL : &s->field; \ 322 } 323 324 #define FRAMESYNC_DEFINE_CLASS_EXT(name, context, field, options) \ 325 FRAMESYNC_AUXILIARY_FUNCS(name, context, field) \ 326 FRAMESYNC_DEFINE_PURE_CLASS(name, #name, name, options) 327 328 #define FRAMESYNC_DEFINE_CLASS(name, context, field) \ 329 FRAMESYNC_DEFINE_CLASS_EXT(name, context, field, name##_options) 330 331 #endif /* AVFILTER_FRAMESYNC_H */ 332