Re: [FFmpeg-devel] [PATCH v2] avfilter: add dumpwave filter.
Hi One more thing regarding asetnsamples->metadata I think it would be hard to set up 2 chains of them for getting 2 different “resolutions" at the same time > On 12 Jan 2018, at 08:36, Kyle Swansonwrote: > > Hi, > > Make sure you go back and read our comments. There were several things you > didn't address in your most recent patch. > > Thanks, > Kyle > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel From d15553e52b9723651bb368264d86d0c5ec414f7a Mon Sep 17 00:00:00 2001 From: Dmytro Humeniuk Date: Fri, 12 Jan 2018 23:48:23 +0100 Subject: [PATCH] avfilter: add dumpwave filter. Signed-off-by: Dmytro Humeniuk --- Changelog| 1 + doc/filters.texi | 22 libavfilter/Makefile | 1 + libavfilter/af_dumpwave.c| 233 +++ libavfilter/allfilters.c | 1 + libavfilter/version.h| 4 +- tests/fate/filter-audio.mak | 13 ++ tests/ref/fate/filter-dumpwave | 1 + tests/ref/fate/filter-dumpwave-24bit | 1 + tests/ref/fate/filter-dumpwave-fltp | 1 + 10 files changed, 276 insertions(+), 2 deletions(-) create mode 100644 libavfilter/af_dumpwave.c create mode 100644 tests/ref/fate/filter-dumpwave create mode 100644 tests/ref/fate/filter-dumpwave-24bit create mode 100644 tests/ref/fate/filter-dumpwave-fltp diff --git a/Changelog b/Changelog index 61075b3392..40fd624449 100644 --- a/Changelog +++ b/Changelog @@ -38,6 +38,7 @@ version : - Removed the ffserver program - Removed the ffmenc and ffmdec muxer and demuxer - VideoToolbox HEVC encoder and hwaccel +- dumpwave audio filter version 3.4: diff --git a/doc/filters.texi b/doc/filters.texi index bd93e0ab84..bd49a8ec91 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2538,6 +2538,28 @@ Optional. It should have a value much less than 1 (e.g. 0.05 or 0.02) and is used to prevent clipping. @end table +@section dumpwave +Dump RMS envelope to a file. +Convert samples to decibels and calculates RMS (Root-Mean-Square) audio power in 0 to 1.0 floats. + +@table @option +@item w, width +Number of data values. +The default value is @var{1800} + +@item n, nb_samples +Samples count per value per channel, default 128 + +@item f, file +Path to a file +@end table + +For example, to generate RMS envelope for 44.1 kHz 6 seconds length audio +with dimensions @var{1800x140}, samples count @code{44100*6/1800=147} and store it to @var{/tmp/out.csv}, you might use: +@example +dumpwave=w=1800:n=147:f=/tmp/out.csv +@end example + @section dynaudnorm Dynamic Audio Normalizer. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index ef4729dd3f..2ffbc9497a 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -87,6 +87,7 @@ OBJS-$(CONFIG_COMPENSATIONDELAY_FILTER) += af_compensationdelay.o OBJS-$(CONFIG_CROSSFEED_FILTER) += af_crossfeed.o OBJS-$(CONFIG_CRYSTALIZER_FILTER)+= af_crystalizer.o OBJS-$(CONFIG_DCSHIFT_FILTER)+= af_dcshift.o +OBJS-$(CONFIG_DUMPWAVE_FILTER) += af_dumpwave.o OBJS-$(CONFIG_DYNAUDNORM_FILTER) += af_dynaudnorm.o OBJS-$(CONFIG_EARWAX_FILTER) += af_earwax.o OBJS-$(CONFIG_EBUR128_FILTER)+= f_ebur128.o diff --git a/libavfilter/af_dumpwave.c b/libavfilter/af_dumpwave.c new file mode 100644 index 00..3d1653d8de --- /dev/null +++ b/libavfilter/af_dumpwave.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2017 Dmytro Humeniuk + * + * 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 + * waveform audio filter â dump RMS amplitude to file + */ + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "libavutil/parseutils.h" +#include "libavformat/avio.h" +#include "avfilter.h" +#include "formats.h" +#include "audio.h" +#include "internal.h" + +typedef struct DumpWaveContext { +const AVClass *class; /**< class for AVOptions */ +int width; /**< number of data
Re: [FFmpeg-devel] [PATCH v2] avfilter: add dumpwave filter.
> On 12 Jan 2018, at 08:36, Kyle Swansonwrote: > > Hi, > > Make sure you go back and read our comments. There were several things you > didn't address in your most recent patch. Sorry, seems I missed few emails. Sure > Thanks, > Kyle > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel smime.p7s Description: S/MIME cryptographic signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v2] avfilter: add dumpwave filter.
Hi, Make sure you go back and read our comments. There were several things you didn't address in your most recent patch. Thanks, Kyle ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v2] avfilter: add dumpwave filter.
On Thu, Jan 11, 2018 at 10:11:47PM +0100, Dmytro Humeniuk wrote: [...] > +static const AVOption dumpwave_options[] = { > +{ "s", "set width and height", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str > = "1800x140"}, 0, 0, FLAGS }, > +{ "size", "set width and height", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, > {.str = "1800x140"}, 0, 0, FLAGS }, > +{ "n", "set number of samples per value per channel", > OFFSET(nb_samples), AV_OPT_TYPE_INT64, {.i64 = 128}, 1, INT64_MAX, FLAGS }, > +{ "nb_samples", "set number of samples per value per channel", > OFFSET(nb_samples), AV_OPT_TYPE_INT64, {.i64 = 128}, 1, INT64_MAX, FLAGS }, > +{ "f", "set json dump file", OFFSET(json_filename), AV_OPT_TYPE_STRING, > { .str = NULL }, 0, 0, FLAGS }, > +{ "json", "set json dump file", OFFSET(json_filename), > AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, > +{ NULL } > +}; > + > +AVFILTER_DEFINE_CLASS(dumpwave); > + > +static av_cold int init(AVFilterContext *ctx) > +{ > +DumpWaveContext *dumpwave = ctx->priv; > + > +dumpwave->sum = dumpwave->i = dumpwave->n = 0; > + > +if (!dumpwave->json_filename) { > +dumpwave->dump_fp = stdout; stdout is not safe as a output for filters and a bad default 2 filters writing to stdout would interfere it would interfere with a user application using stdout > +} else { > +dumpwave->dump_fp = fopen(dumpwave->json_filename, "w"); > +if (!dumpwave->dump_fp) { > +int err = AVERROR(errno); > +char buf[128]; > +av_strerror(err, buf, sizeof(buf)); > +av_log(ctx, AV_LOG_ERROR, "Could not open json file %s: %s\n", > + dumpwave->json_filename, buf); > +return err; > +} > +} > +return 0; > +} > + > +static av_cold void uninit(AVFilterContext *ctx) > +{ > +DumpWaveContext *dumpwave = ctx->priv; > +fclose(dumpwave->dump_fp); > +av_freep(>str); > +av_freep(>values); > +} > + > +static int query_formats(AVFilterContext *ctx) > +{ > +static const enum AVSampleFormat sample_fmts[] = { > +AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8P, > +AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, > +AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32P, > +AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64P, > +AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, > +AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP, > +AV_SAMPLE_FMT_NONE > +}; > +AVFilterFormats *formats; > +AVFilterChannelLayouts *layouts; > +int ret; > + > +if (!(formats = ff_make_format_list(sample_fmts))) > +return AVERROR(ENOMEM); > + > +layouts = ff_all_channel_counts(); > +if (!layouts) > +return AVERROR(ENOMEM); > +ret = ff_set_common_channel_layouts(ctx, layouts); > +if (ret < 0) > +return ret; > + > +return ff_set_common_formats(ctx, formats); > +} > + > +static int config_output(AVFilterLink *outlink) > +{ > +AVFilterContext *ctx = outlink->src; > +DumpWaveContext *dumpwave = ctx->priv; > +const int width = dumpwave->w; > +dumpwave->values = av_realloc(NULL, width * sizeof(double)); > +dumpwave->str = av_realloc(NULL, width * sizeof(int)); > +dumpwave->max_samples = dumpwave->nb_samples * outlink->channels; > + > +return 0; > +} > + > +static int dumpwave_request_frame(AVFilterLink *outlink) > +{ > +AVFilterContext *ctx = outlink->src; > +DumpWaveContext *dumpwave = ctx->priv; > +const int width = dumpwave->w; > +const int height = dumpwave->h; > +char *p, *result = dumpwave->str; > + > +AVFilterLink *inlink = ctx->inputs[0]; > +int ret; > + > +ret = ff_request_frame(inlink); > + > +if (ret == AVERROR_EOF) { > +p = result; > + > +for(int i = 0; i < width; i++) > +p += sprintf(p, "%d,", av_clip(dumpwave->h * > dumpwave->values[i], 0, dumpwave->h)); sprintf is generally not safe as it does not check if there is enough space [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No great genius has ever existed without some touch of madness. -- Aristotle signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2] avfilter: add dumpwave filter.
Signed-off-by: Dmytro Humeniuk--- Changelog| 1 + doc/filters.texi | 23 +++ libavfilter/Makefile | 1 + libavfilter/af_dumpwave.c| 324 +++ libavfilter/allfilters.c | 1 + libavfilter/version.h| 4 +- tests/fate/filter-audio.mak | 13 ++ tests/ref/fate/filter-dumpwave | 1 + tests/ref/fate/filter-dumpwave-24bit | 1 + tests/ref/fate/filter-dumpwave-fltp | 1 + 10 files changed, 368 insertions(+), 2 deletions(-) create mode 100644 libavfilter/af_dumpwave.c create mode 100644 tests/ref/fate/filter-dumpwave create mode 100644 tests/ref/fate/filter-dumpwave-24bit create mode 100644 tests/ref/fate/filter-dumpwave-fltp diff --git a/Changelog b/Changelog index 61075b3392..40fd624449 100644 --- a/Changelog +++ b/Changelog @@ -38,6 +38,7 @@ version : - Removed the ffserver program - Removed the ffmenc and ffmdec muxer and demuxer - VideoToolbox HEVC encoder and hwaccel +- dumpwave audio filter version 3.4: diff --git a/doc/filters.texi b/doc/filters.texi index bd93e0ab84..1f7e4f5380 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2538,6 +2538,29 @@ Optional. It should have a value much less than 1 (e.g. 0.05 or 0.02) and is used to prevent clipping. @end table +@section dumpwave +Dumps RMS amplitude to JSON file. +Converts samples to decibels and calculates RMS (Root-Mean-Square) audio power scaled to desired values. + +@table @option +@item s, size +Dimensions @code{WxH}. +@code{W} - number of data values in json, values will be scaled according to @code{H}. +The default value is @var{1800x140} + +@item n, nb_samples +Samples count per value per channel, default 128 + +@item f, json +Path to json file +@end table + +For example, to generate RMS amplitude for 44.1 kHz 6 seconds length audio +with dimensions @var{1800x140}, samples count @code{44100*6/1800=147} and store it to @var{/tmp/out.json}, you might use: +@example +dumpwave=s=1800x140:n=147:json=/tmp/out.json +@end example + @section dynaudnorm Dynamic Audio Normalizer. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index ef4729dd3f..2ffbc9497a 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -87,6 +87,7 @@ OBJS-$(CONFIG_COMPENSATIONDELAY_FILTER) += af_compensationdelay.o OBJS-$(CONFIG_CROSSFEED_FILTER) += af_crossfeed.o OBJS-$(CONFIG_CRYSTALIZER_FILTER)+= af_crystalizer.o OBJS-$(CONFIG_DCSHIFT_FILTER)+= af_dcshift.o +OBJS-$(CONFIG_DUMPWAVE_FILTER) += af_dumpwave.o OBJS-$(CONFIG_DYNAUDNORM_FILTER) += af_dynaudnorm.o OBJS-$(CONFIG_EARWAX_FILTER) += af_earwax.o OBJS-$(CONFIG_EBUR128_FILTER)+= f_ebur128.o diff --git a/libavfilter/af_dumpwave.c b/libavfilter/af_dumpwave.c new file mode 100644 index 00..486f3a0d79 --- /dev/null +++ b/libavfilter/af_dumpwave.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2017 Dmytro Humeniuk + * + * 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 + * waveform audio filter – dumps RMS amplitude to JSON file + */ + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "libavutil/parseutils.h" +#include "avfilter.h" +#include "formats.h" +#include "audio.h" +#include "internal.h" + +typedef struct DumpWaveContext { +const AVClass *class; /**< class for AVOptions */ +int w; /**< number of data values in json */ +int h; /**< values will be scaled according to provided here */ +int i; /**< index of current value */ +char *json_filename;/**< json filename */ +char *str; /**< comma separated values */ +double *values; /**< scaling factors */ +int64_t nb_samples; /**< samples per value per channel */ +int64_t n; /**< current number of samples counted */ +int64_t max_samples;/**< samples per value */ +double sum; /**< sum of the squared samples per value */ +FILE *dump_fp; +} DumpWaveContext; + +#define