diff options
author | Nicolas George <george@nsup.org> | 2015-09-30 16:11:57 +0200 |
---|---|---|
committer | Nicolas George <george@nsup.org> | 2015-12-22 16:04:30 +0100 |
commit | 16557887127256fb1e491702375e7ea7b3940924 (patch) | |
tree | e6218ca8a613ccf7c54a95047d618de3d7e66724 /libavfilter/avfiltergraph.c | |
parent | 108b4de5529a75b06da72b974b26625a8067001f (diff) | |
download | ffmpeg-16557887127256fb1e491702375e7ea7b3940924.tar.gz |
lavfi: make request_frame() non-recursive.
Instead of calling the input filter request_frame() method,
ff_request_frame() now marks the link and returns immediately.
buffersink is changed to activate the marked filters until
a frame is obtained.
Diffstat (limited to 'libavfilter/avfiltergraph.c')
-rw-r--r-- | libavfilter/avfiltergraph.c | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index ec2245f15b..9f50b4120d 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -1367,11 +1367,14 @@ void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link) int avfilter_graph_request_oldest(AVFilterGraph *graph) { + AVFilterLink *oldest = graph->sink_links[0]; + int r; + while (graph->sink_links_count) { - AVFilterLink *oldest = graph->sink_links[0]; - int r = ff_request_frame(oldest); + oldest = graph->sink_links[0]; + r = ff_request_frame(oldest); if (r != AVERROR_EOF) - return r; + break; av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n", oldest->dst ? oldest->dst->name : "unknown", oldest->dstpad ? oldest->dstpad->name : "unknown"); @@ -1381,5 +1384,52 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph) oldest->age_index); oldest->age_index = -1; } - return AVERROR_EOF; + if (!graph->sink_links_count) + return AVERROR_EOF; + av_assert1(oldest->age_index >= 0); + while (oldest->frame_wanted_out) { + r = ff_filter_graph_run_once(graph); + if (r < 0) + return r; + } + 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"); + 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; } |