[vlc-devel] [PATCH 13/20] player: get vout and spu channel order from SPU es_ids

Thomas Guillem thomas at gllm.fr
Thu Jun 20 17:23:56 CEST 2019


vlc_player_GetVoutFromEsId() can now return the vout used by an SPU es_id.

Add vlc_player_GetEsIdSpuOrder() that return the spu channel order of an SPU
es_id.

The on_vout_changed callback is also used for SPU es_ids. Users could check the
category of the es_id to know if the vout is attached to a VIDEO es or an SPU
one.
---
 include/vlc_player.h                          | 17 ++++++-
 lib/media_player.c                            |  9 ++--
 modules/control/gestures.c                    |  8 +++-
 modules/control/hotkeys.c                     |  8 +++-
 .../gui/macosx/playlist/VLCPlayerController.m |  7 ++-
 .../gui/qt/components/player_controller.cpp   | 12 ++++-
 src/input/player.c                            | 47 +++++++++++++++++--
 src/libvlccore.sym                            |  1 +
 test/src/input/player.c                       |  5 +-
 9 files changed, 100 insertions(+), 14 deletions(-)

diff --git a/include/vlc_player.h b/include/vlc_player.h
index ff4e03f314..3ecab32a5a 100644
--- a/include/vlc_player.h
+++ b/include/vlc_player.h
@@ -828,12 +828,13 @@ struct vlc_player_cbs
      * @param player locked player instance
      * @param action started or stopped
      * @param vout vout (can't be NULL)
+     * @param spu_order spu channel order (only valid for SPU ES)
      * @param es_id the ES id associated with this vout
      * @param data opaque pointer set by vlc_player_AddListener()
      */
     void (*on_vout_changed)(vlc_player_t *player,
         enum vlc_player_vout_action action, vout_thread_t *vout,
-        vlc_es_id_t *es_id, void *data);
+        enum vlc_spu_channel_order spu_order, vlc_es_id_t *es_id, void *data);
 
     /**
      * Called when the player is corked
@@ -1681,11 +1682,23 @@ vlc_player_GetTrack(vlc_player_t *player, vlc_es_id_t *es_id);
  * @param id an ES ID (retrieved from vlc_player_cbs.on_track_list_changed or
  * vlc_player_GetTrackAt())
  * @return a valid vout or NULL (if the track is disabled, it it's not a video
- * track, or if the vout failed to start)
+ * or spu track, or if the vout failed to start)
  */
 VLC_API vout_thread_t *
 vlc_player_GetEsIdVout(vlc_player_t *player, vlc_es_id_t *es_id);
 
