[vlc-devel] [RFC PATCH 4/7] player: add vlc_player_aout_AddLoudnessMeter()

Rémi Denis-Courmont remi at remlab.net
Mon Aug 17 11:55:36 CEST 2020


Hi,

This looks way overkill. Presumably the app would add and remove the callback(s) with the meter, rather than separately.

Le 14 août 2020 15:18:04 GMT+02:00, Thomas Guillem <thomas at gllm.fr> a écrit :
>---
> 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

-- 
Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20200817/d0c14028/attachment.html>


More information about the vlc-devel mailing list