[vlc-devel] [RFC PATCH 4/7] player: add vlc_player_aout_AddLoudnessMeter()
Steve Lhomme
robux4 at ycbcr.xyz
Mon Aug 17 08:50:27 CEST 2020
On 2020-08-15 13:12, Jean-Baptiste Kempf wrote:
> Why a specific function for loundness and not an extra metadata one?
Same remark.
> 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
>
More information about the vlc-devel
mailing list