[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