playback: Update factories list on every access if the registry has changed
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 11 Nov 2009 13:00:26 +0000 (14:00 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 11 Nov 2009 13:00:26 +0000 (14:00 +0100)
This makes application's simpler because the element doesn't need to
go to NULL first to make use of newly installed plugins.

Fixes bug #601480.

gst/playback/gstdecodebin2.c
gst/playback/gstplaybin2.c
gst/playback/gsturidecodebin.c

index 624d27e3acd86fb614dd033221f5c823f7dfd4b1..10cf292ca5f0e7f04d09759f684b5bfece249eed 100644 (file)
@@ -149,6 +149,7 @@ struct _GstDecodeBin
   GstDecodeChain *decode_chain; /* Top level decode chain */
   gint nbpads;                  /* unique identifier for source pads */
 
+  GMutex *factories_lock;
   guint32 factories_cookie;     /* Cookie from last time when factories was updated */
   GValueArray *factories;       /* factories we can use for selecting elements */
 
@@ -840,14 +841,26 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass)
       GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);
 }
 
+/* Must be called with factories lock! */
+static void
+gst_decode_bin_update_factories_list (GstDecodeBin * dbin)
+{
+  if (!dbin->factories
+      || dbin->factories_cookie !=
+      gst_default_registry_get_feature_list_cookie ()) {
+    if (dbin->factories)
+      g_value_array_free (dbin->factories);
+    dbin->factories = gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER);
+    dbin->factories_cookie = gst_default_registry_get_feature_list_cookie ();
+  }
+}
+
 static void
 gst_decode_bin_init (GstDecodeBin * decode_bin)
 {
   /* first filter out the interesting element factories */
-  decode_bin->factories =
-      gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER);
-  decode_bin->factories_cookie =
-      gst_default_registry_get_feature_list_cookie ();
+  decode_bin->factories_lock = g_mutex_new ();
+  gst_decode_bin_update_factories_list (decode_bin);
 
   /* we create the typefind element only once */
   decode_bin->typefind = gst_element_factory_make ("typefind", "typefind");
@@ -951,6 +964,11 @@ gst_decode_bin_finalize (GObject * object)
     decode_bin->subtitle_lock = NULL;
   }
 
+  if (decode_bin->factories_lock) {
+    g_mutex_free (decode_bin->factories_lock);
+    decode_bin->factories_lock = NULL;
+  }
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -1155,12 +1173,15 @@ gst_decode_bin_autoplug_factories (GstElement * element, GstPad * pad,
     GstCaps * caps)
 {
   GValueArray *result;
+  GstDecodeBin *dbin = GST_DECODE_BIN_CAST (element);
 
   GST_DEBUG_OBJECT (element, "finding factories");
 
   /* return all compatible factories for caps */
-  result =
-      gst_factory_list_filter (GST_DECODE_BIN_CAST (element)->factories, caps);
+  g_mutex_lock (dbin->factories_lock);
+  gst_decode_bin_update_factories_list (dbin);
+  result = gst_factory_list_filter (dbin->factories, caps);
+  g_mutex_unlock (dbin->factories_lock);
 
   GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result);
 
@@ -3232,15 +3253,9 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_NULL_TO_READY:
       if (dbin->typefind == NULL)
         goto missing_typefind;
-      if (dbin->factories_cookie !=
-          gst_default_registry_get_feature_list_cookie ()) {
-        if (dbin->factories)
-          g_value_array_free (dbin->factories);
-        dbin->factories =
-            gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER);
-        dbin->factories_cookie =
-            gst_default_registry_get_feature_list_cookie ();
-      }
+      g_mutex_lock (dbin->factories_lock);
+      gst_decode_bin_update_factories_list (dbin);
+      g_mutex_unlock (dbin->factories_lock);
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       DYN_LOCK (dbin);
index 3610b07c8839dfd78a3116515261e8cc25a02d4a..0c39dbe46e4399d816c6f299ac895e53463c28c4 100644 (file)
@@ -373,6 +373,7 @@ struct _GstPlayBin
   /* if we are shutting down or not */
   gint shutdown;
 
+  GMutex *elements_lock;
   guint32 elements_cookie;
   GValueArray *elements;        /* factories we can use for selecting elements */
 
@@ -1103,11 +1104,25 @@ notify_mute_cb (GObject * selector, GParamSpec * pspec, GstPlayBin * playbin)
   g_object_notify (G_OBJECT (playbin), "mute");
 }
 
+/* Must be called with elements lock! */
 static void
-gst_play_bin_init (GstPlayBin * playbin)
+gst_play_bin_update_elements_list (GstPlayBin * playbin)
 {
-  GstFactoryListType type;
+  if (!playbin->elements ||
+      playbin->elements_cookie !=
+      gst_default_registry_get_feature_list_cookie ()) {
+    if (playbin->elements)
+      g_value_array_free (playbin->elements);
+    playbin->elements =
+        gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER |
+        GST_FACTORY_LIST_SINK);
+    playbin->elements_cookie = gst_default_registry_get_feature_list_cookie ();
+  }
+}
 
