mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
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:
parent
52713dac28
commit
c31f9a570c
8 changed files with 423 additions and 215 deletions
|
@ -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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
401
gst/gstpad.c
401
gst/gstpad.c
|
@ -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;
|
||||
}
|
||||
|
|
89
gst/gstpad.h
89
gst/gstpad.h
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue