docs/design/part-gstghostpad.txt: Add a note about activation of proxy pads outside of ghost pads.

Original commit message from CVS:
2005-10-03  Andy Wingo  <wingo@pobox.com>

* docs/design/part-gstghostpad.txt: Add a note about activation of
proxy pads outside of ghost pads.

* gst/gstghostpad.c: Implement the ghost pad activation design.
This commit is contained in:
Andy Wingo 2005-10-02 23:20:26 +00:00
parent 381006822b
commit 9d28c696bd
2 changed files with 109 additions and 81 deletions

View file

@ -400,3 +400,7 @@ Ghost sink pads (e.g. B):
pull: pull:
called by: internal pad called by: internal pad
behavior: proxy to peer behavior: proxy to peer
It doesn't really make sense to have activation functions on proxy pads
that aren't part of a ghost pad arrangement.

View file

@ -180,62 +180,6 @@ gst_proxy_pad_do_bufferalloc (GstPad * pad, guint64 offset, guint size,
return result; return result;
} }
static gboolean
gst_proxy_pad_do_activate (GstPad * pad)
{
gboolean res;
res = gst_pad_activate_push (pad, TRUE);
return res;
}
static gboolean
gst_proxy_pad_do_activatepull (GstPad * pad, gboolean active)
{
GstActivateMode old;
GstPad *target = gst_proxy_pad_get_target (pad);
gboolean res;
g_return_val_if_fail (target != NULL, FALSE);
GST_LOCK (target);
old = GST_PAD_ACTIVATE_MODE (target);
GST_UNLOCK (target);
if ((active && old == GST_ACTIVATE_PULL)
|| (!active && old == GST_ACTIVATE_NONE))
res = TRUE;
else
res = gst_pad_activate_pull (target, active);
gst_object_unref (target);
return res;
}
static gboolean
gst_proxy_pad_do_activatepush (GstPad * pad, gboolean active)
{
GstActivateMode old;
GstPad *target = gst_proxy_pad_get_target (pad);
gboolean res;
g_return_val_if_fail (target != NULL, FALSE);
GST_LOCK (target);
old = GST_PAD_ACTIVATE_MODE (target);
GST_UNLOCK (target);
if ((active && old == GST_ACTIVATE_PUSH)
|| (!active && old == GST_ACTIVATE_NONE))
res = TRUE;
else
res = gst_pad_activate_push (target, active);
gst_object_unref (target);
return res;
}
static GstFlowReturn static GstFlowReturn
gst_proxy_pad_do_chain (GstPad * pad, GstBuffer * buffer) gst_proxy_pad_do_chain (GstPad * pad, GstBuffer * buffer)
{ {
@ -367,9 +311,6 @@ gst_proxy_pad_set_target_unlocked (GstPad * pad, GstPad * target)
SETFUNC (eventfunc, event); SETFUNC (eventfunc, event);
SETFUNC (queryfunc, query); SETFUNC (queryfunc, query);
SETFUNC (intlinkfunc, internal_link); SETFUNC (intlinkfunc, internal_link);
SETFUNC (activatefunc, activate);
SETFUNC (activatepullfunc, activatepull);
SETFUNC (activatepushfunc, activatepush);
SETFUNC (getcapsfunc, getcaps); SETFUNC (getcapsfunc, getcaps);
SETFUNC (acceptcapsfunc, acceptcaps); SETFUNC (acceptcapsfunc, acceptcaps);
SETFUNC (fixatecapsfunc, fixatecaps); SETFUNC (fixatecapsfunc, fixatecaps);
@ -515,6 +456,19 @@ gst_critical (const gchar * format, ...)
va_end (args); va_end (args);
} }
static GstPad *
gst_ghost_pad_get_internal (GstPad * pad)
{
GstPad *internal;
GST_PROXY_LOCK (pad);
internal = GST_GHOST_PAD (pad)->internal;
gst_object_ref (internal);
GST_PROXY_UNLOCK (pad);
return internal;
}
static void static void
gst_ghost_pad_class_init (GstGhostPadClass * klass) gst_ghost_pad_class_init (GstGhostPadClass * klass)
{ {
@ -523,20 +477,56 @@ gst_ghost_pad_class_init (GstGhostPadClass * klass)
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose); gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose);
} }
/* will only be called for src pads (afaict) */ /* see gstghostpad design docs */
static gboolean static gboolean
gst_ghost_proxy_pad_do_activate_pull (GstPad * pad, gboolean active) gst_ghost_pad_internal_do_activate_push (GstPad * pad, gboolean active)
{ {
GstObject *parent; gboolean ret;
gboolean ret = FALSE;
parent = gst_object_get_parent (GST_OBJECT (pad)); if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
if (parent) { g_critical ("how did I get here?");
/* hacky hacky!!! */
if (GST_IS_GHOST_PAD (parent))
ret = gst_pad_activate_pull (GST_PAD (parent), active);
gst_object_unref (parent); ret = FALSE;
} else {
GstPad *peer = gst_pad_get_peer (pad);
if (peer) {
ret = gst_pad_activate_push (peer, active);
gst_object_unref (peer);
} else {
ret = FALSE;
}
}
return ret;
}
static gboolean
gst_ghost_pad_internal_do_activate_pull (GstPad * pad, gboolean active)
{
gboolean ret;
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
GstPad *peer = gst_pad_get_peer (pad);
if (peer) {
ret = gst_pad_activate_pull (peer, active);
gst_object_unref (peer);
} else {
ret = FALSE;
}
} else {
GstPad *parent = GST_PAD (gst_object_get_parent (GST_OBJECT (pad)));
if (parent) {
g_return_val_if_fail (GST_IS_GHOST_PAD (parent), FALSE);
ret = gst_pad_activate_pull (parent, active);
gst_object_unref (parent);
} else {
ret = FALSE;
}
} }
return ret; return ret;
@ -545,19 +535,47 @@ gst_ghost_proxy_pad_do_activate_pull (GstPad * pad, gboolean active)
static gboolean static gboolean
gst_ghost_pad_do_activate_push (GstPad * pad, gboolean active) gst_ghost_pad_do_activate_push (GstPad * pad, gboolean active)
{ {
GstPad *internal;
gboolean ret; gboolean ret;
ret = gst_proxy_pad_do_activatepush (pad, active); if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
GstPad *internal = gst_ghost_pad_get_internal (pad);
GST_PROXY_LOCK (pad); if (internal) {
if ((internal = GST_GHOST_PAD (pad)->internal)) ret = gst_pad_activate_push (internal, active);
gst_object_ref (internal); gst_object_unref (internal);
GST_PROXY_UNLOCK (pad); } else {
ret = FALSE;
}
} else {
ret = TRUE;
}
if (internal) { return ret;
ret &= gst_pad_activate_push (internal, active); }
gst_object_unref (internal);
static gboolean
gst_ghost_pad_do_activate_pull (GstPad * pad, gboolean active)
{
gboolean ret;
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
GstPad *peer = gst_pad_get_peer (pad);
if (peer) {
ret = gst_pad_activate_pull (peer, active);
gst_object_unref (peer);
} else {
ret = FALSE;
}
} else {
GstPad *internal = gst_ghost_pad_get_internal (pad);
if (internal) {
ret = gst_pad_activate_pull (internal, active);
gst_object_unref (internal);
} else {
ret = FALSE;
}
} }
return ret; return ret;
@ -639,6 +657,7 @@ gst_ghost_pad_set_internal (GstGhostPad * pad, GstPad * internal)
GstPad *intpeer; GstPad *intpeer;
gst_pad_set_activatepull_function (pad->internal, NULL); gst_pad_set_activatepull_function (pad->internal, NULL);
gst_pad_set_activatepush_function (pad->internal, NULL);
g_signal_handler_disconnect (pad->internal, pad->notify_id); g_signal_handler_disconnect (pad->internal, pad->notify_id);
@ -665,8 +684,10 @@ gst_ghost_pad_set_internal (GstGhostPad * pad, GstPad * internal)
pad->notify_id = g_signal_connect (internal, "notify::caps", pad->notify_id = g_signal_connect (internal, "notify::caps",
G_CALLBACK (on_int_notify), pad); G_CALLBACK (on_int_notify), pad);
on_int_notify (internal, NULL, pad); on_int_notify (internal, NULL, pad);
gst_pad_set_activatepull_function (internal, gst_pad_set_activatepull_function (GST_PAD (internal),
gst_ghost_proxy_pad_do_activate_pull); gst_ghost_pad_internal_do_activate_pull);
gst_pad_set_activatepush_function (GST_PAD (internal),
gst_ghost_pad_internal_do_activate_push);
/* a ref was taken by set_parent */ /* a ref was taken by set_parent */
} }
pad->internal = internal; pad->internal = internal;
@ -687,7 +708,10 @@ could_not_set:
static void static void
gst_ghost_pad_init (GstGhostPad * pad) gst_ghost_pad_init (GstGhostPad * pad)
{ {
/* noop */ gst_pad_set_activatepull_function (GST_PAD (pad),
gst_ghost_pad_do_activate_pull);
gst_pad_set_activatepush_function (GST_PAD (pad),
gst_ghost_pad_do_activate_push);
} }
static void static void