+/**
+ * Get the spu channel order of a SPU ES identifier
+ *
+ * @param player locked player instance
+ * @param id an ES ID (retrieved from vlc_player_cbs.on_track_list_changed or
+ * vlc_player_GetTrackAt())
+ * @return a valid channel order or VLC_SPU_CHANNEL_ORDER_NONE is the es_id is
+ * invalid
+ */
+VLC_API enum vlc_spu_channel_order
+vlc_player_GetEsIdSpuChannelOrder(vlc_player_t *player, vlc_es_id_t *es_id);
+
 /**
  * Get the ES identifier of a video output
  *
diff --git a/lib/media_player.c b/lib/media_player.c
index 667ec517d0..9d7f7b467e 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -400,12 +400,15 @@ on_cork_changed(vlc_player_t *player, unsigned cork_count, void *data)
 
 static void
 on_vout_changed(vlc_player_t *player, enum vlc_player_vout_action action,
-                vout_thread_t *vout, vlc_es_id_t *es_id,
-                void *data)
+                vout_thread_t *vout, enum vlc_spu_channel_order spu_order,
+                vlc_es_id_t *es_id, void *data)
 {
     (void) action;
     (void) vout;
-    (void) es_id;
+    (void) spu_order;
+
+    if (vlc_es_id_GetCat(es_id) != VIDEO_ES)
+        return;
 
     libvlc_media_player_t *mp = data;
 
diff --git a/modules/control/gestures.c b/modules/control/gestures.c
index 804e6df2eb..e84a80ce81 100644
--- a/modules/control/gestures.c
+++ b/modules/control/gestures.c
@@ -105,6 +105,7 @@ vlc_module_end ()
 static void player_on_vout_changed(vlc_player_t *player,
                                    enum vlc_player_vout_action action,
                                    vout_thread_t *vout,
+                                   enum vlc_spu_channel_order spu_order,
                                    vlc_es_id_t *es_id,
                                    void *data);
 static int MovedEvent( vlc_object_t *, char const *,
@@ -392,11 +393,16 @@ static void
 player_on_vout_changed(vlc_player_t *player,
                        enum vlc_player_vout_action action,
                        vout_thread_t *vout,
+                       enum vlc_spu_channel_order spu_order,
                        vlc_es_id_t *es_id, void *data)
 {
-    VLC_UNUSED(player); VLC_UNUSED(es_id);
+    VLC_UNUSED(player); VLC_UNUSED(spu_order);
     intf_thread_t *intf = data;
     intf_sys_t *sys = intf->p_sys;
+
+    if (vlc_es_id_GetCat(es_id) != VIDEO_ES)
+        return;
+
     switch (action)
     {
         case VLC_PLAYER_VOUT_STARTED:
diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c
index 35d8557038..4ecaaccc91 100644
--- a/modules/control/hotkeys.c
+++ b/modules/control/hotkeys.c
@@ -1053,11 +1053,15 @@ ViewpointMovedCallback(vlc_object_t *obj, char const *var,
 static void
 player_on_vout_changed(vlc_player_t *player,
                        enum vlc_player_vout_action action, vout_thread_t *vout,
-                       vlc_es_id_t *es_id,
+                       enum vlc_spu_channel_order spu_order, vlc_es_id_t *es_id,
                        void *data)
 {
-    VLC_UNUSED(es_id);
+    VLC_UNUSED(spu_order);
     intf_thread_t *intf = data;
+
+    if (vlc_es_id_GetCat(es_id) != VIDEO_ES)
+        return;
+
     bool vrnav = var_GetBool(vout, "viewpoint-changeable");
     switch (action)
     {
diff --git a/modules/gui/macosx/playlist/VLCPlayerController.m b/modules/gui/macosx/playlist/VLCPlayerController.m
index f53cdc9027..cdd44e7065 100644
--- a/modules/gui/macosx/playlist/VLCPlayerController.m
+++ b/modules/gui/macosx/playlist/VLCPlayerController.m
@@ -434,12 +434,17 @@ static void cb_player_item_meta_changed(vlc_player_t *p_player,
 static void cb_player_vout_changed(vlc_player_t *p_player,
                                    enum vlc_player_vout_action action,
                                    vout_thread_t *p_vout,
+                                   enum vlc_spu_channel_order spu_order,
                                    vlc_es_id_t *es_id,
                                    void *p_data)
 {
     VLC_UNUSED(p_player);
     VLC_UNUSED(p_vout);
-    VLC_UNUSED(es_id);
+    VLC_UNUSED(spu_order);
+
+    if (vlc_es_id_GetCat(es_id) != VIDEO_ES)
+        return;
+
     dispatch_async(dispatch_get_main_queue(), ^{
         VLCPlayerController *playerController = (__bridge VLCPlayerController *)p_data;
         [playerController voutListUpdated];
diff --git a/modules/gui/qt/components/player_controller.cpp b/modules/gui/qt/components/player_controller.cpp
index 553d461d41..7de51cf2ce 100644
--- a/modules/gui/qt/components/player_controller.cpp
+++ b/modules/gui/qt/components/player_controller.cpp
@@ -710,11 +710,16 @@ static void on_player_subitems_changed(vlc_player_t *, input_item_t *, input_ite
 }
 
 
-static void on_player_vout_changed(vlc_player_t *player, enum vlc_player_vout_action, vout_thread_t *, vlc_es_id_t *, void *data)
+static void on_player_vout_changed(vlc_player_t *player, enum vlc_player_vout_action,
+    vout_thread_t *, enum vlc_spu_channel_order, vlc_es_id_t *es_id, void *data)
 {
     PlayerControllerPrivate* that = static_cast<PlayerControllerPrivate*>(data);
     msg_Dbg( that->p_intf, "on_player_vout_list_changed");
 
+    switch (vlc_es_id_GetCat(es_id))
+    {
+        case VIDEO_ES:
+        {
     //player is locked within callbacks*
     size_t i_vout = 0;
     vout_thread_t **vouts = vlc_player_vout_HoldAll(player, &i_vout);
@@ -729,6 +734,11 @@ static void on_player_vout_changed(vlc_player_t *player, enum vlc_player_vout_ac
     that->callAsync([that,voutsPtr,i_vout] () {
         that->UpdateVouts(voutsPtr.get(), i_vout);
     });
+            break;
+        }
+        default:
+            break;
+    }
 }
 
 //player vout callbacks
diff --git a/src/input/player.c b/src/input/player.c
index 4a4262d814..18d074fd77 100644
--- a/src/input/player.c
+++ b/src/input/player.c
@@ -57,6 +57,8 @@ struct vlc_player_track_priv
     struct vlc_player_track t;
     vout_thread_t *vout; /* weak reference */
     vlc_tick_t delay;
