[vlc-devel] [PATCH 08/10] Hotkey support for secondary subtitles (Part 3) - Primary / secondary subtitle cycling (Won't overwrite existing primary / secondary subtitle selection)

Roland Bewick roland.bewick at gmail.com
Sun May 5 12:01:48 CEST 2019


---
 include/vlc_input.h       |  1 +
 include/vlc_player.h      |  2 ++
 modules/control/hotkeys.c |  2 ++
 src/input/es_out.c        |  4 ++-
 src/input/player.c        | 55 +++++++++++++++++++++++++++++++++------
 src/input/var.c           |  2 ++
 6 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/include/vlc_input.h b/include/vlc_input.h
index 08cffa0c77..a99f38625d 100644
--- a/include/vlc_input.h
+++ b/include/vlc_input.h
@@ -448,6 +448,7 @@ struct vlc_input_event_es {
         VLC_INPUT_ES_UPDATED,
         VLC_INPUT_ES_SELECTED,
         VLC_INPUT_ES_UNSELECTED,
+        VLC_INPUT_ES_SET_SECONDARY,
     } action;
     /**
      * ES track id: only valid from the event callback, unless the id is held
diff --git a/include/vlc_player.h b/include/vlc_player.h
index d9aeb6dc22..b6dd5327b6 100644
--- a/include/vlc_player.h
+++ b/include/vlc_player.h
@@ -111,6 +111,8 @@ struct vlc_player_track
     es_format_t fmt;
     /** True if the track is selected */
     bool selected;
+    /** True if the track is secondary (e.g. dual subtitles)*/
+    bool secondary;
 };
 
 /**
diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c
index 34901e2f07..6446cc7578 100644
--- a/modules/control/hotkeys.c
+++ b/modules/control/hotkeys.c
@@ -348,6 +348,7 @@ PLAYER_ACTION_HANDLER(NavigateMedia)
 
 PLAYER_ACTION_HANDLER(Track)
 {
+    vlc_player_SetSelectSecondarySubtitle(player, b_control_secondary_subtitles);
     switch (action_id)
     {
         case ACTIONID_AUDIO_TRACK:
@@ -362,6 +363,7 @@ PLAYER_ACTION_HANDLER(Track)
         default:
             vlc_assert_unreachable();
     }
+    vlc_player_SetSelectSecondarySubtitle(player, false);
 }
 
 PLAYER_ACTION_HANDLER(Delay)
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 5080b67a19..4c551cf819 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -2219,7 +2219,9 @@ static void EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force )
     if( es->fmt.i_cat == SPU_ES && es->p_dec )
     {
         input_DecoderSetSecondary( es->p_dec, b_select_secondary_subtitle );
-        EsOutDecoderChangeDelay(out, es);
+        EsOutDecoderChangeDelay( out, es );
+        if ( b_select_secondary_subtitle )
+            EsOutSendEsEvent( out, es, VLC_INPUT_ES_SET_SECONDARY );
     }
 }
 
diff --git a/src/input/player.c b/src/input/player.c
index a3b9fde884..d0129d8ab6 100644
--- a/src/input/player.c
+++ b/src/input/player.c
@@ -133,6 +133,8 @@ struct vlc_player_input
     bool teletext_transparent;
     unsigned teletext_page;
 
+    bool b_select_secondary_subtitle;
+
     struct
     {
         vlc_tick_t time;
@@ -410,7 +412,8 @@ vlc_player_program_vector_FindById(vlc_player_program_vector *vec, int id,
 }
 
 static struct vlc_player_track *
-vlc_player_track_New(vlc_es_id_t *id, const char *name, const es_format_t *fmt)
+vlc_player_track_New(vlc_es_id_t *id, const char *name,
+                     const es_format_t *fmt)
 {
     struct vlc_player_track *track = malloc(sizeof(*track));
     if (!track)
@@ -431,6 +434,7 @@ vlc_player_track_New(vlc_es_id_t *id, const char *name, const es_format_t *fmt)
     }
     track->es_id = vlc_es_id_Hold(id);
     track->selected = false;
+    track->secondary = false;
 
     return track;
 }
@@ -1316,6 +1320,10 @@ static void
 vlc_player_CycleTrack(vlc_player_t *player, enum es_format_category_e cat,
                       bool next)
 {
+    struct vlc_player_input *input = vlc_player_get_input_locked(player);
+    bool b_select_secondary = input && cat == SPU_ES &&
+                              input->b_select_secondary_subtitle;
+
     size_t count = vlc_player_GetTrackCount(player, cat);
     if (!count)
         return;
@@ -1327,12 +1335,12 @@ vlc_player_CycleTrack(vlc_player_t *player, enum es_format_category_e cat,
         const struct vlc_player_track *track =
             vlc_player_GetTrackAt(player, cat, i);
         assert(track);
-        if (track->selected)
+        if (track->selected && track->secondary == b_select_secondary)
         {
             if (selected)
             {
                 /* Can't cycle through tracks if there are more than one
-                 * selected */
+                 * selected, both primary or secondary */
                 return;
             }
             index = i;
