[vlc-devel] [RFC PATCH 4/7] player: add vlc_player_aout_AddLoudnessMeter()
Thomas Guillem
thomas at gllm.fr
Mon Aug 17 09:57:28 CEST 2020
On Mon, Aug 17, 2020, at 09:50, Steve Lhomme wrote:
> On 2020-08-17 9:41, Thomas Guillem wrote:
> > What is metadata in this context ? I don't follow you.
>
> The loudness value for each audio block.
I don't feel the need of putting loudness values in block_t, specially since you calculate them just before the rendering, so the block is eaten by the aout (so metadata will be lost).
>
> > The loudness meter plugin should only be enabled when there is a listener.
>
> That's based on your design. You could enable the metadata generator and
> (a) viewer(s) at the same time.
>
> > What I could do instead of this API:
> >
> > vlc_player_EnableLoudnessMeter(mode);
> > vlc_player_DisableLoudnessMeter(mode);
>
> In this case the viewer is a callback. But that means blending the
> loudness in the video/display is not possible with this API, unless one
> manages the display and blending on their own.
Nothing prevent to propagate audio meters result to :
- VLC player listener
- Vout listener.
I only did the first one for now.
>
> > This will increment/decrement a refcount, the plugin will be loaded, unloaded, restarted (mode change) according to this count. Then the user use the classical vlc_player listener API to receive meter callbacks.
> >
> > On Sat, Aug 15, 2020, at 13:12, Jean-Baptiste Kempf wrote:
> >> Why a specific function for loundness and not an extra metadata one?
> >>
> >> On Fri, 14 Aug 2020, at 15:18, Thomas Guillem wrote:
> >>> ---
> >>> include/vlc_player.h | 76 +++++++++++++++++++++++++++++++
> >>> src/libvlccore.sym | 2 +
> >>> src/player/aout.c | 103 +++++++++++++++++++++++++++++++++++++++++++
> >>> src/player/player.c | 3 ++
> >>> src/player/player.h | 9 ++++
> >>> 5 files changed, 193 insertions(+)
> >>>
> >>> diff --git a/include/vlc_player.h b/include/vlc_player.h
> >>> index ac5991982df..ad4d39536d4 100644
> >>> --- a/include/vlc_player.h
> >>> +++ b/include/vlc_player.h
> >>> @@ -2199,6 +2199,50 @@ struct vlc_player_aout_cbs
> >>> void *data);
> >>> };
> >>>
> >>> +/**
> >>> + * Player aout loudness meter opaque structure.
> >>> + *
> >>> + * This opaque structure is returned by
> >>> vlc_player_aout_AddLoudnessMeter() and
> >>> + * can be used to remove the listener via
> >>> + * vlc_player_aout_RemoveLoudnessMeter().
> >>> + */
> >>> +typedef struct vlc_player_aout_loudness_meter_id
> >>> vlc_player_aout_loudness_meter_id;
> >>> +
> >>> +/**
> >>> + * Loudness meter mode
> >>> + */
> >>> +enum vlc_player_aout_loudness_meter_mode
> >>> +{
> >>> + /** Very low CPU usage, only the Momentary Loudness will be
> >>> processed */
> >>> + VLC_PLAYER_AOUT_LOUDNESS_METER_BEST_PERFS,
> >>> + /** High CPU usage, Momentary Loudness, Short Term Loudness
> >>> Integrated
> >>> + * Loudness, Loudness Range and True Peak will be processed. */
> >>> + VLC_PLAYER_AOUT_LOUDNESS_METER_FULL,
> >>> +};
> >>> +
> >>> +/**
> >>> + * Player aout loudness meter callbacks
> >>> + *
> >>> + * Can be registered with vlc_player_aout_AddLoudnessMeter().
> >>> + */
> >>> +struct vlc_player_aout_loudness_cbs
> >>> +{
> >>> +
> >>> + /**
> >>> + * Called when loudness measurements have changed
> >>> + *
> >>> + * Only sent when audio is playing, approximately every 400ms (but
> >>> can be
> >>> + * higher, depending on the input sample size).
> >>> + *
> >>> + * @param aout the main aout of the player
> >>> + * @param meter last loudness measurements
> >>> + * @param data opaque pointer set by
> >>> vlc_player_aout_AddLoudnessMeter()
> >>> + */
> >>> + void (*on_loudness_changed)(audio_output_t *aout,
> >>> + const struct vlc_audio_loudness_meter
> >>> *meter,
> >>> + void *data);
> >>> +};
> >>> +
> >>> /**
> >>> * Get the audio output
> >>> *
> >>> @@ -2353,6 +2397,38 @@ vlc_player_aout_ToggleMute(vlc_player_t *player)
> >>> VLC_API int
> >>> vlc_player_aout_EnableFilter(vlc_player_t *player, const char *name,
> >>> bool add);
> >>>
> >>> +
> >>> +/**
> >>> + * Add an aout loudness meter
> >>> + *
> >>> + * @note The player instance doesn't need to be locked for
> >>> vlc_player_aout_*()
> >>> + * functions.
> >>> + * @note Every registered loudness meter need to be removed by the
> >>> caller with
> >>> + * vlc_player_aout_RemoveLoudnessMeter().
> >>> + *
> >>> + * @param player player instance
> >>> + * @param cbs pointer to a vlc_player_aout_loudness_cbs structure, the
> >>> + * structure must be valid during the lifetime of the player
> >>> + * @param cbs_data opaque pointer used by the callbacks
> >>> + * @return a valid meter id, or NULL in case of error ("audio-meter"
> >>> plugin
> >>> + * missing)
> >>> + */
> >>> +VLC_API vlc_player_aout_loudness_meter_id *
> >>> +vlc_player_aout_AddLoudnessMeter(vlc_player_t *player,
> >>> + enum
> >>> vlc_player_aout_loudness_meter_mode,
> >>> + const struct
> >>> vlc_player_aout_loudness_cbs *cbs,
> >>> + void *cbs_data);
> >>> +
> >>> +/**
> >>> + * Remove an aout loudness meter
> >>> + *
> >>> + * @param player player instance
> >>> + * @param meter_id meter id returned by
> >>> vlc_player_aout_AddLoudnessMeter()
> >>> + */
> >>> +VLC_API void
> >>> +vlc_player_aout_RemoveLoudnessMeter(vlc_player_t *player,
> >>> + vlc_player_aout_loudness_meter_id
> >>> *meter_id);
> >>> +
> >>> /** @} vlc_player__aout */
> >>>
> >>> /**
> >>> diff --git a/src/libvlccore.sym b/src/libvlccore.sym
> >>> index ed43c17715c..cf1916fd92c 100644
> >>> --- a/src/libvlccore.sym
> >>> +++ b/src/libvlccore.sym
> >>> @@ -774,6 +774,7 @@ vlc_player_AddListener
> >>> vlc_player_AddSmpteTimer
> >>> vlc_player_AddTimer
> >>> vlc_player_aout_AddListener
> >>> +vlc_player_aout_AddLoudnessMeter
> >>> vlc_player_aout_EnableFilter
> >>> vlc_player_aout_GetVolume
> >>> vlc_player_aout_Hold
> >>> @@ -782,6 +783,7 @@ vlc_player_aout_IncrementVolume
> >>> vlc_player_aout_IsMuted
> >>> vlc_player_aout_Mute
> >>> vlc_player_aout_RemoveListener
> >>> +vlc_player_aout_RemoveLoudnessMeter
> >>> vlc_player_aout_SetVolume
> >>> vlc_player_ChangeRate
> >>> vlc_player_CondWait
> >>> diff --git a/src/player/aout.c b/src/player/aout.c
> >>> index 8674cc65359..f962b53329b 100644
> >>> --- a/src/player/aout.c
> >>> +++ b/src/player/aout.c
> >>> @@ -26,6 +26,7 @@
> >>>
> >>> #include <vlc_common.h>
> >>> #include <vlc_decoder.h>
> >>> +#include <vlc_modules.h>
> >>> #include "player.h"
> >>> #include "input/resource.h"
> >>>
> >>> @@ -46,6 +47,106 @@ vlc_player_aout_Hold(vlc_player_t *player)
> >>> return input_resource_HoldAout(player->resource);
> >>> }
> >>>
> >>> +VLC_API vlc_player_aout_loudness_meter_id *
> >>> +vlc_player_aout_AddLoudnessMeter(vlc_player_t *player,
> >>> + enum
> >>> vlc_player_aout_loudness_meter_mode mode,
> >>> + const struct
> >>> vlc_player_aout_loudness_cbs *cbs,
> >>> + void *cbs_data)
> >>> +{
> >>> + assert(cbs && cbs->on_loudness_changed);
> >>> +
> >>> + if (!module_exists("ebur128"))
> >>> + return NULL;
> >>> +
> >>> + vlc_player_aout_loudness_meter_id *meter_id =
> >>> malloc(sizeof(*meter_id));
> >>> + if (meter_id == NULL)
> >>> + return NULL;
> >>> +
> >>> + meter_id->cbs = cbs;
> >>> + meter_id->cbs_data = cbs_data;
> >>> + meter_id->mode = mode;
> >>> +
> >>> + vlc_mutex_lock(&player->aout_listeners_lock);
> >>> +
> >>> + bool has_meter_module =
> >>> !vlc_list_is_empty(&player->aout_loudness_meters);
> >>> +
> >>> + enum vlc_player_aout_loudness_meter_mode prev_mode =
> >>> + VLC_PLAYER_AOUT_LOUDNESS_METER_BEST_PERFS;
> >>> + if (has_meter_module)
> >>> + {
> >>> + vlc_player_aout_loudness_meter_id *other_meter_id;
> >>> + vlc_list_foreach(other_meter_id,
> >>> &player->aout_loudness_meters, node)
> >>> + {
> >>> + if (other_meter_id->mode > prev_mode)
> >>> + prev_mode = other_meter_id->mode;
> >>> + }
> >>> + }
> >>> +
> >>> + vlc_list_append(&meter_id->node, &player->aout_loudness_meters);
> >>> +
> >>> + vlc_mutex_unlock(&player->aout_listeners_lock);
> >>> +
> >>> + if (!has_meter_module || mode > prev_mode)
> >>> + {
> >>> + audio_output_t *aout = vlc_player_aout_Hold(player);
> >>> + if (aout != NULL)
> >>> + {
> >>> + var_SetBool(player, "ebur128-fullmeter",
> >>> + mode == VLC_PLAYER_AOUT_LOUDNESS_METER_FULL);
> >>> + var_SetString(aout, "audio-meter", "ebur128");
> >>> + aout_Release(aout);
> >>> + }
> >>> + }
> >>> +
> >>> + return meter_id;
> >>> +}
> >>> +
> >>> +void
> >>> +vlc_player_aout_RemoveLoudnessMeter(vlc_player_t *player,
> >>> + vlc_player_aout_loudness_meter_id
> >>> *meter_id)
> >>> +{
> >>> + assert(meter_id);
> >>> +
> >>> + vlc_mutex_lock(&player->aout_listeners_lock);
> >>> + vlc_list_remove(&meter_id->node);
> >>> +
> >>> + bool has_meter_module =
> >>> !vlc_list_is_empty(&player->aout_loudness_meters);
> >>> +
> >>> + vlc_mutex_unlock(&player->aout_listeners_lock);
> >>> + free(meter_id);
> >>> +
> >>> + if (!has_meter_module)
> >>> + {
> >>> + audio_output_t *aout = vlc_player_aout_Hold(player);
> >>> + if (aout != NULL)
> >>> + {
> >>> + var_SetString(aout, "audio-meter", NULL);
> >>> + aout_Release(aout);
> >>> + }
> >>> + }
> >>> +}
> >>> +
> >>> +static int
> >>> +vlc_player_AoutLoudnessCallback(vlc_object_t *this, const char *var,
> >>> + vlc_value_t oldval, vlc_value_t
> >>> newval, void *data)
> >>> +{
> >>> + vlc_player_t *player = data;
> >>> +
> >>> + struct vlc_audio_loudness_meter *meter = newval.p_address;
> >>> +
> >>> + vlc_mutex_lock(&player->aout_listeners_lock);
> >>> + vlc_player_aout_loudness_meter_id *meter_id;
> >>> + vlc_list_foreach(meter_id, &player->aout_loudness_meters, node)
> >>> + {
> >>> + meter_id->cbs->on_loudness_changed((audio_output_t *)this,
> >>> + meter, meter_id->cbs_data);
> >>> + }
> >>> + vlc_mutex_unlock(&player->aout_listeners_lock);
> >>> +
> >>> + (void) var; (void) oldval;
> >>> + return VLC_SUCCESS;
> >>> +}
> >>> +
> >>> vlc_player_aout_listener_id *
> >>> vlc_player_aout_AddListener(vlc_player_t *player,
> >>> const struct vlc_player_aout_cbs *cbs,
> >>> @@ -202,6 +303,7 @@ vlc_player_aout_AddCallbacks(vlc_player_t *player)
> >>> var_AddCallback(aout, "volume", vlc_player_AoutCallback, player);
> >>> var_AddCallback(aout, "mute", vlc_player_AoutCallback, player);
> >>> var_AddCallback(aout, "device", vlc_player_AoutCallback, player);
> >>> + var_AddCallback(aout, "loudness-meter",
> >>> vlc_player_AoutLoudnessCallback, player);
> >>>
> >>> aout_Release(aout);
> >>> }
> >>> @@ -216,6 +318,7 @@ vlc_player_aout_DelCallbacks(vlc_player_t *player)
> >>> var_DelCallback(aout, "volume", vlc_player_AoutCallback, player);
> >>> var_DelCallback(aout, "mute", vlc_player_AoutCallback, player);
> >>> var_DelCallback(aout, "device", vlc_player_AoutCallback, player);
> >>> + var_DelCallback(aout, "loudness-meter",
> >>> vlc_player_AoutLoudnessCallback, player);
> >>>
> >>> aout_Release(aout);
> >>> }
> >>> diff --git a/src/player/player.c b/src/player/player.c
> >>> index fd072e414b5..e74c29e6d9c 100644
> >>> --- a/src/player/player.c
> >>> +++ b/src/player/player.c
> >>> @@ -1893,6 +1893,7 @@ vlc_player_Delete(vlc_player_t *player)
> >>> assert(vlc_list_is_empty(&player->listeners));
> >>> assert(vlc_list_is_empty(&player->vout_listeners));
> >>> assert(vlc_list_is_empty(&player->aout_listeners));
> >>> + assert(vlc_list_is_empty(&player->aout_loudness_meters));
> >>>
> >>> vlc_mutex_unlock(&player->lock);
> >>>
> >>> @@ -1934,6 +1935,7 @@ vlc_player_New(vlc_object_t *parent, enum
> >>> vlc_player_lock_type lock_type,
> >>> vlc_list_init(&player->listeners);
> >>> vlc_list_init(&player->vout_listeners);
> >>> vlc_list_init(&player->aout_listeners);
> >>> + vlc_list_init(&player->aout_loudness_meters);
> >>> vlc_list_init(&player->destructor.inputs);
> >>> vlc_list_init(&player->destructor.stopping_inputs);
> >>> vlc_list_init(&player->destructor.joinable_inputs);
> >>> @@ -1973,6 +1975,7 @@ vlc_player_New(vlc_object_t *parent, enum
> >>> vlc_player_lock_type lock_type,
> >>> VAR_CREATE("audio-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
> >>> VAR_CREATE("mute", VLC_VAR_BOOL);
> >>> VAR_CREATE("corks", VLC_VAR_INTEGER);
> >>> + VAR_CREATE("ebur128-fullmeter", VLC_VAR_BOOL);
> >>>
> >>> /* es_out variables */
> >>> VAR_CREATE("sout", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
> >>> diff --git a/src/player/player.h b/src/player/player.h
> >>> index 87b9e430330..e4fafbab087 100644
> >>> --- a/src/player/player.h
> >>> +++ b/src/player/player.h
> >>> @@ -140,6 +140,14 @@ struct vlc_player_aout_listener_id
> >>> struct vlc_list node;
> >>> };
> >>>
> >>> +struct vlc_player_aout_loudness_meter_id
> >>> +{
> >>> + const struct vlc_player_aout_loudness_cbs *cbs;
> >>> + void *cbs_data;
> >>> + enum vlc_player_aout_loudness_meter_mode mode;
> >>> + struct vlc_list node;
> >>> +};
> >>> +
> >>> enum vlc_player_timer_source_type
> >>> {
> >>> VLC_PLAYER_TIMER_TYPE_BEST,
> >>> @@ -224,6 +232,7 @@ struct vlc_player_t
> >>>
> >>> struct vlc_list listeners;
> >>> struct vlc_list aout_listeners;
> >>> + struct vlc_list aout_loudness_meters;
> >>> struct vlc_list vout_listeners;
> >>>
> >>> input_resource_t *resource;
> >>> --
> >>> 2.28.0
> >>>
> >>> _______________________________________________
> >>> vlc-devel mailing list
> >>> To unsubscribe or modify your subscription options:
> >>> https://mailman.videolan.org/listinfo/vlc-devel
> >>
> >> --
> >> Jean-Baptiste Kempf - President
> >> +33 672 704 734
> >> _______________________________________________
> >> vlc-devel mailing list
> >> To unsubscribe or modify your subscription options:
> >> https://mailman.videolan.org/listinfo/vlc-devel
> > _______________________________________________
> > vlc-devel mailing list
> > To unsubscribe or modify your subscription options:
> > https://mailman.videolan.org/listinfo/vlc-devel
> >
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list