diff --git a/doc/filters.texi b/doc/filters.texi index b41fce7ced..3e46229c7b 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -144,6 +144,17 @@ anullsrc=48000:mono Below is a description of the currently available audio sinks. +@section abuffersink + +Buffer audio frames, and make them available to the end of filter chain. + +This sink is mainly intended for programmatic use, in particular +through the interface defined in @file{libavfilter/asink_abuffer.h}. + +It requires a pointer to a ABufferSinkContext structure, which defines the +incoming buffers' format, to be passed as the opaque parameter to +@code{avfilter_init_filter} for initialization. + @section anullsink Null audio sink, do absolutely nothing with the input audio. It is diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 6007fedca5..0a1cbad21d 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -22,6 +22,7 @@ OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o OBJS-$(CONFIG_ANULLSRC_FILTER) += asrc_anullsrc.o +OBJS-$(CONFIG_ABUFFERSINK_FILTER) += asink_abuffer.o OBJS-$(CONFIG_ANULLSINK_FILTER) += asink_anullsink.o OBJS-$(CONFIG_BLACKFRAME_FILTER) += vf_blackframe.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 99f7bc42e2..9c456d33d6 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -38,6 +38,7 @@ void avfilter_register_all(void) REGISTER_FILTER (ANULLSRC, anullsrc, asrc); + REGISTER_FILTER (ABUFFERSINK, abuffersink, asink); REGISTER_FILTER (ANULLSINK, anullsink, asink); REGISTER_FILTER (BLACKFRAME, blackframe, vf); diff --git a/libavfilter/asink_abuffer.c b/libavfilter/asink_abuffer.c new file mode 100644 index 0000000000..f4e7740b6d --- /dev/null +++ b/libavfilter/asink_abuffer.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011 Stefano Sabatini + * Copyright (c) 2011 Mina Nagy Zaki + * + * 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 + * audio buffer sink + */ + +#include "avfilter.h" +#include "asink_abuffer.h" + +static void filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) +{ +} + +static int init(AVFilterContext *ctx, const char *args, void *opaque) +{ + if (!opaque) { + av_log(ctx, AV_LOG_ERROR, "Opaque field required, please pass" + " an initialized ABufferSinkContext"); + return AVERROR(EINVAL); + } + memcpy(ctx->priv, opaque, sizeof(ABufferSinkContext)); + + return 0; +} + +static int query_formats(AVFilterContext *ctx) +{ + ABufferSinkContext *abuffersink = ctx->priv; + AVFilterFormats *formats; + int ret; + + formats = NULL; + if ((ret = avfilter_add_format(&formats, abuffersink->sample_fmt)) < 0) + return ret; + avfilter_set_common_sample_formats(ctx, formats); + + formats = NULL; + if ((ret = avfilter_add_format(&formats, abuffersink->channel_layout)) < 0) + return ret; + avfilter_set_common_channel_layouts(ctx, formats); + + formats = NULL; + if ((ret = avfilter_add_format(&formats, abuffersink->planar)) < 0) + return ret; + avfilter_set_common_packing_formats(ctx, formats); + + return 0; +} + +int av_asink_abuffer_get_audio_buffer_ref(AVFilterContext *abuffersink, + AVFilterBufferRef **samplesref, + int av_unused flags) +{ + int ret; + AVFilterLink * const inlink = abuffersink->inputs[0]; + + if ((ret = avfilter_request_frame(inlink))) + return ret; + if (!inlink->cur_buf) + return AVERROR(EINVAL); + *samplesref = inlink->cur_buf; + inlink->cur_buf = NULL; + + return 0; +} + +AVFilter avfilter_asink_abuffersink = { + .name = "abuffersink", + .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."), + .init = init, + .priv_size = sizeof(ABufferSinkContext), + .query_formats = query_formats, + + .inputs = (AVFilterPad[]) {{ .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .filter_samples = filter_samples, + .min_perms = AV_PERM_READ, }, + { .name = NULL }}, + .outputs = (AVFilterPad[]) {{ .name = NULL }}, +}; + diff --git a/libavfilter/asink_abuffer.h b/libavfilter/asink_abuffer.h new file mode 100644 index 0000000000..2c039fb3af --- /dev/null +++ b/libavfilter/asink_abuffer.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_ASINK_ABUFFER_H +#define AVFILTER_ASINK_ABUFFER_H + +/** + * @file + * audio buffer sink API + */ + +#include "avfilter.h" + +typedef struct { + enum AVSampleFormat sample_fmt; + int64_t channel_layout; + int planar; +} ABufferSinkContext; + + +/** + * Get an audio buffer from abuffersink and put it in samplesref. + * + * @param abuffersink pointer to an abuffersink context + * @param flags unused + * @return >= 0 in case of success, a negative AVERROR code in case of failure + */ +int av_asink_abuffer_get_audio_buffer_ref(AVFilterContext *abuffersink, + AVFilterBufferRef **samplesref, + int av_unused flags); + +#endif /* AVFILTER_ASINK_ABUFFER_H */ diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 4c3192e9d0..da3d05fb47 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -29,8 +29,8 @@ #include "libavutil/rational.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 27 -#define LIBAVFILTER_VERSION_MICRO 5 +#define LIBAVFILTER_VERSION_MINOR 28 +#define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \