#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
+#define FF_INTERNAL_FIELDS 1
+#include "framequeue.h"
+
#include "avfilter.h"
+#include "buffersink.h"
#include "formats.h"
#include "internal.h"
#include "thread.h"
ret->av_class = &filtergraph_class;
av_opt_set_defaults(ret);
+ ff_framequeue_global_init(&ret->internal->frame_queues);
return ret;
}
return AVERROR(EINVAL);
}
- snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
+ snprintf(inst_name, sizeof(inst_name), "auto_scaler_%d",
scaler_count++);
if ((ret = avfilter_graph_create_filter(&convert, filter,
return AVERROR(EINVAL);
}
- snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
+ snprintf(inst_name, sizeof(inst_name), "auto_resampler_%d",
resampler_count++);
scale_args[0] = '\0';
if (graph->aresample_swr_opts)
for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
+ av_assert0(diff < INT_MAX); // This would lead to the use of uninitialized best_diff but is only possible with invalid sample rates
+
if (diff < best_diff) {
best_diff = diff;
best_idx = j;
avfilter_get_by_name("fifo") :
avfilter_get_by_name("afifo");
- snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++);
+ snprintf(name, sizeof(name), "auto_fifo_%d", fifo_count++);
ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL,
NULL, graph);
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) {
oldest = graph->sink_links[0];
+ if (oldest->dst->filter->activate) {
+ /* For now, buffersink is the only filter implementing activate. */
+ return av_buffersink_get_frame_flags(oldest->dst, NULL,
+ AV_BUFFERSINK_FLAG_PEEK);
+ }
r = ff_request_frame(oldest);
if (r != AVERROR_EOF)
break;
}
if (!graph->sink_links_count)
return AVERROR_EOF;
+ av_assert1(!oldest->dst->filter->activate);
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)
+ if (r == AVERROR(EAGAIN) &&
+ !oldest->frame_wanted_out && !oldest->frame_blocked_in &&
+ !oldest->status_in)
+ ff_request_frame(oldest);
+ else 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");
+ 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);
}