diff options
author | Nicolas George <george@nsup.org> | 2016-01-03 15:44:42 +0100 |
---|---|---|
committer | Nicolas George <george@nsup.org> | 2016-12-18 10:38:52 +0100 |
commit | 02aa0701ae0dc2def8db640c9e3c06dc1b5de70c (patch) | |
tree | d36bc5207cb7b5a5cbfd1a8ac9c1dbae90255020 /libavfilter/buffersink.c | |
parent | 62b11db0a08cbb8c338e413a0d1707a8c81ae24e (diff) | |
download | ffmpeg-02aa0701ae0dc2def8db640c9e3c06dc1b5de70c.tar.gz |
lavfi: make filter_frame non-recursive.
A lot of changes happen at the same time:
- Add a framequeue fifo to AVFilterLink.
- split AVFilterLink.status into status_in and status_out: requires
changes to the few filters and programs that use it directly
(f_interleave, split, filtfmts).
- Add a field ready to AVFilterContext, marking when the filter is ready
and its activation priority.
- Add flags to mark blocked links.
- Change ff_filter_frame() to enqueue the frame.
- Change all filtering functions to update the ready field and the
blocked flags.
- Update ff_filter_graph_run_once() to use the ready field.
- buffersrc: always push the frame immediately.
Diffstat (limited to 'libavfilter/buffersink.c')
-rw-r--r-- | libavfilter/buffersink.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index 2feb56dee9..7b7b47747d 100644 --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c @@ -31,6 +31,9 @@ #include "libavutil/mathematics.h" #include "libavutil/opt.h" +#define FF_INTERNAL_FIELDS 1 +#include "framequeue.h" + #include "audio.h" #include "avfilter.h" #include "buffersink.h" @@ -129,18 +132,26 @@ int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFr { BufferSinkContext *buf = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; - int ret; + int peek_in_framequeue = 0, ret; + int64_t frame_count; AVFrame *cur_frame; /* no picref available, fetch it from the filterchain */ while (!av_fifo_size(buf->fifo)) { - if (inlink->status) - return inlink->status; - if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST) + /* if peek_in_framequeue is true later, then ff_request_frame() and + the ff_filter_graph_run_once() loop will take a frame from it and + move it to the internal fifo, ending the global loop */ + av_assert0(!peek_in_framequeue); + if (inlink->status_out) + return inlink->status_out; + peek_in_framequeue = ff_framequeue_queued_frames(&inlink->fifo) && + ff_framequeue_queued_samples(&inlink->fifo) >= inlink->min_samples; + if ((flags & AV_BUFFERSINK_FLAG_NO_REQUEST) && !peek_in_framequeue) return AVERROR(EAGAIN); if ((ret = ff_request_frame(inlink)) < 0) return ret; - while (inlink->frame_wanted_out) { + frame_count = inlink->frame_count_out; + while (frame_count == inlink->frame_count_out) { ret = ff_filter_graph_run_once(ctx->graph); if (ret < 0) return ret; |