@@ -1340,21 +1348,43 @@ vlc_player_CycleTrack(vlc_player_t *player, enum es_format_category_e cat,
         }
     }
 
+    int original_index = selected ? index : -1;
+    bool b_check_first = false;
     if (!selected)
     {
-        /* No track selected: select the first or the last track */
+        /* No track selected: try to select the first or the last track. */
         index = next ? 0 : count - 1;
+        b_check_first = true;
         selected = true;
     }
-    else
+
+    /* Search until we find an unselected track */
+    while (true)
     {
         /* Unselect if we reach the end of the cycle */
         if ((next && index + 1 == count) || (!next && index == 0))
+        {
+            msg_Dbg(player, "Didn't find anything to select. Will deselect %d", index);
+            index = original_index;
             selected = false;
-        else /* Switch to the next or previous track */
-            index = index + (next ? 1 : -1);
+            break;
+        }
+        else /* Switch to the next or previous unselected track */
+        {
+            if (!b_check_first)
+                index = index + (next ? 1 : -1);
+            else
+                b_check_first = false;
+            const struct vlc_player_track *track =
+                vlc_player_GetTrackAt(player, cat, index);
+            if (!track->selected)
+                break;
+        }
     }
 
+    if (index < 0)
+        return; /* no track available nor selected matching request */
+
     const struct vlc_player_track *track =
         vlc_player_GetTrackAt(player, cat, index);
     if (selected)
@@ -1449,6 +1479,8 @@ vlc_player_input_HandleTeletextMenu(struct vlc_player_input *input,
                                      input->teletext_enabled);
             }
             break;
+        case VLC_INPUT_ES_SET_SECONDARY:
+            break;
         default:
             vlc_assert_unreachable();
     }
@@ -1594,11 +1626,17 @@ vlc_player_input_HandleEsEvent(struct vlc_player_input *input,
                                      NULL, track->es_id);
             }
             break;
+        case VLC_INPUT_ES_SET_SECONDARY:
+            track = vlc_player_track_vector_FindById(vec, ev->id, NULL);
+            if (track)
+                track->secondary = true;
+            break;
         case VLC_INPUT_ES_UNSELECTED:
             track = vlc_player_track_vector_FindById(vec, ev->id, NULL);
             if (track)
             {
                 track->selected = false;
+                track->secondary = false;
                 vlc_player_SendEvent(player, on_track_selection_changed,
                                      track->es_id, NULL);
             }
@@ -1793,7 +1831,7 @@ vlc_player_input_HandleVoutEvent(struct vlc_player_input *input,
 {
     assert(ev->vout);
 
-    static const char osd_vars[][sizeof("deinterlace-mode")] = {
+    static const char osd_vars[][sizeof("secondary-sub-margin")] = {
         "aspect-ratio", "autoscale", "crop", "crop-bottom",
         "crop-top", "crop-left", "crop-right", "deinterlace",
         "deinterlace-mode", "sub-margin", "secondary-sub-margin", "zoom"
@@ -2904,6 +2942,7 @@ vlc_player_SetSelectSecondarySubtitle(vlc_player_t *player, bool select)
     struct vlc_player_input *input = vlc_player_get_input_locked(player);
     if (!input)
         return;
+    input->b_select_secondary_subtitle = select;
     input_ControlPushHelper(input->thread,
                             INPUT_CONTROL_SET_SELECT_SECONDARY_SUBTITLE,
                             &(vlc_value_t){ .b_bool = select });
diff --git a/src/input/var.c b/src/input/var.c
index 5255227a03..381b99b586 100644
--- a/src/input/var.c
+++ b/src/input/var.c
@@ -385,6 +385,8 @@ void input_LegacyEvents( input_thread_t *p_input,
                 }
                 case VLC_INPUT_ES_UPDATED:
                     break;
+                case VLC_INPUT_ES_SET_SECONDARY:
+                    break;
             }
             break;
         case INPUT_EVENT_RECORD:
-- 
2.17.1



More information about the vlc-devel mailing list