[FFmpeg-devel] [PATCH 4/5] lavfi: replace link.closed by link.status.

Nicolas George george at nsup.org
Sun Nov 29 17:21:51 CET 2015


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.

Signed-off-by: Nicolas George <george at nsup.org>
---
 libavfilter/avfilter.c         | 25 ++++++++++++++++++-------
 libavfilter/avfilter.h         | 12 ++++++------
 libavfilter/buffersink.c       |  4 ++--
 libavfilter/f_interleave.c     |  4 ++--
 libavfilter/internal.h         | 12 ++++++++++++
 libavfilter/split.c            |  2 +-
 libavfilter/trim.c             |  6 ++++--
 libavfilter/vf_extractplanes.c |  2 +-
 8 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 06a8239..9c7b462 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -177,9 +177,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,
@@ -345,8 +356,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])
@@ -357,8 +368,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;
 }
@@ -1004,9 +1015,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 58a0cbd..f3a0f2d 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 5db86abd..7a19df2 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 e0915b5..422f2bf 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 1cc6bf3..e55ae9d 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -225,6 +225,18 @@ 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.
+ */
+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.
+ */
+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 7353810..1e4fb42 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 e8d023e..b2d9c6f 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 1cb05e4..6da3b2d 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);
-- 
2.6.2



More information about the ffmpeg-devel mailing list