diff --git a/gst/gstcontrolbinding.c b/gst/gstcontrolbinding.c index 11bd65d620..e758ad1fb0 100644 --- a/gst/gstcontrolbinding.c +++ b/gst/gstcontrolbinding.c @@ -71,6 +71,11 @@ static void gst_control_binding_finalize (GObject * object); G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstControlBinding, gst_control_binding, GST_TYPE_OBJECT, _do_init); +struct _GstControlBindingPrivate +{ + GWeakRef object; +}; + enum { PROP_0, @@ -86,6 +91,8 @@ gst_control_binding_class_init (GstControlBindingClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + g_type_class_add_private (klass, sizeof (GstControlBindingPrivate)); + gobject_class->constructor = gst_control_binding_constructor; gobject_class->set_property = gst_control_binding_set_property; gobject_class->get_property = gst_control_binding_get_property; @@ -108,6 +115,10 @@ gst_control_binding_class_init (GstControlBindingClass * klass) static void gst_control_binding_init (GstControlBinding * binding) { + binding->ABI.abi.priv = + G_TYPE_INSTANCE_GET_PRIVATE (binding, GST_TYPE_CONTROL_BINDING, + GstControlBindingPrivate); + g_weak_ref_init (&binding->ABI.abi.priv->object, NULL); } static GObject * @@ -116,19 +127,26 @@ gst_control_binding_constructor (GType type, guint n_construct_params, { GstControlBinding *binding; GParamSpec *pspec; + GstObject *object; binding = GST_CONTROL_BINDING (G_OBJECT_CLASS (gst_control_binding_parent_class) ->constructor (type, n_construct_params, construct_params)); - GST_INFO_OBJECT (binding->object, "trying to put property '%s' under control", + object = g_weak_ref_get (&binding->ABI.abi.priv->object); + if (!object) { + GST_WARNING_OBJECT (object, "no object set"); + return (GObject *) binding; + } + + GST_INFO_OBJECT (object, "trying to put property '%s' under control", binding->name); /* check if the object has a property of that name */ if ((pspec = - g_object_class_find_property (G_OBJECT_GET_CLASS (binding->object), + g_object_class_find_property (G_OBJECT_GET_CLASS (object), binding->name))) { - GST_DEBUG_OBJECT (binding->object, " psec->flags : 0x%08x", pspec->flags); + GST_DEBUG_OBJECT (object, " psec->flags : 0x%08x", pspec->flags); /* check if this param is witable && controlable && !construct-only */ if ((pspec->flags & (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE | @@ -136,15 +154,18 @@ gst_control_binding_constructor (GType type, guint n_construct_params, (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE)) { binding->pspec = pspec; } else { - GST_WARNING_OBJECT (binding->object, + GST_WARNING_OBJECT (object, "property '%s' on class '%s' needs to " "be writeable, controlable and not construct_only", binding->name, - G_OBJECT_TYPE_NAME (binding->object)); + G_OBJECT_TYPE_NAME (object)); } } else { - GST_WARNING_OBJECT (binding->object, "class '%s' has no property '%s'", - G_OBJECT_TYPE_NAME (binding->object), binding->name); + GST_WARNING_OBJECT (object, "class '%s' has no property '%s'", + G_OBJECT_TYPE_NAME (object), binding->name); } + + gst_object_unref (object); + return (GObject *) binding; } @@ -154,9 +175,10 @@ gst_control_binding_dispose (GObject * object) GstControlBinding *self = GST_CONTROL_BINDING (object); /* we did not took a reference */ - g_object_remove_weak_pointer ((GObject *) self->object, - (gpointer *) & self->object); - self->object = NULL; + g_object_remove_weak_pointer ((GObject *) self->__object, + (gpointer *) & self->__object); + self->__object = NULL; + g_weak_ref_clear (&self->ABI.abi.priv->object); ((GObjectClass *) gst_control_binding_parent_class)->dispose (object); } @@ -180,9 +202,11 @@ gst_control_binding_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_OBJECT: /* do not ref to avoid a ref cycle */ - self->object = g_value_get_object (value); - g_object_add_weak_pointer ((GObject *) self->object, - (gpointer *) & self->object); + self->__object = g_value_get_object (value); + g_object_add_weak_pointer ((GObject *) self->__object, + (gpointer *) & self->__object); + + g_weak_ref_set (&self->ABI.abi.priv->object, self->__object); break; case PROP_NAME: self->name = g_value_dup_string (value); @@ -201,7 +225,7 @@ gst_control_binding_get_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_OBJECT: - g_value_set_object (value, self->object); + g_value_take_object (value, g_weak_ref_get (&self->ABI.abi.priv->object)); break; case PROP_NAME: g_value_set_string (value, self->name); diff --git a/gst/gstcontrolbinding.h b/gst/gstcontrolbinding.h index 2f11f2eb55..9a73d4132b 100644 --- a/gst/gstcontrolbinding.h +++ b/gst/gstcontrolbinding.h @@ -46,6 +46,7 @@ G_BEGIN_DECLS typedef struct _GstControlBinding GstControlBinding; typedef struct _GstControlBindingClass GstControlBindingClass; +typedef struct _GstControlBindingPrivate GstControlBindingPrivate; /* FIXME(2.0): remove, this is unused */ typedef void (* GstControlBindingConvert) (GstControlBinding *binding, gdouble src_value, GValue *dest_value); @@ -59,17 +60,26 @@ typedef void (* GstControlBindingConvert) (GstControlBinding *binding, gdouble s */ struct _GstControlBinding { GstObject parent; - + /*< public >*/ gchar *name; GParamSpec *pspec; /*< private >*/ +#ifndef GST_DISABLE_DEPRECATED GstObject *object; /* GstObject owning the property * (== parent when bound) */ +#else + gpointer __object; +#endif gboolean disabled; - gpointer _gst_reserved[GST_PADDING]; + union { + struct { + GstControlBindingPrivate *priv; + } abi; + gpointer _gst_reserved[GST_PADDING]; + } ABI; }; /**