[FFmpeg-devel] [PATCH 1/3] lavfi/ebur128: add metadata injection.

Nicolas George nicolas.george at normalesup.org
Sat Mar 16 17:02:11 CET 2013


Le sextidi 26 ventôse, an CCXXI, Clement Boesch a écrit :
> ---
>  doc/filters.texi        | 11 +++++++++--
>  libavfilter/f_ebur128.c | 35 ++++++++++++++++++++++++++++++++++-
>  2 files changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 0dbec8e..e6d28c7 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -6570,6 +6570,13 @@ Set the EBU scale meter. Default is @code{9}. Common values are @code{9} and
>  @code{18}, respectively for EBU scale meter +9 and EBU scale meter +18. Any
>  other integer value between this range is allowed.
>  
> + at item metadata
> +Set metadata injection. If set to @code{1}, the audio input will be segmented
> +into 100ms output frames, each of them containing various loudness information
> +in metadata.  All the metadata keys are prefixed with @code{lavfi.r128.}.
> +
> +Default is @code{0}.
> +
>  @item framelog
>  Force the frame logging level.
>  
> @@ -6581,8 +6588,8 @@ information logging level
>  verbose logging level
>  @end table
>  
> -By default, the logging level is set to @var{info}. If the @option{video}
> -option is set, it switches to @var{verbose}.
> +By default, the logging level is set to @var{info}. If the @option{video} or
> +the @option{metadata} options are set, it switches to @var{verbose}.
>  @end table
>  
>  @subsection Examples
> diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c
> index 6d7f7af..2050c1f 100644
> --- a/libavfilter/f_ebur128.c
> +++ b/libavfilter/f_ebur128.c
> @@ -33,6 +33,7 @@
>  #include "libavutil/avassert.h"
>  #include "libavutil/avstring.h"
>  #include "libavutil/channel_layout.h"
> +#include "libavutil/dict.h"
>  #include "libavutil/xga_font_data.h"
>  #include "libavutil/opt.h"
>  #include "libavutil/timestamp.h"
> @@ -126,6 +127,7 @@ typedef struct {
>  
>      /* misc */
>      int loglevel;                   ///< log level for frame logging
> +    int metadata;                   ///< whether or not to inject loudness results in frames
>  } EBUR128Context;
>  
>  #define OFFSET(x) offsetof(EBUR128Context, x)
> @@ -139,6 +141,7 @@ static const AVOption ebur128_options[] = {
>      { "framelog", "force frame logging level", OFFSET(loglevel), AV_OPT_TYPE_INT, {.i64 = -1},   INT_MIN, INT_MAX, A|V|F, "level" },
>          { "info",    "information logging level", 0, AV_OPT_TYPE_CONST, {.i64 = AV_LOG_INFO},    INT_MIN, INT_MAX, A|V|F, "level" },
>          { "verbose", "verbose logging level",     0, AV_OPT_TYPE_CONST, {.i64 = AV_LOG_VERBOSE}, INT_MIN, INT_MAX, A|V|F, "level" },
> +    { "metadata", "inject metadata in the filtergraph", OFFSET(metadata), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, A|V|F },
>      { NULL },
>  };
>  
> @@ -316,6 +319,20 @@ static int config_video_output(AVFilterLink *outlink)
>      return 0;
>  }
>  
> +static int config_audio_input(AVFilterLink *inlink)
> +{
> +    AVFilterContext *ctx = inlink->dst;
> +    EBUR128Context *ebur128 = ctx->priv;
> +
> +    /* force 100ms framing in case of metadata injection: the frames must have
> +     * a granularity of the window overlap to be accurately exploited */
> +    if (ebur128->metadata)
> +        inlink->min_samples =
> +        inlink->max_samples =
> +        inlink->partial_buf_size = inlink->sample_rate / 10;

Possibly add a warning if sample_rate % 10 is not 0.

> +    return 0;
> +}
> +
>  static int config_audio_output(AVFilterLink *outlink)
>  {
>      int i;
> @@ -396,7 +413,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
>  

>      if (ebur128->loglevel != AV_LOG_INFO &&
>          ebur128->loglevel != AV_LOG_VERBOSE) {
> -        if (ebur128->do_video)
> +        if (ebur128->do_video || ebur128->metadata)
>              ebur128->loglevel = AV_LOG_VERBOSE;
>          else
>              ebur128->loglevel = AV_LOG_INFO;

I wonder if the surrounding test is valid, but this is not affected by this
patch.

> @@ -661,6 +678,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
>                      return ret;
>              }
>  
> +            if (ebur128->metadata) { /* happens only once per filter_frame call */
> +                char metabuf[128];
> +#define SET_META(name, var) do {                                            \
> +    snprintf(metabuf, sizeof(metabuf), "%.3f", var);                        \
> +    av_dict_set(&insamples->metadata, "lavfi.r128." name, metabuf, 0);      \
> +} while (0)
> +                SET_META("M",        loudness_400);
> +                SET_META("S",        loudness_3000);
> +                SET_META("I",        ebur128->integrated_loudness);
> +                SET_META("LRA",      ebur128->loudness_range);
> +                SET_META("LRA.low",  ebur128->lra_low);
> +                SET_META("LRA.high", ebur128->lra_high);
> +            }
> +
>              av_log(ctx, ebur128->loglevel, "t: %-10s " LOG_FMT "\n",
>                     av_ts2timestr(pts, &outlink->time_base),
>                     loudness_400, loudness_3000,
> @@ -745,6 +776,7 @@ static av_cold void uninit(AVFilterContext *ctx)
>      for (i = 0; i < ctx->nb_outputs; i++)
>          av_freep(&ctx->output_pads[i].name);
>      av_frame_free(&ebur128->outpicref);
> +    av_opt_free(ebur128);
>  }
>  
>  static const AVFilterPad ebur128_inputs[] = {
> @@ -753,6 +785,7 @@ static const AVFilterPad ebur128_inputs[] = {
>          .type             = AVMEDIA_TYPE_AUDIO,
>          .get_audio_buffer = ff_null_get_audio_buffer,
>          .filter_frame     = filter_frame,
> +        .config_props     = config_audio_input,
>      },
>      { NULL }
>  };

LGTM.

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20130316/e4f09f43/attachment.asc>


More information about the ffmpeg-devel mailing list