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.
This commit is contained in:
parent
39a09e995d
commit
108b4de552
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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
|
|||||||
|
|
||||||
/* 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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user