[vlc-devel] [RFC PATCH 3/3] vlc_player: handle teletext controls (fixup!)

Thomas Guillem thomas at gllm.fr
Tue Oct 16 16:35:29 CEST 2018


---
 include/vlc_input.h  |   9 +++
 include/vlc_player.h |  36 ++++++++++
 src/input/player.c   | 152 ++++++++++++++++++++++++++++++++++++++++++-
 src/libvlccore.sym   |   7 ++
 4 files changed, 201 insertions(+), 3 deletions(-)

diff --git a/include/vlc_input.h b/include/vlc_input.h
index 8f6a7be472..e6d5939d3a 100644
--- a/include/vlc_input.h
+++ b/include/vlc_input.h
@@ -388,6 +388,11 @@ typedef enum input_event_type_e
     /* (pre-)parsing events */
     INPUT_EVENT_SUBITEMS,
 
+    /* vbi_page has changed */
+    INPUT_EVENT_VBI_PAGE,
+    /* vbi_transparency has changed */
+    INPUT_EVENT_VBI_TRANSPARENCY,
+
 } input_event_type_e;
 
 #define VLC_INPUT_CAPABILITIES_SEEKABLE (1<<0)
@@ -515,6 +520,10 @@ struct vlc_input_event
         struct vlc_input_event_vout vout;
         /* INPUT_EVENT_SUBITEMS */
         input_item_node_t *subitems;
+        /* INPUT_EVENT_VBI_PAGE */
+        unsigned vbi_page;
+        /* INPUT_EVENT_VBI_TRANSPARENCY */
+        bool vbi_transparent;
     };
 };
 
diff --git a/include/vlc_player.h b/include/vlc_player.h
index 26e8e89408..fa88df0f76 100644
--- a/include/vlc_player.h
+++ b/include/vlc_player.h
@@ -200,6 +200,12 @@ enum vlc_player_media_stopped_action {
 #define VLC_PLAYER_CAP_CHANGE_RATE (1<<2)
 #define VLC_PLAYER_CAP_REWIND (1<<3)
 
+#define VLC_PLAYER_TELETEXT_KEY_RED ('r' << 16)
+#define VLC_PLAYER_TELETEXT_KEY_GREEN ('g' << 16)
+#define VLC_PLAYER_TELETEXT_KEY_YELLOW ('g' << 16)
+#define VLC_PLAYER_TELETEXT_KEY_BLUE ('b' << 16)
+#define VLC_PLAYER_TELETEXT_KEY_INDEX ('i' << 16)
+
 /**
  * Callbacks to get the state of the input.
  *
@@ -250,6 +256,15 @@ struct vlc_player_cbs
     void (*on_teletext_menu_changed)(vlc_player_t *player,
         bool has_teletext_menu, void *data);
 
+    void (*on_teletext_enabled_changed)(vlc_player_t *player,
+        bool enabled, void *data);
+
+    void (*on_teletext_page_changed)(vlc_player_t *player,
+        unsigned new_page, void *data);
+
+    void (*on_teletext_transparency_changed)(vlc_player_t *player,
+        bool enabled, void *data);
+
     void (*on_program_list_changed)(vlc_player_t *player,
         enum vlc_player_list_action action,
         const struct vlc_player_program *prgm, void *data);
@@ -920,6 +935,27 @@ vlc_player_GetProgram(vlc_player_t *player, int id);
 VLC_API void
 vlc_player_SelectProgram(vlc_player_t *player, int id);
 
+VLC_API bool
+vlc_player_HasTeletextMenu(vlc_player_t *player);
+
+VLC_API void
+vlc_player_SetTeletextEnabled(vlc_player_t *player, bool enabled);
+
+VLC_API bool
+vlc_player_IsTeletextEnabled(vlc_player_t *player);
+
+VLC_API void
+vlc_player_SelectTeletextPage(vlc_player_t *player, unsigned page);
+
+VLC_API unsigned
+vlc_player_GetTeletextPage(vlc_player_t *player);
+
+VLC_API void
+vlc_player_SetTeletextTransparency(vlc_player_t *player, bool enabled);
+
+VLC_API bool
+vlc_player_IsTeletextTransparent(vlc_player_t *player);
+
 VLC_API struct vlc_player_title_list *
 vlc_player_GetTitleList(vlc_player_t *player);
 
diff --git a/src/input/player.c b/src/input/player.c
index 5f7f9150e4..5067955130 100644
--- a/src/input/player.c
+++ b/src/input/player.c
@@ -109,6 +109,10 @@ struct vlc_player_input
     size_t chapter_selected;
 
     struct vlc_list node;
+
+    bool teletext_enabled;
+    bool teletext_transparent;
+    unsigned teletext_page;
 };
 
 struct vlc_player_t
@@ -518,6 +522,9 @@ vlc_player_input_New(vlc_player_t *player, input_item_t *item)
     input->titles = NULL;
     input->title_selected = input->chapter_selected = 0;
 
+    input->teletext_enabled = input->teletext_transparent = false;
+    input->teletext_page = 0;
+
     input->thread = input_Create(player, input_thread_events, input, item,
                                  NULL, player->resource, player->renderer);
     if (!input->thread)
@@ -1097,20 +1104,149 @@ vlc_player_SelectDefaultTrack(vlc_player_t *player,
     /* TODO */ (void) cat; (void) lang;
 }
 
