Commit 4a732999 authored by Andreas Rheinhardt's avatar Andreas Rheinhardt

avfilter/avfilter: Move age_index to FilterLinkInternal

Also make FFFilterGraph.sink_links a FilterLinkInternal**
because sink_links is used to access FilterLinkInternal
fields.
Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@outlook.com>
parent 40b91eae
......@@ -207,15 +207,17 @@ void avfilter_link_free(AVFilterLink **link)
av_freep(link);
}
static void update_link_current_pts(AVFilterLink *link, int64_t pts)
static void update_link_current_pts(FilterLinkInternal *li, int64_t pts)
{
AVFilterLink *const link = &li->l;
if (pts == AV_NOPTS_VALUE)
return;
link->current_pts = pts;
link->current_pts_us = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q);
/* TODO use duration */
if (link->graph && link->age_index >= 0)
ff_avfilter_graph_update_heap(link->graph, link);
if (link->graph && li->age_index >= 0)
ff_avfilter_graph_update_heap(link->graph, li);
}
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
......@@ -265,7 +267,7 @@ static void link_set_out_status(AVFilterLink *link, int status, int64_t pts)
av_assert0(!li->status_out);
li->status_out = status;
if (pts != AV_NOPTS_VALUE)
update_link_current_pts(link, pts);
update_link_current_pts(li, pts);
filter_unblock(link->dst);
ff_filter_set_ready(link->src, 200);
}
......@@ -1392,7 +1394,7 @@ int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts
if (!li->status_in)
return *rstatus = 0;
*rstatus = li->status_out = li->status_in;
update_link_current_pts(link, li->status_in_pts);
update_link_current_pts(li, li->status_in_pts);
*rpts = link->current_pts;
return 1;
}
......@@ -1423,9 +1425,10 @@ int ff_inlink_check_available_samples(AVFilterLink *link, unsigned min)
return samples >= min || (li->status_in && samples);
}
static void consume_update(AVFilterLink *link, const AVFrame *frame)
static void consume_update(FilterLinkInternal *li, const AVFrame *frame)
{
update_link_current_pts(link, frame->pts);
AVFilterLink *const link = &li->l;
update_link_current_pts(li, frame->pts);
ff_inlink_process_commands(link, frame);
link->dst->is_disabled = !ff_inlink_evaluate_timeline_at_frame(link, frame);
link->frame_count_out++;
......@@ -1447,7 +1450,7 @@ int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
}
frame = ff_framequeue_take(&li->fifo);
consume_update(link, frame);
consume_update(li, frame);
*rframe = frame;
return 1;
}
......@@ -1468,7 +1471,7 @@ int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max,
ret = take_samples(li, min, max, &frame);
if (ret < 0)
return ret;
consume_update(link, frame);
consume_update(li, frame);
*rframe = frame;
return 1;
}
......
......@@ -628,11 +628,6 @@ struct AVFilterLink {
*/
int64_t current_pts_us;
/**
* Index in the age array.
*/
int age_index;
/**
* Frame rate of the stream on the link, or 1/0 if unknown or variable;
* if left to 0/0, will be automatically copied from the first input
......
......@@ -64,6 +64,11 @@ typedef struct FilterLinkInternal {
*/
int status_out;
/**
* Index in the age array.
*/
int age_index;
/** stage of the initialization of the link properties (dimensions, etc) */
enum {
AVLINK_UNINIT = 0, ///< not started
......@@ -91,7 +96,7 @@ typedef struct FFFilterGraph {
*/
AVFilterGraph p;
AVFilterLink **sink_links;
struct FilterLinkInternal **sink_links;
int sink_links_count;
unsigned disable_auto_convert;
......@@ -109,7 +114,8 @@ static inline FFFilterGraph *fffiltergraph(AVFilterGraph *graph)
/**
* Update the position of a link in the age heap.
*/
void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link);
void ff_avfilter_graph_update_heap(AVFilterGraph *graph,
struct FilterLinkInternal *li);
/**
* Allocate a new filter context and return it.
......
......@@ -1285,17 +1285,17 @@ static int graph_config_pointers(AVFilterGraph *graph, void *log_ctx)
unsigned i, j;
int sink_links_count = 0, n = 0;
AVFilterContext *f;
AVFilterLink **sinks;
FilterLinkInternal **sinks;
for (i = 0; i < graph->nb_filters; i++) {
f = graph->filters[i];
for (j = 0; j < f->nb_inputs; j++) {
f->inputs[j]->graph = graph;
f->inputs[j]->age_index = -1;
ff_link_internal(f->inputs[j])->age_index = -1;
}
for (j = 0; j < f->nb_outputs; j++) {
f->outputs[j]->graph = graph;
f->outputs[j]->age_index= -1;
ff_link_internal(f->outputs[j])->age_index = -1;
}
if (!f->nb_outputs) {
if (f->nb_inputs > INT_MAX - sink_links_count)
......@@ -1310,8 +1310,9 @@ static int graph_config_pointers(AVFilterGraph *graph, void *log_ctx)
f = graph->filters[i];
if (!f->nb_outputs) {
for (j = 0; j < f->nb_inputs; j++) {
sinks[n] = f->inputs[j];
f->inputs[j]->age_index = n++;
sinks[n] = ff_link_internal(f->inputs[j]);
sinks[n]->age_index = n;
n++;
}
}
}
......@@ -1401,28 +1402,28 @@ int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const
}
static void heap_bubble_up(FFFilterGraph *graph,
AVFilterLink *link, int index)
FilterLinkInternal *li, int index)
{
AVFilterLink **links = graph->sink_links;
FilterLinkInternal **links = graph->sink_links;
av_assert0(index >= 0);
while (index) {
int parent = (index - 1) >> 1;
if (links[parent]->current_pts_us >= link->current_pts_us)
if (links[parent]->l.current_pts_us >= li->l.current_pts_us)
break;
links[index] = links[parent];
links[index]->age_index = index;
index = parent;
}
links[index] = link;
link->age_index = index;
links[index] = li;
li->age_index = index;
}
static void heap_bubble_down(FFFilterGraph *graph,
AVFilterLink *link, int index)
FilterLinkInternal *li, int index)
{
AVFilterLink **links = graph->sink_links;
FilterLinkInternal **links = graph->sink_links;
av_assert0(index >= 0);
......@@ -1431,34 +1432,37 @@ static void heap_bubble_down(FFFilterGraph *graph,
if (child >= graph->sink_links_count)
break;
if (child + 1 < graph->sink_links_count &&
links[child + 1]->current_pts_us < links[child]->current_pts_us)
links[child + 1]->l.current_pts_us < links[child]->l.current_pts_us)
child++;
if (link->current_pts_us < links[child]->current_pts_us)
if (li->l.current_pts_us < links[child]->l.current_pts_us)
break;
links[index] = links[child];
links[index]->age_index = index;
index = child;
}
links[index] = link;
link->age_index = index;
links[index] = li;
li->age_index = index;
}
void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
void ff_avfilter_graph_update_heap(AVFilterGraph *graph, FilterLinkInternal *li)
{
FFFilterGraph *graphi = fffiltergraph(graph);
heap_bubble_up (graphi, link, link->age_index);
heap_bubble_down(graphi, link, link->age_index);
FFFilterGraph *graphi = fffiltergraph(graph);
heap_bubble_up (graphi, li, li->age_index);
heap_bubble_down(graphi, li, li->age_index);
}
int avfilter_graph_request_oldest(AVFilterGraph *graph)
{
FFFilterGraph *graphi = fffiltergraph(graph);
AVFilterLink *oldest = graphi->sink_links[0];
FilterLinkInternal *oldesti = graphi->sink_links[0];
AVFilterLink *oldest = &oldesti->l;
int64_t frame_count;
int r;
while (graphi->sink_links_count) {
oldest = graphi->sink_links[0];
oldesti = graphi->sink_links[0];
oldest = &oldesti->l;
if (oldest->dst->filter->activate) {
r = av_buffersink_get_frame_flags(oldest->dst, NULL,
AV_BUFFERSINK_FLAG_PEEK);
......@@ -1473,22 +1477,21 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph)
oldest->dst->name,
oldest->dstpad->name);
/* EOF: remove the link from the heap */
if (oldest->age_index < --graphi->sink_links_count)
if (oldesti->age_index < --graphi->sink_links_count)
heap_bubble_down(graphi, graphi->sink_links[graphi->sink_links_count],
oldest->age_index);
oldest->age_index = -1;
oldesti->age_index);
oldesti->age_index = -1;
}
if (!graphi->sink_links_count)
return AVERROR_EOF;
av_assert1(!oldest->dst->filter->activate);
av_assert1(oldest->age_index >= 0);
av_assert1(oldesti->age_index >= 0);
frame_count = oldest->frame_count_out;
while (frame_count == oldest->frame_count_out) {
FilterLinkInternal * const li = ff_link_internal(oldest);
r = ff_filter_graph_run_once(graph);
if (r == AVERROR(EAGAIN) &&
!oldest->frame_wanted_out && !li->frame_blocked_in &&
!li->status_in)
!oldest->frame_wanted_out && !oldesti->frame_blocked_in &&
!oldesti->status_in)
ff_request_frame(oldest);
else if (r < 0)
return r;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment