diff mbox

[FFmpeg-devel,1/4] lavfi: remove af_resample

Message ID 20170306024651.66336-1-atomnuker@gmail.com
State New
Headers show

Commit Message

Rostislav Pehlivanov March 6, 2017, 2:46 a.m. UTC
af_aresample does the same thing better and doesn't depend on
libavresample

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
---
 libavfilter/Makefile      |   1 -
 libavfilter/af_resample.c | 357 ----------------------------------------------
 2 files changed, 358 deletions(-)
 delete mode 100644 libavfilter/af_resample.c

Comments

wm4 March 6, 2017, 7:51 a.m. UTC | #1
On Mon,  6 Mar 2017 02:46:48 +0000
Rostislav Pehlivanov <atomnuker@gmail.com> wrote:

> af_aresample does the same thing better and doesn't depend on
> libavresample
> 
> Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
> ---
>  libavfilter/Makefile      |   1 -
>  libavfilter/af_resample.c | 357 ----------------------------------------------
>  2 files changed, 358 deletions(-)
>  delete mode 100644 libavfilter/af_resample.c
> 
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 0ba1c74a26..6b9fba2d4c 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -98,7 +98,6 @@ OBJS-$(CONFIG_LOUDNORM_FILTER)               += af_loudnorm.o ebur128.o
>  OBJS-$(CONFIG_LOWPASS_FILTER)                += af_biquads.o
>  OBJS-$(CONFIG_PAN_FILTER)                    += af_pan.o
>  OBJS-$(CONFIG_REPLAYGAIN_FILTER)             += af_replaygain.o
> -OBJS-$(CONFIG_RESAMPLE_FILTER)               += af_resample.o
>  OBJS-$(CONFIG_RUBBERBAND_FILTER)             += af_rubberband.o
>  OBJS-$(CONFIG_SIDECHAINCOMPRESS_FILTER)      += af_sidechaincompress.o
>  OBJS-$(CONFIG_SIDECHAINGATE_FILTER)          += af_agate.o
> diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c
> deleted file mode 100644
> index e3c6a20696..0000000000
> --- a/libavfilter/af_resample.c
> +++ /dev/null
> @@ -1,357 +0,0 @@
> -/*
> - * 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
> - * sample format and channel layout conversion audio filter
> - */
> -
> -#include "libavutil/avassert.h"
> -#include "libavutil/avstring.h"
> -#include "libavutil/common.h"
> -#include "libavutil/dict.h"
> -#include "libavutil/mathematics.h"
> -#include "libavutil/opt.h"
> -
> -#include "libavresample/avresample.h"
> -
> -#include "audio.h"
> -#include "avfilter.h"
> -#include "formats.h"
> -#include "internal.h"
> -
> -typedef struct ResampleContext {
> -    const AVClass *class;
> -    AVAudioResampleContext *avr;
> -    AVDictionary *options;
> -
> -    int resampling;
> -    int64_t next_pts;
> -    int64_t next_in_pts;
> -
> -    /* set by filter_frame() to signal an output frame to request_frame() */
> -    int got_output;
> -} ResampleContext;
> -
> -static av_cold int init(AVFilterContext *ctx, AVDictionary **opts)
> -{
> -    ResampleContext *s = ctx->priv;
> -    const AVClass *avr_class = avresample_get_class();
> -    AVDictionaryEntry *e = NULL;
> -
> -    while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
> -        if (av_opt_find(&avr_class, e->key, NULL, 0,
> -                        AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN))
> -            av_dict_set(&s->options, e->key, e->value, 0);
> -    }
> -
> -    e = NULL;
> -    while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
> -        av_dict_set(opts, e->key, NULL, 0);
> -
> -    /* do not allow the user to override basic format options */
> -    av_dict_set(&s->options,  "in_channel_layout", NULL, 0);
> -    av_dict_set(&s->options, "out_channel_layout", NULL, 0);
> -    av_dict_set(&s->options,  "in_sample_fmt",     NULL, 0);
> -    av_dict_set(&s->options, "out_sample_fmt",     NULL, 0);
> -    av_dict_set(&s->options,  "in_sample_rate",    NULL, 0);
> -    av_dict_set(&s->options, "out_sample_rate",    NULL, 0);
> -
> -    return 0;
> -}
> -
> -static av_cold void uninit(AVFilterContext *ctx)
> -{
> -    ResampleContext *s = ctx->priv;
> -
> -    if (s->avr) {
> -        avresample_close(s->avr);
> -        avresample_free(&s->avr);
> -    }
> -    av_dict_free(&s->options);
> -}
> -
> -static int query_formats(AVFilterContext *ctx)
> -{
> -    AVFilterLink *inlink  = ctx->inputs[0];
> -    AVFilterLink *outlink = ctx->outputs[0];
> -    AVFilterFormats *in_formats, *out_formats, *in_samplerates, *out_samplerates;
> -    AVFilterChannelLayouts *in_layouts, *out_layouts;
> -    int ret;
> -
> -    if (!(in_formats      = ff_all_formats         (AVMEDIA_TYPE_AUDIO)) ||
> -        !(out_formats     = ff_all_formats         (AVMEDIA_TYPE_AUDIO)) ||
> -        !(in_samplerates  = ff_all_samplerates     (                  )) ||
> -        !(out_samplerates = ff_all_samplerates     (                  )) ||
> -        !(in_layouts      = ff_all_channel_layouts (                  )) ||
> -        !(out_layouts     = ff_all_channel_layouts (                  )))
> -        return AVERROR(ENOMEM);
> -
> -    if ((ret = ff_formats_ref         (in_formats,      &inlink->out_formats        )) < 0 ||
> -        (ret = ff_formats_ref         (out_formats,     &outlink->in_formats        )) < 0 ||
> -        (ret = ff_formats_ref         (in_samplerates,  &inlink->out_samplerates    )) < 0 ||
> -        (ret = ff_formats_ref         (out_samplerates, &outlink->in_samplerates    )) < 0 ||
> -        (ret = ff_channel_layouts_ref (in_layouts,      &inlink->out_channel_layouts)) < 0 ||
> -        (ret = ff_channel_layouts_ref (out_layouts,     &outlink->in_channel_layouts)) < 0)
> -        return ret;
> -
> -    return 0;
> -}
> -
> -static int config_output(AVFilterLink *outlink)
> -{
> -    AVFilterContext *ctx = outlink->src;
> -    AVFilterLink *inlink = ctx->inputs[0];
> -    ResampleContext   *s = ctx->priv;
> -    char buf1[64], buf2[64];
> -    int ret;
> -
> -    int64_t resampling_forced;
> -
> -    if (s->avr) {
> -        avresample_close(s->avr);
> -        avresample_free(&s->avr);
> -    }
> -
> -    if (inlink->channel_layout == outlink->channel_layout &&
> -        inlink->sample_rate    == outlink->sample_rate    &&
> -        (inlink->format        == outlink->format ||
> -        (av_get_channel_layout_nb_channels(inlink->channel_layout)  == 1 &&
> -         av_get_channel_layout_nb_channels(outlink->channel_layout) == 1 &&
> -         av_get_planar_sample_fmt(inlink->format) ==
> -         av_get_planar_sample_fmt(outlink->format))))
> -        return 0;
> -
> -    if (!(s->avr = avresample_alloc_context()))
> -        return AVERROR(ENOMEM);
> -
> -    if (s->options) {
> -        int ret;
> -        AVDictionaryEntry *e = NULL;
> -        while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
> -            av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value);
> -
> -        ret = av_opt_set_dict(s->avr, &s->options);
> -        if (ret < 0)
> -            return ret;
> -    }
> -
> -    av_opt_set_int(s->avr,  "in_channel_layout", inlink ->channel_layout, 0);
> -    av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0);
> -    av_opt_set_int(s->avr,  "in_sample_fmt",     inlink ->format,         0);
> -    av_opt_set_int(s->avr, "out_sample_fmt",     outlink->format,         0);
> -    av_opt_set_int(s->avr,  "in_sample_rate",    inlink ->sample_rate,    0);
> -    av_opt_set_int(s->avr, "out_sample_rate",    outlink->sample_rate,    0);
> -
> -    if ((ret = avresample_open(s->avr)) < 0)
> -        return ret;
> -
> -    av_opt_get_int(s->avr, "force_resampling", 0, &resampling_forced);
> -    s->resampling = resampling_forced || (inlink->sample_rate != outlink->sample_rate);
> -
> -    if (s->resampling) {
> -        outlink->time_base = (AVRational){ 1, outlink->sample_rate };
> -        s->next_pts        = AV_NOPTS_VALUE;
> -        s->next_in_pts     = AV_NOPTS_VALUE;
> -    } else
> -        outlink->time_base = inlink->time_base;
> -
> -    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(ctx, AV_LOG_VERBOSE,
> -           "fmt:%s srate:%d cl:%s -> fmt:%s srate:%d cl:%s\n",
> -           av_get_sample_fmt_name(inlink ->format), inlink ->sample_rate, buf1,
> -           av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf2);
> -
> -    return 0;
> -}
> -
> -static int request_frame(AVFilterLink *outlink)
> -{
> -    AVFilterContext *ctx = outlink->src;
> -    ResampleContext   *s = ctx->priv;
> -    int ret = 0;
> -
> -    s->got_output = 0;
> -    while (ret >= 0 && !s->got_output)
> -        ret = ff_request_frame(ctx->inputs[0]);
> -
> -    /* flush the lavr delay buffer */
> -    if (ret == AVERROR_EOF && s->avr) {
> -        AVFrame *frame;
> -        int nb_samples = avresample_get_out_samples(s->avr, 0);
> -
> -        if (!nb_samples)
> -            return ret;
> -
> -        frame = ff_get_audio_buffer(outlink, nb_samples);
> -        if (!frame)
> -            return AVERROR(ENOMEM);
> -
> -        ret = avresample_convert(s->avr, frame->extended_data,
> -                                 frame->linesize[0], nb_samples,
> -                                 NULL, 0, 0);
> -        if (ret <= 0) {
> -            av_frame_free(&frame);
> -            return (ret == 0) ? AVERROR_EOF : ret;
> -        }
> -
> -        frame->nb_samples = ret;
> -        frame->pts = s->next_pts;
> -        return ff_filter_frame(outlink, frame);
> -    }
> -    return ret;
> -}
> -
> -static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> -{
> -    AVFilterContext  *ctx = inlink->dst;
> -    ResampleContext    *s = ctx->priv;
> -    AVFilterLink *outlink = ctx->outputs[0];
> -    int ret;
> -
> -    if (s->avr) {
> -        AVFrame *out;
> -        int delay, nb_samples;
> -
> -        /* maximum possible samples lavr can output */
> -        delay      = avresample_get_delay(s->avr);
> -        nb_samples = avresample_get_out_samples(s->avr, in->nb_samples);
> -
> -        out = ff_get_audio_buffer(outlink, nb_samples);
> -        if (!out) {
> -            ret = AVERROR(ENOMEM);
> -            goto fail;
> -        }
> -
> -        ret = avresample_convert(s->avr, out->extended_data, out->linesize[0],
> -                                 nb_samples, in->extended_data, in->linesize[0],
> -                                 in->nb_samples);
> -        if (ret <= 0) {
> -            av_frame_free(&out);
> -            if (ret < 0)
> -                goto fail;
> -        }
> -
> -        av_assert0(!avresample_available(s->avr));
> -
> -        if (s->resampling && s->next_pts == AV_NOPTS_VALUE) {
> -            if (in->pts == AV_NOPTS_VALUE) {
> -                av_log(ctx, AV_LOG_WARNING, "First timestamp is missing, "
> -                       "assuming 0.\n");
> -                s->next_pts = 0;
> -            } else
> -                s->next_pts = av_rescale_q(in->pts, inlink->time_base,
> -                                           outlink->time_base);
> -        }
> -
> -        if (ret > 0) {
> -            out->nb_samples = ret;
> -
> -            ret = av_frame_copy_props(out, in);
> -            if (ret < 0) {
> -                av_frame_free(&out);
> -                goto fail;
> -            }
> -
> -            if (s->resampling) {
> -                out->sample_rate = outlink->sample_rate;
> -                /* Only convert in->pts if there is a discontinuous jump.
> -                   This ensures that out->pts tracks the number of samples actually
> -                   output by the resampler in the absence of such a jump.
> -                   Otherwise, the rounding in av_rescale_q() and av_rescale()
> -                   causes off-by-1 errors. */
> -                if (in->pts != AV_NOPTS_VALUE && in->pts != s->next_in_pts) {
> -                    out->pts = av_rescale_q(in->pts, inlink->time_base,
> -                                                outlink->time_base) -
> -                                   av_rescale(delay, outlink->sample_rate,
> -                                              inlink->sample_rate);
> -                } else
> -                    out->pts = s->next_pts;
> -
> -                s->next_pts = out->pts + out->nb_samples;
> -                s->next_in_pts = in->pts + in->nb_samples;
> -            } else
> -                out->pts = in->pts;
> -
> -            ret = ff_filter_frame(outlink, out);
> -            s->got_output = 1;
> -        }
> -
> -fail:
> -        av_frame_free(&in);
> -    } else {
> -        in->format = outlink->format;
> -        ret = ff_filter_frame(outlink, in);
> -        s->got_output = 1;
> -    }
> -
> -    return ret;
> -}
> -
> -static const AVClass *resample_child_class_next(const AVClass *prev)
> -{
> -    return prev ? NULL : avresample_get_class();
> -}
> -
> -static void *resample_child_next(void *obj, void *prev)
> -{
> -    ResampleContext *s = obj;
> -    return prev ? NULL : s->avr;
> -}
> -
> -static const AVClass resample_class = {
> -    .class_name       = "resample",
> -    .item_name        = av_default_item_name,
> -    .version          = LIBAVUTIL_VERSION_INT,
> -    .child_class_next = resample_child_class_next,
> -    .child_next       = resample_child_next,
> -};
> -
> -static const AVFilterPad avfilter_af_resample_inputs[] = {
> -    {
> -        .name          = "default",
> -        .type          = AVMEDIA_TYPE_AUDIO,
> -        .filter_frame  = filter_frame,
> -    },
> -    { NULL }
> -};
> -
> -static const AVFilterPad avfilter_af_resample_outputs[] = {
> -    {
> -        .name          = "default",
> -        .type          = AVMEDIA_TYPE_AUDIO,
> -        .config_props  = config_output,
> -        .request_frame = request_frame
> -    },
> -    { NULL }
> -};
> -
> -AVFilter ff_af_resample = {
> -    .name          = "resample",
> -    .description   = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."),
> -    .priv_size     = sizeof(ResampleContext),
> -    .priv_class    = &resample_class,
> -    .init_dict     = init,
> -    .uninit        = uninit,
> -    .query_formats = query_formats,
> -    .inputs        = avfilter_af_resample_inputs,
> -    .outputs       = avfilter_af_resample_outputs,
> -};