+    /* only valid if selected and if category is SPU_ES */
+    enum vlc_spu_channel_order spu_channel_order;
 };
 
 typedef struct VLC_VECTOR(struct vlc_player_program *)
@@ -421,6 +423,8 @@ vlc_player_track_New(vlc_es_id_t *id, const char *name, const es_format_t *fmt)
     struct vlc_player_track *track = &trackpriv->t;
 
     trackpriv->delay = INT64_MAX;
+    trackpriv->vout = NULL;
+    trackpriv->spu_channel_order = VLC_SPU_CHANNEL_ORDER_NONE;
 
     track->name = strdup(name);
     if (!track->name)
@@ -1332,6 +1336,17 @@ vlc_player_GetEsIdVout(vlc_player_t *player, vlc_es_id_t *es_id)
     return trackpriv ? trackpriv->vout : NULL;
 }
 
+enum vlc_spu_channel_order
+vlc_player_GetEsIdSpuChannelOrder(vlc_player_t *player, vlc_es_id_t *es_id)
+{
+    if (vlc_es_id_GetCat(es_id) != SPU_ES)
+        return VLC_SPU_CHANNEL_ORDER_NONE;
+
+    struct vlc_player_track_priv *trackpriv =
+        vlc_player_GetPrivTrack(player, es_id);
+    return trackpriv ? trackpriv->spu_channel_order : VLC_SPU_CHANNEL_ORDER_NONE;
+}
+
 vlc_es_id_t *
 vlc_player_GetEsIdFromVout(vlc_player_t *player, vout_thread_t *vout)
 {
@@ -1341,7 +1356,7 @@ vlc_player_GetEsIdFromVout(vlc_player_t *player, vout_thread_t *vout)
         return NULL;
 
     static const enum es_format_category_e cats[] = {
-        VIDEO_ES, AUDIO_ES /* for visualisation filters */
+        VIDEO_ES, SPU_ES, AUDIO_ES /* for visualisation filters */
     };
     for (size_t i = 0; i < ARRAY_SIZE(cats); ++i)
     {
@@ -1989,7 +2004,8 @@ vlc_player_input_HandleVoutEvent(struct vlc_player_input *input,
         case VLC_INPUT_EVENT_VOUT_ADDED:
             trackpriv->vout = ev->vout;
             vlc_player_SendEvent(player, on_vout_changed,
-                                 VLC_PLAYER_VOUT_STARTED, ev->vout, ev->id);
+                                 VLC_PLAYER_VOUT_STARTED, ev->vout,
+                                 VLC_SPU_CHANNEL_ORDER_NONE, ev->id);
 
             /* Register vout callbacks after the vout list event */
             var_AddCallback(ev->vout, "fullscreen",
@@ -2012,13 +2028,35 @@ vlc_player_input_HandleVoutEvent(struct vlc_player_input *input,
 
             trackpriv->vout = NULL;
             vlc_player_SendEvent(player, on_vout_changed,
-                                 VLC_PLAYER_VOUT_STOPPED, ev->vout, ev->id);
+                                 VLC_PLAYER_VOUT_STOPPED, ev->vout,
+                                 VLC_SPU_CHANNEL_ORDER_NONE, ev->id);
             break;
         default:
             vlc_assert_unreachable();
     }
 }
 
+static void
+vlc_player_input_HandleSpuEvent(struct vlc_player_input *input,
+                                const struct vlc_input_event_spu *ev)
+{
+    assert(ev->id);
+
+    struct vlc_player_track_priv *trackpriv =
+        vlc_player_input_FindTrackById(input, ev->id, NULL);
+    if (!trackpriv)
+        return;
+    trackpriv->vout = ev->vout;
+    trackpriv->spu_channel_order = ev->channel_order;
+
+    const enum vlc_player_vout_action action =
+        ev->channel_order != VLC_SPU_CHANNEL_ORDER_NONE ?
+        VLC_PLAYER_VOUT_STARTED : VLC_PLAYER_VOUT_STOPPED;
+
+    vlc_player_SendEvent(input->player, on_vout_changed, action,
+                         ev->vout, ev->channel_order, ev->id);
+}
+
 static void
 vlc_player_input_HandleStateEvent(struct vlc_player_input *input,
                                   input_state_e state)
@@ -2153,6 +2191,9 @@ input_thread_Events(input_thread_t *input_thread,
         case INPUT_EVENT_VOUT:
             vlc_player_input_HandleVoutEvent(input, &event->vout);
             break;
+        case INPUT_EVENT_SPU:
+            vlc_player_input_HandleSpuEvent(input, &event->spu);
+            break;
         case INPUT_EVENT_ITEM_META:
             vlc_player_SendEvent(player, on_media_meta_changed,
                                  input_GetItem(input->thread));
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 493b3805a1..255a0768c5 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -790,6 +790,7 @@ vlc_player_GetCurrentMedia
 vlc_player_GetError
 vlc_player_GetEsIdDelay
 vlc_player_GetEsIdFromVout
+vlc_player_GetEsIdSpuChannelOrder
 vlc_player_GetEsIdVout
 vlc_player_GetLength
 vlc_player_GetPosition
diff --git a/test/src/input/player.c b/test/src/input/player.c
index c7174cafc8..f487dd3a5f 100644
--- a/test/src/input/player.c
+++ b/test/src/input/player.c
@@ -85,6 +85,7 @@ struct report_vout
 {
     enum vlc_player_vout_action action;
     vout_thread_t *vout;
+    enum vlc_spu_channel_order spu_order;
     vlc_es_id_t *es_id;
 };
 
@@ -437,12 +438,14 @@ player_on_statistics_changed(vlc_player_t *player,
 static void
 player_on_vout_changed(vlc_player_t *player,
                        enum vlc_player_vout_action action,
-                       vout_thread_t *vout, vlc_es_id_t *es_id, void *data)
+                       vout_thread_t *vout, enum vlc_spu_channel_order spu_order,
+                       vlc_es_id_t *es_id, void *data)
 {
     struct ctx *ctx = get_ctx(player, data);
     struct report_vout report = {
         .action = action,
         .vout = vout_Hold(vout),
+        .spu_order = spu_order,
         .es_id = vlc_es_id_Hold(es_id),
     };
     assert(report.es_id);
-- 
2.20.1



More information about the vlc-devel mailing list