From 44f669e7bc4f7f064e3f81d3596637a0e043b501 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sat, 11 Jun 2011 18:43:11 +0200 Subject: lavfi: add vsink_buffer, and use it in ff* tools Also add the public interface libavfilter/vsink_buffer.h. --- libavfilter/Makefile | 3 +- libavfilter/allfilters.c | 1 + libavfilter/avfilter.h | 2 +- libavfilter/vsink_buffer.c | 111 +++++++++++++++++++++++++++++++++++++++++++++ libavfilter/vsink_buffer.h | 47 +++++++++++++++++++ 5 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 libavfilter/vsink_buffer.c create mode 100644 libavfilter/vsink_buffer.h (limited to 'libavfilter') diff --git a/libavfilter/Makefile b/libavfilter/Makefile index c594573798..84a7ac3394 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -6,7 +6,7 @@ FFLIBS-$(CONFIG_MOVIE_FILTER) += avformat avcodec FFLIBS-$(CONFIG_SCALE_FILTER) += swscale FFLIBS-$(CONFIG_MP_FILTER) += avcodec -HEADERS = avcodec.h avfilter.h avfiltergraph.h vsrc_buffer.h +HEADERS = avcodec.h avfilter.h avfiltergraph.h vsink_buffer.hvsrc_buffer.h OBJS = allfilters.o \ avfilter.o \ @@ -69,6 +69,7 @@ OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o OBJS-$(CONFIG_MOVIE_FILTER) += vsrc_movie.o OBJS-$(CONFIG_NULLSRC_FILTER) += vsrc_nullsrc.o +OBJS-$(CONFIG_BUFFERSINK_FILTER) += vsink_buffer.o OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 2983f6bd8c..42047ecbe8 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -85,5 +85,6 @@ void avfilter_register_all(void) REGISTER_FILTER (MOVIE, movie, vsrc); REGISTER_FILTER (NULLSRC, nullsrc, vsrc); + REGISTER_FILTER (BUFFER, buffersink, vsink); REGISTER_FILTER (NULLSINK, nullsink, vsink); } diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index bcfc4c6df9..5ac70399ac 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -26,7 +26,7 @@ #include "libavutil/samplefmt.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 20 +#define LIBAVFILTER_VERSION_MINOR 21 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vsink_buffer.c b/libavfilter/vsink_buffer.c new file mode 100644 index 0000000000..c0824606a9 --- /dev/null +++ b/libavfilter/vsink_buffer.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Stefano Sabatini + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * buffer video sink + */ + +#include "avfilter.h" +#include "vsink_buffer.h" + +typedef struct { + AVFilterBufferRef *picref; ///< cached picref + enum PixelFormat *pix_fmts; ///< accepted pixel formats, must be terminated with -1 +} BufferSinkContext; + +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) +{ + BufferSinkContext *buf = ctx->priv; + + if (!opaque) { + av_log(ctx, AV_LOG_ERROR, "No opaque field provided, which is required.\n"); + return AVERROR(EINVAL); + } + + buf->pix_fmts = opaque; + return 0; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + BufferSinkContext *buf = ctx->priv; + + if (buf->picref) + avfilter_unref_buffer(buf->picref); + buf->picref = NULL; +} + +static void end_frame(AVFilterLink *inlink) +{ + BufferSinkContext *buf = inlink->dst->priv; + + if (buf->picref) /* drop the last cached frame */ + avfilter_unref_buffer(buf->picref); + buf->picref = inlink->cur_buf; +} + +static int query_formats(AVFilterContext *ctx) +{ + BufferSinkContext *buf = ctx->priv; + + avfilter_set_common_formats(ctx, avfilter_make_format_list(buf->pix_fmts)); + return 0; +} + +int av_vsink_buffer_get_video_buffer_ref(AVFilterContext *ctx, + AVFilterBufferRef **picref, int flags) +{ + BufferSinkContext *buf = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + int ret; + *picref = NULL; + + /* no picref available, fetch it from the filterchain */ + if (!buf->picref) { + if ((ret = avfilter_request_frame(inlink)) < 0) + return ret; + } + + if (!buf->picref) + return AVERROR(EINVAL); + + *picref = buf->picref; + if (!(flags & AV_VSINK_BUF_FLAG_PEEK)) + buf->picref = NULL; + + return 0; +} + +AVFilter avfilter_vsink_buffersink = { + .name = "buffersink", + .priv_size = sizeof(BufferSinkContext), + .init = init, + .uninit = uninit, + + .query_formats = query_formats, + + .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/vsink_buffer.h b/libavfilter/vsink_buffer.h new file mode 100644 index 0000000000..88b4c1d258 --- /dev/null +++ b/libavfilter/vsink_buffer.h @@ -0,0 +1,47 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFILTER_VSINK_BUFFER_H +#define AVFILTER_VSINK_BUFFER_H + +/** + * @file + * memory buffer sink API for video + */ + +#include "avfilter.h" + +/** + * Tell av_vsink_buffer_get_video_buffer_ref() to read the picref, but not + * remove it from the buffer. This is useful if you need only to read + * the picref, without to fetch it. + */ +#define AV_VSINK_BUF_FLAG_PEEK 1 + +/** + * Get a video buffer data from buffer_sink and put it in picref. + * + * @param buffer_sink pointer to a buffer sink context + * @param flags a combination of AV_VSINK_BUF_FLAG_* flags + * @return >= 0 in case of success, a negative AVERROR code in case of + * failure + */ +int av_vsink_buffer_get_video_buffer_ref(AVFilterContext *buffer_sink, + AVFilterBufferRef **picref, int flags); + +#endif /* AVFILTER_VSINK_BUFFER_H */ -- cgit v1.2.3