add API to make life easier
authorBenjamin Otte <otte@gnome.org>
Mon, 28 Jan 2002 00:51:39 +0000 (00:51 +0000)
committerBenjamin Otte <otte@gnome.org>
Mon, 28 Jan 2002 00:51:39 +0000 (00:51 +0000)
Original commit message from CVS:
add API to make life easier

gst/gstelement.c
gst/gstelement.h
gst/gstpad.c
gst/gstpad.h

index c4501f1..a2dc9fc 100644 (file)
@@ -698,6 +698,175 @@ gst_element_request_pad_by_name (GstElement *element, const gchar *name)
 }
 
 /**
+ * gst_element_get_compatible_pad_filtered:
+ * @element: the element in which the pad should be found
+ * @pad: the pad to find a compatible one for
+ * @filtercaps: the caps to use as a filter
+ *
+ * Looks for an unconnected pad to which the given pad can connect to.
+ * It is not guaranteed that connecting the pads will work, though
+ * it should work in most cases.
+ *
+ * Returns: the pad to which a connection can be made
+ */
+
+GstPad*                        
+gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad, GstCaps *filtercaps)
+{
+  GList *pads;
+  GstPadTemplate *templ;
+  GstCaps *intersection;
+  GstPad *foundpad = NULL;
+  
+  /* checks */
+  g_return_val_if_fail (element != NULL, NULL);
+  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+  g_return_val_if_fail (pad != NULL, NULL);
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+  
+  /* let's use the real pad */
+  pad = (GstPad *) GST_PAD_REALIZE (pad);
+  g_return_val_if_fail (pad != NULL, NULL);
+  g_return_val_if_fail (GST_RPAD_PEER (pad) == NULL, NULL);
+  
+  /* try to get an existing unconnected pad */
+  pads = gst_element_get_pad_list (element);
+  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))
+    {
+      return current;
+    }
+    pads = g_list_next (pads);
+  }
+  
+  /* try to create a new one */
+  /* requesting is a little crazy, we need a template. Let's create one */
+  if (filtercaps != NULL)
+  {
+    filtercaps = gst_caps_intersect (filtercaps, (GstCaps *) GST_RPAD_CAPS (pad));
+    if (filtercaps == NULL)
+      return NULL;
+  }
+  templ = gst_padtemplate_new ((gchar *) GST_PAD_NAME (pad), GST_RPAD_DIRECTION (pad),
+                    GST_PAD_ALWAYS, filtercaps);
+  foundpad = gst_element_request_compatible_pad (element, templ);
+  gst_object_unref (GST_OBJECT (templ));
+  if (filtercaps != NULL)
+    gst_caps_unref (filtercaps);
+  
+  return foundpad;
+}
+
+/**
+ * gst_element_get_compatible_pad:
+ * @element: the element in which the pad should be found
+ * @pad: the pad to find a compatible one for
+ *
+ * Looks for an unconnected pad to which the given pad can connect to.
+ * It is not guaranteed that connecting the pads will work, though
+ * it should work in most cases.
+ *
+ * Returns: the pad to which a connection can be made
+ */
+
+GstPad*                        
+gst_element_get_compatible_pad (GstElement *element, GstPad *pad)
+{
+  return gst_element_get_compatible_pad_filtered (element, pad, NULL);
+}
+/**
+ * gst_element_connect_elements:
+ * @src: the element containing source pad
+ * @dest: the element containing destination pad
+ * @filtercaps: the caps to use as filter
+ *
+ * Connect the source to the destination element using the filtercaps.
+ * The connection must be from source to destination, the other
+ * direction will not be tried.
+ * The functions looks for existing pads that aren't connected yet. 
+ + It will use request pads if possible. But both pads will not be requested.
+ * If multiple connections are possible, only one is established.
+ *
+ * Return: TRUE if the elements could be connected.
+ */
+gboolean
+gst_element_connect_elements_filtered (GstElement *src, GstElement *dest, 
+                                      GstCaps *filtercaps)
+{
+  GList *srcpads, *destpads;
+  GstPad *srcpad, *destpad;
+
+  /* checks */
+  g_return_val_if_fail (src != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_ELEMENT(src), FALSE);
+  g_return_val_if_fail (dest != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_ELEMENT(dest), FALSE);
+
+  GST_DEBUG (GST_CAT_ELEMENT_PADS, "attempting to connect element %s to element %s\n", GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (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;
+      }
+    }
+    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;  
+}
+
+/**
+ * gst_element_connect_elements:
+ * @src: element containing source pad
+ * @dest: element containing destination pad
+ *
+ * Connect the source to the destination element.
+ * The connection must be from source to destination, the other
+ * direction will not be tried.
+ * The functions looks for existing pads and request pads that aren't
+ * connected yet. If multiple connections are possible, only one is
+ * established.
+ *
+ * Return: TRUE if the elements could be connected.
+ */
+gboolean
+gst_element_connect_elements (GstElement *src, GstElement *dest)
+{
+  return gst_element_connect_elements_filtered (src, dest, NULL);
+}
+/**
  * gst_element_connect_filtered:
  * @src: element containing source pad
  * @srcpadname: name of pad in source element
index 0c0c000..302be82 100644 (file)
@@ -199,7 +199,14 @@ void                       gst_element_remove_ghost_pad    (GstElement *element, GstPad *pad);
 
 GstPad*                        gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ);
 GstPad*                        gst_element_request_pad_by_name (GstElement *element, const gchar *name);
+GstPad*                        gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad, 
+                                                        GstCaps *filtercaps);
+GstPad*                        gst_element_get_compatible_pad  (GstElement *element, GstPad *pad);
 
+/* these functions should probably have another name, but gst_element_connect is already used */
+gboolean               gst_element_connect_elements    (GstElement *src, GstElement *dest);
+gboolean               gst_element_connect_elements_filtered (GstElement *src, GstElement *dest,
+                                                        GstCaps *filtercaps);
 gboolean               gst_element_connect             (GstElement *src, const gchar *srcpadname,
                                                         GstElement *dest, const gchar *destpadname);
 gboolean               gst_element_connect_filtered    (GstElement *src, const gchar *srcpadname,
index fc77e61..5951aee 100644 (file)
@@ -574,6 +574,76 @@ gst_pad_disconnect (GstPad *srcpad,
 }
 
 /**
+ * gst_pad_can_connect_filtered:
+ * @srcpad: the source pad to connect
+ * @sinkpad: the sink pad to connect
+ * @filtercaps: the filter caps.
+ *
+ * Checks if the source pad and the sink pad can be connected. 
+ * The filter indicates the media type that should flow trought this connection.
+ *
+ * Returns: TRUE if the pad can be connected, FALSE otherwise
+ */
+gboolean
+gst_pad_can_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
+{
+  gint num_decoupled = 0;
+  GstRealPad *realsrc, *realsink;
+
+  /* generic checks */
+  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);
+
+  /* now we need to deal with the real/ghost stuff */
+  realsrc = GST_PAD_REALIZE (srcpad);
+  realsink = GST_PAD_REALIZE (sinkpad);
+
+  g_return_val_if_fail (GST_RPAD_PEER (realsrc) == NULL, FALSE);
+  g_return_val_if_fail (GST_RPAD_PEER (realsink) == NULL, FALSE);
+  g_return_val_if_fail (GST_PAD_PARENT (realsrc) != NULL, FALSE);
+  g_return_val_if_fail (GST_PAD_PARENT (realsink) != NULL, FALSE);
+
+  if (realsrc->sched && realsink->sched) {
+    if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsrc), GST_ELEMENT_DECOUPLED))
+      num_decoupled++;
+    if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsink), GST_ELEMENT_DECOUPLED))
+      num_decoupled++;
+
+    if (realsrc->sched != realsink->sched && num_decoupled != 1) {
+      g_warning ("connecting pads with different scheds requires exactly one decoupled element (queue)\n");
+      return FALSE;
+    }
+  }
+  
+  /* check if the directions are compatible */
+  if (!(((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
+         (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) ||
+        ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
+         (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK))))
+  {
+    return FALSE;
+  }
+  
+  return TRUE;
+}
+/**
+ * gst_pad_can_connect:
+ * @srcpad: the source pad to connect
+ * @sinkpad: the sink pad to connect
+ *
+ * Checks if the source pad can be connected to the sink pad.
+ *
+ * Returns: TRUE if the pads can be connected, FALSE otherwise
+ */
+gboolean
+gst_pad_can_connect (GstPad *srcpad, GstPad *sinkpad)
+{
+  return gst_pad_can_connect_filtered (srcpad, sinkpad, NULL);
+}
+
+/**
  * gst_pad_connect_filtered:
  * @srcpad: the source pad to connect
  * @sinkpad: the sink pad to connect
index 22fdcf2..067c088 100644 (file)
@@ -385,6 +385,9 @@ GstPad*                     gst_pad_get_peer                        (GstPad *pad);
 
 GstBufferPool*         gst_pad_get_bufferpool                  (GstPad *pad);
 
+gboolean                gst_pad_can_connect                            (GstPad *srcpad, GstPad *sinkpad);
+gboolean                gst_pad_can_connect_filtered                   (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps);
+
 gboolean                gst_pad_connect                        (GstPad *srcpad, GstPad *sinkpad);
 gboolean                gst_pad_connect_filtered                       (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps);
 void                   gst_pad_disconnect                      (GstPad *srcpad, GstPad *sinkpad);