summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas George <george@nsup.org>2015-09-24 10:07:42 +0200
committerNicolas George <george@nsup.org>2015-12-22 16:04:30 +0100
commit108b4de5529a75b06da72b974b26625a8067001f (patch)
treec38c0fc0600038a55116cbc3246e8158c491df89
parent39a09e995d32d16e4f8c87a6ff5273cb9d98146e (diff)
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.c25
-rw-r--r--libavfilter/avfilter.h12
-rw-r--r--libavfilter/buffersink.c4
-rw-r--r--libavfilter/f_interleave.c4
-rw-r--r--libavfilter/internal.h15
-rw-r--r--libavfilter/split.c2
-rw-r--r--libavfilter/trim.c6
-rw-r--r--libavfilter/vf_extractplanes.c2
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);