I'd rather remove af_aresample.c (and port af_resample.c to
libswsresample or whatever if you want), because af_resample.c has the
better filter name.
Rostislav Pehlivanov March 6, 2017, 8:36 a.m. UTC | #2
On 6 March 2017 at 07:51, wm4 <nfxjfg@googlemail.com> wrote:

>
> I'd rather remove af_aresample.c (and port af_resample.c to
> libswsresample or whatever if you want), because af_resample.c has the
> better filter name.
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>

I'll post a separate commit to rename af_aresample to af_resample and also
register the filter as af_aresample to keep compatibility for now.
James Almer March 6, 2017, 10:45 p.m. UTC | #3
On 3/5/2017 11:46 PM, Rostislav Pehlivanov wrote:
> af_aresample does the same thing better and doesn't depend on
> libavresample

But it depends on libswresample. What about the builds that are using
lavr but nor lswr?

Is the purpose of this set to pave the way for a lavr removal? Because
one thing is dropping ABI compatibility with libav since it was being a
pain in the ass and probably not even working, but another is dropping
whole modules or being increasingly API incompatible.

If it gets in the way of some addition or refactoring then sure, I'm ok
with an eventual removal, but if it's just "Redundant filter/library I
don't want around" then not so much, because said redundancy was accepted
in the first place to make downstream projects' and users' lives easier.

