[totem/wip/hadess/track-lists: 1/3] backend: Move subtitles/languages list caching to video widget




commit ab8d0f3b1b67cddd886d919c54c07b5e5c68e001
Author: Bastien Nocera <hadess hadess net>
Date:   Fri Feb 11 12:39:40 2022 +0100

    backend: Move subtitles/languages list caching to video widget
    
    Instead of having the front-end keep track of track lists, and compare
    them, keep them inside the video widget. This also fixes the old
    totem-menu code that didn't check for title equality when comparing
    lists.
    
    Note that this updates the subtitles and languages menu too often,
    as we're *always* updating the menu even when it hasn't changed.
    
    Fixes: becbe7f8ef61f51ccbbb228f248b85b02e1eeab9

 src/backend/bacon-video-widget.c | 122 +++++++++++++++++++++++++++++++++------
 src/totem-menu.c                 |  58 +------------------
 src/totem-menu.h                 |   1 -
 src/totem-object.c               |   1 -
 src/totem-private.h              |   2 -
 5 files changed, 105 insertions(+), 79 deletions(-)
---
diff --git a/src/backend/bacon-video-widget.c b/src/backend/bacon-video-widget.c
index e85e6e119..ee97efa47 100644
--- a/src/backend/bacon-video-widget.c
+++ b/src/backend/bacon-video-widget.c
@@ -208,6 +208,8 @@ struct _BaconVideoWidget
   gboolean                     is_menu;
   gboolean                     has_angles;
   GList                       *chapters;
+  GList                       *subtitles; /* GList of BvwLangInfo */
+  GList                       *languages; /* GList of BvwLangInfo */
 
   BvwRotation                  rotation;
   
@@ -279,6 +281,8 @@ static gboolean bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw,
                                                      gint64 _time,
                                                      GstSeekFlags flag,
                                                      GError **error);
+static gboolean update_subtitles_tracks (BaconVideoWidget *bvw);
+static gboolean update_languages_tracks (BaconVideoWidget *bvw);
 
 typedef struct {
   GstTagList *tags;
@@ -946,6 +950,8 @@ bvw_update_stream_info (BaconVideoWidget *bvw)
   parse_stream_info (bvw);
 
   g_signal_emit (bvw, bvw_signals[SIGNAL_GOT_METADATA], 0, NULL);
+  update_subtitles_tracks (bvw);
+  update_languages_tracks (bvw);
   g_signal_emit (bvw, bvw_signals[SIGNAL_CHANNELS_CHANGE], 0);
 }
 
@@ -2741,6 +2747,41 @@ bacon_video_widget_has_previous_track (BaconVideoWidget *bvw)
   return FALSE;
 }
 
+static gboolean
+bvw_lang_infos_equal (GList *orig, GList *new)
+{
+  GList *o, *n;
+  gboolean retval;
+
+  if ((orig == NULL && new != NULL) || (orig != NULL && new == NULL))
+    return FALSE;
+  if (orig == NULL && new == NULL)
+    return TRUE;
+
+  if (g_list_length (orig) != g_list_length (new))
+    return FALSE;
+
+  retval = TRUE;
+  o = orig;
+  n = new;
+  while (o != NULL && n != NULL && retval != FALSE) {
+    BvwLangInfo *info_o, *info_n;
+
+    info_o = o->data;
+    info_n = n->data;
+    if (g_strcmp0 (info_o->title, info_n->title) != 0)
+      retval = FALSE;
+    if (g_strcmp0 (info_o->language, info_n->language) != 0)
+      retval = FALSE;
+    if (g_strcmp0 (info_o->codec, info_n->codec) != 0)
+      retval = FALSE;
+    o = g_list_next (o);
+    n = g_list_next (n);
+  }
+
+  return retval;
+}
+
 static GList *
 get_lang_list_for_type (BaconVideoWidget * bvw, const gchar * type_name)
 {
@@ -2790,6 +2831,53 @@ get_lang_list_for_type (BaconVideoWidget * bvw, const gchar * type_name)
   return g_list_reverse (ret);
 }
 
