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 | 32 | #include "libavutil/opt.h" |
| 33 | 33 | #include "libavutil/pixdesc.h" |
| 34 | 34 | |
| 35 | +#define FF_INTERNAL_FIELDS 1 | |
| 36 | +#include "framequeue.h" | |
| 37 | + | |
| 35 | 38 | #include "avfilter.h" |
| 36 | 39 | #include "formats.h" |
| 37 | 40 | #include "internal.h" |
| @@ -87,6 +90,7 @@ AVFilterGraph *avfilter_graph_alloc(void) · 49 unmodified lines | ||
| 87 | 90 | |
| 88 | 91 | ret->av_class = &filtergraph_class; |
| 89 | 92 | av_opt_set_defaults(ret); |
| 93 | + ff_framequeue_global_init(&ret->internal->frame_queues); | |
| 90 | 94 | |
| 91 | 95 | return ret; |
| 92 | 96 | } |
| @@ -1377,10 +1381,10 @@ void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link) · 1284 unmodified lines | ||
| 1377 | 1381 | heap_bubble_down(graph, link, link->age_index); |
| 1378 | 1382 | } |
| 1379 | 1383 | |
| 1380 | − | |
| 1381 | 1384 | int avfilter_graph_request_oldest(AVFilterGraph *graph) |
| 1382 | 1385 | { |
| 1383 | 1386 | AVFilterLink *oldest = graph->sink_links[0]; |
| 1387 | + int64_t frame_count; | |
| 1384 | 1388 | int r; |
| 1385 | 1389 | |
| 1386 | 1390 | while (graph->sink_links_count) { |
| @@ -1400,7 +1404,8 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph) · 13 unmodified lines | ||
| 1400 | 1404 | if (!graph->sink_links_count) |
| 1401 | 1405 | return AVERROR_EOF; |
| 1402 | 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 | 1409 | r = ff_filter_graph_run_once(graph); |
| 1405 | 1410 | if (r < 0) |
| 1406 | 1411 | return r; |
| @@ -1408,41 +1413,17 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph) · 1 unmodified line | ||
| 1408 | 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 | 1416 | int ff_filter_graph_run_once(AVFilterGraph *graph) |
| 1433 | 1417 | { |
| 1434 | − AVFilterLink *link; | |
| 1435 | − int ret; | |
| 1436 | − | |
| 1437 | − link = graph_run_once_find_filter(graph); | |
| 1438 | − if (!link) { | |
| 1439 | − av_log(NULL, AV_LOG_WARNING, "Useless run of a filter graph\n"); | |
| 1418 | + AVFilterContext *filter; | |
| 1419 | + unsigned i; | |
| 1420 | + | |
| 1421 | + av_assert0(graph->nb_filters); | |
| 1422 | + filter = graph->filters[0]; | |
| 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 | 1427 | return AVERROR(EAGAIN); |
| 1441 | − } | |
| 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; | |
| 1428 | + return ff_filter_activate(filter); | |
| 1448 | 1429 | } |