2019-04-18 23:17 GMT+02:00, Paul B Mahol <one...@gmail.com>: > Signed-off-by: Paul B Mahol <one...@gmail.com> > --- > libavfilter/Makefile | 1 + > libavfilter/af_aupsample.c | 159 +++++++++++++++++++++++++++++++++++++ > libavfilter/allfilters.c | 1 + > 3 files changed, 161 insertions(+) > create mode 100644 libavfilter/af_aupsample.c > > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index 682df45ef5..a38bc35231 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -86,6 +86,7 @@ OBJS-$(CONFIG_ASTATS_FILTER) += > af_astats.o > OBJS-$(CONFIG_ASTREAMSELECT_FILTER) += f_streamselect.o > framesync.o > OBJS-$(CONFIG_ATEMPO_FILTER) += af_atempo.o > OBJS-$(CONFIG_ATRIM_FILTER) += trim.o > +OBJS-$(CONFIG_AUPSAMPLE_FILTER) += af_aupsample.o > OBJS-$(CONFIG_AZMQ_FILTER) += f_zmq.o > OBJS-$(CONFIG_BANDPASS_FILTER) += af_biquads.o > OBJS-$(CONFIG_BANDREJECT_FILTER) += af_biquads.o > diff --git a/libavfilter/af_aupsample.c b/libavfilter/af_aupsample.c > new file mode 100644 > index 0000000000..ee35b9c0c6 > --- /dev/null > +++ b/libavfilter/af_aupsample.c > @@ -0,0 +1,159 @@ > +/* > + * Copyright (c) 2019 Paul B Mahol > + * > + * 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 > + */ > + > +#include "libavutil/opt.h" > +#include "libavutil/samplefmt.h" > +#include "avfilter.h" > +#include "audio.h" > +#include "filters.h" > +#include "internal.h" > + > +typedef struct AudioUpSampleContext { > + const AVClass *class; > + int factor; > + > + int64_t next_pts; > +} AudioUpSampleContext; > + > +#define OFFSET(x) offsetof(AudioUpSampleContext, x) > +#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM > + > +static const AVOption aupsample_options[] = { > + { "factor", "set upsampling factor", OFFSET(factor), AV_OPT_TYPE_INT, > {.i64=1}, 1, 64, A }, > + { NULL } > +}; > + > +AVFILTER_DEFINE_CLASS(aupsample); > + > +static int query_formats(AVFilterContext *ctx) > +{ > + AudioUpSampleContext *s = ctx->priv; > + AVFilterChannelLayouts *layouts; > + AVFilterFormats *formats; > + int sample_rates[] = { 44100, -1 }; > + static const enum AVSampleFormat sample_fmts[] = { > + AV_SAMPLE_FMT_DBLP, > + AV_SAMPLE_FMT_NONE > + }; > + AVFilterFormats *avff; > + int ret; > + > + if (!ctx->inputs[0]->in_samplerates || > + !ctx->inputs[0]->in_samplerates->nb_formats) { > + return AVERROR(EAGAIN); > + } > + > + layouts = ff_all_channel_counts(); > + if (!layouts) > + return AVERROR(ENOMEM); > + ret = ff_set_common_channel_layouts(ctx, layouts); > + if (ret < 0) > + return ret; > + > + formats = ff_make_format_list(sample_fmts); > + if (!formats) > + return AVERROR(ENOMEM); > + ret = ff_set_common_formats(ctx, formats); > + if (ret < 0) > + return ret; > + > + avff = ctx->inputs[0]->in_samplerates; > + sample_rates[0] = avff->formats[0]; > + if (!ctx->inputs[0]->out_samplerates) > + if ((ret = ff_formats_ref(ff_make_format_list(sample_rates), > + &ctx->inputs[0]->out_samplerates)) < 0) > + return ret; > + > + sample_rates[0] = avff->formats[0] * s->factor; > + return ff_formats_ref(ff_make_format_list(sample_rates), > + &ctx->outputs[0]->in_samplerates); > +} > + > +static int config_input(AVFilterLink *inlink) > +{ > + AVFilterContext *ctx = inlink->dst; > + AudioUpSampleContext *s = ctx->priv; > + > + s->next_pts = AV_NOPTS_VALUE; > + > + return 0; > +} > + > +static int filter_frame(AVFilterLink *inlink, AVFrame *in) > +{ > + AVFilterContext *ctx = inlink->dst; > + AVFilterLink *outlink = ctx->outputs[0]; > + AudioUpSampleContext *s = ctx->priv; > + const int factor = s->factor; > + AVFrame *out; > + > + if (s->factor == 1) > + return ff_filter_frame(outlink, in); > + > + out = ff_get_audio_buffer(outlink, in->nb_samples * s->factor); > + if (!out) { > + av_frame_free(&in); > + return AVERROR(ENOMEM); > + } > + > + if (s->next_pts == AV_NOPTS_VALUE) > + s->next_pts = in->pts; > + > + for (int c = 0; c < in->channels; c++) { > + const double *src = (const double *)in->extended_data[c]; > + double *dst = (double *)out->extended_data[c]; > + > + for (int n = 0; n < in->nb_samples; n++) > + dst[n*factor] = src[n]; > + } > + > + out->pts = s->next_pts; > + s->next_pts += av_rescale_q(out->nb_samples, (AVRational){1, > outlink->sample_rate}, outlink->time_base); > + av_frame_free(&in); > + return ff_filter_frame(ctx->outputs[0], out); > +} > + > +static const AVFilterPad aupsample_inputs[] = { > + { > + .name = "default", > + .type = AVMEDIA_TYPE_AUDIO, > + .filter_frame = filter_frame, > + .config_props = config_input, > + }, > + { NULL } > +}; > + > +static const AVFilterPad aupsample_outputs[] = { > + { > + .name = "default", > + .type = AVMEDIA_TYPE_AUDIO, > + }, > + { NULL } > +}; > + > +AVFilter ff_af_aupsample = { > + .name = "aupsample", > + .description = NULL_IF_CONFIG_SMALL("Upsample > audio by integer factor."),
Is it faster? Better quality? Just wondering, Carl Eugen _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".