+static void
+print_lang_list (GList *list)
+{
+  GList *l;
+  guint i;
+
+  for (l = list, i = 0; l != NULL; l = l->next, i++) {
+    BvwLangInfo *info = l->data;
+    GST_DEBUG ("  %d: %s / %s / %s", i,
+              GST_STR_NULL (info->title),
+              GST_STR_NULL (info->language),
+              GST_STR_NULL (info->codec));
+  }
+}
+
+static gboolean
+update_subtitles_tracks (BaconVideoWidget *bvw)
+{
+  g_autolist(BvwLangInfo) list;
+
+  list = get_lang_list_for_type (bvw, "TEXT");
+  if (bvw_lang_infos_equal (list, bvw->subtitles))
+    return FALSE;
+  if (bvw->subtitles)
+    g_list_free_full (bvw->subtitles, (GDestroyNotify) bacon_video_widget_lang_info_free);
+  GST_DEBUG ("subtitles changed:");
+  print_lang_list (list);
+  bvw->subtitles = g_steal_pointer (&list);
+  return TRUE;
+}
+
+static gboolean
+update_languages_tracks (BaconVideoWidget *bvw)
+{
+  g_autolist(BvwLangInfo) list;
+
+  list = get_lang_list_for_type (bvw, "AUDIO");
+  if (bvw_lang_infos_equal (list, bvw->languages))
+    return FALSE;
+  if (bvw->languages)
+    g_list_free_full (bvw->languages, (GDestroyNotify) bacon_video_widget_lang_info_free);
+  GST_DEBUG ("languages changed:");
+  print_lang_list (list);
+  bvw->languages = g_steal_pointer (&list);
+  return TRUE;
+}
+
 /**
  * bacon_video_widget_lang_info_free:
  * @info: a #BvwLangInfo
@@ -2813,19 +2901,15 @@ bacon_video_widget_lang_info_free (BvwLangInfo *info)
  *
  * Returns a list of #BvwLangInfo for each subtitle track.
  *
- * Return value: a #GList of #BvwLangInfo, or %NULL; free each element with 
bacon_video_widget_lang_info_free() and the list with g_list_free()
+ * Return value: a #GList of #BvwLangInfo, or %NULL; this list is owned by the @bvw, do not free.
  **/
 GList *
 bacon_video_widget_get_subtitles (BaconVideoWidget * bvw)
 {
-  GList *list;
-
   g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), NULL);
   g_return_val_if_fail (bvw->play != NULL, NULL);
 
-  list = get_lang_list_for_type (bvw, "TEXT");
-
-  return list;
+  return bvw->subtitles;
 }
 
 /**
@@ -2834,26 +2918,15 @@ bacon_video_widget_get_subtitles (BaconVideoWidget * bvw)
  *
  * Returns a list of #BvwLangInfo for each audio track.
  *
- * Return value: a #GList of #BvwLangInfo, or %NULL; free each element with 
bacon_video_widget_lang_info_free() and the list with g_list_free()
+ * Return value: a #GList of #BvwLangInfo, or %NULL; this list is owned by the @bvw, do not free.
  **/
 GList *
 bacon_video_widget_get_languages (BaconVideoWidget * bvw)
 {
-  GList *list;
-
   g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), NULL);
   g_return_val_if_fail (bvw->play != NULL, NULL);
 
-  list = get_lang_list_for_type (bvw, "AUDIO");
-
-  /* When we have only one language, we don't need to show
-   * any languages, we default to the only track */
-  if (g_list_length (list) == 1) {
-    g_list_free_full (list, (GDestroyNotify) bacon_video_widget_lang_info_free);
-    return NULL;
-  }
-
-  return list;
+  return bvw->languages;
 }
 
 /**
@@ -2914,6 +2987,7 @@ bacon_video_widget_set_language (BaconVideoWidget * bvw, int language)
 
   g_signal_emit_by_name (G_OBJECT (bvw->play), "get-audio-tags", language, &tags);
   bvw_update_tags (bvw, tags, "audio");
+  update_languages_tracks (bvw);
 
   /* so it updates its metadata for the newly-selected stream */
   g_signal_emit (bvw, bvw_signals[SIGNAL_GOT_METADATA], 0, NULL);
@@ -3405,6 +3479,8 @@ bacon_video_widget_open (BaconVideoWidget *bvw,
 
   gst_element_set_state (bvw->play, GST_STATE_PAUSED);
 
+  update_subtitles_tracks (bvw);
+  update_languages_tracks (bvw);
   g_signal_emit (bvw, bvw_signals[SIGNAL_CHANNELS_CHANGE], 0);
 }
 
@@ -3741,6 +3817,14 @@ bacon_video_widget_close (BaconVideoWidget * bvw)
     g_list_free_full (bvw->chapters, (GDestroyNotify) gst_mini_object_unref);
     bvw->chapters = NULL;
   }
+  if (bvw->subtitles) {
+    g_list_free_full (bvw->subtitles, (GDestroyNotify) bacon_video_widget_lang_info_free);
+    bvw->subtitles = NULL;
+  }
+  if (bvw->languages) {
+    g_list_free_full (bvw->languages, (GDestroyNotify) bacon_video_widget_lang_info_free);
+    bvw->languages = NULL;
+  }
 
   g_clear_pointer (&bvw->tagcache, gst_tag_list_unref);
   g_clear_pointer (&bvw->audiotags, gst_tag_list_unref);
