[FFmpeg-devel] [PATCH] Add af_resample - sample fmt and channel layout conversion filter
Stefano Sabatini
stefano.sabatini-lala
Wed Jan 12 22:25:26 CET 2011
On date Wednesday 2010-10-06 21:23:12 +0200, Michael Niedermayer encoded:
> On Fri, Oct 01, 2010 at 06:40:24PM +0200, Stefano Sabatini wrote:
> > On date Monday 2010-09-27 02:50:41 +0200, Michael Niedermayer encoded:
> > > On Mon, Sep 27, 2010 at 02:41:16AM +0200, Stefano Sabatini wrote:
> > > > On date Monday 2010-09-27 02:21:49 +0200, Michael Niedermayer encoded:
> > > > > On Mon, Sep 27, 2010 at 12:40:31AM +0200, Stefano Sabatini wrote:
> > > > [...]
> > > > > > > the functions belong to libavfilter
> > > > > > > what is the plan to move them there?
> > > > > >
> > > > > > Impossible as lavc uses that functions internally. The plan was to
> > > > >
> > > > > resample uses them, resample doesnt belong to lavc, not more than
> > > > > sws would belong there
> > > > >
> > > > >
> > > > > > directly use them, and move to something better when we'll have a
> > > > > > revisited resampling/conversion API, a libavresample was mentioned.
> > > > > > Since this is not going to take small time, the idea was to use the
> > > > > > quickest solution and not stall audio lavfi development.
> > > > >
> > > > > the quickest is to copy the 2 pages of poor code not to export it as
> > > > > public ABI/API from the wrong lib
> > > > > that API/ABI requires maintaince and is not a small burden when things
> > > > > have to be moved to the correct place or when API/ABI changes which with
> > > > > such trashy code will happen unless development stops
> > > >
> > > > OK so the quickest path looks like to duplicate the code as it was
> > > > done in the original version from Hemanth...
> > >
> > > yes, i dont like it but i think this is a rare case where this will cause
> > > fewer problems
> > >
> > > also the code in libavcodec should be marked as deprecated as soon as possible
> >
> > Updated patch based on an old patch from Hemanth (Hemanth feel free to
> > continue to discuss starting from this patch).
> >
> > My plan is to get -af implemented in ffplay, this requires these
> > steps:
> > * resample filter
> > * resample filter auto-insertion provided by the lavfi framework
> > * avfilter_get_audio_buffer_ref() or the equivalent, required for
> > eliminating an unnecessary memcpy
> > * ffplay -af
> >
> > Once it is possible to test somehow libavfilter with audio, then we
> > can move to ffmpeg:
> > * asrc_buffer
> > * ffmpeg -af
> > * audio lavfi tests
> >
> > Regards.
> > --
> > FFmpeg = Frenzy Forgiving Minimalistic Pitiless Epic Governor
>
> > Makefile | 1
> > af_resample.c | 467 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > allfilters.c | 1
> > 3 files changed, 469 insertions(+)
> > 60997f9e273101bb923c1c14bb145da860923d92 0001-Add-af_resample-sample-fmt-and-channel-layout-conver.patch
> > From 2b9cf4fc8fa2d55aa18e6e53c9cf8ca600579133 Mon Sep 17 00:00:00 2001
> > From: Stefano Sabatini <stefano.sabatini-lala at poste.it>
> > Date: Fri, 1 Oct 2010 14:58:22 +0200
> > Subject: [PATCH 1/3] Add af_resample - sample fmt and channel layout conversion filter.
> >
> > Patch by "S.N. Hemanth Meenakshisundaram" 5m33nak5 at uc5d.3du.
> > ---
> > libavfilter/Makefile | 1 +
> > libavfilter/af_resample.c | 467 +++++++++++++++++++++++++++++++++++++++++++++
> > libavfilter/allfilters.c | 1 +
> > 3 files changed, 469 insertions(+), 0 deletions(-)
> > create mode 100644 libavfilter/af_resample.c
> >
> > diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> > index 74e55bb..e65995c 100644
> > --- a/libavfilter/Makefile
> > +++ b/libavfilter/Makefile
> > @@ -15,6 +15,7 @@ OBJS = allfilters.o \
> > parseutils.o \
> >
> > OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o
> > +OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o
> >
> > OBJS-$(CONFIG_ANULLSRC_FILTER) += asrc_anullsrc.o
> >
> > diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c
> > new file mode 100644
> > index 0000000..2e7898e
> > --- /dev/null
> > +++ b/libavfilter/af_resample.c
> > @@ -0,0 +1,467 @@
> > +/*
> > + * Copyright (C) 2010 S.N. Hemanth Meenakshisundaram <smeenaks at ucsd.edu>
> > + * based on code in libavcodec/resample.c by Fabrice Bellard
> > + * and libavcodec/audioconvert.c by Michael Neidermayer
> > + *
> > + * 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
> > + * resample audio filter
> > + */
> > +
> > +#include "avfilter.h"
> > +#include "libavcodec/audioconvert.h"
> > +
>
> > +typedef struct {
> > + short reconfig_channel_layout; ///< set when channel layout of incoming buffer changes
> > + short reconfig_sample_fmt; ///< set when sample format of incoming buffer changes
>
> short?
>
>
> [...]
> > +/**
> > + * This is for when we have more than 2 input channels, need to downmix to mono
> > + * and do not have a conversion formula available. We just use first two input
> > + * channels - left and right. This is a placeholder until more conversion
> > + * functions are written.
> > + */
> > +static void mono_downmix(uint8_t *out[], uint8_t *in[], int nb_samples, int in_channels)
> > +{
> > + int i;
> > + short *input = (short *) in[0];
> > + short *output = (short *) out[0];
> > + short left, right;
> > +
> > + for (i = 0; i < nb_samples; i++) {
> > + left = *input++;
> > + right = *input++;
>
> > + *output++ = (left>>1)+(right>>1);
>
> >> after +
>
>
>
> > + input += in_channels-2;
> > + }
> > +}
> > +
>
> > +/* Stereo to 5.1 output */
> > +static void ac3_5p1_mux(uint8_t *out[], uint8_t *in[], int nb_samples, int in_channels)
> > +{
> > + int i;
> > + short *output = (short *) out[0];
> > + short *input = (short *) in[0];
> > + short left, right;
> > +
> > + for (i = 0; i < nb_samples; i++) {
> > + left = *input++; /* Grab next left sample */
> > + right = *input++; /* Grab next right sample */
> > + *output++ = left; /* left */
> > + *output++ = right; /* right */
> > + *output++ = (left>>1)+(right>>1); /* center */
> > + *output++ = 0; /* low freq */
> > + *output++ = 0; /* FIXME: left surround is either -3dB, -6dB or -9dB of stereo left */
> > + *output++ = 0; /* FIXME: right surroud is either -3dB, -6dB or -9dB of stereo right */
> > + }
> > +}
>
> that are alot of fixmes
>
> also we need float versions
>
>
> [...]
> > +static void convert_channel_layout(AVFilterLink *link)
> > +{
> > + ResampleContext *resample = link->dst->priv;
> > + AVFilterBufferRef *insamples = resample->s16_samples_ptr;
> > + AVFilterBufferRef *outsamples = resample->temp_samples;
> > + unsigned int num_ip_channels = avcodec_channel_layout_num_channels(resample->in_channel_layout);
> > +
> > + if (insamples)
> > + resample->in_channel_layout = insamples->audio->channel_layout;
> > +
> > + /* Init stage or input channels changed, so reconfigure conversion function pointer */
> > + if (resample->reconfig_channel_layout || !resample->channel_conversion) {
> > +
> > + int64_t in_channel = resample->in_channel_layout;
> > + int64_t out_channel = resample->out_channel_layout;
> > +
> > + int num_channels = avcodec_channel_layout_num_channels(resample->out_channel_layout);
> > + int out_sample_size = av_get_bits_per_sample_format(insamples->format) >> 3;
> > +
> > + int size = num_channels*out_sample_size*insamples->audio->samples_nb;
> > +
> > + if (outsamples)
> > + avfilter_unref_buffer(outsamples);
> > + outsamples = avfilter_get_audio_buffer(link, AV_PERM_WRITE|AV_PERM_REUSE2,
> > + insamples->format, size,
> > + out_channel, 0);
> > + /*
> > + * Pick appropriate channel conversion function based on input-output channel layouts.
> > + * If no suitable conversion function is available, downmix to stereo and set buffer
> > + * channel layout to stereo.
> > + *
> > + * FIXME: Add error handling if channel conversion is unsupported, more channel conversion
> > + * routines and finally the ability to handle various stride lengths (sample formats).
> > + */
> > + if (in_channel == CH_LAYOUT_STEREO && out_channel == CH_LAYOUT_MONO)
> > + resample->channel_conversion = stereo_to_mono;
> > + else if (in_channel == CH_LAYOUT_MONO && out_channel == CH_LAYOUT_STEREO)
> > + resample->channel_conversion = mono_to_stereo;
> > + else if (in_channel == CH_LAYOUT_STEREO && out_channel == CH_LAYOUT_5POINT1)
> > + resample->channel_conversion = ac3_5p1_mux;
> > + else if (out_channel == CH_LAYOUT_MONO)
> > + resample->channel_conversion = mono_downmix;
>
> missig {}
Updated against latest SVN. Consider this a work in progress, many of
the fixme need yet to be fixed, Michael please mark what you consider
required for the patch to be applied.
--
FFmpeg = Fast and Funny Magic Pacific Ecstatic Guru
More information about the ffmpeg-devel
mailing list