You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
8.2KB

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