> 
> Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
> ---
>  libavfilter/Makefile      |   1 -
>  libavfilter/af_resample.c | 357 ----------------------------------------------
>  2 files changed, 358 deletions(-)
>  delete mode 100644 libavfilter/af_resample.c
> 
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 0ba1c74a26..6b9fba2d4c 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -98,7 +98,6 @@ OBJS-$(CONFIG_LOUDNORM_FILTER)               += af_loudnorm.o ebur128.o
>  OBJS-$(CONFIG_LOWPASS_FILTER)                += af_biquads.o
>  OBJS-$(CONFIG_PAN_FILTER)                    += af_pan.o
>  OBJS-$(CONFIG_REPLAYGAIN_FILTER)             += af_replaygain.o
> -OBJS-$(CONFIG_RESAMPLE_FILTER)               += af_resample.o
>  OBJS-$(CONFIG_RUBBERBAND_FILTER)             += af_rubberband.o
>  OBJS-$(CONFIG_SIDECHAINCOMPRESS_FILTER)      += af_sidechaincompress.o
>  OBJS-$(CONFIG_SIDECHAINGATE_FILTER)          += af_agate.o
> diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c
> deleted file mode 100644
> index e3c6a20696..0000000000
> --- a/libavfilter/af_resample.c
> +++ /dev/null
> @@ -1,357 +0,0 @@
> -/*
> - * 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
> - * sample format and channel layout conversion audio filter
> - */
> -
> -#include "libavutil/avassert.h"
> -#include "libavutil/avstring.h"
> -#include "libavutil/common.h"
> -#include "libavutil/dict.h"
> -#include "libavutil/mathematics.h"
> -#include "libavutil/opt.h"
> -
> -#include "libavresample/avresample.h"
> -
> -#include "audio.h"
> -#include "avfilter.h"
> -#include "formats.h"
> -#include "internal.h"
> -
> -typedef struct ResampleContext {
> -    const AVClass *class;
> -    AVAudioResampleContext *avr;
> -    AVDictionary *options;
> -
> -    int resampling;
> -    int64_t next_pts;
> -    int64_t next_in_pts;
> -
> -    /* set by filter_frame() to signal an output frame to request_frame() */
> -    int got_output;
> -} ResampleContext;
> -
> -static av_cold int init(AVFilterContext *ctx, AVDictionary **opts)
> -{
> -    ResampleContext *s = ctx->priv;
> -    const AVClass *avr_class = avresample_get_class();
> -    AVDictionaryEntry *e = NULL;
> -
> -    while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
> -        if (av_opt_find(&avr_class, e->key, NULL, 0,
> -                        AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN))
> -            av_dict_set(&s->options, e->key, e->value, 0);
> -    }
> -
> -    e = NULL;
> -    while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
> -        av_dict_set(opts, e->key, NULL, 0);
> -
> -    /* do not allow the user to override basic format options */
> -    av_dict_set(&s->options,  "in_channel_layout", NULL, 0);
> -    av_dict_set(&s->options, "out_channel_layout", NULL, 0);
> -    av_dict_set(&s->options,  "in_sample_fmt",     NULL, 0);
> -    av_dict_set(&s->options, "out_sample_fmt",     NULL, 0);
> -    av_dict_set(&s->options,  "in_sample_rate",    NULL, 0);
> -    av_dict_set(&s->options, "out_sample_rate",    NULL, 0);
> -
> -    return 0;
> -}
> -
> -static av_cold void uninit(AVFilterContext *ctx)
> -{
> -    ResampleContext *s = ctx->priv;
> -
> -    if (s->avr) {
> -        avresample_close(s->avr);
> -        avresample_free(&s->avr);
> -    }
> -    av_dict_free(&s->options);
> -}
> -
> -static int query_formats(AVFilterContext *ctx)
> -{
> -    AVFilterLink *inlink  = ctx->inputs[0];
> -    AVFilterLink *outlink = ctx->outputs[0];
> -    AVFilterFormats *in_formats, *out_formats, *in_samplerates, *out_samplerates;
> -    AVFilterChannelLayouts *in_layouts, *out_layouts;
> -    int ret;
> -
> -    if (!(in_formats      = ff_all_formats         (AVMEDIA_TYPE_AUDIO)) ||
> -        !(out_formats     = ff_all_formats         (AVMEDIA_TYPE_AUDIO)) ||
> -        !(in_samplerates  = ff_all_samplerates     (                  )) ||
> -        !(out_samplerates = ff_all_samplerates     (                  )) ||
> -        !(in_layouts      = ff_all_channel_layouts (                  )) ||
> -        !(out_layouts     = ff_all_channel_layouts (                  )))
> -        return AVERROR(ENOMEM);
> -
> -    if ((ret = ff_formats_ref         (in_formats,      &inlink->out_formats        )) < 0 ||
> -        (ret = ff_formats_ref         (out_formats,     &outlink->in_formats        )) < 0 ||
> -        (ret = ff_formats_ref         (in_samplerates,  &inlink->out_samplerates    )) < 0 ||
> -        (ret = ff_formats_ref         (out_samplerates, &outlink->in_samplerates    )) < 0 ||
> -        (ret = ff_channel_layouts_ref (in_layouts,      &inlink->out_channel_layouts)) < 0 ||
> -        (ret = ff_channel_layouts_ref (out_layouts,     &outlink->in_channel_layouts)) < 0)
> -        return ret;
> -
> -    return 0;
> -}
> -
> -static int config_output(AVFilterLink *outlink)
> -{
> -    AVFilterContext *ctx = outlink->src;
> -    AVFilterLink *inlink = ctx->inputs[0];
> -    ResampleContext   *s = ctx->priv;
> -    char buf1[64], buf2[64];
> -    int ret;
> -
> -    int64_t resampling_forced;
> -
> -    if (s->avr) {
> -        avresample_close(s->avr);
> -        avresample_free(&s->avr);
> -    }
> -
> -    if (inlink->channel_layout == outlink->channel_layout &&
> -        inlink->sample_rate    == outlink->sample_rate    &&
> -        (inlink->format        == outlink->format ||
> -        (av_get_channel_layout_nb_channels(inlink->channel_layout)  == 1 &&
> -         av_get_channel_layout_nb_channels(outlink->channel_layout) == 1 &&
> -         av_get_planar_sample_fmt(inlink->format) ==
> -         av_get_planar_sample_fmt(outlink->format))))
> -        return 0;
> -
> -    if (!(s->avr = avresample_alloc_context()))
> -        return AVERROR(ENOMEM);
> -
> -    if (s->options) {
> -        int ret;
> -        AVDictionaryEntry *e = NULL;
> -        while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
> -            av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value);
> -
> -        ret = av_opt_set_dict(s->avr, &s->options);
> -        if (ret < 0)
> -            return ret;
> -    }
> -
> -    av_opt_set_int(s->avr,  "in_channel_layout", inlink ->channel_layout, 0);
> -    av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0);
> -    av_opt_set_int(s->avr,  "in_sample_fmt",     inlink ->format,         0);
> -    av_opt_set_int(s->avr, "out_sample_fmt",     outlink->format,         0);
> -    av_opt_set_int(s->avr,  "in_sample_rate",    inlink ->sample_rate,    0);
> -    av_opt_set_int(s->avr, "out_sample_rate",    outlink->sample_rate,    0);
> -
> -    if ((ret = avresample_open(s->avr)) < 0)
> -        return ret;
> -
> -    av_opt_get_int(s->avr, "force_resampling", 0, &resampling_forced);
> -    s->resampling = resampling_forced || (inlink->sample_rate != outlink->sample_rate);
> -
> -    if (s->resampling) {
> -        outlink->time_base = (AVRational){ 1, outlink->sample_rate };
> -        s->next_pts        = AV_NOPTS_VALUE;
> -        s->next_in_pts     = AV_NOPTS_VALUE;
> -    } else
> -        outlink->time_base = inlink->time_base;
> -
> -    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(ctx, AV_LOG_VERBOSE,
> -           "fmt:%s srate:%d cl:%s -> fmt:%s srate:%d cl:%s\n",
> -           av_get_sample_fmt_name(inlink ->format), inlink ->sample_rate, buf1,
> -           av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf2);
> -
> -    return 0;
> -}
> -
> -static int request_frame(AVFilterLink *outlink)
> -{
> -    AVFilterContext *ctx = outlink->src;
> -    ResampleContext   *s = ctx->priv;
> -    int ret = 0;
> -
> -    s->got_output = 0;
> -    while (ret >= 0 && !s->got_output)
> -        ret = ff_request_frame(ctx->inputs[0]);
> -
> -    /* flush the lavr delay buffer */
> -    if (ret == AVERROR_EOF && s->avr) {
> -        AVFrame *frame;
> -        int nb_samples = avresample_get_out_samples(s->avr, 0);
> -
> -        if (!nb_samples)
> -            return ret;
> -
> -        frame = ff_get_audio_buffer(outlink, nb_samples);
> -        if (!frame)
> -            return AVERROR(ENOMEM);
> -
> -        ret = avresample_convert(s->avr, frame->extended_data,
> -                                 frame->linesize[0], nb_samples,
> -                                 NULL, 0, 0);
> -        if (ret <= 0) {
> -            av_frame_free(&frame);
> -            return (ret == 0) ? AVERROR_EOF : ret;
> -        }
> -
> -        frame->nb_samples = ret;
> -        frame->pts = s->next_pts;
> -        return ff_filter_frame(outlink, frame);
> -    }
> -    return ret;
> -}
> -
> -static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> -{
> -    AVFilterContext  *ctx = inlink->dst;
> -    ResampleContext    *s = ctx->priv;
> -    AVFilterLink *outlink = ctx->outputs[0];
> -    int ret;
> -
> -    if (s->avr) {
> -        AVFrame *out;
> -        int delay, nb_samples;
> -
> -        /* maximum possible samples lavr can output */
> -        delay      = avresample_get_delay(s->avr);
> -        nb_samples = avresample_get_out_samples(s->avr, in->nb_samples);
> -
> -        out = ff_get_audio_buffer(outlink, nb_samples);
> -        if (!out) {
> -            ret = AVERROR(ENOMEM);
> -            goto fail;
> -        }
> -
> -        ret = avresample_convert(s->avr, out->extended_data, out->linesize[0],
> -                                 nb_samples, in->extended_data, in->linesize[0],
> -                                 in->nb_samples);
> -        if (ret <= 0) {
> -            av_frame_free(&out);
> -            if (ret < 0)
> -                goto fail;
> -        }
> -
> -        av_assert0(!avresample_available(s->avr));
> -
> -        if (s->resampling && s->next_pts == AV_NOPTS_VALUE) {
> -            if (in->pts == AV_NOPTS_VALUE) {
> -                av_log(ctx, AV_LOG_WARNING, "First timestamp is missing, "
> -                       "assuming 0.\n");
> -                s->next_pts = 0;
> -            } else
> -                s->next_pts = av_rescale_q(in->pts, inlink->time_base,
> -                                           outlink->time_base);
> -        }
> -
> -        if (ret > 0) {
> -            out->nb_samples = ret;
> -
> -            ret = av_frame_copy_props(out, in);
> -            if (ret < 0) {
> -                av_frame_free(&out);
> -                goto fail;
> -            }
> -
> -            if (s->resampling) {
> -                out->sample_rate = outlink->sample_rate;
> -                /* Only convert in->pts if there is a discontinuous jump.
> -                   This ensures that out->pts tracks the number of samples actually
> -                   output by the resampler in the absence of such a jump.
> -                   Otherwise, the rounding in av_rescale_q() and av_rescale()
> -                   causes off-by-1 errors. */
> -                if (in->pts != AV_NOPTS_VALUE && in->pts != s->next_in_pts) {
> -                    out->pts = av_rescale_q(in->pts, inlink->time_base,
> -                                                outlink->time_base) -
> -                                   av_rescale(delay, outlink->sample_rate,
> -                                              inlink->sample_rate);
> -                } else
> -                    out->pts = s->next_pts;
> -
> -                s->next_pts = out->pts + out->nb_samples;
> -                s->next_in_pts = in->pts + in->nb_samples;
> -            } else
> -                out->pts = in->pts;
> -
> -            ret = ff_filter_frame(outlink, out);
> -            s->got_output = 1;
> -        }
> -
> -fail:
> -        av_frame_free(&in);
> -    } else {
> -        in->format = outlink->format;
> -        ret = ff_filter_frame(outlink, in);
> -        s->got_output = 1;
> -    }
> -
> -    return ret;
> -}
> -
> -static const AVClass *resample_child_class_next(const AVClass *prev)
> -{
> -    return prev ? NULL : avresample_get_class();
> -}
> -
> -static void *resample_child_next(void *obj, void *prev)
> -{
> -    ResampleContext *s = obj;
> -    return prev ? NULL : s->avr;
> -}
> -
> -static const AVClass resample_class = {
> -    .class_name       = "resample",
> -    .item_name        = av_default_item_name,
> -    .version          = LIBAVUTIL_VERSION_INT,
> -    .child_class_next = resample_child_class_next,
> -    .child_next       = resample_child_next,
> -};
> -
> -static const AVFilterPad avfilter_af_resample_inputs[] = {
> -    {
> -        .name          = "default",
> -        .type          = AVMEDIA_TYPE_AUDIO,
> -        .filter_frame  = filter_frame,
> -    },
> -    { NULL }
> -};
> -
> -static const AVFilterPad avfilter_af_resample_outputs[] = {
> -    {
> -        .name          = "default",
> -        .type          = AVMEDIA_TYPE_AUDIO,
> -        .config_props  = config_output,
> -        .request_frame = request_frame
> -    },
> -    { NULL }
> -};
> -
> -AVFilter ff_af_resample = {
> -    .name          = "resample",
> -    .description   = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."),
> -    .priv_size     = sizeof(ResampleContext),
> -    .priv_class    = &resample_class,
> -    .init_dict     = init,
> -    .uninit        = uninit,
> -    .query_formats = query_formats,
> -    .inputs        = avfilter_af_resample_inputs,
> -    .outputs       = avfilter_af_resample_outputs,
> -};
>
Rostislav Pehlivanov March 6, 2017, 11:20 p.m. UTC | #4
On 6 March 2017 at 22:45, James Almer <jamrial@gmail.com> wrote:

