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))