X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Faf_crystalizer.c;h=dec30aa5f48a364e72c51673a73e78f705419879;hb=8dd3a53dbf7dfbca4f8a750936f0ba3849a3f0b8;hp=086549a93d13f83a1c52b36456f1fb883dee5bce;hpb=3a033bc5cfaeec391a8258005e025ddf3971d8bc;p=ffmpeg diff --git a/libavfilter/af_crystalizer.c b/libavfilter/af_crystalizer.c index 086549a93d1..dec30aa5f48 100644 --- a/libavfilter/af_crystalizer.c +++ b/libavfilter/af_crystalizer.c @@ -29,6 +29,8 @@ typedef struct CrystalizerContext { float mult; int clip; AVFrame *prev; + void (*filter)(void **dst, void **prv, const void **src, + int nb_samples, int channels, float mult, int clip); } CrystalizerContext; #define OFFSET(x) offsetof(CrystalizerContext, x) @@ -46,10 +48,18 @@ static int query_formats(AVFilterContext *ctx) { AVFilterFormats *formats = NULL; AVFilterChannelLayouts *layouts = NULL; + static const enum AVSampleFormat sample_fmts[] = { + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_NONE + }; int ret; - if ((ret = ff_add_format (&formats, AV_SAMPLE_FMT_FLT )) < 0 || - (ret = ff_set_common_formats(ctx , formats )) < 0) + formats = ff_make_format_list(sample_fmts); + if (!formats) + return AVERROR(ENOMEM); + ret = ff_set_common_formats(ctx, formats); + if (ret < 0) return ret; layouts = ff_all_channel_counts(); @@ -64,16 +74,123 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_samplerates(ctx, formats); } +static void filter_flt(void **d, void **p, const void **s, + int nb_samples, int channels, + float mult, int clip) +{ + const float *src = s[0]; + float *dst = d[0]; + float *prv = p[0]; + int n, c; + + for (n = 0; n < nb_samples; n++) { + for (c = 0; c < channels; c++) { + float current = src[c]; + + dst[c] = current + (current - prv[c]) * mult; + prv[c] = current; + if (clip) { + dst[c] = av_clipf(dst[c], -1, 1); + } + } + + dst += c; + src += c; + } +} + +static void filter_dbl(void **d, void **p, const void **s, + int nb_samples, int channels, + float mult, int clip) +{ + const double *src = s[0]; + double *dst = d[0]; + double *prv = p[0]; + int n, c; + + for (n = 0; n < nb_samples; n++) { + for (c = 0; c < channels; c++) { + double current = src[c]; + + dst[c] = current + (current - prv[c]) * mult; + prv[c] = current; + if (clip) { + dst[c] = av_clipd(dst[c], -1, 1); + } + } + + dst += c; + src += c; + } +} + +static void filter_fltp(void **d, void **p, const void **s, + int nb_samples, int channels, + float mult, int clip) +{ + int n, c; + + for (c = 0; c < channels; c++) { + const float *src = s[c]; + float *dst = d[c]; + float *prv = p[c]; + + for (n = 0; n < nb_samples; n++) { + float current = src[n]; + + dst[n] = current + (current - prv[0]) * mult; + prv[0] = current; + if (clip) { + dst[n] = av_clipf(dst[n], -1, 1); + } + } + } +} + +static void filter_dblp(void **d, void **p, const void **s, + int nb_samples, int channels, + float mult, int clip) +{ + int n, c; + + for (c = 0; c < channels; c++) { + const double *src = s[c]; + double *dst = d[c]; + double *prv = p[c]; + + for (n = 0; n < nb_samples; n++) { + double current = src[n]; + + dst[n] = current + (current - prv[0]) * mult; + prv[0] = current; + if (clip) { + dst[n] = av_clipd(dst[n], -1, 1); + } + } + } +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + CrystalizerContext *s = ctx->priv; + + switch (inlink->format) { + case AV_SAMPLE_FMT_FLT: s->filter = filter_flt; break; + case AV_SAMPLE_FMT_DBL: s->filter = filter_dbl; break; + case AV_SAMPLE_FMT_FLTP: s->filter = filter_fltp; break; + case AV_SAMPLE_FMT_DBLP: s->filter = filter_dblp; break; + } + + return 0; +} + static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; CrystalizerContext *s = ctx->priv; - const float *src = (const float *)in->data[0]; - const float mult = s->mult; AVFrame *out; - float *dst, *prv; - int n, c; if (!s->prev) { s->prev = ff_get_audio_buffer(inlink, 1); @@ -94,22 +211,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) av_frame_copy_props(out, in); } - dst = (float *)out->data[0]; - prv = (float *)s->prev->data[0]; - - for (n = 0; n < in->nb_samples; n++) { - for (c = 0; c < in->channels; c++) { - float current = src[c]; - - dst[c] = current + (current - prv[c]) * mult; - prv[c] = current; - if (s->clip) { - dst[c] = av_clipf(dst[c], -1, 1); - } - } - dst += c; - src += c; - } + s->filter((void **)out->extended_data, (void **)s->prev->extended_data, (const void **)in->extended_data, + in->nb_samples, in->channels, s->mult, s->clip); if (out != in) av_frame_free(&in); @@ -129,6 +232,7 @@ static const AVFilterPad inputs[] = { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .filter_frame = filter_frame, + .config_props = config_input, }, { NULL } };