> On 3/5/2017 11:46 PM, Rostislav Pehlivanov wrote:
> > af_aresample does the same thing better and doesn't depend on
> > libavresample
>
> But it depends on libswresample. What about the builds that are using
> lavr but nor lswr?
>

You mean that library which is disabled by default? We tell people to use
the actual stuff we support rather than the stuff we've let in "for
convenience", like we've done for the past 5 bloody years.


>
> Is the purpose of this set to pave the way for a lavr removal? Because
> one thing is dropping ABI compatibility with libav since it was being a
> pain in the ass and probably not even working, but another is dropping
> whole modules or being increasingly API incompatible.
>
>
So what if it is?
I'm not interested if it take 1 month, 6 months, a year, 2 years, that crap
is getting out of our code. If you ask me it should never have been merged.
I'll write a shim just to keep people like you happy.


> If it gets in the way of some addition or refactoring then sure, I'm ok
> with an eventual removal, but if it's just "Redundant filter/library I
> don't want around" then not so much, because said redundancy was accepted
> in the first place to make downstream projects' and users' lives easier.
>
>
And who's going to maintain it once their project dies? We? We already have
a better resampling library in our code. We won't need it.
As I said before I'll write a fucking API shim when I submit the patches to
kill that thing. Even if its half working it'll still work just about as
well as that thing's idea of "resampling".