+static void
+gst_play_bin_init (GstPlayBin * playbin)
+{
   playbin->lock = g_mutex_new ();
   playbin->dyn_lock = g_mutex_new ();
 
@@ -1121,9 +1136,8 @@ gst_play_bin_init (GstPlayBin * playbin)
   init_group (playbin, &playbin->groups[1]);
 
   /* first filter out the interesting element factories */
-  type = GST_FACTORY_LIST_DECODER | GST_FACTORY_LIST_SINK;
-  playbin->elements = gst_factory_list_get_elements (type);
-  playbin->elements_cookie = gst_default_registry_get_feature_list_cookie ();
+  playbin->elements_lock = g_mutex_new ();
+  gst_play_bin_update_elements_list (playbin);
   gst_factory_list_debug (playbin->elements);
 
   /* add sink */
@@ -1171,6 +1185,7 @@ gst_play_bin_finalize (GObject * object)
   g_free (playbin->encoding);
   g_mutex_free (playbin->lock);
   g_mutex_free (playbin->dyn_lock);
+  g_mutex_free (playbin->elements_lock);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -2467,7 +2482,10 @@ autoplug_factories_cb (GstElement * decodebin, GstPad * pad,
       group, GST_DEBUG_PAD_NAME (pad), caps);
 
   /* filter out the elements based on the caps. */
+  g_mutex_lock (playbin->elements_lock);
+  gst_play_bin_update_elements_list (playbin);
   result = gst_factory_list_filter (playbin->elements, caps);
+  g_mutex_unlock (playbin->elements_lock);
 
   GST_DEBUG_OBJECT (playbin, "found factories %p", result);
   gst_factory_list_debug (result);
@@ -2965,15 +2983,9 @@ gst_play_bin_change_state (GstElement * element, GstStateChange transition)
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
-      if (playbin->elements_cookie !=
-          gst_default_registry_get_feature_list_cookie ()) {
-        if (playbin->elements)
-          g_value_array_free (playbin->elements);
-        playbin->elements =
-            gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER);
-        playbin->elements_cookie =
-            gst_default_registry_get_feature_list_cookie ();
-      }
+      g_mutex_lock (playbin->elements_lock);
+      gst_play_bin_update_elements_list (playbin);
+      g_mutex_unlock (playbin->elements_lock);
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       GST_LOG_OBJECT (playbin, "clearing shutdown flag");
index 0bbcf611ddb8c9c76e08022e534f3df2f7fcab4e..5bbbe1fa99d44f07a92a0904e12ac84aac867566 100644 (file)
@@ -68,6 +68,7 @@ struct _GstURIDecodeBin
 
   GMutex *lock;                 /* lock for constructing */
 
+  GMutex *factories_lock;
   guint32 factories_cookie;
   GValueArray *factories;       /* factories we can use for selecting elements */
 
@@ -250,18 +251,34 @@ gst_uri_decode_bin_autoplug_continue (GstElement * element, GstPad * pad,
   return TRUE;
 }
 
+/* Must be called with factories lock! */
+static void
+gst_uri_decode_bin_update_factories_list (GstURIDecodeBin * dec)
+{
+  if (!dec->factories ||
+      dec->factories_cookie !=
+      gst_default_registry_get_feature_list_cookie ()) {
+    if (dec->factories)
+      g_value_array_free (dec->factories);
+    dec->factories = gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER);
+    dec->factories_cookie = gst_default_registry_get_feature_list_cookie ();
+  }
+}
+
 static GValueArray *
 gst_uri_decode_bin_autoplug_factories (GstElement * element, GstPad * pad,
     GstCaps * caps)
 {
   GValueArray *result;
+  GstURIDecodeBin *dec = GST_URI_DECODE_BIN_CAST (element);
 
   GST_DEBUG_OBJECT (element, "finding factories");
 
   /* return all compatible factories for caps */
-  result =
-      gst_factory_list_filter (GST_URI_DECODE_BIN_CAST (element)->factories,
-      caps);
+  g_mutex_lock (dec->factories_lock);
+  gst_uri_decode_bin_update_factories_list (dec);
+  result = gst_factory_list_filter (dec->factories, caps);
+  g_mutex_unlock (dec->factories_lock);
 
   GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result);
 
@@ -471,8 +488,8 @@ static void
 gst_uri_decode_bin_init (GstURIDecodeBin * dec, GstURIDecodeBinClass * klass)
 {
   /* first filter out the interesting element factories */
-  dec->factories = gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER);
-  dec->factories_cookie = gst_default_registry_get_feature_list_cookie ();
+  dec->factories_lock = g_mutex_new ();
+  gst_uri_decode_bin_update_factories_list (dec);
 
   dec->lock = g_mutex_new ();
 
@@ -494,6 +511,7 @@ gst_uri_decode_bin_finalize (GObject * obj)
 
   remove_decoders (dec, TRUE);
   g_mutex_free (dec->lock);
+  g_mutex_free (dec->factories_lock);
   g_free (dec->uri);
   g_free (dec->encoding);
   if (dec->factories)
@@ -2043,15 +2061,9 @@ gst_uri_decode_bin_change_state (GstElement * element,
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
-      if (decoder->factories_cookie !=
-          gst_default_registry_get_feature_list_cookie ()) {
-        if (decoder->factories)
-          g_value_array_free (decoder->factories);
-        decoder->factories =
-            gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER);
-        decoder->factories_cookie =
-            gst_default_registry_get_feature_list_cookie ();
-      }
+      g_mutex_lock (decoder->factories_lock);
+      gst_uri_decode_bin_update_factories_list (decoder);
+      g_mutex_unlock (decoder->factories_lock);
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       if (!setup_source (decoder))