+static void
+vlc_player_input_HandleTeletextMenu(struct vlc_player_input *input,
+                                    const struct vlc_input_event_es *ev)
+{
+    vlc_player_t *player = input->player;
+    switch (ev->action)
+    {
+        case VLC_INPUT_ES_ADDED:
+            if (input->teletext_menu)
+            {
+                msg_Warn(player, "Can't handle more than one teletext menu "
+                         "track. Using the last one.");
+                vlc_player_track_Delete(input->teletext_menu);
+            }
+            input->teletext_menu = vlc_player_track_New(ev->id, ev->title,
+                                                        ev->fmt);
+            if (!input->teletext_menu)
+                return;
+
+            vlc_player_SendEvent(player, on_teletext_menu_changed, true);
+            break;
+        case VLC_INPUT_ES_DELETED:
+        {
+            if (input->teletext_menu && input->teletext_menu->id == ev->id)
+            {
+                assert(!input->teletext_enabled);
+
+                vlc_player_track_Delete(input->teletext_menu);
+                input->teletext_menu = NULL;
+                vlc_player_SendEvent(player, on_teletext_menu_changed, false);
+            }
+            break;
+        }
+        case VLC_INPUT_ES_UPDATED:
+            break;
+        case VLC_INPUT_ES_SELECTED:
+        case VLC_INPUT_ES_UNSELECTED:
+            if (input->teletext_menu->id == ev->id)
+            {
+                input->teletext_enabled = ev->action == VLC_INPUT_ES_SELECTED;
+                vlc_player_SendEvent(player, on_teletext_enabled_changed,
+                                     input->teletext_enabled);
+            }
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
+}
+
+void
+vlc_player_SetTeletextEnabled(vlc_player_t *player, bool enabled)
+{
+    struct vlc_player_input *input = vlc_player_get_input_locked(player);
+    if (!input || !input->teletext_menu)
+        return;
+    if (enabled)
+        vlc_player_SelectTrack(player, input->teletext_menu->id);
+    else
+        vlc_player_UnselectTrack(player, input->teletext_menu->id);
+}
+
+void
+vlc_player_SelectTeletextPage(vlc_player_t *player, unsigned page)
+{
+    struct vlc_player_input *input = vlc_player_get_input_locked(player);
+    if (!input || !input->teletext_menu)
+        return;
+
+    input_ControlPush(input->thread, INPUT_CONTROL_SET_VBI_PAGE,
+        &(input_control_param_t) {
+            .vbi_page.id = input->teletext_menu->id,
+            .vbi_page.page = page,
+    });
+}
+
+void
+vlc_player_SetTeletextTransparency(vlc_player_t *player, bool enabled)
+{
+    struct vlc_player_input *input = vlc_player_get_input_locked(player);
+    if (!input || !input->teletext_menu)
+        return;
+
+    input_ControlPush(input->thread, INPUT_CONTROL_SET_VBI_TRANSPARENCY,
+        &(input_control_param_t) {
+            .vbi_transparency.id = input->teletext_menu->id,
+            .vbi_transparency.enabled = enabled,
+    });
+}
+
+bool
+vlc_player_HasTeletextMenu(vlc_player_t *player)
+{
+    struct vlc_player_input *input = vlc_player_get_input_locked(player);
+    return input && input->teletext_menu;
+}
+
+bool
+vlc_player_IsTeletextEnabled(vlc_player_t *player)
+{
+    struct vlc_player_input *input = vlc_player_get_input_locked(player);
+    if (input && input->teletext_enabled)
+    {
+        assert(input->teletext_menu);
+        return true;
+    }
+    return false;
+}
+
+unsigned
+vlc_player_GetTeletextPage(vlc_player_t *player)
+{
+    struct vlc_player_input *input = vlc_player_get_input_locked(player);
+    return vlc_player_IsTeletextEnabled(player) ? input->teletext_page : 0;
+}
+
+bool
+vlc_player_IsTeletextTransparent(vlc_player_t *player)
+{
+    struct vlc_player_input *input = vlc_player_get_input_locked(player);
+    return vlc_player_IsTeletextEnabled(player) && input->teletext_transparent;
+}
+
 static void
 vlc_player_input_HandleEsEvent(struct vlc_player_input *input,
                                const struct vlc_input_event_es *ev)
 {
     assert(ev->id && ev->title && ev->fmt);
 
-    vlc_player_t *player = input->player;
-    struct vlc_player_track *track;
+    if (ev->fmt->i_cat == SPU_ES && ev->fmt->i_codec == VLC_CODEC_TELETEXT
+     && (ev->fmt->subs.teletext.i_magazine == 1
+      || ev->fmt->subs.teletext.i_magazine == -1))
+    {
+        vlc_player_input_HandleTeletextMenu(input, ev);
+        return;
+    }
+
     vlc_player_track_vector *vec =
         vlc_player_input_GetTrackVector(input, ev->fmt->i_cat);
-
     if (!vec)
         return; /* UNKNOWN_ES or DATA_ES not handled */
 
+    vlc_player_t *player = input->player;
+    struct vlc_player_track *track;
     switch (ev->action)
     {
         case VLC_INPUT_ES_ADDED:
@@ -1501,6 +1637,16 @@ input_thread_events(input_thread_t *input_thread,
             assert(!input->started);
             vlc_player_destructor_AddJoinableInput(player, input);
             break;
+        case INPUT_EVENT_VBI_PAGE:
+            input->teletext_page = event->vbi_page < 999 ? event->vbi_page : 100;
+            vlc_player_SendEvent(player, on_teletext_page_changed,
+                                 input->teletext_page);
+            break;
+        case INPUT_EVENT_VBI_TRANSPARENCY:
+            input->teletext_transparent = event->vbi_transparent;
+            vlc_player_SendEvent(player, on_teletext_transparency_changed,
+                                 input->teletext_transparent);
+            break;
         default:
             break;
     }
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 660884d00a..89d5d8ba0c 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -859,6 +859,13 @@ vlc_player_track_Delete
 vlc_player_track_Dup
 vlc_player_vout_IsFullscreen
 vlc_player_vout_SetFullscreen
+vlc_player_HasTeletextMenu
+vlc_player_SetTeletextEnabled
+vlc_player_IsTeletextEnabled
+vlc_player_SelectTeletextPage
+vlc_player_GetTeletextPage
+vlc_player_SetTeletextTransparency
+vlc_player_IsTeletextTransparent
 vlc_playlist_item_Hold
 vlc_playlist_item_Release
 vlc_playlist_item_GetMedia
-- 
2.19.1



More information about the vlc-devel mailing list