summaryrefslogtreecommitdiff
path: root/libavfilter
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2012-04-27 06:56:56 +0200
committerAnton Khirnov <anton@khirnov.net>2012-05-09 08:59:37 +0200
commitac71230902af1a8ebc7abf85143139ffb49838eb (patch)
tree1b3b3b4c484a35e0be341eca4cafe80d8befd930 /libavfilter
parentab165047a6142ca0c8c333c36f4ebb96477622d7 (diff)
lavfi: add video buffer sink, and use it in avtools
Also add the public interface libavfilter/buffersink.h. Based on a commit by Stefano Sabatini.
Diffstat (limited to 'libavfilter')
-rw-r--r--libavfilter/Makefile2
-rw-r--r--libavfilter/allfilters.c4
-rw-r--r--libavfilter/buffersink.c114
-rw-r--r--libavfilter/buffersink.h43
4 files changed, 163 insertions, 0 deletions
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index ae858397df..e786b6d2fe 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -4,6 +4,7 @@ FFLIBS-$(CONFIG_MOVIE_FILTER) += avformat avcodec
HEADERS = avfilter.h \
avfiltergraph.h \
+ buffersink.h \
buffersrc.h \
version.h \
vsrc_buffer.h \
@@ -11,6 +12,7 @@ HEADERS = avfilter.h \
OBJS = allfilters.o \
avfilter.o \
avfiltergraph.o \
+ buffersink.o \
defaults.o \
drawutils.o \
formats.o \
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 198e152cb0..f887002b66 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -95,6 +95,10 @@ void avfilter_register_all(void)
avfilter_register(&avfilter_vsrc_buffer);
}
{
+ extern AVFilter avfilter_vsink_buffer;
+ avfilter_register(&avfilter_vsink_buffer);
+ }
+ {
extern AVFilter avfilter_vf_scale;
avfilter_register(&avfilter_vf_scale);
}
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
new file mode 100644
index 0000000000..e4cbe3be42
--- /dev/null
+++ b/libavfilter/buffersink.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * buffer sink
+ */
+
+#include "libavutil/fifo.h"
+
+#include "avfilter.h"
+#include "buffersink.h"
+
+typedef struct {
+ AVFifoBuffer *fifo; ///< FIFO buffer of video frame references
+} BufferSinkContext;
+
+#define FIFO_INIT_SIZE 8
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ BufferSinkContext *sink = ctx->priv;
+
+ while (sink->fifo && av_fifo_size(sink->fifo)) {
+ AVFilterBufferRef *buf;
+ av_fifo_generic_read(sink->fifo, &buf, sizeof(buf), NULL);
+ avfilter_unref_buffer(buf);
+ }
+ av_fifo_free(sink->fifo);
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+ BufferSinkContext *sink = ctx->priv;
+
+ if (!(sink->fifo = av_fifo_alloc(FIFO_INIT_SIZE*sizeof(AVFilterBufferRef*)))) {
+ av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo\n");
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
+static void end_frame(AVFilterLink *link)
+{
+ AVFilterContext *ctx = link->dst;
+ BufferSinkContext *sink = ctx->priv;
+
+ if (av_fifo_space(sink->fifo) < sizeof(AVFilterBufferRef *) &&
+ (av_fifo_realloc2(sink->fifo, av_fifo_size(sink->fifo) * 2) < 0)) {
+ av_log(ctx, AV_LOG_ERROR, "Error reallocating the FIFO.\n");
+ return;
+ }
+
+ av_fifo_generic_write(sink->fifo, &link->cur_buf, sizeof(link->cur_buf), NULL);
+ link->cur_buf = NULL;
+}
+
+int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
+{
+ BufferSinkContext *sink = ctx->priv;
+ AVFilterLink *link = ctx->inputs[0];
+ int ret;
+
+ if (!buf) {
+ if (av_fifo_size(sink->fifo))
+ return av_fifo_size(sink->fifo)/sizeof(*buf);
+ else
+ return avfilter_poll_frame(ctx->inputs[0]);
+ }
+
+ if (!av_fifo_size(sink->fifo) &&
+ (ret = avfilter_request_frame(link)) < 0)
+ return ret;
+
+ if (!av_fifo_size(sink->fifo))
+ return AVERROR(EINVAL);
+
+ av_fifo_generic_read(sink->fifo, buf, sizeof(*buf), NULL);
+
+ return 0;
+}
+
+AVFilter avfilter_vsink_buffer = {
+ .name = "buffersink",
+ .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
+ .priv_size = sizeof(BufferSinkContext),
+ .init = init,
+ .uninit = uninit,
+
+ .inputs = (AVFilterPad[]) {{ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .end_frame = end_frame,
+ .min_perms = AV_PERM_READ, },
+ { .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = NULL }},
+};
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
new file mode 100644
index 0000000000..e579b9ad03
--- /dev/null
+++ b/libavfilter/buffersink.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFILTER_BUFFERSINK_H
+#define AVFILTER_BUFFERSINK_H
+
+/**
+ * @file
+ * memory buffer sink API
+ */
+
+#include "avfilter.h"
+
+/**
+ * Get a buffer with filtered data from sink and put it in buf.
+ *
+ * @param sink pointer to a context of a buffersink AVFilter.
+ * @param buf pointer to the buffer will be written here if buf is non-NULL. buf
+ * must be freed by the caller using avfilter_unref_buffer().
+ * Buf may also be NULL to query whether a buffer is ready to be
+ * output.
+ *
+ * @return >= 0 in case of success, a negative AVERROR code in case of
+ * failure.
+ */
+int av_buffersink_read(AVFilterContext *sink, AVFilterBufferRef **buf);
+
+#endif /* AVFILTER_BUFFERSINK_H */