mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-02 04:52:09 +00:00
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: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
40b91eaea9
commit
4a7329994a
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user