[FFmpeg-devel] [PATCH] Add af_resample - sample fmt and channel layout conversion filter

Michael Niedermayer michaelni
Wed Oct 6 21:23:12 CEST 2010


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 {}

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Why not whip the teacher when the pupil misbehaves? -- Diogenes of Sinope
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20101006/128de650/attachment.pgp>



More information about the ffmpeg-devel mailing list