[vlc-devel] [PATCH 01/10] Enable secondary SPU ES and selection from the GUI

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


Secondary subtitles will show directly above or below primary subtitles.

Currently only QT supported (See change in input_models.cpp)
---
 include/vlc_player.h                 | 13 ++++++++
 modules/gui/qt/util/input_models.cpp |  6 ++++
 src/input/es_out.c                   | 47 ++++++++++++++++++++++++++--
 src/input/es_out.h                   |  5 ++-
 src/input/input.c                    |  5 +++
 src/input/input_internal.h           |  1 +
 src/input/player.c                   | 11 +++++++
 src/libvlccore.sym                   |  1 +
 8 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/include/vlc_player.h b/include/vlc_player.h
index 17e927c948..f1f43b7478 100644
--- a/include/vlc_player.h
+++ b/include/vlc_player.h
@@ -2429,6 +2429,19 @@ vlc_player_SetSubtitleTextScale(vlc_player_t *player, unsigned scale);
 VLC_API unsigned
 vlc_player_GetSubtitleTextScale(vlc_player_t *player);
 
+/**
+ * Set whether to select a subtitle as secondary (Dual subtitles)
+ *
+ * @note This function allows a user to select a secondary subtitle from
+ * the GUI. Immediately after selecting a secondary subtitle track this
+ * should be returned to false.
+ *
+ * @param player locked player instance
+ * @param select true to select a secondary subtitle
+ */
+VLC_API void
+vlc_player_SetSelectSecondarySubtitle(vlc_player_t *player, bool select);
+
 /**
  * Get the signal quality and strength of the current media
  *
diff --git a/modules/gui/qt/util/input_models.cpp b/modules/gui/qt/util/input_models.cpp
index e381fbb917..b480171b5c 100644
--- a/modules/gui/qt/util/input_models.cpp
+++ b/modules/gui/qt/util/input_models.cpp
@@ -62,7 +62,13 @@ bool TrackListModel::setData(const QModelIndex &index, const QVariant &value, in
     vlc_player_locker lock{ m_player };
 
     if (select)
+    {
+        /* Only allow secondary subtitles to be manually selected
+        by the user through the GUI. */
+        vlc_player_SetSelectSecondarySubtitle(m_player, true);
         vlc_player_SelectTrack(m_player, m_data[row].m_id.get());
+        vlc_player_SetSelectSecondarySubtitle(m_player, false);
+    }
     else
         vlc_player_UnselectTrack(m_player, m_data[row].m_id.get());
     return true;
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 3352602849..78d0d3330b 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -208,6 +208,9 @@ typedef struct
     /* Used only to limit debugging output */
     int         i_prev_stream_level;
 
+    /* Used to temporarily allow dual subtitle selection */
+    bool        b_select_secondary_subtitle;
+
     es_out_t out;
 } es_out_sys_t;
 
@@ -2029,6 +2032,24 @@ static void EsOutUnselectEs( es_out_t *out, es_out_id_t *es, bool b_update )
     EsOutSendEsEvent(out, es, VLC_INPUT_ES_UNSELECTED);
 }
 
+/**
+ * Count the number of selected ES of the given category
+ * \param i_cat the ES category (e.g. SPU_ES)
+ * \return count
+ */
+static int EsOutCountSelected( es_out_sys_t *p_sys, 
+                               enum es_format_category_e i_cat )
+{
+    int i_selected_count = 0;
+    es_out_id_t *other;
+    foreach_es_then_es_slaves(other)
+        if( other->fmt.i_cat == i_cat && EsIsSelected( other ) )
+        {
+            ++i_selected_count;
+        }
+    return i_selected_count;
+}
+
 /**
  * Select an ES given the current mode
  * XXX: you need to take a the lock before (stream.stream_lock)
@@ -2049,9 +2070,24 @@ static void EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force )
         return;
     }
 
+    /* Select secondary if the user has already selected a primary sub track */
+    bool b_select_secondary_subtitle = es->fmt.i_cat == SPU_ES && 
+                               p_sys->b_select_secondary_subtitle &&
+                               p_esprops->p_main_es != NULL &&
+                               EsIsSelected(p_esprops->p_main_es);
+
+    if ( b_select_secondary_subtitle &&
+         EsOutCountSelected( p_sys, es->fmt.i_cat ) > 1 )
+    {
+        /* Don't allow more than one secondary SPU ES selected at a time. */
+        EsOutSendEsEvent(out, es, VLC_INPUT_ES_UNSELECTED);
+        return;
+    }
+
     bool b_auto_unselect = p_esprops && p_sys->i_mode == ES_OUT_MODE_AUTO &&
                            p_esprops->e_policy == ES_OUT_ES_POLICY_EXCLUSIVE &&
