mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
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:
parent
9c5e022c92
commit
2cb0dd9d9b
6 changed files with 104 additions and 48 deletions
123
gst/gstelement.c
123
gst/gstelement.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue