summaryrefslogtreecommitdiff
path: root/libavfilter/buffersink.c
diff options
context:
space:
mode:
authorNicolas George <george@nsup.org>2016-01-03 15:44:42 +0100
committerNicolas George <george@nsup.org>2016-12-18 10:38:52 +0100
commit02aa0701ae0dc2def8db640c9e3c06dc1b5de70c (patch)
treed36bc5207cb7b5a5cbfd1a8ac9c1dbae90255020 /libavfilter/buffersink.c
parent62b11db0a08cbb8c338e413a0d1707a8c81ae24e (diff)
downloadffmpeg-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.c21
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;