-                           p_esprops->p_main_es && p_esprops->p_main_es != es;
+                           p_esprops->p_main_es && p_esprops->p_main_es != es &&
+                           !b_select_secondary_subtitle;
 
     if( p_sys->i_mode == ES_OUT_MODE_ALL || b_force )
     {
@@ -2171,7 +2207,8 @@ static void EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force )
     }
 
     /* FIXME TODO handle priority here */
-    if( p_esprops && p_sys->i_mode == ES_OUT_MODE_AUTO && EsIsSelected( es ) )
+    if( p_esprops && p_sys->i_mode == ES_OUT_MODE_AUTO && EsIsSelected( es ) && 
+        !b_select_secondary_subtitle )
         p_esprops->p_main_es = es;
 }
 
@@ -3181,6 +3218,12 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
         }
         return ret;
     }
+    case ES_OUT_SET_SELECT_SECONDARY_SUBTITLE:
+    {
+        es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+        p_sys->b_select_secondary_subtitle = va_arg( args, int );
+        return VLC_SUCCESS;
+    }
     default:
         msg_Err( p_sys->p_input, "unknown query 0x%x in %s", i_query,
                  __func__  );
diff --git a/src/input/es_out.h b/src/input/es_out.h
index 7cbea71728..42b7d0152a 100644
--- a/src/input/es_out.h
+++ b/src/input/es_out.h
@@ -89,7 +89,10 @@ enum es_out_query_private_e
     ES_OUT_SET_VBI_PAGE,                            /* arg1=unsigned res=can fail */
 
     /* Set VBI/Teletext menu transparent */
-    ES_OUT_SET_VBI_TRANSPARENCY                     /* arg1=bool res=can fail */
+    ES_OUT_SET_VBI_TRANSPARENCY,                    /* arg1=bool res=can fail */
+    
+    /* Set to select a secondary SPU ES instead of the primary one */
+    ES_OUT_SET_SELECT_SECONDARY_SUBTITLE            /* arg1=bool res=cannot fail */
 };
 
 static inline void es_out_SetMode( es_out_t *p_out, int i_mode )
diff --git a/src/input/input.c b/src/input/input.c
index 506e269ecc..0965800f90 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -2397,6 +2397,11 @@ static bool Control( input_thread_t *p_input,
                             param.vbi_transparency.id,
                             param.vbi_transparency.enabled );
             break;
+        case INPUT_CONTROL_SET_SELECT_SECONDARY_SUBTITLE:
+             es_out_Control( priv->p_es_out_display,
+                             ES_OUT_SET_SELECT_SECONDARY_SUBTITLE,
+                             param.val.b_bool );
+             break;
 
         case INPUT_CONTROL_NAV_ACTIVATE:
         case INPUT_CONTROL_NAV_UP:
diff --git a/src/input/input_internal.h b/src/input/input_internal.h
index 18495881c2..0cd8484ca8 100644
--- a/src/input/input_internal.h
+++ b/src/input/input_internal.h
@@ -268,6 +268,7 @@ enum input_control_e
 
     INPUT_CONTROL_SET_VBI_PAGE,
     INPUT_CONTROL_SET_VBI_TRANSPARENCY,
+    INPUT_CONTROL_SET_SELECT_SECONDARY_SUBTITLE,
 };
 
 /* Internal helpers */
diff --git a/src/input/player.c b/src/input/player.c
index da74eb4ee4..977fc95d94 100644
--- a/src/input/player.c
+++ b/src/input/player.c
@@ -2886,6 +2886,17 @@ vlc_player_SetSubtitleSync(vlc_player_t *player,
     }
 }
 
+void
+vlc_player_SetSelectSecondarySubtitle(vlc_player_t *player, bool select)
+{
+    struct vlc_player_input *input = vlc_player_get_input_locked(player);
+    if (!input)
+        return;
+    input_ControlPushHelper(input->thread,
+                            INPUT_CONTROL_SET_SELECT_SECONDARY_SUBTITLE,
+                            &(vlc_value_t){ .b_bool = select });
+}
+
 vlc_tick_t
 vlc_player_GetSubtitleDelay(vlc_player_t *player)
 {
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index ed5e1ee661..403375678e 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -908,6 +908,7 @@ vlc_player_SetStartPaused
 vlc_player_SetSubtitleDelay
 vlc_player_SetSubtitleSync
 vlc_player_SetSubtitleTextScale
+vlc_player_SetSelectSecondarySubtitle
 vlc_player_SetTeletextEnabled
 vlc_player_SetTeletextTransparency
 vlc_player_SetTrackCategoryEnabled
-- 
2.17.1



More information about the vlc-devel mailing list