mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
Moved deep notify to GstObject
Original commit message from CVS: Moved deep notify to GstObject
This commit is contained in:
parent
4992cb5838
commit
6637a949e7
4 changed files with 116 additions and 110 deletions
119
gst/gstelement.c
119
gst/gstelement.c
|
@ -41,7 +41,6 @@ enum {
|
||||||
PAD_REMOVED,
|
PAD_REMOVED,
|
||||||
ERROR,
|
ERROR,
|
||||||
EOS,
|
EOS,
|
||||||
DEEP_NOTIFY,
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,7 +59,6 @@ static void gst_element_real_set_property (GObject *object, guint prop_id,
|
||||||
const GValue *value, GParamSpec *pspec);
|
const GValue *value, GParamSpec *pspec);
|
||||||
static void gst_element_real_get_property (GObject *object, guint prop_id, GValue *value,
|
static void gst_element_real_get_property (GObject *object, guint prop_id, GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
static void gst_element_dispatch_properties_changed (GObject * object, guint n_pspecs, GParamSpec **pspecs);
|
|
||||||
|
|
||||||
static void gst_element_dispose (GObject *object);
|
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_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL,
|
G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL,
|
||||||
gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
|
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->set_property = GST_DEBUG_FUNCPTR (gst_element_real_set_property);
|
||||||
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_element_real_get_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);
|
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
|
||||||
|
|
||||||
#ifndef GST_DISABLE_LOADSAVE
|
#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);
|
(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:
|
* gst_element_default_error:
|
||||||
* @object: a #GObject that signalled the error.
|
* @object: a #GObject that signalled the error.
|
||||||
|
@ -1085,10 +991,9 @@ gst_element_get_pad (GstElement *element, const gchar *name)
|
||||||
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
|
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
|
||||||
g_return_val_if_fail (name != NULL, NULL);
|
g_return_val_if_fail (name != NULL, NULL);
|
||||||
|
|
||||||
if ((pad = gst_element_get_static_pad (element, name)))
|
pad = gst_element_get_static_pad (element, name);
|
||||||
return pad;
|
if (!pad)
|
||||||
|
pad = gst_element_get_request_pad (element, name);
|
||||||
pad = gst_element_get_request_pad (element, name);
|
|
||||||
|
|
||||||
return pad;
|
return pad;
|
||||||
}
|
}
|
||||||
|
@ -2201,20 +2106,13 @@ gst_element_change_state (GstElement *element)
|
||||||
break;
|
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);
|
parent = GST_ELEMENT_PARENT (element);
|
||||||
|
|
||||||
GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
|
GST_DEBUG_ELEMENT (GST_CAT_STATES, element,
|
||||||
"signaling state change from %s to %s",
|
"signaling state change from %s to %s",
|
||||||
gst_element_state_get_name (old_state),
|
gst_element_state_get_name (old_state),
|
||||||
gst_element_state_get_name (GST_STATE (element)));
|
gst_element_state_get_name (GST_STATE (element)));
|
||||||
|
|
||||||
g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
|
g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE],
|
||||||
0, old_state, GST_STATE (element));
|
0, old_state, GST_STATE (element));
|
||||||
|
|
||||||
|
@ -2224,11 +2122,20 @@ gst_element_change_state (GstElement *element)
|
||||||
GST_STATE (element), element);
|
GST_STATE (element), element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* signal the state change in case somebody is waiting for us */
|
/* signal the state change in case somebody is waiting for us */
|
||||||
g_mutex_lock (element->state_mutex);
|
g_mutex_lock (element->state_mutex);
|
||||||
g_cond_signal (element->state_cond);
|
g_cond_signal (element->state_cond);
|
||||||
g_mutex_unlock (element->state_mutex);
|
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;
|
return GST_STATE_SUCCESS;
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
|
|
|
@ -128,6 +128,7 @@ struct _GstElement {
|
||||||
GstElementSetClockFunction setclockfunc;
|
GstElementSetClockFunction setclockfunc;
|
||||||
GstElementGetClockFunction getclockfunc;
|
GstElementGetClockFunction getclockfunc;
|
||||||
GstClock *clock;
|
GstClock *clock;
|
||||||
|
GstClockTime base_time;
|
||||||
|
|
||||||
/* element pads */
|
/* element pads */
|
||||||
guint16 numpads;
|
guint16 numpads;
|
||||||
|
@ -160,7 +161,6 @@ struct _GstElementClass {
|
||||||
void (*pad_removed) (GstElement *element, GstPad *pad);
|
void (*pad_removed) (GstElement *element, GstPad *pad);
|
||||||
void (*error) (GstElement *element, GstElement *source, gchar *error);
|
void (*error) (GstElement *element, GstElement *source, gchar *error);
|
||||||
void (*eos) (GstElement *element);
|
void (*eos) (GstElement *element);
|
||||||
void (*deep_notify) (GstObject *object, GstObject *orig, GParamSpec *pspec);
|
|
||||||
|
|
||||||
/* local pointers for get/set */
|
/* local pointers for get/set */
|
||||||
void (*set_property) (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
|
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,
|
void gst_element_class_install_std_props (GstElementClass *klass,
|
||||||
const gchar *first_name, ...);
|
const gchar *first_name, ...);
|
||||||
|
|
||||||
void gst_element_default_deep_notify (GObject *object, GstObject *orig,
|
#define gst_element_default_deep_notify gst_object_default_deep_notify
|
||||||
GParamSpec *pspec, gchar **excluded_props);
|
|
||||||
void gst_element_default_error (GObject *object, GstObject *orig, gchar *error);
|
void gst_element_default_error (GObject *object, GstObject *orig, gchar *error);
|
||||||
|
|
||||||
GType gst_element_get_type (void);
|
GType gst_element_get_type (void);
|
||||||
|
|
|
@ -32,6 +32,7 @@ enum {
|
||||||
#ifndef GST_DISABLE_LOADSAVE_REGISTRY
|
#ifndef GST_DISABLE_LOADSAVE_REGISTRY
|
||||||
OBJECT_SAVED,
|
OBJECT_SAVED,
|
||||||
#endif
|
#endif
|
||||||
|
DEEP_NOTIFY,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,6 +67,9 @@ static void gst_object_set_property (GObject * object, guint prop_id, const G
|
||||||
GParamSpec * pspec);
|
GParamSpec * pspec);
|
||||||
static void gst_object_get_property (GObject * object, guint prop_id, GValue * value,
|
static void gst_object_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
GParamSpec * pspec);
|
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_dispose (GObject *object);
|
||||||
static void gst_object_finalize (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;
|
klass->restore_thyself = gst_object_real_restore_thyself;
|
||||||
#endif
|
#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->path_string_separator = "/";
|
||||||
|
|
||||||
klass->signal_object = g_object_new (gst_signal_object_get_type (), NULL);
|
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->dispose = gst_object_dispose;
|
||||||
gobject_class->finalize = gst_object_finalize;
|
gobject_class->finalize = gst_object_finalize;
|
||||||
|
@ -265,6 +279,87 @@ gst_object_finalize (GObject *object)
|
||||||
parent_class->finalize (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
|
static void
|
||||||
gst_object_set_name_default (GstObject *object)
|
gst_object_set_name_default (GstObject *object)
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,6 +92,7 @@ struct _GstObjectClass {
|
||||||
#ifndef GST_DISABLE_LOADSAVE_REGISTRY
|
#ifndef GST_DISABLE_LOADSAVE_REGISTRY
|
||||||
void (*object_saved) (GstObject *object, xmlNodePtr parent);
|
void (*object_saved) (GstObject *object, xmlNodePtr parent);
|
||||||
#endif
|
#endif
|
||||||
|
void (*deep_notify) (GstObject *object, GstObject *orig, GParamSpec *pspec);
|
||||||
|
|
||||||
/* functions go here */
|
/* functions go here */
|
||||||
void (*destroy) (GstObject *object);
|
void (*destroy) (GstObject *object);
|
||||||
|
@ -132,6 +133,9 @@ void gst_object_set_parent (GstObject *object, GstObject *parent);
|
||||||
GstObject* gst_object_get_parent (GstObject *object);
|
GstObject* gst_object_get_parent (GstObject *object);
|
||||||
void gst_object_unparent (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);
|
gboolean gst_object_check_uniqueness (GList *list, const gchar *name);
|
||||||
|
|
||||||
#ifndef GST_DISABLE_LOADSAVE_REGISTRY
|
#ifndef GST_DISABLE_LOADSAVE_REGISTRY
|
||||||
|
|
Loading…
Reference in a new issue