vsrc_buffer: allow using a NULL buffer to signal EOF.
authorAnton Khirnov <anton@khirnov.net>
Sun, 1 Apr 2012 16:53:58 +0000 (18:53 +0200)
committerAnton Khirnov <anton@khirnov.net>
Sat, 14 Apr 2012 07:25:46 +0000 (09:25 +0200)
libavfilter/buffersrc.h
libavfilter/vsrc_buffer.c

index bd82c06..918a54f 100644 (file)
@@ -32,6 +32,7 @@
  *
  * @param buf buffer containing frame data to be passed down the filtergraph.
  * This function will take ownership of buf, the user must not free it.
+ * A NULL buf signals EOF -- i.e. no more frames will be sent to this filter.
  */
 int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf);
 
index dfe5bf5..46a18df 100644 (file)
@@ -35,6 +35,7 @@ typedef struct {
     enum PixelFormat  pix_fmt;
     AVRational        time_base;     ///< time_base to set in the output link
     AVRational        pixel_aspect;
+    int eof;
 } BufferSourceContext;
 
 #define CHECK_PARAM_CHANGE(s, c, width, height, format)\
@@ -50,6 +51,12 @@ int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame,
     AVFilterBufferRef *buf;
     int ret;
 
+    if (!buf) {
+        c->eof = 1;
+        return 0;
+    } else if (c->eof)
+        return AVERROR(EINVAL);
+
     if (!av_fifo_space(c->fifo) &&
         (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
                                          sizeof(buf))) < 0)
@@ -79,6 +86,12 @@ int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
     BufferSourceContext *c = s->priv;
     int ret;
 
+    if (!buf) {
+        c->eof = 1;
+        return 0;
+    } else if (c->eof)
+        return AVERROR(EINVAL);
+
     if (!av_fifo_space(c->fifo) &&
         (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
                                          sizeof(buf))) < 0)
@@ -160,6 +173,8 @@ static int request_frame(AVFilterLink *link)
     AVFilterBufferRef *buf;
 
     if (!av_fifo_size(c->fifo)) {
+        if (c->eof)
+            return AVERROR_EOF;
         av_log(link->src, AV_LOG_ERROR,
                "request_frame() called with no available frame!\n");
         return AVERROR(EINVAL);
@@ -177,7 +192,10 @@ static int request_frame(AVFilterLink *link)
 static int poll_frame(AVFilterLink *link)
 {
     BufferSourceContext *c = link->src->priv;
-    return !!av_fifo_size(c->fifo);
+    int size = av_fifo_size(c->fifo);
+    if (!size && c->eof)
+        return AVERROR_EOF;
+    return size/sizeof(AVFilterBufferRef*);
 }
 
 AVFilter avfilter_vsrc_buffer = {