From 6637a949e72d465c6ed7238f5424e51582ea4f5c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sat, 2 Nov 2002 13:19:30 +0000 Subject: [PATCH] Moved deep notify to GstObject Original commit message from CVS: Moved deep notify to GstObject --- gst/gstelement.c | 121 ++++++----------------------------------------- gst/gstelement.h | 6 +-- gst/gstobject.c | 95 +++++++++++++++++++++++++++++++++++++ gst/gstobject.h | 4 ++ 4 files changed, 116 insertions(+), 110 deletions(-) diff --git a/gst/gstelement.c b/gst/gstelement.c index e0f2998ff0..dedfa89d12 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -41,7 +41,6 @@ enum { PAD_REMOVED, ERROR, EOS, - DEEP_NOTIFY, LAST_SIGNAL }; @@ -60,7 +59,6 @@ static void gst_element_real_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_element_real_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void gst_element_dispatch_properties_changed (GObject * object, guint n_pspecs, GParamSpec **pspecs); static void gst_element_dispose (GObject *object); @@ -137,21 +135,10 @@ gst_element_class_init (GstElementClass *klass) g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0); - gst_element_signals[DEEP_NOTIFY] = - g_signal_new ("deep_notify", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS, - G_STRUCT_OFFSET (GstElementClass, deep_notify), NULL, NULL, - gst_marshal_VOID__OBJECT_PARAM, G_TYPE_NONE, - 2, G_TYPE_OBJECT, G_TYPE_PARAM); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_element_real_set_property); gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_element_real_get_property); - /* see the comments at gst_element_dispatch_properties_changed */ - gobject_class->dispatch_properties_changed - = GST_DEBUG_FUNCPTR (gst_element_dispatch_properties_changed); - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose); #ifndef GST_DISABLE_LOADSAVE @@ -214,87 +201,6 @@ gst_element_real_get_property (GObject *object, guint prop_id, GValue *value, GP (oclass->get_property) (object, prop_id, value, pspec); } -/* Changing a GObject property of an element will result in "deep_notify" - * signals being emitted by the element itself, as well as in each parent - * element. This is so that an application can connect a listener to the - * top-level bin to catch property-change notifications for all contained - * elements. */ -static void -gst_element_dispatch_properties_changed (GObject *object, - guint n_pspecs, - GParamSpec **pspecs) -{ - GstObject *gst_object; - guint i; - - /* do the standard dispatching */ - G_OBJECT_CLASS (parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs); - - /* now let the parent dispatch those, too */ - gst_object = GST_OBJECT_PARENT (object); - while (gst_object) { - /* need own category? */ - for (i = 0; i < n_pspecs; i++) { - GST_DEBUG (GST_CAT_EVENT, "deep notification from %s to %s (%s)", GST_OBJECT_NAME (object), - GST_OBJECT_NAME (gst_object), pspecs[i]->name); - g_signal_emit (gst_object, gst_element_signals[DEEP_NOTIFY], g_quark_from_string (pspecs[i]->name), - (GstObject *) object, pspecs[i]); - } - - gst_object = GST_OBJECT_PARENT (gst_object); - } -} - -/** - * gst_element_default_deep_notify: - * @object: the #GObject that signalled the notify. - * @orig: a #GstObject that initiated the notify. - * @pspec: a #GParamSpec of the property. - * @excluded_props: a set of user-specified properties to exclude. - * - * Adds a default deep_notify signal callback to an - * element. The user data should contain a pointer to an array of - * strings that should be excluded from the notify. - * The default handler will print the new value of the property - * using g_print. - */ -void -gst_element_default_deep_notify (GObject *object, GstObject *orig, - GParamSpec *pspec, gchar **excluded_props) -{ - GValue value = { 0, }; /* the important thing is that value.type = 0 */ - gchar *str = 0; - - if (pspec->flags & G_PARAM_READABLE) { - /* let's not print these out for excluded properties... */ - while (excluded_props != NULL && *excluded_props != NULL) { - if (strcmp (pspec->name, *excluded_props) == 0) - return; - excluded_props++; - } - g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_object_get_property (G_OBJECT (orig), pspec->name, &value); - - if (G_IS_PARAM_SPEC_ENUM (pspec)) { - GEnumValue *enum_value; - enum_value = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (pspec->value_type)), - g_value_get_enum (&value)); - - str = g_strdup_printf ("%s (%d)", enum_value->value_nick, - enum_value->value); - } - else { - str = g_strdup_value_contents (&value); - } - g_print ("%s: %s = %s\n", GST_OBJECT_NAME (orig), pspec->name, str); - g_free (str); - g_value_unset (&value); - } else { - g_warning ("Parameter %s not readable in %s.", - pspec->name, GST_OBJECT_NAME (orig)); - } -} - /** * gst_element_default_error: * @object: a #GObject that signalled the error. @@ -1085,11 +991,10 @@ gst_element_get_pad (GstElement *element, const gchar *name) g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); g_return_val_if_fail (name != NULL, NULL); - if ((pad = gst_element_get_static_pad (element, name))) - return pad; - - pad = gst_element_get_request_pad (element, name); - + pad = gst_element_get_static_pad (element, name); + if (!pad) + pad = gst_element_get_request_pad (element, name); + return pad; } @@ -2201,20 +2106,13 @@ gst_element_change_state (GstElement *element) break; } - /* tell the scheduler if we have one */ - if (element->sched) { - if (gst_scheduler_state_transition (element->sched, element, - old_transition) != GST_STATE_SUCCESS) { - goto failure; - } - } - parent = GST_ELEMENT_PARENT (element); GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "signaling state change from %s to %s", gst_element_state_get_name (old_state), gst_element_state_get_name (GST_STATE (element))); + g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE], 0, old_state, GST_STATE (element)); @@ -2224,11 +2122,20 @@ gst_element_change_state (GstElement *element) GST_STATE (element), element); } + /* signal the state change in case somebody is waiting for us */ g_mutex_lock (element->state_mutex); g_cond_signal (element->state_cond); g_mutex_unlock (element->state_mutex); + /* tell the scheduler if we have one */ + if (element->sched) { + if (gst_scheduler_state_transition (element->sched, element, + old_transition) != GST_STATE_SUCCESS) { + goto failure; + } + } + return GST_STATE_SUCCESS; failure: diff --git a/gst/gstelement.h b/gst/gstelement.h index b74af8bfb1..a8266400d4 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -128,6 +128,7 @@ struct _GstElement { GstElementSetClockFunction setclockfunc; GstElementGetClockFunction getclockfunc; GstClock *clock; + GstClockTime base_time; /* element pads */ guint16 numpads; @@ -160,7 +161,6 @@ struct _GstElementClass { void (*pad_removed) (GstElement *element, GstPad *pad); void (*error) (GstElement *element, GstElement *source, gchar *error); void (*eos) (GstElement *element); - void (*deep_notify) (GstObject *object, GstObject *orig, GParamSpec *pspec); /* local pointers for get/set */ void (*set_property) (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); @@ -182,8 +182,8 @@ void gst_element_class_add_pad_template (GstElementClass *klass, GstPadTemplat void gst_element_class_install_std_props (GstElementClass *klass, const gchar *first_name, ...); -void gst_element_default_deep_notify (GObject *object, GstObject *orig, - GParamSpec *pspec, gchar **excluded_props); +#define gst_element_default_deep_notify gst_object_default_deep_notify + void gst_element_default_error (GObject *object, GstObject *orig, gchar *error); GType gst_element_get_type (void); diff --git a/gst/gstobject.c b/gst/gstobject.c index 2d1d3a5505..e43112e772 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -32,6 +32,7 @@ enum { #ifndef GST_DISABLE_LOADSAVE_REGISTRY OBJECT_SAVED, #endif + DEEP_NOTIFY, LAST_SIGNAL }; @@ -66,6 +67,9 @@ static void gst_object_set_property (GObject * object, guint prop_id, const G GParamSpec * pspec); static void gst_object_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static void gst_object_dispatch_properties_changed (GObject *object, + guint n_pspecs, + GParamSpec **pspecs); static void gst_object_dispose (GObject *object); static void gst_object_finalize (GObject *object); @@ -133,10 +137,20 @@ gst_object_class_init (GstObjectClass *klass) klass->restore_thyself = gst_object_real_restore_thyself; #endif + gst_object_signals[DEEP_NOTIFY] = + g_signal_new ("deep_notify", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS, + G_STRUCT_OFFSET (GstObjectClass, deep_notify), NULL, NULL, + gst_marshal_VOID__OBJECT_PARAM, G_TYPE_NONE, + 2, G_TYPE_OBJECT, G_TYPE_PARAM); klass->path_string_separator = "/"; klass->signal_object = g_object_new (gst_signal_object_get_type (), NULL); + /* see the comments at gst_element_dispatch_properties_changed */ + + gobject_class->dispatch_properties_changed + = GST_DEBUG_FUNCPTR (gst_object_dispatch_properties_changed); gobject_class->dispose = gst_object_dispose; gobject_class->finalize = gst_object_finalize; @@ -265,6 +279,87 @@ gst_object_finalize (GObject *object) parent_class->finalize (object); } +/* Changing a GObject property of an element will result in "deep_notify" + * signals being emitted by the element itself, as well as in each parent + * element. This is so that an application can connect a listener to the + * top-level bin to catch property-change notifications for all contained + * elements. */ +static void +gst_object_dispatch_properties_changed (GObject *object, + guint n_pspecs, + GParamSpec **pspecs) +{ + GstObject *gst_object; + guint i; + + /* do the standard dispatching */ + G_OBJECT_CLASS (parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs); + + /* now let the parent dispatch those, too */ + gst_object = GST_OBJECT_PARENT (object); + while (gst_object) { + /* need own category? */ + for (i = 0; i < n_pspecs; i++) { + GST_DEBUG (GST_CAT_EVENT, "deep notification from %s to %s (%s)", GST_OBJECT_NAME (object), + GST_OBJECT_NAME (gst_object), pspecs[i]->name); + g_signal_emit (gst_object, gst_object_signals[DEEP_NOTIFY], g_quark_from_string (pspecs[i]->name), + (GstObject *) object, pspecs[i]); + } + + gst_object = GST_OBJECT_PARENT (gst_object); + } +} + +/** + * gst_object_default_deep_notify: + * @object: the #GObject that signalled the notify. + * @orig: a #GstObject that initiated the notify. + * @pspec: a #GParamSpec of the property. + * @excluded_props: a set of user-specified properties to exclude. + * + * Adds a default deep_notify signal callback to an + * element. The user data should contain a pointer to an array of + * strings that should be excluded from the notify. + * The default handler will print the new value of the property + * using g_print. + */ +void +gst_object_default_deep_notify (GObject *object, GstObject *orig, + GParamSpec *pspec, gchar **excluded_props) +{ + GValue value = { 0, }; /* the important thing is that value.type = 0 */ + gchar *str = 0; + + if (pspec->flags & G_PARAM_READABLE) { + /* let's not print these out for excluded properties... */ + while (excluded_props != NULL && *excluded_props != NULL) { + if (strcmp (pspec->name, *excluded_props) == 0) + return; + excluded_props++; + } + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + g_object_get_property (G_OBJECT (orig), pspec->name, &value); + + if (G_IS_PARAM_SPEC_ENUM (pspec)) { + GEnumValue *enum_value; + enum_value = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (pspec->value_type)), + g_value_get_enum (&value)); + + str = g_strdup_printf ("%s (%d)", enum_value->value_nick, + enum_value->value); + } + else { + str = g_strdup_value_contents (&value); + } + g_print ("%s: %s = %s\n", GST_OBJECT_NAME (orig), pspec->name, str); + g_free (str); + g_value_unset (&value); + } else { + g_warning ("Parameter %s not readable in %s.", + pspec->name, GST_OBJECT_NAME (orig)); + } +} + static void gst_object_set_name_default (GstObject *object) { diff --git a/gst/gstobject.h b/gst/gstobject.h index d372de5894..711bdb92d7 100644 --- a/gst/gstobject.h +++ b/gst/gstobject.h @@ -92,6 +92,7 @@ struct _GstObjectClass { #ifndef GST_DISABLE_LOADSAVE_REGISTRY void (*object_saved) (GstObject *object, xmlNodePtr parent); #endif + void (*deep_notify) (GstObject *object, GstObject *orig, GParamSpec *pspec); /* functions go here */ void (*destroy) (GstObject *object); @@ -132,6 +133,9 @@ void gst_object_set_parent (GstObject *object, GstObject *parent); GstObject* gst_object_get_parent (GstObject *object); void gst_object_unparent (GstObject *object); +void gst_object_default_deep_notify (GObject *object, GstObject *orig, + GParamSpec *pspec, gchar **excluded_props); + gboolean gst_object_check_uniqueness (GList *list, const gchar *name); #ifndef GST_DISABLE_LOADSAVE_REGISTRY