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:
@@ -207,15 +207,17 @@ void avfilter_link_free(AVFilterLink **link)
|
|||||||
av_freep(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)
|
if (pts == AV_NOPTS_VALUE)
|
||||||
return;
|
return;
|
||||||
link->current_pts = pts;
|
link->current_pts = pts;
|
||||||
link->current_pts_us = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q);
|
link->current_pts_us = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q);
|
||||||
/* TODO use duration */
|
/* TODO use duration */
|
||||||
if (link->graph && link->age_index >= 0)
|
if (link->graph && li->age_index >= 0)
|
||||||
ff_avfilter_graph_update_heap(link->graph, link);
|
ff_avfilter_graph_update_heap(link->graph, li);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
|
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);
|
av_assert0(!li->status_out);
|
||||||
li->status_out = status;
|
li->status_out = status;
|
||||||
if (pts != AV_NOPTS_VALUE)
|
if (pts != AV_NOPTS_VALUE)
|
||||||
update_link_current_pts(link, pts);
|
update_link_current_pts(li, pts);
|
||||||
filter_unblock(link->dst);
|
filter_unblock(link->dst);
|
||||||
ff_filter_set_ready(link->src, 200);
|
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)
|
if (!li->status_in)
|
||||||
return *rstatus = 0;
|
return *rstatus = 0;
|
||||||
*rstatus = li->status_out = li->status_in;
|
*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;
|
*rpts = link->current_pts;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1423,9 +1425,10 @@ int ff_inlink_check_available_samples(AVFilterLink *link, unsigned min)
|
|||||||
return samples >= min || (li->status_in && samples);
|
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);
|
ff_inlink_process_commands(link, frame);
|
||||||
link->dst->is_disabled = !ff_inlink_evaluate_timeline_at_frame(link, frame);
|
link->dst->is_disabled = !ff_inlink_evaluate_timeline_at_frame(link, frame);
|
||||||
link->frame_count_out++;
|
link->frame_count_out++;
|
||||||
@@ -1447,7 +1450,7 @@ int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame = ff_framequeue_take(&li->fifo);
|
frame = ff_framequeue_take(&li->fifo);
|
||||||
consume_update(link, frame);
|
consume_update(li, frame);
|
||||||
*rframe = frame;
|
*rframe = frame;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1468,7 +1471,7 @@ int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max,
|
|||||||
ret = take_samples(li, min, max, &frame);
|
ret = take_samples(li, min, max, &frame);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
consume_update(link, frame);
|
consume_update(li, frame);
|
||||||
*rframe = frame;
|
*rframe = frame;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@@ -628,11 +628,6 @@ struct AVFilterLink {
|
|||||||
*/
|
*/
|
||||||
int64_t current_pts_us;
|
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;
|
* 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
|
* if left to 0/0, will be automatically copied from the first input
|
||||||
|
@@ -64,6 +64,11 @@ typedef struct FilterLinkInternal {
|
|||||||
*/
|
*/
|
||||||
int status_out;
|
int status_out;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index in the age array.
|
||||||
|
*/
|
||||||
|
int age_index;
|
||||||
|
|
||||||
/** stage of the initialization of the link properties (dimensions, etc) */
|
/** stage of the initialization of the link properties (dimensions, etc) */
|
||||||
enum {
|
enum {
|
||||||
AVLINK_UNINIT = 0, ///< not started
|
AVLINK_UNINIT = 0, ///< not started
|
||||||
@@ -91,7 +96,7 @@ typedef struct FFFilterGraph {
|
|||||||
*/
|
*/
|
||||||
AVFilterGraph p;
|
AVFilterGraph p;
|
||||||
|
|
||||||
AVFilterLink **sink_links;
|
struct FilterLinkInternal **sink_links;
|
||||||
int sink_links_count;
|
int sink_links_count;
|
||||||
|
|
||||||
unsigned disable_auto_convert;
|
unsigned disable_auto_convert;
|
||||||
@@ -109,7 +114,8 @@ static inline FFFilterGraph *fffiltergraph(AVFilterGraph *graph)
|
|||||||
/**
|
/**
|
||||||
* Update the position of a link in the age heap.
|
* 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.
|
* 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;
|
unsigned i, j;
|
||||||
int sink_links_count = 0, n = 0;
|
int sink_links_count = 0, n = 0;
|
||||||
AVFilterContext *f;
|
AVFilterContext *f;
|
||||||
AVFilterLink **sinks;
|
FilterLinkInternal **sinks;
|
||||||
|
|
||||||
for (i = 0; i < graph->nb_filters; i++) {
|
for (i = 0; i < graph->nb_filters; i++) {
|
||||||
f = graph->filters[i];
|
f = graph->filters[i];
|
||||||
for (j = 0; j < f->nb_inputs; j++) {
|
for (j = 0; j < f->nb_inputs; j++) {
|
||||||
f->inputs[j]->graph = graph;
|
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++) {
|
for (j = 0; j < f->nb_outputs; j++) {
|
||||||
f->outputs[j]->graph = graph;
|
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_outputs) {
|
||||||
if (f->nb_inputs > INT_MAX - sink_links_count)
|
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];
|
f = graph->filters[i];
|
||||||
if (!f->nb_outputs) {
|
if (!f->nb_outputs) {
|
||||||
for (j = 0; j < f->nb_inputs; j++) {
|
for (j = 0; j < f->nb_inputs; j++) {
|
||||||
sinks[n] = f->inputs[j];
|
sinks[n] = ff_link_internal(f->inputs[j]);
|
||||||
f->inputs[j]->age_index = n++;
|
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,
|
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);
|
av_assert0(index >= 0);
|
||||||
|
|
||||||
while (index) {
|
while (index) {
|
||||||
int parent = (index - 1) >> 1;
|
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;
|
break;
|
||||||
links[index] = links[parent];
|
links[index] = links[parent];
|
||||||
links[index]->age_index = index;
|
links[index]->age_index = index;
|
||||||
index = parent;
|
index = parent;
|
||||||
}
|
}
|
||||||
links[index] = link;
|
links[index] = li;
|
||||||
link->age_index = index;
|
li->age_index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void heap_bubble_down(FFFilterGraph *graph,
|
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);
|
av_assert0(index >= 0);
|
||||||
|
|
||||||
@@ -1431,34 +1432,37 @@ static void heap_bubble_down(FFFilterGraph *graph,
|
|||||||
if (child >= graph->sink_links_count)
|
if (child >= graph->sink_links_count)
|
||||||
break;
|
break;
|
||||||
if (child + 1 < graph->sink_links_count &&
|
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++;
|
child++;
|
||||||
if (link->current_pts_us < links[child]->current_pts_us)
|
if (li->l.current_pts_us < links[child]->l.current_pts_us)
|
||||||
break;
|
break;
|
||||||
links[index] = links[child];
|
links[index] = links[child];
|
||||||
links[index]->age_index = index;
|
links[index]->age_index = index;
|
||||||
index = child;
|
index = child;
|
||||||
}
|
}
|
||||||
links[index] = link;
|
links[index] = li;
|
||||||
link->age_index = index;
|
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);
|
FFFilterGraph *graphi = fffiltergraph(graph);
|
||||||
heap_bubble_up (graphi, link, link->age_index);
|
|
||||||
heap_bubble_down(graphi, link, link->age_index);
|
heap_bubble_up (graphi, li, li->age_index);
|
||||||
|
heap_bubble_down(graphi, li, li->age_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int avfilter_graph_request_oldest(AVFilterGraph *graph)
|
int avfilter_graph_request_oldest(AVFilterGraph *graph)
|
||||||
{
|
{
|
||||||
FFFilterGraph *graphi = fffiltergraph(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;
|
int64_t frame_count;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
while (graphi->sink_links_count) {
|
while (graphi->sink_links_count) {
|
||||||
oldest = graphi->sink_links[0];
|
oldesti = graphi->sink_links[0];
|
||||||
|
oldest = &oldesti->l;
|
||||||
if (oldest->dst->filter->activate) {
|
if (oldest->dst->filter->activate) {
|
||||||
r = av_buffersink_get_frame_flags(oldest->dst, NULL,
|
r = av_buffersink_get_frame_flags(oldest->dst, NULL,
|
||||||
AV_BUFFERSINK_FLAG_PEEK);
|
AV_BUFFERSINK_FLAG_PEEK);
|
||||||
@@ -1473,22 +1477,21 @@ int avfilter_graph_request_oldest(AVFilterGraph *graph)
|
|||||||
oldest->dst->name,
|
oldest->dst->name,
|
||||||
oldest->dstpad->name);
|
oldest->dstpad->name);
|
||||||
/* EOF: remove the link from the heap */
|
/* 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],
|
heap_bubble_down(graphi, graphi->sink_links[graphi->sink_links_count],
|
||||||
oldest->age_index);
|
oldesti->age_index);
|
||||||
oldest->age_index = -1;
|
oldesti->age_index = -1;
|
||||||
}
|
}
|
||||||
if (!graphi->sink_links_count)
|
if (!graphi->sink_links_count)
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
av_assert1(!oldest->dst->filter->activate);
|
av_assert1(!oldest->dst->filter->activate);
|
||||||
av_assert1(oldest->age_index >= 0);
|
av_assert1(oldesti->age_index >= 0);
|
||||||
frame_count = oldest->frame_count_out;
|
frame_count = oldest->frame_count_out;
|
||||||
while (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);
|
r = ff_filter_graph_run_once(graph);
|
||||||
if (r == AVERROR(EAGAIN) &&
|
if (r == AVERROR(EAGAIN) &&
|
||||||
!oldest->frame_wanted_out && !li->frame_blocked_in &&
|
!oldest->frame_wanted_out && !oldesti->frame_blocked_in &&
|
||||||
!li->status_in)
|
!oldesti->status_in)
|
||||||
ff_request_frame(oldest);
|
ff_request_frame(oldest);
|
||||||
else if (r < 0)
|
else if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
Reference in New Issue
Block a user