FFmpeg
framesync.c
Go to the documentation of this file.
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 #include "libavutil/avassert.h"
22 #include "libavutil/mem.h"
23 #include "libavutil/opt.h"
24 #include "avfilter.h"
25 #include "filters.h"
26 #include "framesync.h"
27 
28 #define OFFSET(member) offsetof(FFFrameSync, member)
29 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
30 
31 static const char *framesync_name(void *ptr)
32 {
33  return "framesync";
34 }
35 
36 static const AVOption framesync_options[] = {
37  { "eof_action", "Action to take when encountering EOF from secondary input ",
38  OFFSET(opt_eof_action), AV_OPT_TYPE_INT, { .i64 = EOF_ACTION_REPEAT },
39  EOF_ACTION_REPEAT, EOF_ACTION_PASS, .flags = FLAGS, .unit = "eof_action" },
40  { "repeat", "Repeat the previous frame.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_REPEAT }, .flags = FLAGS, .unit = "eof_action" },
41  { "endall", "End both streams.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_ENDALL }, .flags = FLAGS, .unit = "eof_action" },
42  { "pass", "Pass through the main input.", 0, AV_OPT_TYPE_CONST, { .i64 = EOF_ACTION_PASS }, .flags = FLAGS, .unit = "eof_action" },
43  { "shortest", "force termination when the shortest input terminates", OFFSET(opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
44  { "repeatlast", "extend last frame of secondary streams beyond EOF", OFFSET(opt_repeatlast), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
45  { "ts_sync_mode", "How strictly to sync streams based on secondary input timestamps",
46  OFFSET(opt_ts_sync_mode), AV_OPT_TYPE_INT, { .i64 = TS_DEFAULT },
47  TS_DEFAULT, TS_NEAREST, .flags = FLAGS, .unit = "ts_sync_mode" },
48  { "default", "Frame from secondary input with the nearest lower or equal timestamp to the primary input frame",
49  0, AV_OPT_TYPE_CONST, { .i64 = TS_DEFAULT }, .flags = FLAGS, .unit = "ts_sync_mode" },
50  { "nearest", "Frame from secondary input with the absolute nearest timestamp to the primary input frame",
51  0, AV_OPT_TYPE_CONST, { .i64 = TS_NEAREST }, .flags = FLAGS, .unit = "ts_sync_mode" },
52  { NULL }
53 };
56  .class_name = "framesync",
57  .item_name = framesync_name,
58  .category = AV_CLASS_CATEGORY_FILTER,
59  .option = framesync_options,
60  .parent_log_context_offset = OFFSET(parent),
61 };
62 
64 {
65  const AVClass *c = *iter ? NULL : &ff_framesync_class;
66  *iter = (void *)(uintptr_t)c;
67  return c;
68 }
69 
70 enum {
74 };
75 
76 static int consume_from_fifos(FFFrameSync *fs);
77 
79 {
80  if (fs->class)
81  return;
82  fs->class = &ff_framesync_class;
84 }
85 
86 int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
87 {
88  /* For filters with several outputs, we will not be able to assume which
89  output is relevant for ff_outlink_frame_wanted() and
90  ff_outlink_set_status(). To be designed when needed. */
91  av_assert0(parent->nb_outputs == 1);
92 
94  fs->parent = parent;
95  fs->nb_in = nb_in;
96 
97  fs->in = av_calloc(nb_in, sizeof(*fs->in));
98  if (!fs->in) {
99  fs->nb_in = 0;
100  return AVERROR(ENOMEM);
101  }
102 
103  return 0;
104 }
105 
107 {
108  fs->eof = 1;
109  fs->frame_ready = 0;
110  ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE);
111 }
112 
114 {
115  unsigned i, level = 0;
116 
117  for (i = 0; i < fs->nb_in; i++)
118  if (fs->in[i].state != STATE_EOF)
119  level = FFMAX(level, fs->in[i].sync);
120  av_assert0(level <= fs->sync_level);
121  if (level < fs->sync_level)
122  av_log(fs, AV_LOG_VERBOSE, "Sync level %u\n", level);
123  if (fs->opt_ts_sync_mode > TS_DEFAULT) {
124  for (i = 0; i < fs->nb_in; i++) {
125  if (fs->in[i].sync < level)
126  fs->in[i].ts_mode = fs->opt_ts_sync_mode;
127  else
128  fs->in[i].ts_mode = TS_DEFAULT;
129  }
130  }
131  if (level)
132  fs->sync_level = level;
133  else
134  framesync_eof(fs);
135 }
136 
138 {
139  unsigned i;
140 
141  if (!fs->opt_repeatlast || fs->opt_eof_action == EOF_ACTION_PASS) {
142  fs->opt_repeatlast = 0;
143  fs->opt_eof_action = EOF_ACTION_PASS;
144  }
145  if (fs->opt_shortest || fs->opt_eof_action == EOF_ACTION_ENDALL) {
146  fs->opt_shortest = 1;
147  fs->opt_eof_action = EOF_ACTION_ENDALL;
148  }
149  if (!fs->opt_repeatlast) {
150  for (i = 1; i < fs->nb_in; i++) {
151  fs->in[i].after = EXT_NULL;
152  fs->in[i].sync = 0;
153  }
154  }
155  if (fs->opt_shortest) {
156  for (i = 0; i < fs->nb_in; i++)
157  fs->in[i].after = EXT_STOP;
158  }
159 
160  if (!fs->time_base.num) {
161  for (i = 0; i < fs->nb_in; i++) {
162  if (fs->in[i].sync) {
163  if (fs->time_base.num) {
164  fs->time_base = av_gcd_q(fs->time_base, fs->in[i].time_base,
166  } else {
167  fs->time_base = fs->in[i].time_base;
168  }
169  }
170  }
171  if (!fs->time_base.num) {
172  av_log(fs, AV_LOG_ERROR, "Impossible to set time base\n");
173  return AVERROR(EINVAL);
174  }
175  av_log(fs, AV_LOG_VERBOSE, "Selected %d/%d time base\n",
176  fs->time_base.num, fs->time_base.den);
177  }
178 
179  for (i = 0; i < fs->nb_in; i++)
180  fs->in[i].pts = fs->in[i].pts_next = AV_NOPTS_VALUE;
181  fs->sync_level = UINT_MAX;
183 
184  return 0;
185 }
186 
188 {
189  unsigned i;
190  int64_t pts;
191  int ret;
192 
193  while (!(fs->frame_ready || fs->eof)) {
195  if (ret <= 0)
196  return ret;
197 
198  pts = INT64_MAX;
199  for (i = 0; i < fs->nb_in; i++)
200  if (fs->in[i].have_next && fs->in[i].pts_next < pts)
201  pts = fs->in[i].pts_next;
202  if (pts == INT64_MAX) {
203  framesync_eof(fs);
204  break;
205  }
206  for (i = 0; i < fs->nb_in; i++) {
207  if (fs->in[i].pts_next == pts ||
208  (fs->in[i].ts_mode == TS_NEAREST &&
209  fs->in[i].have_next &&
210  fs->in[i].pts_next != INT64_MAX && fs->in[i].pts != AV_NOPTS_VALUE &&
211  fs->in[i].pts_next - pts < pts - fs->in[i].pts) ||
212  (fs->in[i].before == EXT_INFINITY &&
213  fs->in[i].state == STATE_BOF)) {
214  av_frame_free(&fs->in[i].frame);
215  fs->in[i].frame = fs->in[i].frame_next;
216  fs->in[i].pts = fs->in[i].pts_next;
217  fs->in[i].frame_next = NULL;
218  fs->in[i].pts_next = AV_NOPTS_VALUE;
219  fs->in[i].have_next = 0;
220  fs->in[i].state = fs->in[i].frame ? STATE_RUN : STATE_EOF;
221  if (fs->in[i].sync == fs->sync_level && fs->in[i].frame)
222  fs->frame_ready = 1;
223  if (fs->in[i].state == STATE_EOF &&
224  fs->in[i].after == EXT_STOP)
225  framesync_eof(fs);
226  }
227  }
228  if (fs->frame_ready)
229  for (i = 0; i < fs->nb_in; i++)
230  if ((fs->in[i].state == STATE_BOF &&
231  fs->in[i].before == EXT_STOP))
232  fs->frame_ready = 0;
233  fs->pts = pts;
234  }
235  return 0;
236 }
237 
238 static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in,
239  int64_t pts)
240 {
241  /* Possible enhancement: use the link's frame rate */
242  return pts + 1;
243 }
244 
245 static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame)
246 {
247  int64_t pts;
248 
249  av_assert0(!fs->in[in].have_next);
250  av_assert0(frame);
251  pts = av_rescale_q(frame->pts, fs->in[in].time_base, fs->time_base);
252  frame->pts = pts;
253  fs->in[in].frame_next = frame;
254  fs->in[in].pts_next = pts;
255  fs->in[in].have_next = 1;
256 }
257 
258 static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t pts)
259 {
260  av_assert0(!fs->in[in].have_next);
261  pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY
262  ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts);
263  fs->in[in].sync = 0;
265  fs->in[in].frame_next = NULL;
266  fs->in[in].pts_next = pts;
267  fs->in[in].have_next = 1;
268 }
269 
270 int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe,
271  unsigned get)
272 {
273  AVFrame *frame;
274  unsigned need_copy = 0, i;
275  int64_t pts_next;
276  int ret;
277 
278  if (!fs->in[in].frame) {
279  *rframe = NULL;
280  return 0;
281  }
282  frame = fs->in[in].frame;
283  if (get) {
284  /* Find out if we need to copy the frame: is there another sync
285  stream, and do we know if its current frame will outlast this one? */
286  pts_next = fs->in[in].have_next ? fs->in[in].pts_next : INT64_MAX;
287  for (i = 0; i < fs->nb_in && !need_copy; i++)
288  if (i != in && fs->in[i].sync &&
289  (!fs->in[i].have_next || fs->in[i].pts_next < pts_next))
290  need_copy = 1;
291  if (need_copy) {
292  if (!(frame = av_frame_clone(frame)))
293  return AVERROR(ENOMEM);
294  if ((ret = ff_inlink_make_frame_writable(fs->parent->inputs[in], &frame)) < 0) {
296  return ret;
297  }
298  } else {
299  fs->in[in].frame = NULL;
300  }
301  fs->frame_ready = 0;
302  }
303  *rframe = frame;
304  return 0;
305 }
306 
308 {
309  unsigned i;
310 
311  for (i = 0; i < fs->nb_in; i++) {
312  av_frame_free(&fs->in[i].frame);
313  av_frame_free(&fs->in[i].frame_next);
314  }
315 
316  av_freep(&fs->in);
317 }
318 
320 {
321  AVFilterContext *ctx = fs->parent;
322  AVFrame *frame = NULL;
323  int64_t pts;
324  unsigned i, nb_active, nb_miss;
325  int ret, status;
326 
327  nb_active = nb_miss = 0;
328  for (i = 0; i < fs->nb_in; i++) {
329  if (fs->in[i].have_next || fs->in[i].state == STATE_EOF)
330  continue;
331  nb_active++;
332  ret = ff_inlink_consume_frame(ctx->inputs[i], &frame);
333  if (ret < 0)
334  return ret;
335  if (ret) {
336  av_assert0(frame);
338  } else {
340  if (ret > 0) {
342  } else if (!ret) {
343  nb_miss++;
344  }
345  }
346  }
347  if (nb_miss) {
348  if (nb_miss == nb_active && !ff_outlink_frame_wanted(ctx->outputs[0]))
349  return FFERROR_NOT_READY;
350  for (i = 0; i < fs->nb_in; i++)
351  if (!fs->in[i].have_next && fs->in[i].state != STATE_EOF)
352  ff_inlink_request_frame(ctx->inputs[i]);
353  return 0;
354  }
355  return 1;
356 }
357 
359 {
360  AVFilterContext *ctx = fs->parent;
361  int ret;
362 
364 
366  if (ret < 0)
367  return ret;
368  if (fs->eof || !fs->frame_ready)
369  return 0;
370  ret = fs->on_event(fs);
371  if (ret < 0)
372  return ret;
373  fs->frame_ready = 0;
374 
375  return 0;
376 }
377 
379 {
380  int ret;
381 
382  ret = ff_framesync_init(fs, parent, 2);
383  if (ret < 0)
384  return ret;
385  fs->in[0].time_base = parent->inputs[0]->time_base;
386  fs->in[1].time_base = parent->inputs[1]->time_base;
387  fs->in[0].sync = 2;
388  fs->in[0].before = EXT_STOP;
389  fs->in[0].after = EXT_INFINITY;
390  fs->in[1].sync = 1;
391  fs->in[1].before = EXT_NULL;
392  fs->in[1].after = EXT_INFINITY;
393  return 0;
394 }
395 
397 {
398  AVFilterContext *ctx = fs->parent;
399  AVFrame *mainpic = NULL, *secondpic = NULL;
400  int ret;
401 
402  if ((ret = ff_framesync_get_frame(fs, 0, &mainpic, 1)) < 0 ||
403  (ret = ff_framesync_get_frame(fs, 1, &secondpic, 0)) < 0) {
404  av_frame_free(&mainpic);
405  return ret;
406  }
407  av_assert0(mainpic);
408  mainpic->pts = av_rescale_q(fs->pts, fs->time_base, ctx->outputs[0]->time_base);
409  if (ctx->is_disabled)
410  secondpic = NULL;
411  *f0 = mainpic;
412  *f1 = secondpic;
413  return 0;
414 }
415 
417 {
418  int ret;
419 
420  ret = ff_framesync_dualinput_get(fs, f0, f1);
421  if (ret < 0)
422  return ret;
423  ret = ff_inlink_make_frame_writable(fs->parent->inputs[0], f0);
424  if (ret < 0) {
425  av_frame_free(f0);
426  *f1 = NULL;
427  return ret;
428  }
429  return 0;
430 }
ff_framesync_configure
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:137
level
uint8_t level
Definition: svq3.c:205
av_opt_set_defaults
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition: opt.c:1654
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:307
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
consume_from_fifos
static int consume_from_fifos(FFFrameSync *fs)
Definition: framesync.c:319
ff_framesync_get_frame
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
Definition: framesync.c:270
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
AVClass::version
int version
LIBAVUTIL_VERSION with which this structure was created.
Definition: log.h:92
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:486
AVOption
AVOption.
Definition: opt.h:357
EOF_ACTION_ENDALL
@ EOF_ACTION_ENDALL
Definition: framesync.h:28
AVFilterContext::nb_outputs
unsigned nb_outputs
number of output pads
Definition: avfilter.h:420
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
FFFrameSync
Frame sync structure.
Definition: framesync.h:168
EXT_INFINITY
@ EXT_INFINITY
Extend the frame to infinity.
Definition: framesync.h:75
STATE_BOF
@ STATE_BOF
Definition: framesync.c:71
framesync_advance
static int framesync_advance(FFFrameSync *fs)
Definition: framesync.c:187
ff_inlink_consume_frame
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1442
EXT_STOP
@ EXT_STOP
Completely stop all streams with this one.
Definition: framesync.h:65
FF_FILTER_FORWARD_STATUS_BACK_ALL
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
Definition: filters.h:212
ff_framesync_child_class_iterate
const AVClass * ff_framesync_child_class_iterate(void **iter)
Definition: framesync.c:63
framesync_inject_frame
static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame)
Definition: framesync.c:245
EXT_NULL
@ EXT_NULL
Ignore this stream and continue processing the other ones.
Definition: framesync.h:70
framesync_pts_extrapolate
static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in, int64_t pts)
Definition: framesync.c:238
pts
static int64_t pts
Definition: transcode_aac.c:644
OFFSET
#define OFFSET(member)
Definition: framesync.c:28
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FLAGS
#define FLAGS
Definition: framesync.c:29
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1568
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
filters.h
ctx
AVFormatContext * ctx
Definition: movenc.c:49
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:593
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
EOF_ACTION_PASS
@ EOF_ACTION_PASS
Definition: framesync.h:29
ff_inlink_make_frame_writable
int ff_inlink_make_frame_writable(AVFilterLink *link, AVFrame **rframe)
Make sure a frame is writable.
Definition: avfilter.c:1489
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
ff_framesync_class
const AVClass ff_framesync_class
Definition: framesync.c:54
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
TS_DEFAULT
@ TS_DEFAULT
Sync to frames from secondary input with the nearest, lower or equal timestamp to the frame event one...
Definition: framesync.h:90
NULL
#define NULL
Definition: coverity.c:32
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:200
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:415
framesync_inject_status
static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t pts)
Definition: framesync.c:258
get
static void get(const uint8_t *pixels, int stride, int16_t *block)
Definition: proresenc_anatoliy.c:317
ff_inlink_acknowledge_status
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1389
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AV_CLASS_CATEGORY_FILTER
@ AV_CLASS_CATEGORY_FILTER
Definition: log.h:36
framesync_sync_level_update
static void framesync_sync_level_update(FFFrameSync *fs)
Definition: framesync.c:113
ff_framesync_init_dualinput
int ff_framesync_init_dualinput(FFFrameSync *fs, AVFilterContext *parent)
Initialize a frame sync structure for dualinput.
Definition: framesync.c:378
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
framesync_options
static const AVOption framesync_options[]
Definition: framesync.c:36
STATE_EOF
@ STATE_EOF
Definition: framesync.c:73
STATE_RUN
@ STATE_RUN
Definition: framesync.c:72
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_gcd_q
AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def)
Return the best rational so that a and b are multiple of it.
Definition: rational.c:186
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
framesync_eof
static void framesync_eof(FFFrameSync *fs)
Definition: framesync.c:106
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
ff_framesync_init
int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
Initialize a frame sync structure.
Definition: framesync.c:86
EOF_ACTION_REPEAT
@ EOF_ACTION_REPEAT
Definition: framesync.h:27
status
ov_status_e status
Definition: dnn_backend_openvino.c:121
framesync.h
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:245
avfilter.h
TS_NEAREST
@ TS_NEAREST
Sync to frames from secondary input with the absolute nearest timestamp to the frame event one.
Definition: framesync.h:96
framesync_name
static const char * framesync_name(void *ptr)
Definition: framesync.c:31
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
mem.h
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:261
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ff_outlink_frame_wanted
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
ff_framesync_activate
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
Definition: framesync.c:358
ff_framesync_dualinput_get
int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
Definition: framesync.c:396
ff_framesync_dualinput_get_writable
int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1)
Same as ff_framesync_dualinput_get(), but make sure that f0 is writable.
Definition: framesync.c:416
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:254
ff_framesync_preinit
void ff_framesync_preinit(FFFrameSync *fs)
Pre-initialize a frame sync structure.
Definition: framesync.c:78