First pass at updating to new ghostpad system. The objects are in place,

Original commit message from CVS:
First pass at updating to new ghostpad system.  The objects are in place,
I now need to go and get all the Bin end of things worked out.  Testing
should be fairly easy, at least for verification.

Everything I've tried so far works with no changes, with is amazing.
That's just cool.  Once again we rewrite an entire subsystem, and nothing
else notices anything but the new features ;-)
This commit is contained in:
Erik Walthinsen 2001-01-19 02:23:35 +00:00
parent 52713dac28
commit c31f9a570c
8 changed files with 423 additions and 215 deletions

View file

@ -180,7 +180,7 @@ cothread_stub (void)
thread->pc = 0;
thread->sp = thread->top_sp;
GST_DEBUG_LEAVE("");
fprintf(stderr,"uh, yeah, we shouldn't be here, but we should deal anyway\n");
// fprintf(stderr,"uh, yeah, we shouldn't be here, but we should deal anyway\n");
}
/**

View file

@ -210,8 +210,10 @@ gst_autoplug_pads (GstPad *srcpad, GstPad *sinkpad)
{
caps_struct caps;
caps.src = srcpad->caps;
caps.sink = sinkpad->caps;
// caps.src = srcpad->caps;
// caps.sink = sinkpad->caps;
caps.src = gst_pad_get_caps_list(srcpad);
caps.sink = gst_pad_get_caps_list(sinkpad);
GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");

View file

@ -754,12 +754,12 @@ gst_bin_iterate_func (GstBin *bin)
pads = entry->pads;
while (pads) {
pad = GST_PAD (pads->data);
if (pad->direction == GST_PAD_SRC) {
if (GST_REAL_PAD(pad)->direction == GST_PAD_SRC) {
GST_DEBUG (0,"calling getfunc of %s:%s\n",GST_DEBUG_PAD_NAME(pad));
if (pad->getfunc == NULL)
if (GST_REAL_PAD(pad)->getfunc == NULL)
fprintf(stderr, "error, no getfunc in \"%s\"\n", gst_element_get_name (entry));
else
buf = (pad->getfunc)(pad);
buf = (GST_REAL_PAD(pad)->getfunc)(pad);
gst_pad_push(pad,buf);
}
pads = g_list_next (pads);

View file

@ -43,18 +43,11 @@ enum {
};
/***** Start with the base GstPad class *****/
static void gst_pad_class_init (GstPadClass *klass);
static void gst_pad_init (GstPad *pad);
static void gst_pad_set_arg (GtkObject *object,GtkArg *arg,guint id);
static void gst_pad_get_arg (GtkObject *object,GtkArg *arg,guint id);
static void gst_pad_real_destroy (GtkObject *object);
static void gst_pad_push_func (GstPad *pad, GstBuffer *buf);
static GstObject *pad_parent_class = NULL;
static guint gst_pad_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_pad_get_type(void) {
@ -77,35 +70,88 @@ gst_pad_get_type(void) {
}
static void
gst_pad_class_init (GstPadClass *klass)
gst_pad_class_init (GstPadClass *klass)
{
pad_parent_class = gtk_type_class(GST_TYPE_OBJECT);
}
static void
gst_pad_init (GstPad *pad)
{
pad->name = NULL;
pad->element_private = NULL;
pad->parent = NULL;
pad->padtemplate = NULL;
}
/***** Then do the Real Pad *****/
static void gst_real_pad_class_init (GstRealPadClass *klass);
static void gst_real_pad_init (GstRealPad *pad);
static void gst_real_pad_set_arg (GtkObject *object,GtkArg *arg,guint id);
static void gst_real_pad_get_arg (GtkObject *object,GtkArg *arg,guint id);
static void gst_real_pad_destroy (GtkObject *object);
static void gst_pad_push_func (GstPad *pad, GstBuffer *buf);
static GstPad *real_pad_parent_class = NULL;
static guint gst_real_pad_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_real_pad_get_type(void) {
static GtkType pad_type = 0;
if (!pad_type) {
static const GtkTypeInfo pad_info = {
"GstRealPad",
sizeof(GstRealPad),
sizeof(GstRealPadClass),
(GtkClassInitFunc)gst_real_pad_class_init,
(GtkObjectInitFunc)gst_real_pad_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
pad_type = gtk_type_unique(GST_TYPE_PAD,&pad_info);
}
return pad_type;
}
static void
gst_real_pad_class_init (GstRealPadClass *klass)
{
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
pad_parent_class = gtk_type_class(GST_TYPE_OBJECT);
real_pad_parent_class = gtk_type_class(GST_TYPE_PAD);
gst_pad_signals[SET_ACTIVE] =
gst_real_pad_signals[SET_ACTIVE] =
gtk_signal_new ("set_active", GTK_RUN_LAST, gtkobject_class->type,
GTK_SIGNAL_OFFSET (GstPadClass, set_active),
GTK_SIGNAL_OFFSET (GstRealPadClass, set_active),
gtk_marshal_NONE__BOOL, GTK_TYPE_NONE, 1,
GTK_TYPE_BOOL);
gst_pad_signals[CAPS_CHANGED] =
gst_real_pad_signals[CAPS_CHANGED] =
gtk_signal_new ("caps_changed", GTK_RUN_LAST, gtkobject_class->type,
GTK_SIGNAL_OFFSET (GstPadClass, caps_changed),
GTK_SIGNAL_OFFSET (GstRealPadClass, caps_changed),
gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
GTK_TYPE_POINTER);
gtk_object_class_add_signals (gtkobject_class, gst_real_pad_signals, LAST_SIGNAL);
gtk_object_add_arg_type ("GstPad::active", GTK_TYPE_BOOL,
gtk_object_add_arg_type ("GstRealPad::active", GTK_TYPE_BOOL,
GTK_ARG_READWRITE, ARG_ACTIVE);
gtkobject_class->destroy = gst_pad_real_destroy;
gtkobject_class->set_arg = gst_pad_set_arg;
gtkobject_class->get_arg = gst_pad_get_arg;
gtkobject_class->destroy = gst_real_pad_destroy;
gtkobject_class->set_arg = gst_real_pad_set_arg;
gtkobject_class->get_arg = gst_real_pad_get_arg;
}
static void
gst_pad_init (GstPad *pad)
gst_real_pad_init (GstRealPad *pad)
{
pad->direction = GST_PAD_UNKNOWN;
pad->peer = NULL;
@ -120,15 +166,13 @@ gst_pad_init (GstPad *pad)
pad->pullfunc = NULL;
pad->pullregionfunc = NULL;
pad->parent = NULL;
pad->ghostparents = NULL;
pad->caps = NULL;
pad->padtemplate = NULL;
}
static void
gst_pad_set_arg (GtkObject *object,GtkArg *arg,guint id) {
gst_real_pad_set_arg (GtkObject *object, GtkArg *arg, guint id)
{
g_return_if_fail(GST_IS_PAD(object));
switch (id) {
@ -140,7 +184,7 @@ gst_pad_set_arg (GtkObject *object,GtkArg *arg,guint id) {
gst_info("gstpad: de-activating pad\n");
GST_FLAG_SET(object,GST_PAD_DISABLED);
}
gtk_signal_emit(GTK_OBJECT(object), gst_pad_signals[SET_ACTIVE],
gtk_signal_emit(GTK_OBJECT(object), gst_real_pad_signals[SET_ACTIVE],
! GST_FLAG_IS_SET(object,GST_PAD_DISABLED));
break;
default:
@ -149,9 +193,7 @@ gst_pad_set_arg (GtkObject *object,GtkArg *arg,guint id) {
}
static void
gst_pad_get_arg (GtkObject *object,
GtkArg *arg,
guint id)
gst_real_pad_get_arg (GtkObject *object, GtkArg *arg, guint id)
{
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_PAD (object));
@ -180,13 +222,15 @@ gst_pad_new (gchar *name,
GstPadDirection direction)
{
GstPad *pad;
GstRealPad *realpad;
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
pad = GST_PAD (gtk_type_new (gst_pad_get_type ()));
realpad = gtk_type_new (gst_real_pad_get_type ());
pad = GST_PAD(realpad);
pad->name = g_strdup (name);
pad->direction = direction;
realpad->direction = direction;
return pad;
}
@ -201,17 +245,19 @@ gst_pad_new (gchar *name,
* Returns: new pad
*/
GstPad*
gst_pad_new_from_template (GstPadTemplate *temp,
gst_pad_new_from_template (GstPadTemplate *templ,
gchar *name)
{
GstPad *pad;
GstRealPad *realpad;
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (temp != NULL, NULL);
g_return_val_if_fail (templ != NULL, NULL);
pad = gst_pad_new (name, temp->direction);
pad->caps = temp->caps;
pad->padtemplate = temp;
pad = gst_pad_new (name, templ->direction);
realpad = GST_REAL_PAD (pad);
realpad->caps = templ->caps;
pad->padtemplate = templ;
return pad;
}
@ -228,9 +274,9 @@ GstPadDirection
gst_pad_get_direction (GstPad *pad)
{
g_return_val_if_fail (pad != NULL, GST_PAD_UNKNOWN);
g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_PAD_UNKNOWN);
return pad->direction;
return GST_REAL_PAD(pad)->direction;
}
/**
@ -281,9 +327,9 @@ void gst_pad_set_chain_function (GstPad *pad,
GstPadChainFunction chain)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (GST_IS_REAL_PAD (pad));
pad->chainfunc = chain;
GST_REAL_PAD(pad)->chainfunc = chain;
}
/**
@ -298,13 +344,14 @@ gst_pad_set_get_function (GstPad *pad,
GstPadGetFunction get)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (GST_IS_REAL_PAD (pad));
// the if and such should optimize out when DEBUG is off
GST_DEBUG (0,"setting get function for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
pad->getfunc = get;
GST_DEBUG (0,"getfunc for %s:%s(@%p) at %p is set to %p\n",GST_DEBUG_PAD_NAME(pad),pad,&pad->getfunc,get);
GST_REAL_PAD(pad)->getfunc = get;
GST_DEBUG (0,"getfunc for %s:%s(@%p) at %p is set to %p\n",
GST_DEBUG_PAD_NAME(pad),pad,&GST_REAL_PAD(pad)->getfunc,get);
}
/**
@ -319,11 +366,11 @@ gst_pad_set_getregion_function (GstPad *pad,
GstPadGetRegionFunction getregion)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (GST_IS_REAL_PAD (pad));
GST_DEBUG (0,"gstpad: pad setting getregion function\n");
pad->getregionfunc = getregion;
GST_REAL_PAD(pad)->getregionfunc = getregion;
}
/**
@ -338,9 +385,9 @@ gst_pad_set_qos_function (GstPad *pad,
GstPadQoSFunction qos)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (GST_IS_REAL_PAD (pad));
pad->qosfunc = qos;
GST_REAL_PAD(pad)->qosfunc = qos;
}
/**
@ -355,9 +402,9 @@ gst_pad_set_eos_function (GstPad *pad,
GstPadEOSFunction eos)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (GST_IS_REAL_PAD (pad));
pad->eosfunc = eos;
GST_REAL_PAD(pad)->eosfunc = eos;
}
@ -365,32 +412,15 @@ gst_pad_set_eos_function (GstPad *pad,
static void
gst_pad_push_func(GstPad *pad, GstBuffer *buf)
{
if (pad->peer->chainfunc != NULL) {
GstRealPad *realpad = GST_REAL_PAD(pad);
if (realpad->peer->chainfunc != NULL) {
GST_DEBUG (0,"calling chain function\n");
(pad->peer->chainfunc)(pad,buf);
(realpad->peer->chainfunc)(pad,buf);
} else {
GST_DEBUG (0,"got a problem here: default pad_push handler in place, no chain function\n");
}
}
/**
* gst_pad_chain:
* @pad: the pad to chain
*
* Call the chain function of the given pad.
*/
void
gst_pad_chain (GstPad *pad)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (pad->peer != NULL);
g_return_if_fail (pad->chainfunc != NULL);
if (pad->bufpen && pad->chainfunc)
(pad->chainfunc) (pad,pad->bufpen);
}
/**
* gst_pad_handle_qos:
@ -403,23 +433,23 @@ void
gst_pad_handle_qos(GstPad *pad,
glong qos_message)
{
GstRealPad *realpad = GST_REAL_PAD (pad);
GstElement *element;
GList *pads;
GstPad *target_pad;
GST_DEBUG (0,"gst_pad_handle_qos(\"%s\",%08ld)\n", GST_ELEMENT(pad->parent)->name,qos_message);
if (pad->qosfunc) {
(pad->qosfunc) (pad,qos_message);
}
else {
element = GST_ELEMENT (pad->peer->parent);
if (realpad->qosfunc) {
(realpad->qosfunc) (pad,qos_message);
} else {
element = GST_ELEMENT (GST_PAD(realpad->peer)->parent);
pads = element->pads;
GST_DEBUG (0,"gst_pad_handle_qos recurse(\"%s\",%08ld)\n", element->name,qos_message);
GST_DEBUG (0,"gst_pad_handle_qos recurse(\"%s\",%08ld)\n", element->name, qos_message);
while (pads) {
target_pad = GST_PAD (pads->data);
if (target_pad->direction == GST_PAD_SINK) {
if (GST_REAL_PAD(target_pad)->direction == GST_PAD_SINK) {
gst_pad_handle_qos (target_pad, qos_message);
}
pads = g_list_next (pads);
@ -440,20 +470,29 @@ void
gst_pad_disconnect (GstPad *srcpad,
GstPad *sinkpad)
{
GstRealPad *realsrc, *realsink;
/* generic checks */
g_return_if_fail (srcpad != NULL);
g_return_if_fail (GST_IS_PAD (srcpad));
g_return_if_fail (srcpad->peer != NULL);
g_return_if_fail (sinkpad != NULL);
g_return_if_fail (GST_IS_PAD (sinkpad));
g_return_if_fail (sinkpad->peer != NULL);
g_return_if_fail ((srcpad->direction == GST_PAD_SRC) &&
(sinkpad->direction == GST_PAD_SINK));
// now we need to deal with the real/ghost stuff
if (GST_IS_GHOST_PAD(srcpad)) realsrc = GST_GHOST_PAD(srcpad)->realpad;
else realsrc = GST_REAL_PAD(srcpad);
if (GST_IS_GHOST_PAD(sinkpad)) realsink = GST_GHOST_PAD(sinkpad)->realpad;
else realsink = GST_REAL_PAD(sinkpad);
g_return_if_fail (realsrc->peer != NULL);
g_return_if_fail (realsink->peer != NULL);
g_return_if_fail ((realsrc->direction == GST_PAD_SRC) &&
(realsink->direction == GST_PAD_SINK));
/* first clear peers */
srcpad->peer = NULL;
sinkpad->peer = NULL;
realsrc->peer = NULL;
realsink->peer = NULL;
GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
@ -470,26 +509,34 @@ void
gst_pad_connect (GstPad *srcpad,
GstPad *sinkpad)
{
GstPad *temppad;
GstRealPad *realsrc, *realsink;
GstRealPad *temppad;
/* generic checks */
g_return_if_fail(srcpad != NULL);
g_return_if_fail(GST_IS_PAD(srcpad));
g_return_if_fail(srcpad->peer == NULL);
g_return_if_fail(sinkpad != NULL);
g_return_if_fail(GST_IS_PAD(sinkpad));
g_return_if_fail(sinkpad->peer == NULL);
// g_return_if_fail(sinkpad->chain != NULL);
// now we need to deal with the real/ghost stuff
if (GST_IS_GHOST_PAD(srcpad)) realsrc = GST_GHOST_PAD(srcpad)->realpad;
else realsrc = GST_REAL_PAD(srcpad);
if (GST_IS_GHOST_PAD(sinkpad)) realsink = GST_GHOST_PAD(sinkpad)->realpad;
else realsink = GST_REAL_PAD(sinkpad);
g_return_if_fail(realsrc->peer == NULL);
g_return_if_fail(realsink->peer == NULL);
/* check for reversed directions and swap if necessary */
if ((srcpad->direction == GST_PAD_SINK) &&
(sinkpad->direction == GST_PAD_SRC)) {
temppad = srcpad;
srcpad = sinkpad;
sinkpad = temppad;
if ((realsrc->direction == GST_PAD_SINK) &&
(realsink->direction == GST_PAD_SRC)) {
temppad = realsrc;
realsrc = realsink;
realsink = temppad;
}
g_return_if_fail((srcpad->direction == GST_PAD_SRC) &&
(sinkpad->direction == GST_PAD_SINK));
g_return_if_fail((realsrc->direction == GST_PAD_SRC) &&
(realsink->direction == GST_PAD_SINK));
if (!gst_pad_check_compatibility (srcpad, sinkpad)) {
g_warning ("gstpad: connecting incompatible pads (%s:%s) and (%s:%s)\n",
@ -501,11 +548,12 @@ gst_pad_connect (GstPad *srcpad,
}
/* first set peers */
srcpad->peer = sinkpad;
sinkpad->peer = srcpad;
realsrc->peer = realsink;
realsink->peer = realsrc;
// FIXME this is irrelevant now
/* now copy the chain pointer from sink to src */
srcpad->chainfunc = sinkpad->chainfunc;
//srcpad->chainfunc = sinkpad->chainfunc;
/* and the pull function */
//srcpad->pullfunc = sinkpad->pullfunc;
@ -550,12 +598,22 @@ void
gst_pad_add_ghost_parent (GstPad *pad,
GstObject *parent)
{
GstRealPad *realpad;
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (GST_IS_REAL_PAD (pad)); // NOTE this restriction
g_return_if_fail (parent != NULL);
g_return_if_fail (GTK_IS_OBJECT (parent));
pad->ghostparents = g_list_prepend (pad->ghostparents, parent);
realpad = GST_REAL_PAD (pad);
/* FIXME is this going to be needed?
// now we need to deal with the real/ghost stuff
if (GST_IS_GHOST_PAD(srcpad)) realsrc = GST_GHOST_PAD(srcpad)->realpad;
else realsrc = GST_REAL_PAD(srcpad);
*/
realpad->ghostparents = g_list_prepend (realpad->ghostparents, parent);
}
@ -570,12 +628,16 @@ void
gst_pad_remove_ghost_parent (GstPad *pad,
GstObject *parent)
{
GstRealPad *realpad;
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (GST_IS_REAL_PAD (pad)); // NOTE this restriction
g_return_if_fail (parent != NULL);
g_return_if_fail (GTK_IS_OBJECT (parent));
pad->ghostparents = g_list_remove (pad->ghostparents, parent);
realpad = GST_REAL_PAD (pad);
realpad->ghostparents = g_list_remove (realpad->ghostparents, parent);
}
/**
@ -607,9 +669,9 @@ GList*
gst_pad_get_ghost_parents (GstPad *pad)
{
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL); // NOTE this restriction
return pad->ghostparents;
return GST_REAL_PAD(pad)->ghostparents;
}
/**
@ -624,9 +686,9 @@ gst_pad_set_caps_list (GstPad *pad,
GList *caps)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (GST_IS_REAL_PAD (pad)); // NOTE this restriction
pad->caps = caps;
GST_REAL_PAD(pad)->caps = caps;
}
/**
@ -640,10 +702,16 @@ gst_pad_set_caps_list (GstPad *pad,
GList *
gst_pad_get_caps_list (GstPad *pad)
{
GstRealPad *realpad;
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
return pad->caps;
// find the real pad
if (GST_IS_GHOST_PAD (pad)) realpad = GST_GHOST_PAD(pad)->realpad;
else realpad = GST_REAL_PAD(pad);
return realpad->caps;
}
/**
@ -658,12 +726,17 @@ gst_pad_get_caps_list (GstPad *pad)
GstCaps *
gst_pad_get_caps_by_name (GstPad *pad, gchar *name)
{
GstRealPad *realpad;
GList *caps;
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
caps = pad->caps;
// find the real pad
if (GST_IS_GHOST_PAD (pad)) realpad = GST_GHOST_PAD(pad)->realpad;
else realpad = GST_REAL_PAD(pad);
caps = realpad->caps;
while (caps) {
GstCaps *cap = (GstCaps *)caps->data;
@ -690,13 +763,21 @@ gst_pad_get_caps_by_name (GstPad *pad, gchar *name)
gboolean
gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
{
GstRealPad *realsrc, *realsink;
g_return_val_if_fail (srcpad != NULL, FALSE);
g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
g_return_val_if_fail (sinkpad != NULL, FALSE);
g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
if (srcpad->caps && sinkpad->caps) {
if (!gst_caps_list_check_compatibility (srcpad->caps, sinkpad->caps)) {
// find the real pad
if (GST_IS_GHOST_PAD (srcpad)) realsrc = GST_GHOST_PAD(srcpad)->realpad;
else realsrc = GST_REAL_PAD(srcpad);
if (GST_IS_GHOST_PAD (sinkpad)) realsink = GST_GHOST_PAD(sinkpad)->realpad;
else realsink = GST_REAL_PAD(sinkpad);
if (realsrc->caps && realsink->caps) {
if (!gst_caps_list_check_compatibility (realsrc->caps, realsink->caps)) {
return FALSE;
}
else {
@ -721,14 +802,20 @@ gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad)
GstPad*
gst_pad_get_peer (GstPad *pad)
{
GstRealPad *realpad;
g_return_val_if_fail (pad != NULL, NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
return pad->peer;
// find the real pad
if (GST_IS_GHOST_PAD (pad)) realpad = GST_GHOST_PAD(pad)->realpad;
else realpad = GST_REAL_PAD(pad);
return GST_PAD(realpad->peer);
}
// FIXME this needs to be rethought soon
static void
gst_pad_real_destroy (GtkObject *object)
gst_real_pad_destroy (GtkObject *object)
{
GstPad *pad = GST_PAD (object);
@ -736,7 +823,7 @@ gst_pad_real_destroy (GtkObject *object)
if (pad->name)
g_free (pad->name);
g_list_free (pad->ghostparents);
g_list_free (GST_REAL_PAD(pad)->ghostparents);
}
@ -754,7 +841,7 @@ gst_pad_load_and_connect (xmlNodePtr parent,
GstObject *element,
GHashTable *elements)
{
xmlNodePtr field = parent->xmlChildrenNode;
xmlNodePtr field = parent->childs;
GstPad *pad = NULL, *targetpad;
guchar *peer = NULL;
gchar **split;
@ -806,11 +893,17 @@ xmlNodePtr
gst_pad_save_thyself (GstPad *pad,
xmlNodePtr parent)
{
GstRealPad *realpad;
GstPad *peer;
// FIXME ?
if (GST_IS_GHOST_PAD(pad)) return NULL;
realpad = GST_REAL_PAD(pad);
xmlNewChild(parent,NULL,"name",pad->name);
if (pad->peer != NULL) {
peer = pad->peer;
if (realpad->peer != NULL) {
peer = GST_PAD(realpad->peer);
// first check to see if the peer's parent's parent is the same
//if (pad->parent->parent == peer->parent->parent)
// we just save it off
@ -848,11 +941,12 @@ gst_pad_ghost_save_thyself (GstPad *pad,
#ifndef gst_pad_push
void gst_pad_push(GstPad *pad,GstBuffer *buf) {
GstRealPad *realpad = GST_REAL_PAD(pad);
GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
if (pad->peer->pushfunc) {
if (realpad->peer->pushfunc) {
GST_DEBUG (0,"calling pushfunc &%s of peer pad %s:%s\n",
GST_DEBUG_FUNCPTR_NAME(pad->peer->pushfunc),GST_DEBUG_PAD_NAME(pad->peer));
(pad->peer->pushfunc)(pad->peer,buf);
GST_DEBUG_FUNCPTR_NAME(realpad->peer->pushfunc),GST_DEBUG_PAD_NAME(GST_PAD(realpad->peer)));
(realpad->peer->pushfunc)(GST_PAD(realpad->peer),buf);
} else
GST_DEBUG (0,"no pushfunc\n");
}
@ -860,14 +954,15 @@ void gst_pad_push(GstPad *pad,GstBuffer *buf) {
#ifndef gst_pad_pull
GstBuffer *gst_pad_pull(GstPad *pad) {
GstPad *peer = pad->peer;
GstRealPad *realpad = GST_REAL_PAD(pad);
GstRealPad *peer = realpad->peer;
GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
if (peer->pullfunc) {
GST_DEBUG (0,"calling pullfunc &%s (@%p) of peer pad %s:%s\n",
GST_DEBUG_FUNCPTR_NAME(peer->pullfunc),&peer->pullfunc,GST_DEBUG_PAD_NAME(peer));
return (peer->pullfunc)(peer);
GST_DEBUG_FUNCPTR_NAME(peer->pullfunc),&peer->pullfunc,GST_DEBUG_PAD_NAME(GST_PAD(peer)));
return (peer->pullfunc)(GST_PAD(peer));
} else {
GST_DEBUG (0,"no pullfunc for peer pad %s:%s at %p\n",GST_DEBUG_PAD_NAME(peer),&peer->pullfunc);
GST_DEBUG (0,"no pullfunc for peer pad %s:%s at %p\n",GST_DEBUG_PAD_NAME(GST_PAD(peer)),&peer->pullfunc);
return NULL;
}
}
@ -875,11 +970,12 @@ GstBuffer *gst_pad_pull(GstPad *pad) {
#ifndef gst_pad_pullregion
GstBuffer *gst_pad_pullregion(GstPad *pad,gulong offset,gulong size) {
GstRealPad *realpad = GST_REAL_PAD(pad);
GST_DEBUG_ENTER("(%s:%s,%ld,%ld)",GST_DEBUG_PAD_NAME(pad),offset,size);
if (pad->peer->pullregionfunc) {
if (realpad->peer->pullregionfunc) {
GST_DEBUG (0,"calling pullregionfunc &%s of peer pad %s:%s\n",
GST_DEBUG_FUNCPTR_NAME(pad->peer->pullregionfunc),GST_DEBUG_PAD_NAME(pad->peer));
return (pad->peer->pullregionfunc)(pad->peer,offset,size);
GST_DEBUG_FUNCPTR_NAME(realpad->peer->pullregionfunc),GST_DEBUG_PAD_NAME(GST_PAD(realpad->peer)));
return (realpad->peer->pullregionfunc)(GST_PAD(realpad->peer),offset,size);
} else {
GST_DEBUG (0,"no pullregionfunc\n");
return NULL;
@ -1022,7 +1118,7 @@ gst_padtemplate_save_thyself (GstPadTemplate *pad, xmlNodePtr parent)
GstPadTemplate*
gst_padtemplate_load_thyself (xmlNodePtr parent)
{
xmlNodePtr field = parent->xmlChildrenNode;
xmlNodePtr field = parent->childs;
GstPadTemplate *factory = g_new0 (GstPadTemplate, 1);
while (field) {
@ -1073,7 +1169,7 @@ gst_pad_eos_func(GstPad *pad)
gboolean result = TRUE, success;
g_return_val_if_fail (pad != NULL, FALSE);
g_return_val_if_fail (GST_IS_PAD(pad), FALSE);
g_return_val_if_fail (GST_IS_REAL_PAD(pad), FALSE); // NOTE the restriction
GST_INFO (GST_CAT_PADS,"attempting to set EOS on sink pad %s:%s",GST_DEBUG_PAD_NAME(pad));
@ -1087,7 +1183,7 @@ gst_pad_eos_func(GstPad *pad)
pads = g_list_next(pads);
if (gst_pad_get_direction(srcpad) == GST_PAD_SRC) {
result = gst_pad_eos(srcpad);
result = gst_pad_eos(GST_REAL_PAD(srcpad));
if (result == FALSE) success = FALSE;
}
}
@ -1112,14 +1208,14 @@ gboolean
gst_pad_set_eos(GstPad *pad)
{
g_return_val_if_fail (pad != NULL, FALSE);
g_return_val_if_fail (GST_IS_PAD(pad), FALSE);
g_return_val_if_fail (GST_IS_REAL_PAD(pad), FALSE); // NOTE the restriction
g_return_val_if_fail (GST_PAD_CONNECTED(pad), FALSE);
GST_INFO (GST_CAT_PADS,"attempting to set EOS on src pad %s:%s",GST_DEBUG_PAD_NAME(pad));
gst_element_announce_eos (GST_ELEMENT (pad->parent), TRUE);
if (!gst_pad_eos(pad)) {
if (!gst_pad_eos(GST_REAL_PAD(pad))) {
gst_element_announce_eos (GST_ELEMENT (pad->parent), FALSE);
return FALSE;
}
@ -1161,3 +1257,54 @@ gst_pad_get_element_private (GstPad *pad)
return pad->element_private;
}
/***** ghost pads *****/
static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
static void gst_ghost_pad_init (GstGhostPad *pad);
static GstPad *ghost_pad_parent_class = NULL;
//static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 };
GtkType
gst_ghost_pad_get_type(void) {
static GtkType pad_type = 0;
if (!pad_type) {
static const GtkTypeInfo pad_info = {
"GstGhostPad",
sizeof(GstGhostPad),
sizeof(GstGhostPadClass),
(GtkClassInitFunc)gst_ghost_pad_class_init,
(GtkObjectInitFunc)gst_ghost_pad_init,
(GtkArgSetFunc)NULL,
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
pad_type = gtk_type_unique(GST_TYPE_PAD,&pad_info);
}
return pad_type;
}
static void
gst_ghost_pad_class_init (GstGhostPadClass *klass)
{
GtkObjectClass *gtkobject_class;
gtkobject_class = (GtkObjectClass*)klass;
ghost_pad_parent_class = gtk_type_class(GST_TYPE_PAD);
}
static void
gst_ghost_pad_init (GstGhostPad *pad)
{
pad->realpad = NULL;
}

View file

@ -1,6 +1,6 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
* 2000 Wim Taymans <wim.taymans@chello.be>
*
* gstpad.h: Header for GstPad object
*
@ -26,13 +26,6 @@
#include <parser.h> // NOTE: This is xml-config's fault
// Include compatability defines: if libxml hasn't already defined these,
// we have an old version 1.x
#ifndef xmlChildrenNode
#define xmlChildrenNode childs
#define xmlRootNode root
#endif
#include <gst/gstobject.h>
#include <gst/gstbuffer.h>
#include <gst/cothreads.h>
@ -44,22 +37,35 @@ extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_PAD (gst_pad_get_type ())
#define GST_PAD(obj) (GTK_CHECK_CAST ((obj), GST_TYPE_PAD,GstPad))
#define GST_PAD_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GST_TYPE_PAD,GstPadClass))
#define GST_IS_PAD(obj) (GTK_CHECK_TYPE ((obj), GST_TYPE_PAD))
#define GST_IS_PAD_CLASS(obj) (GTK_CHECK_CLASS_TYPE ((klass), GST_TYPE_PAD))
#define GST_TYPE_PAD (gst_pad_get_type ())
#define GST_PAD(obj) (GTK_CHECK_CAST ((obj), GST_TYPE_PAD,GstPad))
#define GST_PAD_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GST_TYPE_PAD,GstPadClass))
#define GST_IS_PAD(obj) (GTK_CHECK_TYPE ((obj), GST_TYPE_PAD))
#define GST_IS_PAD_CLASS(obj) (GTK_CHECK_CLASS_TYPE ((klass), GST_TYPE_PAD))
/* quick test to see if the pad is connected */
#define GST_PAD_CONNECTED(pad) ((pad) && (pad)->peer != NULL)
#define GST_PAD_CAN_PULL(pad) ((pad) && (pad)->pullfunc != NULL)
#define GST_TYPE_REAL_PAD (gst_real_pad_get_type ())
#define GST_REAL_PAD(obj) (GTK_CHECK_CAST ((obj), GST_TYPE_REAL_PAD,GstRealPad))
#define GST_REAL_PAD_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GST_TYPE_REAL_PAD,GstRealPadClass))
#define GST_IS_REAL_PAD(obj) (GTK_CHECK_TYPE ((obj), GST_TYPE_REAL_PAD))
#define GST_IS_REAL_PAD_CLASS(obj) (GTK_CHECK_CLASS_TYPE ((klass), GST_TYPE_REAL_PAD))
#define GST_TYPE_GHOST_PAD (gst_ghost_pad_get_type ())
#define GST_GHOST_PAD(obj) (GTK_CHECK_CAST ((obj), GST_TYPE_GHOST_PAD,GstGhostPad))
#define GST_GHOST_PAD_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD,GstGhostPadClass))
#define GST_IS_GHOST_PAD(obj) (GTK_CHECK_TYPE ((obj), GST_TYPE_GHOST_PAD))
#define GST_IS_GHOST_PAD_CLASS(obj) (GTK_CHECK_CLASS_TYPE ((klass), GST_TYPE_GHOST_PAD))
typedef struct _GstPad GstPad;
typedef struct _GstPadClass GstPadClass;
typedef struct _GstRealPad GstRealPad;
typedef struct _GstRealPadClass GstRealPadClass;
typedef struct _GstGhostPad GstGhostPad;
typedef struct _GstGhostPadClass GstGhostPadClass;
typedef struct _GstPadTemplate GstPadTemplate;
typedef struct _GstPadTemplateClass GstPadTemplateClass;
/* this defines the functions used to chain buffers
* pad is the sink pad (so the same chain function can be used for N pads)
* buf is the buffer being passed */
@ -91,14 +97,30 @@ struct _GstPad {
GstObject object;
gchar *name;
GList *caps;
gpointer element_private;
GstObject *parent;
GstPadTemplate *padtemplate; /* the template for this pad */
};
struct _GstPadClass {
GstObjectClass parent_class;
};
/* quick access macros */
#define GST_PAD_NAME(pad) (GST_PAD(pad)->name)
#define GST_PAD_DIRECTION(pad) (GST_PAD(pad)->direction)
#define GST_PAD_PARENT(pad) (GST_PAD(pad)->parent)
struct _GstRealPad {
GstPad pad;
GList *caps;
GstPadDirection direction;
cothread_state *threadstate;
GstPadDirection direction;
GstPad *peer;
GstRealPad *peer;
GstBuffer *bufpen;
@ -112,14 +134,15 @@ struct _GstPad {
GstPadPullFunction pullfunc;
GstPadPullRegionFunction pullregionfunc;
GstObject *parent;
GList *ghostparents;
GstPadTemplate *padtemplate; /* the template for this pad */
};
struct _GstPadClass {
GstObjectClass parent_class;
/* quick test to see if the pad is connected */
#define GST_PAD_CONNECTED(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->peer != NULL)
#define GST_PAD_CAN_PULL(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->pullfunc != NULL)
struct _GstRealPadClass {
GstPadClass parent_class;
/* signal callbacks */
void (*set_active) (GstPad *pad, gboolean active);
@ -127,6 +150,16 @@ struct _GstPadClass {
void (*eos) (GstPad *pad);
};
struct _GstGhostPad {
GstPad pad;
GstRealPad *realpad;
};
struct _GstGhostPadClass {
GstPadClass parent_class;
};
/* template */
#define GST_TYPE_PADTEMPLATE (gst_padtemplate_get_type ())
#define GST_PADTEMPLATE(obj) (GTK_CHECK_CAST ((obj), GST_TYPE_PADTEMPLATE,GstPad))
@ -170,7 +203,10 @@ typedef GstPadFactoryEntry GstPadFactory[];
#define GST_PAD_FACTORY_CAPS(a...) GINT_TO_POINTER(1),##a,NULL
GtkType gst_pad_get_type (void);
GtkType gst_real_pad_get_type (void);
GtkType gst_ghost_pad_get_type (void);
GstPad* gst_pad_new (gchar *name, GstPadDirection direction);
#define gst_pad_destroy(pad) gst_object_destroy (GST_OBJECT (pad))
@ -235,6 +271,9 @@ xmlNodePtr gst_pad_save_thyself (GstPad *pad, xmlNodePtr parent);
void gst_pad_load_and_connect (xmlNodePtr parent, GstObject *element, GHashTable *elements);
/* templates and factories */
GtkType gst_padtemplate_get_type (void);

View file

@ -196,10 +196,10 @@ gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
GstPad *sinkpad = (GstPad *)sinkpads->data;
// if we have a match, connect the pads
if (sinkpad->direction == GST_PAD_SINK &&
if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
!GST_PAD_CONNECTED(sinkpad))
{
if (gst_caps_list_check_compatibility (pad->caps, sinkpad->caps)) {
if (gst_caps_list_check_compatibility (gst_pad_get_caps_list(pad), gst_pad_get_caps_list(sinkpad))) {
gst_pad_connect(pad, sinkpad);
GST_DEBUG (0,"gstpipeline: autoconnect pad \"%s\" in element %s <-> ", pad->name,
gst_element_get_name(src));
@ -232,7 +232,7 @@ gst_pipeline_pads_autoplug (GstElement *src, GstElement *sink)
while (srcpads && !connected) {
GstPad *srcpad = (GstPad *)srcpads->data;
if (srcpad->direction == GST_PAD_SRC)
if (gst_pad_get_direction(srcpad) == GST_PAD_SRC)
connected = gst_pipeline_pads_autoplug_func (src, srcpad, sink);
srcpads = g_list_next(srcpads);
@ -362,7 +362,8 @@ gst_pipeline_autoplug (GstPipeline *pipeline)
pad = (GstPad *)gst_element_get_pad_list (element)->data;
base_factories[i] = factories[i] = gst_autoplug_caps_list (g_list_append(NULL,src_caps), pad->caps);
base_factories[i] = factories[i] = gst_autoplug_caps_list (g_list_append(NULL,src_caps),
gst_pad_get_caps_list(pad));
// if we have a succesfull connection, proceed
if (factories[i] != NULL) {
i++;
@ -456,7 +457,7 @@ differ:
sinkpad = (GstPad *)sinkpads->data;
// FIXME connect matching pads, not just the first one...
if (sinkpad->direction == GST_PAD_SINK &&
if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
!GST_PAD_CONNECTED(sinkpad)) {
GList *caps = gst_pad_get_caps_list (sinkpad);

View file

@ -53,6 +53,7 @@ gst_bin_chain_wrapper (int argc,char *argv[])
G_GNUC_UNUSED const gchar *name = gst_element_get_name (element);
GList *pads;
GstPad *pad;
GstRealPad *realpad;
GstBuffer *buf;
GST_DEBUG_ENTER("(\"%s\")",name);
@ -62,11 +63,13 @@ gst_bin_chain_wrapper (int argc,char *argv[])
while (pads) {
pad = GST_PAD (pads->data);
pads = g_list_next (pads);
if (pad->direction == GST_PAD_SINK) {
if (!GST_IS_REAL_PAD(pad)) continue;
realpad = GST_REAL_PAD(pad);
if (realpad->direction == GST_PAD_SINK) {
GST_DEBUG (0,"pulling a buffer from %s:%s\n", name, gst_pad_get_name (pad));
buf = gst_pad_pull (pad);
GST_DEBUG (0,"calling chain function of %s:%s\n", name, gst_pad_get_name (pad));
(pad->chainfunc) (pad,buf);
(realpad->chainfunc) (pad,buf);
GST_DEBUG (0,"calling chain function of %s:%s done\n", name, gst_pad_get_name (pad));
}
}
@ -83,6 +86,7 @@ gst_bin_src_wrapper (int argc,char *argv[])
GstElement *element = GST_ELEMENT (argv);
GList *pads;
GstPad *pad;
GstRealPad *realpad;
GstBuffer *buf;
G_GNUC_UNUSED const gchar *name = gst_element_get_name (element);
@ -92,24 +96,26 @@ gst_bin_src_wrapper (int argc,char *argv[])
pads = element->pads;
while (pads) {
pad = GST_PAD (pads->data);
if (pad->direction == GST_PAD_SRC) {
pads = g_list_next(pads);
if (!GST_IS_REAL_PAD(pad)) continue;
realpad = GST_REAL_PAD(pad);
if (realpad->direction == GST_PAD_SRC) {
// region_struct *region = cothread_get_data (element->threadstate, "region");
GST_DEBUG (0,"calling _getfunc for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
// if (region) {
//gst_src_push_region (GST_SRC (element), region->offset, region->size);
// if (pad->getregionfunc == NULL)
// if (eralpad->getregionfunc == NULL)
// fprintf(stderr,"error, no getregionfunc in \"%s\"\n", name);
// buf = (pad->getregionfunc)(pad, region->offset, region->size);
// buf = (realpad->getregionfunc)(pad, region->offset, region->size);
// } else {
if (pad->getfunc == NULL)
if (realpad->getfunc == NULL)
fprintf(stderr,"error, no getfunc in \"%s\"\n", name);
buf = (pad->getfunc)(pad);
buf = (realpad->getfunc)(pad);
// }
GST_DEBUG (0,"calling gst_pad_push on pad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
gst_pad_push (pad, buf);
}
pads = g_list_next(pads);
}
} while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
GST_FLAG_UNSET(element,GST_ELEMENT_COTHREAD_STOPPING);
@ -124,7 +130,7 @@ gst_bin_pushfunc_proxy (GstPad *pad, GstBuffer *buf)
cothread_state *threadstate = GST_ELEMENT(pad->parent)->threadstate;
GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
GST_DEBUG (0,"putting buffer %p in peer's pen\n",buf);
pad->peer->bufpen = buf;
GST_REAL_PAD(pad)->peer->bufpen = buf;
GST_DEBUG (0,"switching to %p (@%p)\n",threadstate,&(GST_ELEMENT(pad->parent)->threadstate));
cothread_switch (threadstate);
GST_DEBUG (0,"done switching\n");
@ -132,18 +138,19 @@ gst_bin_pushfunc_proxy (GstPad *pad, GstBuffer *buf)
static GstBuffer*
gst_bin_pullfunc_proxy (GstPad *pad)
{
{
GstRealPad *realpad = GST_REAL_PAD(pad);
GstBuffer *buf;
cothread_state *threadstate = GST_ELEMENT(pad->parent)->threadstate;
GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
if (pad->bufpen == NULL) {
if (realpad->bufpen == NULL) {
GST_DEBUG (0,"switching to %p (@%p)\n",threadstate,&(GST_ELEMENT(pad->parent)->threadstate));
cothread_switch (threadstate);
}
GST_DEBUG (0,"done switching\n");
buf = pad->bufpen;
pad->bufpen = NULL;
buf = realpad->bufpen;
realpad->bufpen = NULL;
return buf;
}
@ -183,6 +190,7 @@ gst_schedule_cothreaded_chain (GstBin *bin, _GstBinChain *chain) {
cothread_func wrapper_function;
GList *pads;
GstPad *pad;
GstRealPad *realpad;
GST_DEBUG (0,"chain is using cothreads\n");
@ -225,28 +233,30 @@ gst_schedule_cothreaded_chain (GstBin *bin, _GstBinChain *chain) {
while (pads) {
pad = GST_PAD (pads->data);
pads = g_list_next (pads);
if (!GST_IS_REAL_PAD(pad)) continue;
realpad = GST_REAL_PAD(pad);
// if the element is DECOUPLED or outside the manager, we have to chain
if ((wrapper_function == NULL) ||
(GST_ELEMENT(pad->peer->parent)->manager != GST_ELEMENT(bin))) {
(GST_ELEMENT(GST_PAD(realpad->peer)->parent)->manager != GST_ELEMENT(bin))) {
// set the chain proxies
if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
GST_DEBUG (0,"copying chain function into push proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
pad->pushfunc = pad->chainfunc;
realpad->pushfunc = realpad->chainfunc;
} else {
GST_DEBUG (0,"copying get function into pull proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
pad->pullfunc = pad->getfunc;
pad->pullregionfunc = pad->getregionfunc;
realpad->pullfunc = realpad->getfunc;
realpad->pullregionfunc = realpad->getregionfunc;
}
// otherwise we really are a cothread
} else {
if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
GST_DEBUG (0,"setting cothreaded push proxy for sinkpad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
pad->pushfunc = GST_DEBUG_FUNCPTR(gst_bin_pushfunc_proxy);
realpad->pushfunc = GST_DEBUG_FUNCPTR(gst_bin_pushfunc_proxy);
} else {
GST_DEBUG (0,"setting cothreaded pull proxy for srcpad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
pad->pullfunc = GST_DEBUG_FUNCPTR(gst_bin_pullfunc_proxy);
realpad->pullfunc = GST_DEBUG_FUNCPTR(gst_bin_pullfunc_proxy);
}
}
}
@ -270,6 +280,7 @@ gst_schedule_chained_chain (GstBin *bin, _GstBinChain *chain) {
GstElement *element;
GList *pads;
GstPad *pad;
GstRealPad *realpad;
GST_DEBUG (0,"chain entered\n");
// walk through all the elements
@ -283,14 +294,16 @@ gst_schedule_chained_chain (GstBin *bin, _GstBinChain *chain) {
while (pads) {
pad = GST_PAD (pads->data);
pads = g_list_next (pads);
if (!GST_IS_REAL_PAD(pad)) continue;
realpad = GST_REAL_PAD(pad);
if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
GST_DEBUG (0,"copying chain function into push proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
pad->pushfunc = pad->chainfunc;
realpad->pushfunc = realpad->chainfunc;
} else {
GST_DEBUG (0,"copying get function into pull proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
pad->pullfunc = pad->getfunc;
pad->pullregionfunc = pad->getregionfunc;
realpad->pullfunc = realpad->getfunc;
realpad->pullregionfunc = realpad->getregionfunc;
}
}
}
@ -316,15 +329,13 @@ static void gst_bin_schedule_cleanup(GstBin *bin) {
}
void gst_bin_schedule_func(GstBin *bin) {
// GstElement *manager;
GList *elements;
GstElement *element;
// const gchar *elementname;
GSList *pending = NULL;
// GstBin *pending_bin;
GList *pads;
GstPad *pad;
// GstElement *peer_manager;
GstRealPad *realpad;
GstElement *peerparent;
GList *chains;
_GstBinChain *chain;
@ -393,30 +404,34 @@ void gst_bin_schedule_func(GstBin *bin) {
while (pads) {
pad = GST_PAD (pads->data);
pads = g_list_next (pads);
if (!GST_IS_REAL_PAD(pad)) continue;
realpad = GST_REAL_PAD(pad);
GST_DEBUG (0,"have pad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
if (pad->peer == NULL) GST_ERROR(pad,"peer is null!");
g_assert(pad->peer != NULL);
g_assert(pad->peer->parent != NULL);
//g_assert(GST_ELEMENT(pad->peer->parent)->manager != NULL);
if (realpad->peer == NULL) GST_ERROR(pad,"peer is null!");
g_assert(realpad->peer != NULL);
g_assert(GST_PAD(realpad->peer)->parent != NULL);
GST_DEBUG (0,"peer pad %p\n", pad->peer);
peerparent = GST_ELEMENT(GST_PAD(realpad->peer)->parent);
GST_DEBUG (0,"peer pad %p\n", realpad->peer);
// only bother with if the pad's peer's parent is this bin or it's DECOUPLED
// only add it if it's in the list of un-visited elements still
if ((g_list_find (elements, pad->peer->parent) != NULL) ||
GST_FLAG_IS_SET (pad->peer->parent, GST_ELEMENT_DECOUPLED)) {
if ((g_list_find (elements, peerparent) != NULL) ||
GST_FLAG_IS_SET (peerparent, GST_ELEMENT_DECOUPLED)) {
// add the peer element to the pending list
GST_DEBUG (0,"adding '%s' to list of pending elements\n",gst_element_get_name(GST_ELEMENT(pad->peer->parent)));
pending = g_slist_prepend (pending, GST_ELEMENT(pad->peer->parent));
GST_DEBUG (0,"adding '%s' to list of pending elements\n",
gst_element_get_name(peerparent));
pending = g_slist_prepend (pending, peerparent);
// if this is a sink pad, then the element on the other side is an entry
if ((gst_pad_get_direction (pad) == GST_PAD_SINK) &&
(GST_FLAG_IS_SET (pad->peer->parent, GST_ELEMENT_DECOUPLED))) {
chain->entries = g_list_prepend (chain->entries, pad->peer->parent);
GST_DEBUG (0,"added '%s' as DECOUPLED entry into the chain\n",gst_element_get_name(GST_ELEMENT(pad->peer->parent)));
(GST_FLAG_IS_SET (peerparent, GST_ELEMENT_DECOUPLED))) {
chain->entries = g_list_prepend (chain->entries, peerparent);
GST_DEBUG (0,"added '%s' as DECOUPLED entry into the chain\n",gst_element_get_name(peerparent));
}
} else
GST_DEBUG (0,"element '%s' has already been dealt with\n",gst_element_get_name(GST_ELEMENT(pad->peer->parent)));
GST_DEBUG (0,"element '%s' has already been dealt with\n",gst_element_get_name(peerparent));
}
}
} while (pending);

View file

@ -87,6 +87,7 @@ gint print_element_info(GstElementFactory *factory) {
GstElementClass *gstelement_class;
GList *pads, *caps;
GstPad *pad;
GstRealPad *realpad;
GstPadTemplate *padtemplate;
GstCaps *cap;
GtkArg *args;
@ -196,6 +197,7 @@ gint print_element_info(GstElementFactory *factory) {
while (pads) {
pad = GST_PAD(pads->data);
pads = g_list_next(pads);
realpad = GST_REAL_PAD(pad);
if (gst_pad_get_direction(pad) == GST_PAD_SRC)
printf(" SRC: '%s'\n",gst_pad_get_name(pad));
@ -205,27 +207,27 @@ gint print_element_info(GstElementFactory *factory) {
printf(" UNKNOWN!!!: '%s'\n",gst_pad_get_name(pad));
printf(" Implementation:\n");
if (pad->chainfunc)
printf(" Has chainfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->chainfunc));
if (pad->getfunc)
printf(" Has getfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->getfunc));
if (pad->getregionfunc)
printf(" Has getregionfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->getregionfunc));
if (pad->qosfunc)
printf(" Has qosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->qosfunc));
if (pad->eosfunc) {
if (pad->eosfunc == gst_pad_eos_func)
if (realpad->chainfunc)
printf(" Has chainfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->chainfunc));
if (realpad->getfunc)
printf(" Has getfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->getfunc));
if (realpad->getregionfunc)
printf(" Has getregionfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->getregionfunc));
if (realpad->qosfunc)
printf(" Has qosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->qosfunc));
if (realpad->eosfunc) {
if (realpad->eosfunc == gst_pad_eos_func)
printf(" Has default eosfunc() gst_pad_eos_func()\n");
else
printf(" Has eosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->eosfunc));
printf(" Has eosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->eosfunc));
}
if (pad->padtemplate)
printf(" Pad Template: '%s'\n",pad->padtemplate->name_template);
if (pad->caps) {
if (realpad->caps) {
printf(" Capabilities:\n");
caps = pad->caps;
caps = realpad->caps;
while (caps) {
GstType *type;
@ -255,6 +257,8 @@ gint print_element_info(GstElementFactory *factory) {
for (i=0;i<num_args;i++) {
gtk_object_getv(GTK_OBJECT(element), 1, &args[i]);
// FIXME should say whether it's read-only or not
printf(" %s: ",args[i].name);
switch (args[i].type) {
case GTK_TYPE_STRING: printf("String");break;