From 1da5a3f7d3ad6c44b14f3337af1786ef649b00a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 11 Nov 2009 14:00:26 +0100 Subject: [PATCH] playback: Update factories list on every access if the registry has changed 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 | 45 ++++++++++++++++++++++------------ gst/playback/gstplaybin2.c | 40 +++++++++++++++++++----------- gst/playback/gsturidecodebin.c | 40 +++++++++++++++++++----------- 3 files changed, 82 insertions(+), 43 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 624d27e3ac..10cf292ca5 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -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); diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 3610b07c88..0c39dbe46e 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -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_update_elements_list (GstPlayBin * playbin) +{ + 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) { - GstFactoryListType type; - 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"); diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index 0bbcf611dd..5bbbe1fa99 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -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))