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.
Showing the changes to libavfilter/avfiltergraph.c (1 of 10 files). Show all
Unified · Split
| @@ -32,6 +32,9 @@ · 31 unmodified lines | |||
| 32 | #include "libavutil/opt.h" | 32 | #include "libavutil/opt.h" |
| 33 | #include "libavutil/pixdesc.h" | 33 | #include "libavutil/pixdesc.h" |
| 34 | 34 | ||
| 35 | #define FF_INTERNAL_FIELDS 1 | ||
| 36 | #include "framequeue.h" | ||
| 37 | |||
| 35 | #include "avfilter.h" | 38 | #include "avfilter.h" |
| 36 | #include "formats.h" | 39 | #include "formats.h" |
| 37 | #include "internal.h" | 40 | #include "internal.h" |
| @@ -87,6 +90,7 @@ AVFilterGraph *avfilter_graph_alloc(void) · 49 unmodified lines | |||
| 87 | 90 | ||
| 88 | ret->av_class = &filtergraph_class; | 91 | ret->av_class = &filtergraph_class; |
| 89 | av_opt_set_defaults(ret); | 92 | av_opt_set_defaults(ret); |
| 93 | ff_framequeue_global_init(&ret->internal->frame_queues); | ||
| 90 | 94 | ||
| 91 | return ret; | 95 | return ret; |
| 92 | } | 96 | } |
| @@ -1377,10 +1381,10 @@ void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link) · 1284 unmodified lines | |||
| 1377 | heap_bubble_down(graph, link, link->age_index); | 1381 | heap_bubble_down(graph, link, link->age_index); |
| 1378 | } | 1382 | } |
| 1379 | 1383 | ||
| 1380 | |||
| 1381 | int avfilter_graph_request_oldest(AVFilterGraph *graph) | 1384 | int avfilter_graph_request_oldest(AVFilterGraph *graph) |
| 1382 | { | 1385 | { |
| 1383 | AVFilterLink *oldest = graph->sink_links[0]; | 1386 | AVFilterLink *oldest = graph->sink_links[0]; |
| 1387 | int64_t frame_count; | ||
| 1384 | int r; | 1388 | int r; |
| 1385 | 1389 | ||
| 1386 | while (graph->sink_links_count) { | 1390 | while (graph->sink_links_count) { |
| @@ -1400,7 +1404,8 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph) · 13 unmodified lines | |||
| 1400 | if (!graph->sink_links_count) | 1404 | if (!graph->sink_links_count) |
| 1401 | return AVERROR_EOF; | 1405 | return AVERROR_EOF; |
| 1402 | av_assert1(oldest->age_index >= 0); | 1406 | av_assert1(oldest->age_index >= 0); |
| 1403 | while (oldest->frame_wanted_out) { | 1407 | frame_count = oldest->frame_count_out; |
| 1408 | while (frame_count == oldest->frame_count_out) { | ||
| 1404 | r = ff_filter_graph_run_once(graph); | 1409 | r = ff_filter_graph_run_once(graph); |
| 1405 | if (r < 0) | 1410 | if (r < 0) |
| 1406 | return r; | 1411 | return r; |
| @@ -1408,41 +1413,17 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph) · 1 unmodified line | |||
| 1408 | return 0; | 1413 | return 0; |
| 1409 | } | 1414 | } |
| 1410 | 1415 | ||
| 1411 | static AVFilterLink *graph_run_once_find_filter(AVFilterGraph *graph) | ||
| 1412 | { | ||
| 1413 | unsigned i, j; | ||
| 1414 | AVFilterContext *f; | ||
| 1415 | |||
| 1416 | /* TODO: replace scanning the graph with a priority list */ | ||
| 1417 | for (i = 0; i < graph->nb_filters; i++) { | ||
| 1418 | f = graph->filters[i]; | ||
| 1419 | for (j = 0; j < f->nb_outputs; j++) | ||
| 1420 | if (f->outputs[j]->frame_wanted_in) | ||
| 1421 | return f->outputs[j]; | ||
| 1422 | } | ||
| 1423 | for (i = 0; i < graph->nb_filters; i++) { | ||
| 1424 | f = graph->filters[i]; | ||
| 1425 | for (j = 0; j < f->nb_outputs; j++) | ||
| 1426 | if (f->outputs[j]->frame_wanted_out) | ||
| 1427 | return f->outputs[j]; | ||
| 1428 | } | ||
| 1429 | return NULL; | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | int ff_filter_graph_run_once(AVFilterGraph *graph) | 1416 | int ff_filter_graph_run_once(AVFilterGraph *graph) |
| 1433 | { | 1417 | { |
| 1434 | AVFilterLink *link; | 1418 | AVFilterContext *filter; |
| 1435 | int ret; | 1419 | unsigned i; |
| 1436 | 1420 | ||
| 1437 | link = graph_run_once_find_filter(graph); | 1421 | av_assert0(graph->nb_filters); |
| 1438 | if (!link) { | 1422 | filter = graph->filters[0]; |
| 1439 | av_log(NULL, AV_LOG_WARNING, "Useless run of a filter graph\n"); | 1423 | for (i = 1; i < graph->nb_filters; i++) |
| 1424 | if (graph->filters[i]->ready > filter->ready) | ||
| 1425 | filter = graph->filters[i]; | ||
| 1426 | if (!filter->ready) | ||
| 1440 | return AVERROR(EAGAIN); | 1427 | return AVERROR(EAGAIN); |
| 1441 | } | 1428 | return ff_filter_activate(filter); |
| 1442 | ret = ff_request_frame_to_filter(link); | ||
| 1443 | if (ret == AVERROR_EOF) | ||
| 1444 | /* local EOF will be forwarded through request_frame() / | ||
| 1445 | set_status() until it reaches the sink */ | ||
| 1446 | ret = 0; | ||
| 1447 | return ret < 0 ? ret : 1; | ||
| 1448 | } | 1429 | } |