static void gst_ghost_pad_init (GstGhostPad * pad) { GST_GHOST_PAD_PRIVATE (pad) = gst_ghost_pad_get_instance_private (pad); gst_pad_set_activatemode_function (GST_PAD_CAST (pad), gst_ghost_pad_activate_mode_default); }
static void gst_ghost_pad_init (GstGhostPad * pad) { GST_GHOST_PAD_PRIVATE (pad) = G_TYPE_INSTANCE_GET_PRIVATE (pad, GST_TYPE_GHOST_PAD, GstGhostPadPrivate); gst_pad_set_activatemode_function (GST_PAD_CAST (pad), gst_ghost_pad_activate_mode_default); }
static void gst_ghost_pad_init (GstGhostPad * pad) { GST_GHOST_PAD_PRIVATE (pad) = G_TYPE_INSTANCE_GET_PRIVATE (pad, GST_TYPE_GHOST_PAD, GstGhostPadPrivate); gst_pad_set_setcaps_function (GST_PAD_CAST (pad), GST_DEBUG_FUNCPTR (gst_ghost_pad_do_setcaps)); gst_pad_set_activatepull_function (GST_PAD_CAST (pad), GST_DEBUG_FUNCPTR (gst_ghost_pad_do_activate_pull)); gst_pad_set_activatepush_function (GST_PAD_CAST (pad), GST_DEBUG_FUNCPTR (gst_ghost_pad_do_activate_push)); }
static void gst_ghost_pad_dispose (GObject * object) { GstPad *pad; GstPad *internal; GstPad *peer; pad = GST_PAD (object); GST_DEBUG_OBJECT (pad, "dispose"); gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL); /* Unlink here so that gst_pad_dispose doesn't. That would lead to a call to * gst_ghost_pad_do_unlink when the ghost pad is in an inconsistent state */ peer = gst_pad_get_peer (pad); if (peer) { if (GST_PAD_IS_SRC (pad)) gst_pad_unlink (pad, peer); else gst_pad_unlink (peer, pad); gst_object_unref (peer); } GST_PROXY_LOCK (pad); internal = GST_PROXY_PAD_INTERNAL (pad); gst_pad_set_activatepull_function (internal, NULL); gst_pad_set_activatepush_function (internal, NULL); g_signal_handler_disconnect (internal, GST_GHOST_PAD_PRIVATE (pad)->notify_id); /* disposes of the internal pad, since the ghostpad is the only possible object * that has a refcount on the internal pad. */ gst_object_unparent (GST_OBJECT_CAST (internal)); GST_PROXY_PAD_INTERNAL (pad) = NULL; GST_PROXY_UNLOCK (pad); G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object); }
/** * 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) { GstPadDirection dir, otherdir; GstPadTemplate *templ; GstPad *pad, *internal; g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE); g_return_val_if_fail (GST_GHOST_PAD_PRIVATE (gpad)->constructed == FALSE, FALSE); 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_chain_function (pad, gst_proxy_pad_chain_default); gst_pad_set_chain_list_function (pad, gst_proxy_pad_chain_list_default); } else { gst_pad_set_getrange_function (pad, gst_proxy_pad_getrange_default); } /* INTERNAL PAD, it always exists and is child of the ghostpad */ otherdir = (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC; if (templ) { internal = g_object_new (GST_TYPE_PROXY_PAD, "name", NULL, "direction", otherdir, "template", templ, NULL); /* release ref obtained via g_object_get */ gst_object_unref (templ); } else { internal = g_object_new (GST_TYPE_PROXY_PAD, "name", NULL, "direction", otherdir, NULL); } GST_PAD_UNSET_FLUSHING (internal); /* Set directional padfunctions for internal pad */ if (dir == GST_PAD_SRC) { gst_pad_set_chain_function (internal, gst_proxy_pad_chain_default); gst_pad_set_chain_list_function (internal, gst_proxy_pad_chain_list_default); } else { gst_pad_set_getrange_function (internal, gst_proxy_pad_getrange_default); } GST_OBJECT_LOCK (pad); /* now make the ghostpad a parent of the internal pad */ if (!gst_object_set_parent (GST_OBJECT_CAST (internal), GST_OBJECT_CAST (pad))) goto parent_failed; /* The ghostpad is the parent of the internal pad and is the only object that * can have a refcount on the internal pad. * At this point, the GstGhostPad has a refcount of 1, and the internal pad has * a refcount of 1. * When the refcount of the GstGhostPad drops to 0, the ghostpad will dispose * its 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 (pad) = internal; GST_PROXY_PAD_INTERNAL (internal) = pad; /* special activation functions for the internal pad */ gst_pad_set_activatemode_function (internal, gst_ghost_pad_internal_activate_mode_default); GST_OBJECT_UNLOCK (pad); GST_GHOST_PAD_PRIVATE (gpad)->constructed = TRUE; return TRUE; /* ERRORS */ parent_failed: { 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_OBJECT_UNLOCK (pad); gst_object_unref (internal); return FALSE; } }
/** * 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. * * Since: 0.10.22 */ gboolean gst_ghost_pad_construct (GstGhostPad * gpad) { GstPadDirection dir, otherdir; GstPadTemplate *templ; GstPad *pad, *internal; g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE); g_return_val_if_fail (GST_GHOST_PAD_PRIVATE (gpad)->constructed == FALSE, FALSE); 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 (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_bufferalloc)); gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_chain)); } else { gst_pad_set_getrange_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_getrange)); gst_pad_set_checkgetrange_function (pad, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_checkgetrange)); } /* link/unlink functions */ 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)); /* INTERNAL PAD, it always exists and is child of the ghostpad */ otherdir = (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC; if (templ) { internal = g_object_new (GST_TYPE_PROXY_PAD, "name", NULL, "direction", otherdir, "template", templ, NULL); /* release ref obtained via g_object_get */ gst_object_unref (templ); } else { internal = g_object_new (GST_TYPE_PROXY_PAD, "name", NULL, "direction", otherdir, NULL); } GST_PAD_UNSET_FLUSHING (internal); /* Set directional padfunctions for internal pad */ if (dir == GST_PAD_SRC) { gst_pad_set_bufferalloc_function (internal, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_bufferalloc)); gst_pad_set_chain_function (internal, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_chain)); } else { gst_pad_set_getrange_function (internal, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_getrange)); gst_pad_set_checkgetrange_function (internal, GST_DEBUG_FUNCPTR (gst_proxy_pad_do_checkgetrange)); } 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 (pad))) goto parent_failed; /* The ghostpad is the parent of the internal pad and is the only object that * can have a refcount on the internal pad. * At this point, the GstGhostPad has a refcount of 1, and the internal pad has * a refcount of 1. * When the refcount of the GstGhostPad drops to 0, the ghostpad will dispose * 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 (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_PRIVATE (pad)->notify_id = g_signal_connect (internal, "notify::caps", G_CALLBACK (on_int_notify), pad); /* call function to init values of the pad caps */ on_int_notify (internal, NULL, GST_GHOST_PAD_CAST (pad)); /* special activation functions for the internal pad */ gst_pad_set_activatepull_function (internal, GST_DEBUG_FUNCPTR (gst_ghost_pad_internal_do_activate_pull)); gst_pad_set_activatepush_function (internal, GST_DEBUG_FUNCPTR (gst_ghost_pad_internal_do_activate_push)); GST_PROXY_UNLOCK (pad); GST_GHOST_PAD_PRIVATE (gpad)->constructed = TRUE; return TRUE; /* ERRORS */ parent_failed: { 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 (pad); gst_object_unref (internal); return FALSE; } }