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.
This commit is contained in:
Sebastian Dröge 2009-11-11 14:00:26 +01:00
parent ab96265c57
commit 1da5a3f7d3
3 changed files with 82 additions and 43 deletions

View file

@ -149,6 +149,7 @@ struct _GstDecodeBin
GstDecodeChain *decode_chain; /* Top level decode chain */ GstDecodeChain *decode_chain; /* Top level decode chain */
gint nbpads; /* unique identifier for source pads */ gint nbpads; /* unique identifier for source pads */
GMutex *factories_lock;
guint32 factories_cookie; /* Cookie from last time when factories was updated */ guint32 factories_cookie; /* Cookie from last time when factories was updated */
GValueArray *factories; /* factories we can use for selecting elements */ 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); 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 static void
gst_decode_bin_init (GstDecodeBin * decode_bin) gst_decode_bin_init (GstDecodeBin * decode_bin)
{ {
/* first filter out the interesting element factories */ /* first filter out the interesting element factories */
decode_bin->factories = decode_bin->factories_lock = g_mutex_new ();
gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER); gst_decode_bin_update_factories_list (decode_bin);
decode_bin->factories_cookie =
gst_default_registry_get_feature_list_cookie ();
/* we create the typefind element only once */ /* we create the typefind element only once */
decode_bin->typefind = gst_element_factory_make ("typefind", "typefind"); decode_bin->typefind = gst_element_factory_make ("typefind", "typefind");
@ -951,6 +964,11 @@ gst_decode_bin_finalize (GObject * object)
decode_bin->subtitle_lock = NULL; 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); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -1155,12 +1173,15 @@ gst_decode_bin_autoplug_factories (GstElement * element, GstPad * pad,
GstCaps * caps) GstCaps * caps)
{ {
GValueArray *result; GValueArray *result;
GstDecodeBin *dbin = GST_DECODE_BIN_CAST (element);
GST_DEBUG_OBJECT (element, "finding factories"); GST_DEBUG_OBJECT (element, "finding factories");
/* return all compatible factories for caps */ /* return all compatible factories for caps */
result = g_mutex_lock (dbin->factories_lock);
gst_factory_list_filter (GST_DECODE_BIN_CAST (element)->factories, caps); 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); 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: case GST_STATE_CHANGE_NULL_TO_READY:
if (dbin->typefind == NULL) if (dbin->typefind == NULL)
goto missing_typefind; goto missing_typefind;
if (dbin->factories_cookie != g_mutex_lock (dbin->factories_lock);
gst_default_registry_get_feature_list_cookie ()) { gst_decode_bin_update_factories_list (dbin);
if (dbin->factories) g_mutex_unlock (dbin->factories_lock);
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 ();
}
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
DYN_LOCK (dbin); DYN_LOCK (dbin);

View file

@ -373,6 +373,7 @@ struct _GstPlayBin
/* if we are shutting down or not */ /* if we are shutting down or not */
gint shutdown; gint shutdown;
GMutex *elements_lock;
guint32 elements_cookie; guint32 elements_cookie;
GValueArray *elements; /* factories we can use for selecting elements */ 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"); 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 static void
gst_play_bin_init (GstPlayBin * playbin) gst_play_bin_init (GstPlayBin * playbin)
{ {
GstFactoryListType type;
playbin->lock = g_mutex_new (); playbin->lock = g_mutex_new ();
playbin->dyn_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]); init_group (playbin, &playbin->groups[1]);
/* first filter out the interesting element factories */ /* first filter out the interesting element factories */
type = GST_FACTORY_LIST_DECODER | GST_FACTORY_LIST_SINK; playbin->elements_lock = g_mutex_new ();
playbin->elements = gst_factory_list_get_elements (type); gst_play_bin_update_elements_list (playbin);
playbin->elements_cookie = gst_default_registry_get_feature_list_cookie ();
gst_factory_list_debug (playbin->elements); gst_factory_list_debug (playbin->elements);
/* add sink */ /* add sink */
@ -1171,6 +1185,7 @@ gst_play_bin_finalize (GObject * object)
g_free (playbin->encoding); g_free (playbin->encoding);
g_mutex_free (playbin->lock); g_mutex_free (playbin->lock);
g_mutex_free (playbin->dyn_lock); g_mutex_free (playbin->dyn_lock);
g_mutex_free (playbin->elements_lock);
G_OBJECT_CLASS (parent_class)->finalize (object); 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); group, GST_DEBUG_PAD_NAME (pad), caps);
/* filter out the elements based on the 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); result = gst_factory_list_filter (playbin->elements, caps);
g_mutex_unlock (playbin->elements_lock);
GST_DEBUG_OBJECT (playbin, "found factories %p", result); GST_DEBUG_OBJECT (playbin, "found factories %p", result);
gst_factory_list_debug (result); gst_factory_list_debug (result);
@ -2965,15 +2983,9 @@ gst_play_bin_change_state (GstElement * element, GstStateChange transition)
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_NULL_TO_READY:
if (playbin->elements_cookie != g_mutex_lock (playbin->elements_lock);
gst_default_registry_get_feature_list_cookie ()) { gst_play_bin_update_elements_list (playbin);
if (playbin->elements) g_mutex_unlock (playbin->elements_lock);
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 ();
}
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
GST_LOG_OBJECT (playbin, "clearing shutdown flag"); GST_LOG_OBJECT (playbin, "clearing shutdown flag");

View file

@ -68,6 +68,7 @@ struct _GstURIDecodeBin
GMutex *lock; /* lock for constructing */ GMutex *lock; /* lock for constructing */
GMutex *factories_lock;
guint32 factories_cookie; guint32 factories_cookie;
GValueArray *factories; /* factories we can use for selecting elements */ 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; 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 * static GValueArray *
gst_uri_decode_bin_autoplug_factories (GstElement * element, GstPad * pad, gst_uri_decode_bin_autoplug_factories (GstElement * element, GstPad * pad,
GstCaps * caps) GstCaps * caps)
{ {
GValueArray *result; GValueArray *result;
GstURIDecodeBin *dec = GST_URI_DECODE_BIN_CAST (element);
GST_DEBUG_OBJECT (element, "finding factories"); GST_DEBUG_OBJECT (element, "finding factories");
/* return all compatible factories for caps */ /* return all compatible factories for caps */
result = g_mutex_lock (dec->factories_lock);
gst_factory_list_filter (GST_URI_DECODE_BIN_CAST (element)->factories, gst_uri_decode_bin_update_factories_list (dec);
caps); result = gst_factory_list_filter (dec->factories, caps);
g_mutex_unlock (dec->factories_lock);
GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result); GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result);
@ -471,8 +488,8 @@ static void
gst_uri_decode_bin_init (GstURIDecodeBin * dec, GstURIDecodeBinClass * klass) gst_uri_decode_bin_init (GstURIDecodeBin * dec, GstURIDecodeBinClass * klass)
{ {
/* first filter out the interesting element factories */ /* first filter out the interesting element factories */
dec->factories = gst_factory_list_get_elements (GST_FACTORY_LIST_DECODER); dec->factories_lock = g_mutex_new ();
dec->factories_cookie = gst_default_registry_get_feature_list_cookie (); gst_uri_decode_bin_update_factories_list (dec);
dec->lock = g_mutex_new (); dec->lock = g_mutex_new ();
@ -494,6 +511,7 @@ gst_uri_decode_bin_finalize (GObject * obj)
remove_decoders (dec, TRUE); remove_decoders (dec, TRUE);
g_mutex_free (dec->lock); g_mutex_free (dec->lock);
g_mutex_free (dec->factories_lock);
g_free (dec->uri); g_free (dec->uri);
g_free (dec->encoding); g_free (dec->encoding);
if (dec->factories) if (dec->factories)
@ -2043,15 +2061,9 @@ gst_uri_decode_bin_change_state (GstElement * element,
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_NULL_TO_READY:
if (decoder->factories_cookie != g_mutex_lock (decoder->factories_lock);
gst_default_registry_get_feature_list_cookie ()) { gst_uri_decode_bin_update_factories_list (decoder);
if (decoder->factories) g_mutex_unlock (decoder->factories_lock);
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 ();
}
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
if (!setup_source (decoder)) if (!setup_source (decoder))