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 */
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);

View 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_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");

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