From f7ae133fec0842cc721555baa2f7e24b5b49bdb3 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 6 Oct 2008 17:57:25 +0000 Subject: [PATCH] gst/gstghostpad.*: New function, finishes the initialization of ghost pad. Useful for language bindings and subclasse... Original commit message from CVS: 2008-10-06 Andy Wingo * gst/gstghostpad.h: * gst/gstghostpad.c (gst_ghost_pad_construct): New function, finishes the initialization of ghost pad. Useful for language bindings and subclassers of GstGhostPad. Fixes #539108. (gst_ghost_pad_new_full): Use the new constructor. --- ChangeLog | 8 ++++ gst/gstghostpad.c | 110 +++++++++++++++++++++++++++++++++++++----------------- gst/gstghostpad.h | 2 + 3 files changed, 85 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index b4b58d7..3e9d128 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-10-06 Andy Wingo + + * gst/gstghostpad.h: + * gst/gstghostpad.c (gst_ghost_pad_construct): New function, + finishes the initialization of ghost pad. Useful for language + bindings and subclassers of GstGhostPad. Fixes #539108. + (gst_ghost_pad_new_full): Use the new constructor. + 2008-10-06 Wim Taymans Base on Patch by: Olivier Crete diff --git a/gst/gstghostpad.c b/gst/gstghostpad.c index e727cec..48bf263 100644 --- a/gst/gstghostpad.c +++ b/gst/gstghostpad.c @@ -509,8 +509,10 @@ struct _GstGhostPad /* with PROXY_LOCK */ gulong notify_id; + gpointer constructed; + /*< private > */ - gpointer _gst_reserved[GST_PADDING]; + gpointer _gst_reserved[GST_PADDING - 1]; }; struct _GstGhostPadClass @@ -758,41 +760,51 @@ gst_ghost_pad_dispose (GObject * object) G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object); } -static GstPad * -gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir, - GstPadTemplate * templ) +/** + * gst_ghost_pad_construct: + * @gpad: the newly allocated ghost pad + * + * Finish initialization of a newly allocated ghost pad. + * + * This function is most useful in language bindings and when subclassing + * #GstGhostPad; plugin and application developers normally will not call this + * function. Call this function directly after a call to g_object_new + * (GST_TYPE_GHOST_PAD, "direction", @dir, ..., NULL). + * + * Returns: %TRUE if the construction succeeds, %FALSE otherwise. + */ +gboolean +gst_ghost_pad_construct (GstGhostPad * gpad) { - GstPad *ret; - GstPad *internal; - GstPadDirection otherdir; + GstPadDirection dir, otherdir; + GstPadTemplate *templ; + GstPad *pad, *internal; - g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL); + g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE); + g_return_val_if_fail (!gpad->constructed, FALSE); - /* OBJECT CREATION */ - if (templ) { - ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name, - "direction", dir, "template", templ, NULL); - } else { - ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name, - "direction", dir, NULL); - } + g_object_get (gpad, "direction", &dir, "template", &templ, NULL); + + g_return_val_if_fail (dir != GST_PAD_UNKNOWN, FALSE); + + pad = GST_PAD (gpad); /* Set directional padfunctions for ghostpad */ if (dir == GST_PAD_SINK) { - gst_pad_set_bufferalloc_function (ret, + gst_pad_set_bufferalloc_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_bufferalloc)); - gst_pad_set_chain_function (ret, + gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_chain)); } else { - gst_pad_set_getrange_function (ret, + gst_pad_set_getrange_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_getrange)); - gst_pad_set_checkgetrange_function (ret, + gst_pad_set_checkgetrange_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_checkgetrange)); } /* link/unlink functions */ - gst_pad_set_link_function (ret, GST_DEBUG_FUNCPTR (gst_ghost_pad_do_link)); - gst_pad_set_unlink_function (ret, + gst_pad_set_link_function (pad, GST_DEBUG_FUNCPTR (gst_ghost_pad_do_link)); + gst_pad_set_unlink_function (pad, GST_DEBUG_FUNCPTR (gst_ghost_pad_do_unlink)); @@ -822,11 +834,11 @@ gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_checkgetrange)); } - GST_PROXY_LOCK (ret); + GST_PROXY_LOCK (pad); /* now make the ghostpad a parent of the internal pad */ if (!gst_object_set_parent (GST_OBJECT_CAST (internal), - GST_OBJECT_CAST (ret))) + GST_OBJECT_CAST (pad))) goto parent_failed; /* The ghostpad is the parent of the internal pad and is the only object that @@ -837,17 +849,17 @@ gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir, * it's refcount on the internal pad in the dispose method by un-parenting it. * This is why we don't take extra refcounts in the assignments below */ - GST_PROXY_PAD_INTERNAL (ret) = internal; - GST_PROXY_PAD_INTERNAL (internal) = ret; + GST_PROXY_PAD_INTERNAL (pad) = internal; + GST_PROXY_PAD_INTERNAL (internal) = pad; /* could be more general here, iterating over all writable properties... * taking the short road for now tho */ - GST_GHOST_PAD_CAST (ret)->notify_id = + GST_GHOST_PAD_CAST (pad)->notify_id = g_signal_connect (internal, "notify::caps", G_CALLBACK (on_int_notify), - ret); + pad); /* call function to init values of the pad caps */ - on_int_notify (internal, NULL, GST_GHOST_PAD_CAST (ret)); + on_int_notify (internal, NULL, GST_GHOST_PAD_CAST (pad)); /* special activation functions for the internal pad */ gst_pad_set_activatepull_function (internal, @@ -855,22 +867,50 @@ gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir, gst_pad_set_activatepush_function (internal, GST_DEBUG_FUNCPTR (gst_ghost_pad_internal_do_activate_push)); - GST_PROXY_UNLOCK (ret); + GST_PROXY_UNLOCK (pad); - return ret; + gpad->constructed = (gpointer) 1; + return TRUE; /* ERRORS */ parent_failed: { - GST_WARNING_OBJECT (ret, "Could not set internal pad %s:%s", + GST_WARNING_OBJECT (gpad, "Could not set internal pad %s:%s", GST_DEBUG_PAD_NAME (internal)); g_critical ("Could not set internal pad %s:%s", GST_DEBUG_PAD_NAME (internal)); - GST_PROXY_UNLOCK (ret); - gst_object_unref (ret); + GST_PROXY_UNLOCK (pad); gst_object_unref (internal); - return NULL; + return FALSE; + } +} + +static GstPad * +gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir, + GstPadTemplate * templ) +{ + GstGhostPad *ret; + + g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL); + + /* OBJECT CREATION */ + if (templ) { + ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name, + "direction", dir, "template", templ, NULL); + } else { + ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name, + "direction", dir, NULL); } + + if (!gst_ghost_pad_construct (ret)) + goto construct_failed; + + return GST_PAD (ret); + +construct_failed: + /* already logged */ + gst_object_unref (ret); + return NULL; } /** diff --git a/gst/gstghostpad.h b/gst/gstghostpad.h index dd9dd83..53b4fa1 100644 --- a/gst/gstghostpad.h +++ b/gst/gstghostpad.h @@ -57,6 +57,8 @@ GstPad* gst_ghost_pad_new_no_target_from_template (const gchar *name, GstPadTe GstPad* gst_ghost_pad_get_target (GstGhostPad *gpad); gboolean gst_ghost_pad_set_target (GstGhostPad *gpad, GstPad *newtarget); +gboolean gst_ghost_pad_construct (GstGhostPad *gpad); + G_END_DECLS #endif /* __GST_GHOST_PAD_H__ */ -- 2.7.4