diff --git a/src/totem-menu.c b/src/totem-menu.c
index 42bc93019..dfd9d8866 100644
--- a/src/totem-menu.c
+++ b/src/totem-menu.c
@@ -544,39 +544,6 @@ create_lang_actions (GMenu        *menu,
        g_list_free_full (ui_list, (GDestroyNotify) g_free);
 }
 
-static gboolean
-totem_sublang_equal_lists (GList *orig, GList *new)
-{
-       GList *o, *n;
-       gboolean retval;
-
-       if ((orig == NULL && new != NULL) || (orig != NULL && new == NULL))
-               return FALSE;
-       if (orig == NULL && new == NULL)
-               return TRUE;
-
-       if (g_list_length (orig) != g_list_length (new))
-               return FALSE;
-
-       retval = TRUE;
-       o = orig;
-       n = new;
-       while (o != NULL && n != NULL && retval != FALSE) {
-               BvwLangInfo *info_o, *info_n;
-
-               info_o = o->data;
-               info_n = n->data;
-               if (g_strcmp0 (info_o->language, info_n->language) != 0)
-                       retval = FALSE;
-               if (g_strcmp0 (info_o->codec, info_n->codec) != 0)
-                       retval = FALSE;
-                o = g_list_next (o);
-                n = g_list_next (n);
-       }
-
-       return retval;
-}
-
 static void
 totem_languages_update (Totem *totem, GList *list)
 {
@@ -597,9 +564,6 @@ totem_languages_update (Totem *totem, GList *list)
        current = bacon_video_widget_get_language (totem->bvw);
        g_action_change_state (action, g_variant_new_int32 (current));
        totem->updating_menu = FALSE;
-
-       g_list_free_full (totem->languages_list, (GDestroyNotify) bacon_video_widget_lang_info_free);
-       totem->languages_list = list;
 }
 
 static void
@@ -622,9 +586,6 @@ totem_subtitles_update (Totem *totem, GList *list)
        current = bacon_video_widget_get_subtitle (totem->bvw);
        g_action_change_state (action, g_variant_new_int32 (current));
        totem->updating_menu = FALSE;
-
-       g_list_free_full (totem->subtitles_list, (GDestroyNotify) bacon_video_widget_lang_info_free);
-       totem->subtitles_list = list;
 }
 
 void
@@ -633,23 +594,8 @@ totem_sublang_update (Totem *totem)
        GList *list;
 
        list = bacon_video_widget_get_languages (totem->bvw);
-       if (totem_sublang_equal_lists (totem->languages_list, list) == TRUE) {
-               g_list_free_full (list, (GDestroyNotify) bacon_video_widget_lang_info_free);
-       } else {
-               totem_languages_update (totem, list);
-       }
+       totem_languages_update (totem, list);
 
        list = bacon_video_widget_get_subtitles (totem->bvw);
-       if (totem_sublang_equal_lists (totem->subtitles_list, list) == TRUE) {
-               g_list_free_full (list, (GDestroyNotify) bacon_video_widget_lang_info_free);
-       } else {
-               totem_subtitles_update (totem, list);
-       }
-}
-
-void
-totem_sublang_exit (Totem *totem)
-{
-       g_list_free_full (totem->subtitles_list, (GDestroyNotify) bacon_video_widget_lang_info_free);
-       g_list_free_full (totem->languages_list, (GDestroyNotify) bacon_video_widget_lang_info_free);
+       totem_subtitles_update (totem, list);
 }
diff --git a/src/totem-menu.h b/src/totem-menu.h
index 0f165c689..3c1086316 100644
--- a/src/totem-menu.h
+++ b/src/totem-menu.h
@@ -32,7 +32,6 @@ void totem_app_menu_setup (Totem *totem);
 void totem_app_actions_setup (Totem *totem);
 
 void totem_sublang_update (Totem *totem);
-void totem_sublang_exit (Totem *totem);
 
 /* For test use only */
 GList *bvw_lang_info_to_menu_labels (GList        *langs,
diff --git a/src/totem-object.c b/src/totem-object.c
index 56497f6d9..9f3aa84be 100644
--- a/src/totem-object.c
+++ b/src/totem-object.c
@@ -1404,7 +1404,6 @@ totem_object_exit (TotemObject *totem)
 
        totem_object_save_state (totem);
 
-       totem_sublang_exit (totem);
        totem_destroy_file_filters ();
 
        g_clear_object (&totem->settings);
diff --git a/src/totem-private.h b/src/totem-private.h
index ee56a7130..6337210dd 100644
--- a/src/totem-private.h
+++ b/src/totem-private.h
@@ -108,8 +108,6 @@ struct _TotemObject {
 
        /* Subtitles/Languages menus */
        gboolean updating_menu;
-       GList *subtitles_list;
-       GList *languages_list;
 
        /* controls management */
        ControlsVisibility controls_visibility;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]