Commit 108b4de5 authored by Nicolas George's avatar Nicolas George

lavfi: replace link.closed by link.status.

The status field can carry any error code instead of just EOF.
Also only update it through a wrapper function and provide a timestamp.
Update the few filters that used it directly.
parent 39a09e99
...@@ -178,9 +178,20 @@ int avfilter_link_get_channels(AVFilterLink *link) ...@@ -178,9 +178,20 @@ int avfilter_link_get_channels(AVFilterLink *link)
return link->channels; return link->channels;
} }
void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts)
{
ff_avfilter_link_set_out_status(link, status, pts);
}
void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts)
{
link->status = status;
ff_update_link_current_pts(link, pts);
}
void avfilter_link_set_closed(AVFilterLink *link, int closed) void avfilter_link_set_closed(AVFilterLink *link, int closed)
{ {
link->closed = closed; ff_avfilter_link_set_out_status(link, closed ? AVERROR_EOF : 0, AV_NOPTS_VALUE);
} }
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
...@@ -346,8 +357,8 @@ int ff_request_frame(AVFilterLink *link) ...@@ -346,8 +357,8 @@ int ff_request_frame(AVFilterLink *link)
int ret = -1; int ret = -1;
FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1); FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1);
if (link->closed) if (link->status)
return AVERROR_EOF; return link->status;
if (link->srcpad->request_frame) if (link->srcpad->request_frame)
ret = link->srcpad->request_frame(link); ret = link->srcpad->request_frame(link);
else if (link->src->inputs[0]) else if (link->src->inputs[0])
...@@ -358,8 +369,8 @@ int ff_request_frame(AVFilterLink *link) ...@@ -358,8 +369,8 @@ int ff_request_frame(AVFilterLink *link)
ret = ff_filter_frame_framed(link, pbuf); ret = ff_filter_frame_framed(link, pbuf);
} }
if (ret < 0) { if (ret < 0) {
if (ret == AVERROR_EOF) if (ret != AVERROR(EAGAIN) && ret != link->status)
link->closed = 1; ff_avfilter_link_set_in_status(link, ret, AV_NOPTS_VALUE);
} }
return ret; return ret;
} }
...@@ -1005,9 +1016,9 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) ...@@ -1005,9 +1016,9 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame)
AVFilterCommand *cmd= link->dst->command_queue; AVFilterCommand *cmd= link->dst->command_queue;
int64_t pts; int64_t pts;
if (link->closed) { if (link->status) {
av_frame_free(&frame); av_frame_free(&frame);
return AVERROR_EOF; return link->status;
} }
if (!(filter_frame = dst->filter_frame)) if (!(filter_frame = dst->filter_frame))
......
...@@ -490,16 +490,16 @@ struct AVFilterLink { ...@@ -490,16 +490,16 @@ struct AVFilterLink {
int max_samples; int max_samples;
/** /**
* True if the link is closed. * Link status.
* If set, all attempts of start_frame, filter_frame or request_frame * If not zero, all attempts of start_frame, filter_frame or request_frame
* will fail with AVERROR_EOF, and if necessary the reference will be * will fail with the corresponding code, and if necessary the reference
* destroyed. * will be destroyed.
* If request_frame returns AVERROR_EOF, this flag is set on the * If request_frame returns an error, the status is set on the
* corresponding link. * corresponding link.
* It can be set also be set by either the source or the destination * It can be set also be set by either the source or the destination
* filter. * filter.
*/ */
int closed; int status;
/** /**
* Number of channels. * Number of channels.
......
...@@ -134,8 +134,8 @@ int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFr ...@@ -134,8 +134,8 @@ int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFr
/* no picref available, fetch it from the filterchain */ /* no picref available, fetch it from the filterchain */
while (!av_fifo_size(buf->fifo)) { while (!av_fifo_size(buf->fifo)) {
if (inlink->closed) if (inlink->status)
return AVERROR_EOF; return inlink->status;
if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST) if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST)
return AVERROR(EAGAIN); return AVERROR(EAGAIN);
if ((ret = ff_request_frame(inlink)) < 0) if ((ret = ff_request_frame(inlink)) < 0)
......
...@@ -59,7 +59,7 @@ inline static int push_frame(AVFilterContext *ctx) ...@@ -59,7 +59,7 @@ inline static int push_frame(AVFilterContext *ctx)
for (i = 0; i < ctx->nb_inputs; i++) { for (i = 0; i < ctx->nb_inputs; i++) {
struct FFBufQueue *q = &s->queues[i]; struct FFBufQueue *q = &s->queues[i];
if (!q->available && !ctx->inputs[i]->closed) if (!q->available && !ctx->inputs[i]->status)
return 0; return 0;
if (q->available) { if (q->available) {
frame = ff_bufqueue_peek(q, 0); frame = ff_bufqueue_peek(q, 0);
...@@ -190,7 +190,7 @@ static int request_frame(AVFilterLink *outlink) ...@@ -190,7 +190,7 @@ static int request_frame(AVFilterLink *outlink)
int i, ret; int i, ret;
for (i = 0; i < ctx->nb_inputs; i++) { for (i = 0; i < ctx->nb_inputs; i++) {
if (!s->queues[i].available && !ctx->inputs[i]->closed) { if (!s->queues[i].available && !ctx->inputs[i]->status) {
ret = ff_request_frame(ctx->inputs[i]); ret = ff_request_frame(ctx->inputs[i]);
if (ret != AVERROR_EOF) if (ret != AVERROR_EOF)
return ret; return ret;
......
...@@ -226,6 +226,21 @@ int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg, ...@@ -226,6 +226,21 @@ int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
void ff_update_link_current_pts(AVFilterLink *link, int64_t pts); void ff_update_link_current_pts(AVFilterLink *link, int64_t pts);
/**
* Set the status field of a link from the source filter.
* The pts should reflect the timestamp of the status change,
* in link time base and relative to the frames timeline.
* In particular, for AVERROR_EOF, it should reflect the
* end time of the last frame.
*/
void ff_avfilter_link_set_in_status(AVFilterLink *link, int status, int64_t pts);
/**
* Set the status field of a link from the destination filter.
* The pts should probably be left unset (AV_NOPTS_VALUE).
*/
void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts);
void ff_command_queue_pop(AVFilterContext *filter); void ff_command_queue_pop(AVFilterContext *filter);
/* misc trace functions */ /* misc trace functions */
......
...@@ -77,7 +77,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) ...@@ -77,7 +77,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
for (i = 0; i < ctx->nb_outputs; i++) { for (i = 0; i < ctx->nb_outputs; i++) {
AVFrame *buf_out; AVFrame *buf_out;
if (ctx->outputs[i]->closed) if (ctx->outputs[i]->status)
continue; continue;
buf_out = av_frame_clone(frame); buf_out = av_frame_clone(frame);
if (!buf_out) { if (!buf_out) {
......
...@@ -174,7 +174,8 @@ static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame) ...@@ -174,7 +174,8 @@ static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
drop = 0; drop = 0;
if (drop) { if (drop) {
s->eof = inlink->closed = 1; s->eof = 1;
ff_avfilter_link_set_out_status(inlink, AVERROR_EOF, AV_NOPTS_VALUE);
goto drop; goto drop;
} }
} }
...@@ -305,7 +306,8 @@ static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame) ...@@ -305,7 +306,8 @@ static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
} }
if (drop) { if (drop) {
s->eof = inlink->closed = 1; s->eof = 1;
ff_avfilter_link_set_out_status(inlink, AVERROR_EOF, AV_NOPTS_VALUE);
goto drop; goto drop;
} }
} }
......
...@@ -219,7 +219,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) ...@@ -219,7 +219,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
const int idx = s->map[i]; const int idx = s->map[i];
AVFrame *out; AVFrame *out;
if (outlink->closed) if (outlink->status)
continue; continue;
out = ff_get_video_buffer(outlink, outlink->w, outlink->h); out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
......
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