[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