Anyway I'm pushing this patch in a few days unless someone objects validly.
James Almer March 6, 2017, 11:58 p.m. UTC | #5
On 3/6/2017 8:20 PM, Rostislav Pehlivanov wrote:
> On 6 March 2017 at 22:45, James Almer <jamrial@gmail.com> wrote:
> 
>> On 3/5/2017 11:46 PM, Rostislav Pehlivanov wrote:
>>> af_aresample does the same thing better and doesn't depend on
>>> libavresample
>>
>> But it depends on libswresample. What about the builds that are using
>> lavr but nor lswr?
>>
> 
> You mean that library which is disabled by default? We tell people to use
> the actual stuff we support rather than the stuff we've let in "for
> convenience", like we've done for the past 5 bloody years.

Yes, the library we disable by default but that some downstream projects
enable to easily support both projects without a massive amount of custom
codepaths or ifdeffery.

> 
> 
>>
>> Is the purpose of this set to pave the way for a lavr removal? Because
>> one thing is dropping ABI compatibility with libav since it was being a
>> pain in the ass and probably not even working, but another is dropping
>> whole modules or being increasingly API incompatible.
>>
>>
> So what if it is?
> I'm not interested if it take 1 month, 6 months, a year, 2 years, that crap
> is getting out of our code. If you ask me it should never have been merged.

