many fixes related to dynamic pipelines.

Original commit message from CVS:
* many fixes related to dynamic pipelines.
* addition of gst_element_disconnect_elements(), as per connect_elements()
* don't have a cow if typefind changes state in its signal handlers
* support of request pad -> request pad in connect_elements()
* some fixes in int2float that will eventually need to be ported to float2int and
adder

the gstelement api is getting bloated, expect a rewrite within the next month.
This commit is contained in:
Andy Wingo 2002-02-18 00:40:56 +00:00
parent 9c5e022c92
commit 2cb0dd9d9b
6 changed files with 104 additions and 48 deletions

View file

@ -780,12 +780,10 @@ gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad, GstCa
/* try to get an existing unconnected pad */
pads = gst_element_get_pad_list (element);
while (pads)
{
while (pads) {
GstPad *current = GST_PAD (pads->data);
if ((GST_PAD_PEER (GST_PAD_REALIZE (current)) == NULL) &&
gst_pad_can_connect_filtered (pad, current, filtercaps))
{
gst_pad_can_connect_filtered (pad, current, filtercaps)) {
return current;
}
pads = g_list_next (pads);
@ -793,8 +791,7 @@ gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad, GstCa
/* try to create a new one */
/* requesting is a little crazy, we need a template. Let's create one */
if (filtercaps != NULL)
{
if (filtercaps != NULL) {
filtercaps = gst_caps_intersect (filtercaps, (GstCaps *) GST_RPAD_CAPS (pad));
if (filtercaps == NULL)
return NULL;
@ -845,8 +842,9 @@ gboolean
gst_element_connect_elements_filtered (GstElement *src, GstElement *dest,
GstCaps *filtercaps)
{
GList *srcpads, *destpads;
GList *srcpads, *destpads, *srctempls, *desttempls, *l;
GstPad *srcpad, *destpad;
GstPadTemplate *srctempl, *desttempl;
/* checks */
g_return_val_if_fail (src != NULL, FALSE);
@ -858,40 +856,66 @@ gst_element_connect_elements_filtered (GstElement *src, GstElement *dest,
/* loop through the existing pads in the source */
srcpads = gst_element_get_pad_list (src);
while (srcpads)
{
srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
if ((GST_RPAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
(GST_PAD_PEER (srcpad) == NULL))
{
destpad = gst_element_get_compatible_pad_filtered (dest, srcpad, filtercaps);
if (destpad && gst_pad_connect_filtered (srcpad, destpad, filtercaps))
{
GST_DEBUG (GST_CAT_ELEMENT_PADS, "connected pad %s:%s to pad %s:%s\n", GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
return TRUE;
}
}
srcpads = g_list_next (srcpads);
}
/* loop through the existing pads in the destination */
destpads = gst_element_get_pad_list (dest);
while (destpads)
{
destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
if ((GST_RPAD_DIRECTION (destpad) == GST_PAD_SINK) &&
(GST_PAD_PEER (destpad) == NULL))
{
srcpad = gst_element_get_compatible_pad_filtered (src, destpad, filtercaps);
if (srcpad && gst_pad_connect_filtered (srcpad, destpad, filtercaps))
{
GST_DEBUG (GST_CAT_ELEMENT_PADS, "connected pad %s:%s to pad %s:%s\n", GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
return TRUE;
if (srcpads || destpads) {
while (srcpads) {
srcpad = (GstPad *) GST_PAD_REALIZE (srcpads->data);
if ((GST_RPAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
(GST_PAD_PEER (srcpad) == NULL)) {
destpad = gst_element_get_compatible_pad_filtered (dest, srcpad, filtercaps);
if (destpad && gst_pad_connect_filtered (srcpad, destpad, filtercaps)) {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "connected pad %s:%s to pad %s:%s\n", GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
return TRUE;
}
}
srcpads = g_list_next (srcpads);
}
/* loop through the existing pads in the destination */
while (destpads) {
destpad = (GstPad *) GST_PAD_REALIZE (destpads->data);
if ((GST_RPAD_DIRECTION (destpad) == GST_PAD_SINK) &&
(GST_PAD_PEER (destpad) == NULL)) {
srcpad = gst_element_get_compatible_pad_filtered (src, destpad, filtercaps);
if (srcpad && gst_pad_connect_filtered (srcpad, destpad, filtercaps)) {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "connected pad %s:%s to pad %s:%s\n", GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
return TRUE;
}
}
destpads = g_list_next (destpads);
}
destpads = g_list_next (destpads);
}
GST_DEBUG (GST_CAT_ELEMENT_PADS, "we might have request pads on both sides, checking...");
srctempls = gst_element_get_padtemplate_list (src);
desttempls = gst_element_get_padtemplate_list (dest);
if (srctempls && desttempls) {
while (srctempls) {
srctempl = (GstPadTemplate*) srctempls->data;
if (srctempl->presence == GST_PAD_REQUEST) {
for (l=desttempls; l; l=l->next) {
desttempl = (GstPadTemplate*) desttempls->data;
if (desttempl->presence == GST_PAD_REQUEST && desttempl->direction != srctempl->direction) {
if (gst_caps_check_compatibility (gst_padtemplate_get_caps (srctempl),
gst_padtemplate_get_caps (desttempl))) {
srcpad = gst_element_request_pad_by_name (src, srctempl->name_template);
destpad = gst_element_request_pad_by_name (dest, desttempl->name_template);
if (gst_pad_connect_filtered (srcpad, destpad, filtercaps)) {
GST_DEBUG (GST_CAT_ELEMENT_PADS, "connected pad %s:%s to pad %s:%s\n",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
return TRUE;
}
/* FIXME: we have extraneous request pads lying around */
}
}
}
}
srctempls = srctempls->next;
}
}
GST_DEBUG (GST_CAT_ELEMENT_PADS, "no connection possible from %s to %s\n", GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
return FALSE;
}
@ -1018,6 +1042,33 @@ gst_element_disconnect (GstElement *src, const gchar *srcpadname,
/* we're satisified they can be disconnected, let's do it */
gst_pad_disconnect(srcpad,destpad);
}
/**
* gst_element_disconnect_elements:
* @src: element 1
* @dest: element 2
*
* Disconnect all pads connecting the two elements.
*/
void
gst_element_disconnect_elements (GstElement *src, GstElement *dest)
{
GstPad *src, *dst;
GList *srcpads, *destpads, *l;
g_return_if_fail (GST_IS_ELEMENT(src));
g_return_if_fail (GST_IS_ELEMENT(dest));
/* loop through the existing pads in the source */
srcpads = gst_element_get_pad_list (src);
destpads = gst_element_get_pad_list (dest);
for (; srcpads; srcpads=srcpads->next)
for (l=destpads; l; l=l->next)
if (GST_PAD_PEER ((GstPad*) srcpads->data) == (GstPad*) l->data)
gst_pad_disconnect ((GstPad*) srcpads->data, (GstPad*) l->data);
}
static void
gst_element_error_func (GstElement* element, GstElement *source, gchar *errormsg)
{

View file

@ -223,6 +223,7 @@ gboolean gst_element_connect_filtered (GstElement *src, const gchar *srcpadname
GstCaps *filtercaps);
void gst_element_disconnect (GstElement *src, const gchar *srcpadname,
GstElement *dest, const gchar *destpadname);
void gst_element_disconnect_elements (GstElement *src, GstElement *dest);
void gst_element_set_eos (GstElement *element);

View file

@ -251,9 +251,9 @@ gst_elementfactory_create (GstElementFactory *factory,
GST_DEBUG (GST_CAT_ELEMENTFACTORY,"class %s\n", GST_OBJECT_NAME (factory));
oclass->elementfactory = factory;
/* copy pad template pointers to the element class */
oclass->padtemplates = g_list_copy(factory->padtemplates);
oclass->numpadtemplates = factory->numpadtemplates;
/* copy pad template pointers to the element class, allow for custom padtemplates */
oclass->padtemplates = g_list_concat (oclass->padtemplates, factory->padtemplates);
oclass->numpadtemplates += factory->numpadtemplates;
}
gst_object_set_name (GST_OBJECT (element),name);

View file

@ -565,12 +565,19 @@ gst_pad_disconnect (GstPad *srcpad,
else if (GST_PAD_PARENT (realsink)->sched)
gst_scheduler_pad_disconnect (GST_PAD_PARENT (realsink)->sched, (GstPad *)realsrc, (GstPad *)realsink);
/* hold a reference, as they can go away in the signal handlers */
gst_object_ref (GST_OBJECT (realsrc));
gst_object_ref (GST_OBJECT (realsink));
/* fire off a signal to each of the pads telling them that they've been disconnected */
g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsink);
g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_DISCONNECTED], 0, realsrc);
GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
gst_object_unref (GST_OBJECT (realsrc));
gst_object_unref (GST_OBJECT (realsink));
}
/**

View file

@ -196,10 +196,10 @@ gst_typefind_chain (GstPad *pad, GstBuffer *buf)
gst_object_ref (GST_OBJECT (typefind));
g_signal_emit (G_OBJECT (typefind), gst_typefind_signals[HAVE_TYPE], 0,
typefind->caps);
if (GST_STATE(typefind) != oldstate) {
/* if (GST_STATE(typefind) != oldstate) {
GST_DEBUG(0, "state changed during signal, aborting\n");
gst_element_interrupt (GST_ELEMENT (typefind));
}
} */
gst_object_unref (GST_OBJECT (typefind));
goto end;

View file

@ -294,8 +294,7 @@ gst_standard_scheduler_chain_wrapper (int argc, char *argv[])
GST_DEBUG (GST_CAT_DATAFLOW, "calling chain function of %s:%s\n", name,
GST_PAD_NAME (pad));
GST_RPAD_CHAINFUNC (realpad) (pad, buf);
GST_DEBUG (GST_CAT_DATAFLOW, "calling chain function of %s:%s done\n", name,
GST_PAD_NAME (pad));
GST_DEBUG (GST_CAT_DATAFLOW, "calling chain function of element %s done\n", name);
}
}
else {
@ -763,7 +762,6 @@ gst_standard_scheduler_chain_remove_element (GstSchedulerChain * chain, GstEleme
/* if there are no more elements in the chain, destroy the chain */
if (chain->num_elements == 0)
gst_standard_scheduler_chain_destroy (chain);
}
static void
@ -997,11 +995,10 @@ gst_standard_scheduler_remove_element (GstScheduler * sched, GstElement * elemen
/* remove it from the list of elements */
bsched->elements = g_list_remove (bsched->elements, element);
bsched->num_elements--;
/* unset the scheduler pointer in the element */
GST_ELEMENT_SCHED (element) = NULL;
}
/* unset the scheduler pointer in the element */
GST_ELEMENT_SCHED (element) = NULL;
}
static GstElementStateReturn