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/avfiltergraph.c | |
parent | 62b11db0a08cbb8c338e413a0d1707a8c81ae24e (diff) |
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/avfiltergraph.c')
-rw-r--r-- | libavfilter/avfiltergraph.c | 53 |
1 files changed, 17 insertions, 36 deletions
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 3af698d4be..6b5a6f34ec 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -32,6 +32,9 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" +#define FF_INTERNAL_FIELDS 1 +#include "framequeue.h" + #include "avfilter.h" #include "formats.h" #include "internal.h" @@ -87,6 +90,7 @@ AVFilterGraph *avfilter_graph_alloc(void) ret->av_class = &filtergraph_class; av_opt_set_defaults(ret); + ff_framequeue_global_init(&ret->internal->frame_queues); return ret; } @@ -1377,10 +1381,10 @@ void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link) heap_bubble_down(graph, link, link->age_index); } - int avfilter_graph_request_oldest(AVFilterGraph *graph) { AVFilterLink *oldest = graph->sink_links[0]; + int64_t frame_count; int r; while (graph->sink_links_count) { @@ -1400,7 +1404,8 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph) if (!graph->sink_links_count) return AVERROR_EOF; av_assert1(oldest->age_index >= 0); - while (oldest->frame_wanted_out) { + frame_count = oldest->frame_count_out; + while (frame_count == oldest->frame_count_out) { r = ff_filter_graph_run_once(graph); if (r < 0) return r; @@ -1408,41 +1413,17 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph) return 0; } -static AVFilterLink *graph_run_once_find_filter(AVFilterGraph *graph) -{ - unsigned i, j; - AVFilterContext *f; - - /* TODO: replace scanning the graph with a priority list */ - for (i = 0; i < graph->nb_filters; i++) { - f = graph->filters[i]; - for (j = 0; j < f->nb_outputs; j++) - if (f->outputs[j]->frame_wanted_in) - return f->outputs[j]; - } - for (i = 0; i < graph->nb_filters; i++) { - f = graph->filters[i]; - for (j = 0; j < f->nb_outputs; j++) - if (f->outputs[j]->frame_wanted_out) - return f->outputs[j]; - } - return NULL; -} - int ff_filter_graph_run_once(AVFilterGraph *graph) { - AVFilterLink *link; - int ret; - - link = graph_run_once_find_filter(graph); - if (!link) { - av_log(NULL, AV_LOG_WARNING, "Useless run of a filter graph\n"); + AVFilterContext *filter; + unsigned i; + + av_assert0(graph->nb_filters); + filter = graph->filters[0]; + for (i = 1; i < graph->nb_filters; i++) + if (graph->filters[i]->ready > filter->ready) + filter = graph->filters[i]; + if (!filter->ready) return AVERROR(EAGAIN); - } - ret = ff_request_frame_to_filter(link); - if (ret == AVERROR_EOF) - /* local EOF will be forwarded through request_frame() / - set_status() until it reaches the sink */ - ret = 0; - return ret < 0 ? ret : 1; + return ff_filter_activate(filter); } |