[FFmpeg-devel] [PATCH 2/2] lavfi/volume: support volume normalization through metadata.
Stefano Sabatini
stefasab at gmail.com
Sun Feb 24 23:53:38 CET 2013
On date Friday 2013-02-22 00:22:40 +0100, Clément Bœsch encoded:
> ---
> libavfilter/af_volume.c | 39 ++++++++++++++++++++++++++++++++-------
> libavfilter/af_volume.h | 1 +
> libavfilter/x86/af_volume_init.c | 2 +-
> 3 files changed, 34 insertions(+), 8 deletions(-)
>
> diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
> index 5ffa1fe..39c9cd1 100644
> --- a/libavfilter/af_volume.c
> +++ b/libavfilter/af_volume.c
> @@ -51,11 +51,18 @@ static const AVOption volume_options[] = {
> { "fixed", "select 8-bit fixed-point", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_FIXED }, INT_MIN, INT_MAX, A|F, "precision" },
> { "float", "select 32-bit floating-point", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_FLOAT }, INT_MIN, INT_MAX, A|F, "precision" },
> { "double", "select 64-bit floating-point", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_DOUBLE }, INT_MIN, INT_MAX, A|F, "precision" },
> + { "metadata", "set the metadata key for loudness normalization", OFFSET(metadata), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = A|F },
missing docs upddates
> { NULL },
> };
>
> AVFILTER_DEFINE_CLASS(volume);
>
> +static void set_fixed_volume(VolumeContext *vol, double volume)
> +{
> + vol->volume_i = (int)(volume * 256 + 0.5);
> + vol->volume = vol->volume_i / 256.0;
> +}
> +
> static av_cold int init(AVFilterContext *ctx, const char *args)
> {
> VolumeContext *vol = ctx->priv;
> @@ -69,8 +76,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
> return ret;
>
> if (vol->precision == PRECISION_FIXED) {
> - vol->volume_i = (int)(vol->volume * 256 + 0.5);
> - vol->volume = vol->volume_i / 256.0;
> + set_fixed_volume(vol, vol->volume);
> av_log(ctx, AV_LOG_VERBOSE, "volume:(%d/256)(%f)(%1.2fdB) precision:fixed\n",
> vol->volume_i, vol->volume, 20.0*log(vol->volume)/M_LN10);
> } else {
> @@ -79,7 +85,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
> precision_str[vol->precision]);
> }
>
> - av_opt_free(vol);
> return ret;
> }
>
> @@ -183,13 +188,13 @@ static void volume_init(VolumeContext *vol)
>
> switch (av_get_packed_sample_fmt(vol->sample_fmt)) {
> case AV_SAMPLE_FMT_U8:
> - if (vol->volume_i < 0x1000000)
> + if (vol->volume_i < 0x1000000 && !vol->metadata)
> vol->scale_samples = scale_samples_u8_small;
> else
> vol->scale_samples = scale_samples_u8;
> break;
> case AV_SAMPLE_FMT_S16:
> - if (vol->volume_i < 0x10000)
> + if (vol->volume_i < 0x10000 && !vol->metadata)
> vol->scale_samples = scale_samples_s16_small;
Uhm so this basically it's setting scale_samples_u8_small only in case
metadata is not used? Can you say which are the optimization
implications (I ask because this affects also another patch from me).
> else
> vol->scale_samples = scale_samples_s16;
> @@ -228,11 +233,24 @@ static int config_output(AVFilterLink *outlink)
>
> static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
> {
> - VolumeContext *vol = inlink->dst->priv;
> - AVFilterLink *outlink = inlink->dst->outputs[0];
> + AVFilterContext *ctx = inlink->dst;
> + VolumeContext *vol = ctx->priv;
> + AVFilterLink *outlink = ctx->outputs[0];
> int nb_samples = buf->audio->nb_samples;
> AVFilterBufferRef *out_buf;
>
> + if (vol->metadata) {
> + double loudness, new_volume;
> + AVDictionaryEntry *e = av_dict_get(buf->metadata, vol->metadata, NULL, 0);
> + if (e) {
> + loudness = av_strtod(e->value, NULL);
> + new_volume = -23 - loudness;
can you explain the magic number?
> + //av_log(0,0,"loudness=%f => %f => volume=%f\n", loudness, new_volume, pow(10, new_volume / 20));
av_log DEBUG?
[...]
--
FFmpeg = Fostering and Faithless Mortal Perfectionist Experimenting Geek
More information about the ffmpeg-devel
mailing list