many fixes related to dynamic pipelines.
authorAndy Wingo <wingo@pobox.com>
Mon, 18 Feb 2002 00:40:56 +0000 (00:40 +0000)
committerAndy Wingo <wingo@pobox.com>
Mon, 18 Feb 2002 00:40:56 +0000 (00:40 +0000)
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.

gst/gstelement.c
gst/gstelement.h
gst/gstelementfactory.c
gst/gstpad.c
gst/gsttypefind.c
gst/schedulers/gststandardscheduler.c

index 2c8485e..76a1d0c 100644 (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;
+  destpads = gst_element_get_pad_list (dest);
+
+  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);
     }
-    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;
+  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;
     }
-    destpads = g_list_next (destpads);
   }
-
+  
   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)
 {
index 76a7452..2725950 100644 (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);
 
index b35e1c2..a27bb9c 100644 (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);
index de81301..21497a7 100644 (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));
 }
 
 /**
index ef7e70b..44839bd 100644 (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;
index e30c6f1..4676b8d 100644 (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