You seem to have forgotten the very long years where Debian shipped libav
and not ffmpeg. Had we not merged that library and dropped API/ABI support
from the get go, who knows what would have happened.

> I'll write a shim just to keep people like you happy.

I'd very much like if every other of your emails could stop being so
aggressive when it's completely unjustifiable. You seem to be reacting to
some old frustration with this code (or code you dislike in general) rather
than to an email by "people like me" where I'm simply expressing the need
to not disrupt downstream projects too much unless necessary.

> 
> 
>> If it gets in the way of some addition or refactoring then sure, I'm ok
>> with an eventual removal, but if it's just "Redundant filter/library I
>> don't want around" then not so much, because said redundancy was accepted
>> in the first place to make downstream projects' and users' lives easier.
>>
>>
> And who's going to maintain it once their project dies? We? We already have
> a better resampling library in our code. We won't need it.
> As I said before I'll write a fucking API shim when I submit the patches to
> kill that thing. Even if its half working it'll still work just about as
> well as that thing's idea of "resampling".
> 
> Anyway I'm pushing this patch in a few days unless someone objects validly.

My concerns are very valid, and i ask you again to drop the aggressiveness.
You'll write a shim? That's great. Just don't be a dick when you're informing
me about it.

And for that matter, if the general consensus is to drop all pretenses of API
compatibility then i have no issues with all this. You wouldn't even need to
write a shim in that case.
wm4 March 7, 2017, 6:37 a.m. UTC | #6
On Mon, 6 Mar 2017 20:58:53 -0300
James Almer <jamrial@gmail.com> wrote:

> On 3/6/2017 8:20 PM, Rostislav Pehlivanov wrote:
> > On 6 March 2017 at 22:45, James Almer <jamrial@gmail.com> wrote:
> >   
> >> On 3/5/2017 11:46 PM, Rostislav Pehlivanov wrote:  
> >>> af_aresample does the same thing better and doesn't depend on
> >>> libavresample  
> >>
> >> But it depends on libswresample. What about the builds that are using
> >> lavr but nor lswr?
> >>  
> > 
> > You mean that library which is disabled by default? We tell people to use
> > the actual stuff we support rather than the stuff we've let in "for
> > convenience", like we've done for the past 5 bloody years.  
> 
> Yes, the library we disable by default but that some downstream projects
> enable to easily support both projects without a massive amount of custom
> codepaths or ifdeffery.

I still think that it's moronic bullshit to disable lavr by default.
How about you don't take your moronic fork drama bullshit out on your
API users?

> > 
> >   
> >>
> >> Is the purpose of this set to pave the way for a lavr removal? Because
> >> one thing is dropping ABI compatibility with libav since it was being a
> >> pain in the ass and probably not even working, but another is dropping
> >> whole modules or being increasingly API incompatible.
> >>
> >>  
> > So what if it is?
> > I'm not interested if it take 1 month, 6 months, a year, 2 years, that crap
> > is getting out of our code. If you ask me it should never have been merged.  
> 
> You seem to have forgotten the very long years where Debian shipped libav
> and not ffmpeg. Had we not merged that library and dropped API/ABI support
> from the get go, who knows what would have happened.

I doubt anyone really made use of the ABI compat. (you needed a special
configure flag to make fully use of it).

> > I'll write a shim just to keep people like you happy.  
> 
> I'd very much like if every other of your emails could stop being so
> aggressive when it's completely unjustifiable. You seem to be reacting to
> some old frustration with this code (or code you dislike in general) rather
> than to an email by "people like me" where I'm simply expressing the need
> to not disrupt downstream projects too much unless necessary.
> 
> > 
> >   
> >> If it gets in the way of some addition or refactoring then sure, I'm ok
> >> with an eventual removal, but if it's just "Redundant filter/library I
> >> don't want around" then not so much, because said redundancy was accepted
> >> in the first place to make downstream projects' and users' lives easier.
> >>
> >>  
> > And who's going to maintain it once their project dies? We? We already have
> > a better resampling library in our code. We won't need it.
> > As I said before I'll write a fucking API shim when I submit the patches to
> > kill that thing. Even if its half working it'll still work just about as
> > well as that thing's idea of "resampling".
> > 
> > Anyway I'm pushing this patch in a few days unless someone objects validly.  
> 
> My concerns are very valid, and i ask you again to drop the aggressiveness.
> You'll write a shim? That's great. Just don't be a dick when you're informing
> me about it.
> 
> And for that matter, if the general consensus is to drop all pretenses of API
> compatibility then i have no issues with all this. You wouldn't even need to
> write a shim in that case.

Who is talking about dropping API-compatibility? As long as there are
aliases for these extremely similar filters, the level of potential
breakages should be very minimal. I'm all for removing redundant code.
(Patch 2/4 is potentially contentious, but if someone tried to use that
in a portable way, he had to ifdef it between FFmpeg/Libav anyway,
because the main use is changing the options of auto-inserted
resamplers.)
Carl Eugen Hoyos March 7, 2017, 7:15 a.m. UTC | #7
2017-03-07 7:37 GMT+01:00 wm4 <nfxjfg@googlemail.com>:

> I still think that it's moronic bullshit to disable lavr by default.
> How about you don't take your moronic fork drama bullshit out on your
> API users?

How about you stop breaking development rules for once?

Carl Eugen
diff mbox

Patch

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 0ba1c74a26..6b9fba2d4c 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -98,7 +98,6 @@  OBJS-$(CONFIG_LOUDNORM_FILTER)               += af_loudnorm.o ebur128.o
 OBJS-$(CONFIG_LOWPASS_FILTER)                += af_biquads.o
 OBJS-$(CONFIG_PAN_FILTER)                    += af_pan.o
 OBJS-$(CONFIG_REPLAYGAIN_FILTER)             += af_replaygain.o
-OBJS-$(CONFIG_RESAMPLE_FILTER)               += af_resample.o
 OBJS-$(CONFIG_RUBBERBAND_FILTER)             += af_rubberband.o
 OBJS-$(CONFIG_SIDECHAINCOMPRESS_FILTER)      += af_sidechaincompress.o
 OBJS-$(CONFIG_SIDECHAINGATE_FILTER)          += af_agate.o
diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c
deleted file mode 100644
index e3c6a20696..0000000000
--- a/libavfilter/af_resample.c
+++ /dev/null
@@ -1,357 +0,0 @@ 
-/*
- * 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
- * sample format and channel layout conversion audio filter
- */
-
-#include "libavutil/avassert.h"
-#include "libavutil/avstring.h"
-#include "libavutil/common.h"
-#include "libavutil/dict.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/opt.h"
-
-#include "libavresample/avresample.h"
-
-#include "audio.h"
-#include "avfilter.h"
-#include "formats.h"
-#include "internal.h"
-
-typedef struct ResampleContext {
-    const AVClass *class;
-    AVAudioResampleContext *avr;
-    AVDictionary *options;
-
-    int resampling;
-    int64_t next_pts;
-    int64_t next_in_pts;
-
-    /* set by filter_frame() to signal an output frame to request_frame() */
-    int got_output;
-} ResampleContext;
-
-static av_cold int init(AVFilterContext *ctx, AVDictionary **opts)
-{
-    ResampleContext *s = ctx->priv;
-    const AVClass *avr_class = avresample_get_class();
-    AVDictionaryEntry *e = NULL;
-
-    while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
-        if (av_opt_find(&avr_class, e->key, NULL, 0,
-                        AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN))
-            av_dict_set(&s->options, e->key, e->value, 0);
-    }
-
-    e = NULL;
-    while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
-        av_dict_set(opts, e->key, NULL, 0);
-
-    /* do not allow the user to override basic format options */
-    av_dict_set(&s->options,  "in_channel_layout", NULL, 0);
-    av_dict_set(&s->options, "out_channel_layout", NULL, 0);
-    av_dict_set(&s->options,  "in_sample_fmt",     NULL, 0);
-    av_dict_set(&s->options, "out_sample_fmt",     NULL, 0);
-    av_dict_set(&s->options,  "in_sample_rate",    NULL, 0);
-    av_dict_set(&s->options, "out_sample_rate",    NULL, 0);
-
-    return 0;
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
-    ResampleContext *s = ctx->priv;
-
-    if (s->avr) {
-        avresample_close(s->avr);
-        avresample_free(&s->avr);
-    }
-    av_dict_free(&s->options);
-}
-
-static int query_formats(AVFilterContext *ctx)
-{
-    AVFilterLink *inlink  = ctx->inputs[0];
-    AVFilterLink *outlink = ctx->outputs[0];
-    AVFilterFormats *in_formats, *out_formats, *in_samplerates, *out_samplerates;
-    AVFilterChannelLayouts *in_layouts, *out_layouts;
-    int ret;
-
-    if (!(in_formats      = ff_all_formats         (AVMEDIA_TYPE_AUDIO)) ||
-        !(out_formats     = ff_all_formats         (AVMEDIA_TYPE_AUDIO)) ||
-        !(in_samplerates  = ff_all_samplerates     (                  )) ||
-        !(out_samplerates = ff_all_samplerates     (                  )) ||
-        !(in_layouts      = ff_all_channel_layouts (                  )) ||
-        !(out_layouts     = ff_all_channel_layouts (                  )))
-        return AVERROR(ENOMEM);
-
-    if ((ret = ff_formats_ref         (in_formats,      &inlink->out_formats        )) < 0 ||
-        (ret = ff_formats_ref         (out_formats,     &outlink->in_formats        )) < 0 ||
-        (ret = ff_formats_ref         (in_samplerates,  &inlink->out_samplerates    )) < 0 ||
-        (ret = ff_formats_ref         (out_samplerates, &outlink->in_samplerates    )) < 0 ||
-        (ret = ff_channel_layouts_ref (in_layouts,      &inlink->out_channel_layouts)) < 0 ||
-        (ret = ff_channel_layouts_ref (out_layouts,     &outlink->in_channel_layouts)) < 0)
-        return ret;
-
-    return 0;
-}
-
-static int config_output(AVFilterLink *outlink)
-{
-    AVFilterContext *ctx = outlink->src;
-    AVFilterLink *inlink = ctx->inputs[0];
-    ResampleContext   *s = ctx->priv;
-    char buf1[64], buf2[64];
-    int ret;
-
-    int64_t resampling_forced;
-
-    if (s->avr) {
-        avresample_close(s->avr);
-        avresample_free(&s->avr);
-    }
-
-    if (inlink->channel_layout == outlink->channel_layout &&
-        inlink->sample_rate    == outlink->sample_rate    &&
-        (inlink->format        == outlink->format ||
-        (av_get_channel_layout_nb_channels(inlink->channel_layout)  == 1 &&
-         av_get_channel_layout_nb_channels(outlink->channel_layout) == 1 &&
-         av_get_planar_sample_fmt(inlink->format) ==
-         av_get_planar_sample_fmt(outlink->format))))
-        return 0;
-
-    if (!(s->avr = avresample_alloc_context()))
-        return AVERROR(ENOMEM);
-
-    if (s->options) {
-        int ret;
-        AVDictionaryEntry *e = NULL;
-        while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
-            av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value);
-
-        ret = av_opt_set_dict(s->avr, &s->options);
-        if (ret < 0)
-            return ret;
-    }
-
-    av_opt_set_int(s->avr,  "in_channel_layout", inlink ->channel_layout, 0);
-    av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0);
-    av_opt_set_int(s->avr,  "in_sample_fmt",     inlink ->format,         0);
-    av_opt_set_int(s->avr, "out_sample_fmt",     outlink->format,         0);
-    av_opt_set_int(s->avr,  "in_sample_rate",    inlink ->sample_rate,    0);
-    av_opt_set_int(s->avr, "out_sample_rate",    outlink->sample_rate,    0);
-
-    if ((ret = avresample_open(s->avr)) < 0)
-        return ret;
-
-    av_opt_get_int(s->avr, "force_resampling", 0, &resampling_forced);
-    s->resampling = resampling_forced || (inlink->sample_rate != outlink->sample_rate);
-
-    if (s->resampling) {
-        outlink->time_base = (AVRational){ 1, outlink->sample_rate };
-        s->next_pts        = AV_NOPTS_VALUE;
-        s->next_in_pts     = AV_NOPTS_VALUE;
-    } else
-        outlink->time_base = inlink->time_base;
-
-    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(ctx, AV_LOG_VERBOSE,
-           "fmt:%s srate:%d cl:%s -> fmt:%s srate:%d cl:%s\n",
-           av_get_sample_fmt_name(inlink ->format), inlink ->sample_rate, buf1,
-           av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf2);
-
-    return 0;
-}
-
-static int request_frame(AVFilterLink *outlink)
-{
-    AVFilterContext *ctx = outlink->src;
-    ResampleContext   *s = ctx->priv;
-    int ret = 0;
-
-    s->got_output = 0;
-    while (ret >= 0 && !s->got_output)
-        ret = ff_request_frame(ctx->inputs[0]);
-
-    /* flush the lavr delay buffer */
-    if (ret == AVERROR_EOF && s->avr) {
-        AVFrame *frame;
-        int nb_samples = avresample_get_out_samples(s->avr, 0);
-
-        if (!nb_samples)
-            return ret;
-
-        frame = ff_get_audio_buffer(outlink, nb_samples);
-        if (!frame)
-            return AVERROR(ENOMEM);
-
-        ret = avresample_convert(s->avr, frame->extended_data,
-                                 frame->linesize[0], nb_samples,
-                                 NULL, 0, 0);
-        if (ret <= 0) {
-            av_frame_free(&frame);
-            return (ret == 0) ? AVERROR_EOF : ret;
-        }
-
-        frame->nb_samples = ret;
-        frame->pts = s->next_pts;
-        return ff_filter_frame(outlink, frame);
-    }
-    return ret;
-}
-
-static int filter_frame(AVFilterLink *inlink, AVFrame *in)
-{
-    AVFilterContext  *ctx = inlink->dst;
-    ResampleContext    *s = ctx->priv;
-    AVFilterLink *outlink = ctx->outputs[0];
-    int ret;
-
-    if (s->avr) {
-        AVFrame *out;
-        int delay, nb_samples;
-
-        /* maximum possible samples lavr can output */
-        delay      = avresample_get_delay(s->avr);
-        nb_samples = avresample_get_out_samples(s->avr, in->nb_samples);
-
-        out = ff_get_audio_buffer(outlink, nb_samples);
-        if (!out) {
-            ret = AVERROR(ENOMEM);
-            goto fail;
-        }
-
-        ret = avresample_convert(s->avr, out->extended_data, out->linesize[0],
-                                 nb_samples, in->extended_data, in->linesize[0],
-                                 in->nb_samples);
-        if (ret <= 0) {
-            av_frame_free(&out);
-            if (ret < 0)
-                goto fail;
-        }
-
-        av_assert0(!avresample_available(s->avr));
-
-        if (s->resampling && s->next_pts == AV_NOPTS_VALUE) {
-            if (in->pts == AV_NOPTS_VALUE) {
-                av_log(ctx, AV_LOG_WARNING, "First timestamp is missing, "
-                       "assuming 0.\n");
-                s->next_pts = 0;
-            } else
-                s->next_pts = av_rescale_q(in->pts, inlink->time_base,
-                                           outlink->time_base);
-        }
-
-        if (ret > 0) {
-            out->nb_samples = ret;
-
-            ret = av_frame_copy_props(out, in);
-            if (ret < 0) {
-                av_frame_free(&out);
-                goto fail;
-            }
-
-            if (s->resampling) {
-                out->sample_rate = outlink->sample_rate;
-                /* Only convert in->pts if there is a discontinuous jump.
-                   This ensures that out->pts tracks the number of samples actually
-                   output by the resampler in the absence of such a jump.
-                   Otherwise, the rounding in av_rescale_q() and av_rescale()
-                   causes off-by-1 errors. */
-                if (in->pts != AV_NOPTS_VALUE && in->pts != s->next_in_pts) {
-                    out->pts = av_rescale_q(in->pts, inlink->time_base,
-                                                outlink->time_base) -
-                                   av_rescale(delay, outlink->sample_rate,
-                                              inlink->sample_rate);
-                } else
-                    out->pts = s->next_pts;
-
-                s->next_pts = out->pts + out->nb_samples;
-                s->next_in_pts = in->pts + in->nb_samples;
-            } else
-                out->pts = in->pts;
-
-            ret = ff_filter_frame(outlink, out);
-            s->got_output = 1;
-        }
-
-fail:
-        av_frame_free(&in);
-    } else {
-        in->format = outlink->format;
-        ret = ff_filter_frame(outlink, in);
-        s->got_output = 1;
-    }
-
-    return ret;
-}
-
-static const AVClass *resample_child_class_next(const AVClass *prev)
-{
-    return prev ? NULL : avresample_get_class();
-}
-
-static void *resample_child_next(void *obj, void *prev)
-{
-    ResampleContext *s = obj;
-    return prev ? NULL : s->avr;
-}
-
-static const AVClass resample_class = {
-    .class_name       = "resample",
-    .item_name        = av_default_item_name,
-    .version          = LIBAVUTIL_VERSION_INT,
-    .child_class_next = resample_child_class_next,
-    .child_next       = resample_child_next,
-};
-
-static const AVFilterPad avfilter_af_resample_inputs[] = {
-    {
-        .name          = "default",
-        .type          = AVMEDIA_TYPE_AUDIO,
-        .filter_frame  = filter_frame,
-    },
-    { NULL }
-};
-
-static const AVFilterPad avfilter_af_resample_outputs[] = {
-    {
-        .name          = "default",
-        .type          = AVMEDIA_TYPE_AUDIO,
-        .config_props  = config_output,
-        .request_frame = request_frame
-    },
-    { NULL }
-};
-
-AVFilter ff_af_resample = {
-    .name          = "resample",
-    .description   = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."),
-    .priv_size     = sizeof(ResampleContext),
-    .priv_class    = &resample_class,
-    .init_dict     = init,
-    .uninit        = uninit,
-    .query_formats = query_formats,
-    .inputs        = avfilter_af_resample_inputs,
-    .outputs       = avfilter_af_resample_outputs,
-};