diff options
author | Nicolas George <george@nsup.org> | 2015-09-24 10:07:42 +0200 |
---|---|---|
committer | Nicolas George <george@nsup.org> | 2015-12-22 16:04:30 +0100 |
commit | 108b4de5529a75b06da72b974b26625a8067001f (patch) | |
tree | c38c0fc0600038a55116cbc3246e8158c491df89 | |
parent | 39a09e995d32d16e4f8c87a6ff5273cb9d98146e (diff) | |
download | ffmpeg-108b4de5529a75b06da72b974b26625a8067001f.tar.gz |
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.
-rw-r--r-- | libavfilter/avfilter.c | 25 | ||||
-rw-r--r-- | libavfilter/avfilter.h | 12 | ||||
-rw-r--r-- | libavfilter/buffersink.c | 4 | ||||
-rw-r--r-- | libavfilter/f_interleave.c | 4 | ||||
-rw-r--r-- | libavfilter/internal.h | 15 | ||||
-rw-r--r-- | libavfilter/split.c | 2 | ||||
-rw-r--r-- | libavfilter/trim.c | 6 | ||||
-rw-r--r-- | libavfilter/vf_extractplanes.c | 2 |
8 files changed, 49 insertions, 21 deletions
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 2911b48fd8..cdb47f7f3e 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -178,9 +178,20 @@ int avfilter_link_get_channels(AVFilterLink *link) 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) { - 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, @@ -346,8 +357,8 @@ int ff_request_frame(AVFilterLink *link) int ret = -1; FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1); - if (link->closed) - return AVERROR_EOF; + if (link->status) + return link->status; if (link->srcpad->request_frame) ret = link->srcpad->request_frame(link); else if (link->src->inputs[0]) @@ -358,8 +369,8 @@ int ff_request_frame(AVFilterLink *link) ret = ff_filter_frame_framed(link, pbuf); } if (ret < 0) { - if (ret == AVERROR_EOF) - link->closed = 1; + if (ret != AVERROR(EAGAIN) && ret != link->status) + ff_avfilter_link_set_in_status(link, ret, AV_NOPTS_VALUE); } return ret; } @@ -1005,9 +1016,9 @@ static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) AVFilterCommand *cmd= link->dst->command_queue; int64_t pts; - if (link->closed) { + if (link->status) { av_frame_free(&frame); - return AVERROR_EOF; + return link->status; } if (!(filter_frame = dst->filter_frame)) diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 5022036faf..c52175b4c9 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -490,16 +490,16 @@ struct AVFilterLink { int max_samples; /** - * True if the link is closed. - * If set, all attempts of start_frame, filter_frame or request_frame - * will fail with AVERROR_EOF, and if necessary the reference will be - * destroyed. - * If request_frame returns AVERROR_EOF, this flag is set on the + * Link status. + * If not zero, all attempts of start_frame, filter_frame or request_frame + * will fail with the corresponding code, and if necessary the reference + * will be destroyed. + * If request_frame returns an error, the status is set on the * corresponding link. * It can be set also be set by either the source or the destination * filter. */ - int closed; + int status; /** * Number of channels. diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index 5db86abd8a..7a19df2c3a 100644 --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c @@ -134,8 +134,8 @@ int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFr /* no picref available, fetch it from the filterchain */ while (!av_fifo_size(buf->fifo)) { - if (inlink->closed) - return AVERROR_EOF; + if (inlink->status) + return inlink->status; if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST) return AVERROR(EAGAIN); if ((ret = ff_request_frame(inlink)) < 0) diff --git a/libavfilter/f_interleave.c b/libavfilter/f_interleave.c index e0915b56eb..422f2bfb29 100644 --- a/libavfilter/f_interleave.c +++ b/libavfilter/f_interleave.c @@ -59,7 +59,7 @@ inline static int push_frame(AVFilterContext *ctx) for (i = 0; i < ctx->nb_inputs; i++) { struct FFBufQueue *q = &s->queues[i]; - if (!q->available && !ctx->inputs[i]->closed) + if (!q->available && !ctx->inputs[i]->status) return 0; if (q->available) { frame = ff_bufqueue_peek(q, 0); @@ -190,7 +190,7 @@ static int request_frame(AVFilterLink *outlink) int i, ret; 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]); if (ret != AVERROR_EOF) return ret; diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 6ae1535281..836733ff76 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -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); +/** + * 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); /* misc trace functions */ diff --git a/libavfilter/split.c b/libavfilter/split.c index 7353810677..1e4fb42ad0 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -77,7 +77,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) for (i = 0; i < ctx->nb_outputs; i++) { AVFrame *buf_out; - if (ctx->outputs[i]->closed) + if (ctx->outputs[i]->status) continue; buf_out = av_frame_clone(frame); if (!buf_out) { diff --git a/libavfilter/trim.c b/libavfilter/trim.c index e8d023ec65..b2d9c6f17b 100644 --- a/libavfilter/trim.c +++ b/libavfilter/trim.c @@ -174,7 +174,8 @@ static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame) drop = 0; if (drop) { - s->eof = inlink->closed = 1; + s->eof = 1; + ff_avfilter_link_set_out_status(inlink, AVERROR_EOF, AV_NOPTS_VALUE); goto drop; } } @@ -305,7 +306,8 @@ static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame) } if (drop) { - s->eof = inlink->closed = 1; + s->eof = 1; + ff_avfilter_link_set_out_status(inlink, AVERROR_EOF, AV_NOPTS_VALUE); goto drop; } } diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c index 1cb05e443a..6da3b2db66 100644 --- a/libavfilter/vf_extractplanes.c +++ b/libavfilter/vf_extractplanes.c @@ -219,7 +219,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) const int idx = s->map[i]; AVFrame *out; - if (outlink->closed) + if (outlink->status) continue; out = ff_get_video_buffer(outlink, outlink->w, outlink->h); |