[FFmpeg-devel] [PATCH 3/4] lavfi/aconvert: use libswresample.

Stefano Sabatini stefasab at gmail.com
Tue Jan 31 16:08:48 CET 2012


On date Tuesday 2012-01-31 08:31:47 +0100, Clément Bœsch encoded:
> This commit also drops the planar parameter; you now need to use the 'p'
> suffix in order to request a planar sample format.
> ---
>  configure                          |    1 +
>  doc/filters.texi                   |   19 +--
>  libavfilter/Makefile               |    2 +-
>  libavfilter/af_aconvert.c          |  307 ++++--------------------------------
>  libavfilter/af_aconvert_rematrix.c |  172 --------------------
>  libavfilter/version.h              |    2 +-
>  6 files changed, 44 insertions(+), 459 deletions(-)
>  delete mode 100644 libavfilter/af_aconvert_rematrix.c
> 
> diff --git a/configure b/configure
> index b4e433c..aa45fd7 100755
> --- a/configure
> +++ b/configure
> @@ -1648,6 +1648,7 @@ tls_protocol_select="tcp_protocol"
>  udp_protocol_deps="network"
>  
>  # filters
> +aconvert_filter_deps="swresample"
>  amovie_filter_deps="avcodec avformat"
>  aresample_filter_deps="swresample"
>  ass_filter_deps="libass"
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 7d008bc..ef96910 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -104,17 +104,15 @@ Below is a description of the currently available audio filters.
>  Convert the input audio format to the specified formats.
>  
>  The filter accepts a string of the form:
> -"@var{sample_format}:@var{channel_layout}:@var{packing_format}".
> +"@var{sample_format}:@var{channel_layout}".
>  
> - at var{sample_format} specifies the sample format, and can be a string or
> -the corresponding numeric value defined in @file{libavutil/samplefmt.h}.
> + at var{sample_format} specifies the sample format, and can be a string or the
> +corresponding numeric value defined in @file{libavutil/samplefmt.h}. Use 'p'
> +suffix for a planar sample format.
>  
>  @var{channel_layout} specifies the channel layout, and can be a string
>  or the corresponding number value defined in @file{libavutil/audioconvert.h}.
>  
> - at var{packing_format} specifies the type of packing in output, can be one
> -of "planar" or "packed", or the corresponding numeric values "0" or "1".
> -
>  The special parameter "auto", signifies that the filter will
>  automatically select the output format depending on the output filter.
>  
> @@ -122,16 +120,15 @@ Some examples follow.
>  
>  @itemize
>  @item
> -Convert input to unsigned 8-bit, stereo, packed:
> +Convert input to float, planar, stereo:
>  @example
> -aconvert=u8:stereo:packed
> +aconvert=fltp:stereo
>  @end example
>  
>  @item
> -Convert input to unsigned 8-bit, automatically select out channel layout
> -and packing format:
> +Convert input to unsigned 8-bit, automatically select out channel layout:
>  @example
> -aconvert=u8:auto:auto
> +aconvert=u8:auto
>  @end example
>  @end itemize
>  
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index ff0ba75..9fbb59b 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -3,7 +3,7 @@ include $(SUBDIR)../config.mak
>  NAME = avfilter
>  FFLIBS = avutil
>  
> -FFLIBS-$(CONFIG_ACONVERT_FILTER)             += avcodec
> +FFLIBS-$(CONFIG_ACONVERT_FILTER)             += swresample
>  FFLIBS-$(CONFIG_AMOVIE_FILTER)               += avformat avcodec
>  FFLIBS-$(CONFIG_ARESAMPLE_FILTER)            += swresample
>  FFLIBS-$(CONFIG_MOVIE_FILTER)                += avformat avcodec
> diff --git a/libavfilter/af_aconvert.c b/libavfilter/af_aconvert.c
> index e3c7f8c..8c1b5dc 100644
> --- a/libavfilter/af_aconvert.c
> +++ b/libavfilter/af_aconvert.c
> @@ -23,98 +23,19 @@
>  /**
>   * @file
>   * sample format and channel layout conversion audio filter
> - * based on code in libavcodec/resample.c by Fabrice Bellard and
> - * libavcodec/audioconvert.c by Michael Niedermayer
>   */
>  
> -#include "libavutil/audioconvert.h"
>  #include "libavutil/avstring.h"
> -#include "libavcodec/audioconvert.h"
> +#include "libswresample/swresample.h"
>  #include "avfilter.h"
>  #include "internal.h"
>  
>  typedef struct {
> -    enum AVSampleFormat  out_sample_fmt,  in_sample_fmt;   ///< in/out sample formats
> -    int64_t              out_chlayout,    in_chlayout;     ///< in/out channel layout
> -    int                  out_nb_channels, in_nb_channels;  ///< number of in/output channels
> -    enum AVFilterPacking out_packing_fmt, in_packing_fmt;  ///< output packing format
> -
> -    int max_nb_samples;                     ///< maximum number of buffered samples
> -    AVFilterBufferRef *mix_samplesref;      ///< rematrixed buffer
> -    AVFilterBufferRef *out_samplesref;      ///< output buffer after required conversions
> -
> -    uint8_t *in_mix[8], *out_mix[8];        ///< input/output for rematrixing functions
> -    uint8_t *packed_data[8];                ///< pointers for packing conversion
> -    int out_strides[8], in_strides[8];      ///< input/output strides for av_audio_convert
> -    uint8_t **in_conv, **out_conv;          ///< input/output for av_audio_convert
> -
> -    AVAudioConvert *audioconvert_ctx;       ///< context for conversion to output sample format
> -
> -    void (*convert_chlayout)();             ///< function to do the requested rematrixing
> +    enum AVSampleFormat  out_sample_fmt;
> +    int64_t              out_chlayout;
> +    struct SwrContext *swr;
>  } AConvertContext;
>  
> -#define REMATRIX_FUNC_SIG(NAME) static void REMATRIX_FUNC_NAME(NAME) \
> -    (FMT_TYPE *outp[], FMT_TYPE *inp[], int nb_samples, AConvertContext *aconvert)
> -
> -#define FMT_TYPE uint8_t
> -#define REMATRIX_FUNC_NAME(NAME) NAME ## _u8
> -#include "af_aconvert_rematrix.c"
> -
> -#define FMT_TYPE int16_t
> -#define REMATRIX_FUNC_NAME(NAME) NAME ## _s16
> -#include "af_aconvert_rematrix.c"
> -
> -#define FMT_TYPE int32_t
> -#define REMATRIX_FUNC_NAME(NAME) NAME ## _s32
> -#include "af_aconvert_rematrix.c"
> -
> -#define FLOATING
> -
> -#define FMT_TYPE float
> -#define REMATRIX_FUNC_NAME(NAME) NAME ## _flt
> -#include "af_aconvert_rematrix.c"
> -
> -#define FMT_TYPE double
> -#define REMATRIX_FUNC_NAME(NAME) NAME ## _dbl
> -#include "af_aconvert_rematrix.c"
> -
> -#define FMT_TYPE uint8_t
> -#define REMATRIX_FUNC_NAME(NAME) NAME
> -REMATRIX_FUNC_SIG(stereo_remix_planar)
> -{
> -    int size = av_get_bytes_per_sample(aconvert->in_sample_fmt) * nb_samples;
> -
> -    memcpy(outp[0], inp[0], size);
> -    memcpy(outp[1], inp[aconvert->in_nb_channels == 1 ? 0 : 1], size);
> -}
> -
> -#define REGISTER_FUNC_PACKING(INCHLAYOUT, OUTCHLAYOUT, FUNC, PACKING)   \
> -    {INCHLAYOUT, OUTCHLAYOUT, PACKING, AV_SAMPLE_FMT_U8,  FUNC##_u8},   \
> -    {INCHLAYOUT, OUTCHLAYOUT, PACKING, AV_SAMPLE_FMT_S16, FUNC##_s16},  \
> -    {INCHLAYOUT, OUTCHLAYOUT, PACKING, AV_SAMPLE_FMT_S32, FUNC##_s32},  \
> -    {INCHLAYOUT, OUTCHLAYOUT, PACKING, AV_SAMPLE_FMT_FLT, FUNC##_flt},  \
> -    {INCHLAYOUT, OUTCHLAYOUT, PACKING, AV_SAMPLE_FMT_DBL, FUNC##_dbl},
> -
> -#define REGISTER_FUNC(INCHLAYOUT, OUTCHLAYOUT, FUNC)                                \
> -    REGISTER_FUNC_PACKING(INCHLAYOUT, OUTCHLAYOUT, FUNC##_packed, AVFILTER_PACKED)  \
> -    REGISTER_FUNC_PACKING(INCHLAYOUT, OUTCHLAYOUT, FUNC##_planar, AVFILTER_PLANAR)
> -
> -static const struct RematrixFunctionInfo {
> -    int64_t in_chlayout, out_chlayout;
> -    int planar, sfmt;
> -    void (*func)();
> -} rematrix_funcs[] = {
> -    REGISTER_FUNC        (AV_CH_LAYOUT_STEREO,  AV_CH_LAYOUT_5POINT1, stereo_to_surround_5p1)
> -    REGISTER_FUNC        (AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_STEREO,  surround_5p1_to_stereo)
> -    REGISTER_FUNC_PACKING(AV_CH_LAYOUT_STEREO,  AV_CH_LAYOUT_MONO,    stereo_to_mono_packed, AVFILTER_PACKED)
> -    REGISTER_FUNC_PACKING(AV_CH_LAYOUT_MONO,    AV_CH_LAYOUT_STEREO,  mono_to_stereo_packed, AVFILTER_PACKED)
> -    REGISTER_FUNC        (0,                    AV_CH_LAYOUT_MONO,    mono_downmix)
> -    REGISTER_FUNC_PACKING(0,                    AV_CH_LAYOUT_STEREO,  stereo_downmix_packed, AVFILTER_PACKED)
> -
> -    // This function works for all sample formats
> -    {0, AV_CH_LAYOUT_STEREO, AVFILTER_PLANAR, -1, stereo_remix_planar}
> -};
> -
>  static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
>  {
>      AConvertContext *aconvert = ctx->priv;
> @@ -124,7 +45,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
>  
>      aconvert->out_sample_fmt  = AV_SAMPLE_FMT_NONE;
>      aconvert->out_chlayout    = 0;
> -    aconvert->out_packing_fmt = -1;
>  
>      if ((arg = av_strtok(args, ":", &ptr)) && strcmp(arg, "auto")) {
>          if ((ret = ff_parse_sample_format(&aconvert->out_sample_fmt, arg, ctx)) < 0)
> @@ -134,10 +54,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
>          if ((ret = ff_parse_channel_layout(&aconvert->out_chlayout, arg, ctx)) < 0)
>              goto end;
>      }
> -    if ((arg = av_strtok(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
> -        if ((ret = ff_parse_packing_format((int *)&aconvert->out_packing_fmt, arg, ctx)) < 0)
> -            goto end;
> -    }
>  
>  end:
>      av_freep(&args);
> @@ -147,10 +63,7 @@ end:
>  static av_cold void uninit(AVFilterContext *ctx)
>  {
>      AConvertContext *aconvert = ctx->priv;
> -    avfilter_unref_buffer(aconvert->mix_samplesref);
> -    avfilter_unref_buffer(aconvert->out_samplesref);
> -    if (aconvert->audioconvert_ctx)
> -        av_audio_convert_free(aconvert->audioconvert_ctx);
> +    swr_free(&aconvert->swr);
>  }
>  
>  static int query_formats(AVFilterContext *ctx)
> @@ -159,6 +72,7 @@ static int query_formats(AVFilterContext *ctx)
>      AConvertContext *aconvert = ctx->priv;
>      AVFilterLink *inlink  = ctx->inputs[0];
>      AVFilterLink *outlink = ctx->outputs[0];
> +    int out_packing = av_sample_fmt_is_planar(aconvert->out_sample_fmt);
>  
>      avfilter_formats_ref(avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO),
>                           &inlink->out_formats);
> @@ -182,219 +96,64 @@ static int query_formats(AVFilterContext *ctx)
>  
>      avfilter_formats_ref(avfilter_make_all_packing_formats(),
>                           &inlink->out_packing);
> -    if (aconvert->out_packing_fmt != -1) {
> -        formats = NULL;
> -        avfilter_add_format(&formats, aconvert->out_packing_fmt);
> -        avfilter_formats_ref(formats, &outlink->in_packing);
> -    } else
> -        avfilter_formats_ref(avfilter_make_all_packing_formats(),
> -                             &outlink->in_packing);
> +    formats = NULL;
> +    avfilter_add_format(&formats, out_packing);
> +    avfilter_formats_ref(formats, &outlink->in_packing);
>  
>      return 0;
>  }
>  
>  static int config_output(AVFilterLink *outlink)
>  {
> -    AVFilterLink *inlink = outlink->src->inputs[0];
> -    AConvertContext *aconvert = outlink->src->priv;
> +    int ret;
> +    AVFilterContext *ctx = outlink->src;
> +    AVFilterLink *inlink = ctx->inputs[0];
> +    AConvertContext *aconvert = ctx->priv;
>      char buf1[64], buf2[64];
>  
> -    aconvert->in_sample_fmt  = inlink->format;
> -    aconvert->in_packing_fmt = inlink->planar;
> -    if (aconvert->out_packing_fmt == -1)
> -        aconvert->out_packing_fmt = outlink->planar;
> -    aconvert->in_chlayout    = inlink->channel_layout;
> -    aconvert->in_nb_channels =
> -        av_get_channel_layout_nb_channels(inlink->channel_layout);
> -
>      /* if not specified in args, use the format and layout of the output */
>      if (aconvert->out_sample_fmt == AV_SAMPLE_FMT_NONE)
>          aconvert->out_sample_fmt = outlink->format;
>      if (aconvert->out_chlayout   == 0)
>          aconvert->out_chlayout   = outlink->channel_layout;
> -    aconvert->out_nb_channels  =
> -        av_get_channel_layout_nb_channels(outlink->channel_layout);
> +
> +    aconvert->swr = swr_alloc_set_opts(aconvert->swr,
> +                                       aconvert->out_chlayout, aconvert->out_sample_fmt, inlink->sample_rate,
> +                                       inlink->channel_layout, inlink->format,           inlink->sample_rate,
> +                                       0, ctx);
> +    if (!aconvert->swr)
> +        return AVERROR(ENOMEM);
> +    ret = swr_init(aconvert->swr);
> +    if (ret < 0)
> +        return ret;
>  
>      av_get_channel_layout_string(buf1, sizeof(buf1),
>                                   -1, inlink ->channel_layout);
>      av_get_channel_layout_string(buf2, sizeof(buf2),
>                                   -1, outlink->channel_layout);
> -    av_log(outlink->src, AV_LOG_INFO,
> +    av_log(ctx, AV_LOG_INFO,
>             "fmt:%s cl:%s planar:%i -> fmt:%s cl:%s planar:%i\n",
>             av_get_sample_fmt_name(inlink ->format), buf1, inlink ->planar,
>             av_get_sample_fmt_name(outlink->format), buf2, outlink->planar);
>  
> -    /* compute which channel layout conversion to use */
> -    if (inlink->channel_layout != outlink->channel_layout) {
> -        int i;
> -        for (i = 0; i < sizeof(rematrix_funcs); i++) {
> -            const struct RematrixFunctionInfo *f = &rematrix_funcs[i];
> -            if ((f->in_chlayout  == 0 || f->in_chlayout  == inlink ->channel_layout) &&
> -                (f->out_chlayout == 0 || f->out_chlayout == outlink->channel_layout) &&
> -                (f->planar == -1 || f->planar == inlink->planar) &&
> -                (f->sfmt   == -1 || f->sfmt   == inlink->format)
> -               ) {
> -                aconvert->convert_chlayout = f->func;
> -                break;
> -            }
> -        }
> -        if (!aconvert->convert_chlayout) {
> -            av_log(outlink->src, AV_LOG_ERROR,
> -                   "Unsupported channel layout conversion '%s -> %s' requested!\n",
> -                   buf1, buf2);
> -            return AVERROR(EINVAL);
> -        }
> -    }
> -
>      return 0;
>  }
>  
> -static int init_buffers(AVFilterLink *inlink, int nb_samples)
> -{
> -    AConvertContext *aconvert = inlink->dst->priv;
> -    AVFilterLink * const outlink = inlink->dst->outputs[0];
> -    int i, packed_stride = 0;
> -    const unsigned
> -        packing_conv = inlink->planar != outlink->planar &&
> -                       aconvert->out_nb_channels != 1,
> -        format_conv  = inlink->format != outlink->format;
> -    int nb_channels  = aconvert->out_nb_channels;
> -
> -    uninit(inlink->dst);
> -    aconvert->max_nb_samples = nb_samples;
> -
> -    if (aconvert->convert_chlayout) {
> -        /* allocate buffer for storing intermediary mixing samplesref */
> -        uint8_t *data[8];
> -        int linesize[8];
> -        int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout);
> -
> -        if (av_samples_alloc(data, linesize, nb_channels, nb_samples,
> -                             inlink->format, 16) < 0)
> -            goto fail_no_mem;
> -        aconvert->mix_samplesref =
> -            avfilter_get_audio_buffer_ref_from_arrays(data, linesize, AV_PERM_WRITE,
> -                                                      nb_samples, inlink->format,
> -                                                      outlink->channel_layout,
> -                                                      inlink->planar);
> -        if (!aconvert->mix_samplesref)
> -            goto fail_no_mem;
> -    }
> -
> -    // if there's a format/packing conversion we need an audio_convert context
> -    if (format_conv || packing_conv) {
> -        aconvert->out_samplesref =
> -            avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
> -        if (!aconvert->out_samplesref)
> -            goto fail_no_mem;
> -
> -        aconvert->in_strides [0] = av_get_bytes_per_sample(inlink ->format);
> -        aconvert->out_strides[0] = av_get_bytes_per_sample(outlink->format);
> -
> -        aconvert->out_conv = aconvert->out_samplesref->data;
> -        if (aconvert->mix_samplesref)
> -            aconvert->in_conv = aconvert->mix_samplesref->data;
> -
> -        if (packing_conv) {
> -            // packed -> planar
> -            if (outlink->planar == AVFILTER_PLANAR) {
> -                if (aconvert->mix_samplesref)
> -                    aconvert->packed_data[0] = aconvert->mix_samplesref->data[0];
> -                aconvert->in_conv         = aconvert->packed_data;
> -                packed_stride             = aconvert->in_strides[0];
> -                aconvert->in_strides[0]  *= nb_channels;
> -            // planar -> packed
> -            } else {
> -                aconvert->packed_data[0]  = aconvert->out_samplesref->data[0];
> -                aconvert->out_conv        = aconvert->packed_data;
> -                packed_stride             = aconvert->out_strides[0];
> -                aconvert->out_strides[0] *= nb_channels;
> -            }
> -        } else if (outlink->planar == AVFILTER_PACKED) {
> -            /* If there's no packing conversion, and the stream is packed
> -             * then we treat the entire stream as one big channel
> -             */
> -            nb_channels = 1;
> -        }
> -
> -        for (i = 1; i < nb_channels; i++) {
> -            aconvert->packed_data[i] = aconvert->packed_data[i-1] + packed_stride;
> -            aconvert->in_strides[i]  = aconvert->in_strides[0];
> -            aconvert->out_strides[i] = aconvert->out_strides[0];
> -        }
> -
> -        aconvert->audioconvert_ctx =
> -                av_audio_convert_alloc(outlink->format, nb_channels,
> -                                       inlink->format,  nb_channels, NULL, 0);
> -        if (!aconvert->audioconvert_ctx)
> -            goto fail_no_mem;
> -    }
> -
> -    return 0;
> -
> -fail_no_mem:
> -    av_log(inlink->dst, AV_LOG_ERROR, "Could not allocate memory.\n");
> -    return AVERROR(ENOMEM);
> -}
> -
>  static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
>  {
>      AConvertContext *aconvert = inlink->dst->priv;
> -    AVFilterBufferRef *curbuf = insamplesref;
> -    AVFilterLink * const outlink = inlink->dst->outputs[0];
> -    int chan_mult;
> -
> -    /* in/reinint the internal buffers if this is the first buffer
> -     * provided or it is needed to use a bigger one */
> -    if (!aconvert->max_nb_samples ||
> -        (curbuf->audio->nb_samples > aconvert->max_nb_samples))
> -        if (init_buffers(inlink, curbuf->audio->nb_samples) < 0) {
> -            av_log(inlink->dst, AV_LOG_ERROR, "Could not initialize buffers.\n");
> -            return;
> -        }
> +    const int n = insamplesref->audio->nb_samples;
> +    AVFilterLink *const outlink = inlink->dst->outputs[0];
> +    AVFilterBufferRef *outsamplesref = avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, n);
>  
> -    /* if channel mixing is required */
> -    if (aconvert->mix_samplesref) {
> -        memcpy(aconvert->in_mix,  curbuf->data, sizeof(aconvert->in_mix));
> -        memcpy(aconvert->out_mix, aconvert->mix_samplesref->data, sizeof(aconvert->out_mix));
> -        aconvert->convert_chlayout(aconvert->out_mix,
> -                                   aconvert->in_mix,
> -                                   curbuf->audio->nb_samples,
> -                                   aconvert);
> -        curbuf = aconvert->mix_samplesref;
> -    }
> -
> -    if (aconvert->audioconvert_ctx) {
> -        if (!aconvert->mix_samplesref) {
> -            if (aconvert->in_conv == aconvert->packed_data) {
> -                int i, packed_stride = av_get_bytes_per_sample(inlink->format);
> -                aconvert->packed_data[0] = curbuf->data[0];
> -                for (i = 1; i < aconvert->out_nb_channels; i++)
> -                    aconvert->packed_data[i] = aconvert->packed_data[i-1] + packed_stride;
> -            } else {
> -                aconvert->in_conv = curbuf->data;
> -            }
> -        }
> -
> -        chan_mult = inlink->planar == outlink->planar && inlink->planar == 0 ?
> -            aconvert->out_nb_channels : 1;
> -
> -        av_audio_convert(aconvert->audioconvert_ctx,
> -                         (void * const *) aconvert->out_conv,
> -                         aconvert->out_strides,
> -                         (const void * const *) aconvert->in_conv,
> -                         aconvert->in_strides,
> -                         curbuf->audio->nb_samples * chan_mult);
> -
> -        curbuf = aconvert->out_samplesref;
> -    }
> +    swr_convert(aconvert->swr, outsamplesref->data, n,
> +                        (void *)insamplesref->data, n);
>  
> -    avfilter_copy_buffer_ref_props(curbuf, insamplesref);
> -    curbuf->audio->channel_layout = outlink->channel_layout;
> -    curbuf->audio->planar         = outlink->planar;
> +    avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
> +    outsamplesref->audio->channel_layout = outlink->channel_layout;
> +    outsamplesref->audio->planar         = outlink->planar;
>  
> -    avfilter_filter_samples(inlink->dst->outputs[0],
> -                            avfilter_ref_buffer(curbuf, ~0));
> +    avfilter_filter_samples(outlink, outsamplesref);
>      avfilter_unref_buffer(insamplesref);
>  }
>  
> diff --git a/libavfilter/af_aconvert_rematrix.c b/libavfilter/af_aconvert_rematrix.c
> deleted file mode 100644
> index d75ca5a..0000000
> --- a/libavfilter/af_aconvert_rematrix.c
> +++ /dev/null
> @@ -1,172 +0,0 @@
> -/*
> - * 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 rematrixing functions, based on functions from libavcodec/resample.c
> - */
> -
> -#if defined(FLOATING)
> -# define DIV2 /2
> -#else
> -# define DIV2 >>1
> -#endif
> -
> -REMATRIX_FUNC_SIG(stereo_to_mono_packed)
> -{
> -    while (nb_samples >= 4) {
> -        outp[0][0] = (inp[0][0] + inp[0][1]) DIV2;
> -        outp[0][1] = (inp[0][2] + inp[0][3]) DIV2;
> -        outp[0][2] = (inp[0][4] + inp[0][5]) DIV2;
> -        outp[0][3] = (inp[0][6] + inp[0][7]) DIV2;
> -        outp[0] += 4;
> -        inp[0]  += 8;
> -        nb_samples -= 4;
> -    }
> -    while (nb_samples--) {
> -        outp[0][0] = (inp[0][0] + inp[0][1]) DIV2;
> -        outp[0]++;
> -        inp[0] += 2;
> -    }
> -}
> -
> -REMATRIX_FUNC_SIG(stereo_downmix_packed)
> -{
> -    while (nb_samples--) {
> -        *outp[0]++ = inp[0][0];
> -        *outp[0]++ = inp[0][1];
> -        inp[0] += aconvert->in_nb_channels;
> -    }
> -}
> -
> -REMATRIX_FUNC_SIG(mono_to_stereo_packed)
> -{
> -    while (nb_samples >= 4) {
> -        outp[0][0] = outp[0][1] = inp[0][0];
> -        outp[0][2] = outp[0][3] = inp[0][1];
> -        outp[0][4] = outp[0][5] = inp[0][2];
> -        outp[0][6] = outp[0][7] = inp[0][3];
> -        outp[0] += 8;
> -        inp[0]  += 4;
> -        nb_samples -= 4;
> -    }
> -    while (nb_samples--) {
> -        outp[0][0] = outp[0][1] = inp[0][0];
> -        outp[0] += 2;
> -        inp[0]  += 1;
> -    }
> -}
> -
> -/**
> - * 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.
> - */
> -REMATRIX_FUNC_SIG(mono_downmix_packed)
> -{
> -    while (nb_samples--) {
> -        outp[0][0] = (inp[0][0] + inp[0][1]) DIV2;
> -        inp[0] += aconvert->in_nb_channels;
> -        outp[0]++;
> -    }
> -}
> -
> -REMATRIX_FUNC_SIG(mono_downmix_planar)
> -{
> -    FMT_TYPE *out = outp[0];
> -
> -    while (nb_samples >= 4) {
> -        out[0] = (inp[0][0] + inp[1][0]) DIV2;
> -        out[1] = (inp[0][1] + inp[1][1]) DIV2;
> -        out[2] = (inp[0][2] + inp[1][2]) DIV2;
> -        out[3] = (inp[0][3] + inp[1][3]) DIV2;
> -        out    += 4;
> -        inp[0] += 4;
> -        inp[1] += 4;
> -        nb_samples -= 4;
> -    }
> -    while (nb_samples--) {
> -        out[0] = (inp[0][0] + inp[1][0]) DIV2;
> -        out++;
> -        inp[0]++;
> -        inp[1]++;
> -    }
> -}
> -
> -/* Stereo to 5.1 output */
> -REMATRIX_FUNC_SIG(stereo_to_surround_5p1_packed)
> -{
> -    while (nb_samples--) {
> -      outp[0][0] = inp[0][0];  /* left */
> -      outp[0][1] = inp[0][1];  /* right */
> -      outp[0][2] = (inp[0][0] + inp[0][1]) DIV2; /* center */
> -      outp[0][3] = 0;          /* low freq */
> -      outp[0][4] = 0;          /* FIXME: left surround: -3dB or -6dB or -9dB of stereo left  */
> -      outp[0][5] = 0;          /* FIXME: right surroud: -3dB or -6dB or -9dB of stereo right */
> -      inp[0]  += 2;
> -      outp[0] += 6;
> -    }
> -}
> -
> -REMATRIX_FUNC_SIG(stereo_to_surround_5p1_planar)
> -{
> -    while (nb_samples--) {
> -      *outp[0]++ = *inp[0];    /* left */
> -      *outp[1]++ = *inp[1];    /* right */
> -      *outp[2]++ = (*inp[0] + *inp[1]) DIV2; /* center */
> -      *outp[3]++ = 0;          /* low freq */
> -      *outp[4]++ = 0;          /* FIXME: left surround: -3dB or -6dB or -9dB of stereo left  */
> -      *outp[5]++ = 0;          /* FIXME: right surroud: -3dB or -6dB or -9dB of stereo right */
> -      inp[0]++; inp[1]++;
> -    }
> -}
> -
> -
> -/*
> -5.1 to stereo input: [fl, fr, c, lfe, rl, rr]
> -- Left = front_left + rear_gain * rear_left + center_gain * center
> -- Right = front_right + rear_gain * rear_right + center_gain * center
> -Where rear_gain is usually around 0.5-1.0 and
> -      center_gain is almost always 0.7 (-3 dB)
> -*/
> -REMATRIX_FUNC_SIG(surround_5p1_to_stereo_packed)
> -{
> -    while (nb_samples--) {
> -        *outp[0]++ = inp[0][0] + (0.5 * inp[0][4]) + (0.7 * inp[0][2]); //FIXME CLIPPING!
> -        *outp[0]++ = inp[0][1] + (0.5 * inp[0][5]) + (0.7 * inp[0][2]); //FIXME CLIPPING!
> -
> -        inp[0] += 6;
> -    }
> -}
> -
> -REMATRIX_FUNC_SIG(surround_5p1_to_stereo_planar)
> -{
> -    while (nb_samples--) {
> -        *outp[0]++ = *inp[0] + (0.5 * *inp[4]) + (0.7 * *inp[2]); //FIXME CLIPPING!
> -        *outp[1]++ = *inp[1] + (0.5 * *inp[5]) + (0.7 * *inp[2]); //FIXME CLIPPING!
> -
> -        inp[0]++; inp[1]++; inp[2]++; inp[3]++; inp[4]++; inp[5]++;
> -    }
> -}
> -
> -#undef DIV2
> -#undef REMATRIX_FUNC_NAME
> -#undef FMT_TYPE
> diff --git a/libavfilter/version.h b/libavfilter/version.h
> index 60e496d..cd8bd95 100644
> --- a/libavfilter/version.h
> +++ b/libavfilter/version.h
> @@ -29,7 +29,7 @@
>  #include "libavutil/avutil.h"
>  
>  #define LIBAVFILTER_VERSION_MAJOR  2
> -#define LIBAVFILTER_VERSION_MINOR 60
> +#define LIBAVFILTER_VERSION_MINOR 61
>  #define LIBAVFILTER_VERSION_MICRO 100
>  
>  #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \

Sounds good, I suppose some minimal tests have been done on it, a
complete FATE test is definitively welcome at this point.
-- 
FFmpeg = Fabulous and Fundamental Mystic Pitiful Erotic Game


More information about the ffmpeg-devel mailing list