Added mthodes to request an element to create pads: gst_element_request_pad*
authorWim Taymans <wim.taymans@gmail.com>
Thu, 18 Jan 2001 23:46:15 +0000 (23:46 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Thu, 18 Jan 2001 23:46:15 +0000 (23:46 +0000)
Original commit message from CVS:
Added mthodes to request an element to create pads: gst_element_request_pad*
This can be used to construct a tee and a muxer/mixer/aggregator element.
Moved the tee element to elements/ because it can now be handled with the
new pad request features.
The padfactory also has some changes: a pad can now be of presence REQUEST,
which means that the pad can be requested from this plugin (doh).

16 files changed:
gst/Makefile.am
gst/elements/Makefile.am
gst/elements/gstelements.c
gst/elements/gsttee.c [new file with mode: 0644]
gst/elements/gsttee.h [moved from gst/gsttee.h with 91% similarity]
gst/gst.c
gst/gst.h
gst/gstelement.c
gst/gstelement.h
gst/gstpad.c
gst/gstpad.h
gst/gsttee.c [deleted file]
plugins/elements/Makefile.am
plugins/elements/gstelements.c
plugins/elements/gsttee.c [new file with mode: 0644]
plugins/elements/gsttee.h [new file with mode: 0644]

index 94aadce..607ab9e 100644 (file)
@@ -33,7 +33,6 @@ libgst_la_SOURCES =           \
        gstplugin.c             \
        gstprops.c              \
        gstscheduler.c          \
-       gsttee.c                \
        gstthread.c             \
        gsttrace.c              \
        gsttype.c               \
@@ -88,7 +87,6 @@ libgstinclude_HEADERS =               \
        gstplugin.h             \
        gstprops.h              \
        gstscheduler.h          \
-       gsttee.h                \
        gstthread.h             \
        gsttrace.h              \
        gsttype.h               \
index 2078a21..3a14027 100644 (file)
@@ -22,6 +22,7 @@ libgstelements_la_SOURCES =   \
        gstfdsink.c             \
        gstpipefilter.c         \
        gstqueue.c              \
+       gsttee.c                \
        gsttypefind.c           \
        gstsinesrc.c            \
        $(GSTHTTPSRC)
@@ -39,6 +40,7 @@ noinst_HEADERS =              \
        gstfdsink.h             \
        gstpipefilter.h         \
        gstqueue.h              \
+       gsttee.h                \
        gsttypefind.h           \
        gstsinesrc.h
 
index 15091a0..da7c0f6 100644 (file)
 
 #include <gst/gst.h>
 
-#include <gstasyncdisksrc.h>
-#include <gstaudiosink.h>
-#include <gstaudiosrc.h>
-#include <gstdisksrc.h>
-#include <gstidentity.h>
-#include <gstfakesink.h>
-#include <gstfakesrc.h>
-#include <gstfdsink.h>
-#include <gstfdsrc.h>
-#include <gstpipefilter.h>
-#include <gstqueue.h>
-#include <gstsinesrc.h>
-#include <gsttypefind.h>
+#include "gstasyncdisksrc.h"
+#include "gstaudiosink.h"
+#include "gstaudiosrc.h"
+#include "gstdisksrc.h"
+#include "gstidentity.h"
+#include "gstfakesink.h"
+#include "gstfakesrc.h"
+#include "gstfdsink.h"
+#include "gstfdsrc.h"
+#include "gstpipefilter.h"
+#include "gstqueue.h"
+#include "gstsinesrc.h"
+#include "gsttee.h"
+#include "gsttypefind.h"
 
 #if HAVE_LIBGHTTP
 #include <gsthttpsrc.h>
@@ -62,6 +63,7 @@ static struct _elements_entry _elements[] = {
   { "pipefilter",   gst_pipefilter_get_type,   &gst_pipefilter_details,   NULL },
   { "queue",       gst_queue_get_type,         &gst_queue_details,        NULL },
   { "sinesrc",             gst_sinesrc_get_type,       &gst_sinesrc_details,      NULL },
+  { "tee",                 gst_tee_get_type,           &gst_tee_details,          gst_tee_factory_init },
   { "typefind",     gst_typefind_get_type,     &gst_typefind_details,     NULL },
 
 #if HAVE_LIBGHTTP
diff --git a/gst/elements/gsttee.c b/gst/elements/gsttee.c
new file mode 100644 (file)
index 0000000..ffb0ed0
--- /dev/null
@@ -0,0 +1,205 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wim.taymans@chello.be>
+ *
+ * gsttee.c: Tee element, one in N out
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gsttee.h"
+
+
+GstElementDetails gst_tee_details = {
+  "Tee pipe fitting",
+  "Tee",
+  "1-to-N pipe fitting",
+  VERSION,
+  "Erik Walthinsen <omega@cse.ogi.edu>\n"
+  "Wim Taymans <wim.taymans@chello.be>",
+  "(C) 1999, 2000",
+};
+
+/* Tee signals and args */
+enum {
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  ARG_NUM_PADS,
+  /* FILL ME */
+};
+
+static GstPadFactory tee_src_factory = {
+  "src%d",
+  GST_PAD_FACTORY_SRC,
+  GST_PAD_FACTORY_REQUEST,
+  NULL,                        /* no caps */
+  NULL,
+};
+
+
+static void    gst_tee_class_init      (GstTeeClass *klass);
+static void    gst_tee_init            (GstTee *tee);
+
+static GstPad*         gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp);
+
+static void    gst_tee_get_arg         (GtkObject *object, GtkArg *arg, guint id);
+
+static void    gst_tee_chain           (GstPad *pad, GstBuffer *buf);
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_tee_signals[LAST_SIGNAL] = { 0 };
+static GstPadTemplate *gst_tee_src_template;
+
+GtkType
+gst_tee_get_type(void) {
+  static GtkType tee_type = 0;
+
+  if (!tee_type) {
+    static const GtkTypeInfo tee_info = {
+      "GstTee",
+      sizeof(GstTee),
+      sizeof(GstTeeClass),
+      (GtkClassInitFunc)gst_tee_class_init,
+      (GtkObjectInitFunc)gst_tee_init,
+      (GtkArgSetFunc)NULL,
+      (GtkArgGetFunc)NULL,
+      (GtkClassInitFunc)NULL,
+    };
+    tee_type = gtk_type_unique (GST_TYPE_ELEMENT, &tee_info);
+  }
+  return tee_type;
+}
+
+static void
+gst_tee_class_init (GstTeeClass *klass) 
+{
+  GtkObjectClass *gtkobject_class;
+  GstElementClass *gstelement_class;
+
+  gtkobject_class = (GtkObjectClass*)klass;
+  gstelement_class = (GstElementClass*)klass;
+
+  parent_class = gtk_type_class(GST_TYPE_ELEMENT);
+
+  gtk_object_add_arg_type ("GstTee::num_pads", GTK_TYPE_INT,
+                            GTK_ARG_READABLE, ARG_NUM_PADS);
+
+  gtkobject_class->get_arg = gst_tee_get_arg;
+
+  gstelement_class->request_new_pad = gst_tee_request_new_pad;
+}
+
+static void 
+gst_tee_init (GstTee *tee) 
+{
+  tee->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
+  gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad);
+  gst_pad_set_chain_function (tee->sinkpad, gst_tee_chain);
+
+  tee->numsrcpads = 0;
+  tee->srcpads = NULL;
+}
+
+static GstPad*
+gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ) 
+{
+  gchar *name;
+  GstPad *srcpad;
+  GstTee *tee;
+
+  g_return_val_if_fail (GST_IS_TEE (element), NULL);
+
+  if (templ->direction != GST_PAD_SRC) {
+    g_warning ("gsttee: request new pad that is not a SRC pad\n");
+    return NULL;
+  }
+
+  tee = GST_TEE (element);
+
+  name = g_strdup_printf ("src%d",tee->numsrcpads);
+  
+  srcpad = gst_pad_new_from_template (templ, name);
+  gst_element_add_pad (GST_ELEMENT (tee), srcpad);
+  
+  tee->srcpads = g_slist_prepend (tee->srcpads, srcpad);
+  tee->numsrcpads++;
+  
+  return srcpad;
+}
+
+static void
+gst_tee_get_arg (GtkObject *object, GtkArg *arg, guint id)
+{
+  GstTee *tee;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_TEE (object));
+
+  tee = GST_TEE (object);
+
+  switch(id) {
+    case ARG_NUM_PADS:
+      GTK_VALUE_INT (*arg) = tee->numsrcpads;
+      break;
+    default:
+      break;
+  }
+}
+
+/**
+ * gst_tee_chain:
+ * @pad: the pad to follow
+ * @buf: the buffer to pass
+ *
+ * Chain a buffer on a pad.
+ */
+static void 
+gst_tee_chain (GstPad *pad, GstBuffer *buf) 
+{
+  GstTee *tee;
+  GSList *srcpads;
+  int i;
+
+  g_return_if_fail (pad != NULL);
+  g_return_if_fail (GST_IS_PAD (pad));
+  g_return_if_fail (buf != NULL);
+
+  tee = GST_TEE (pad->parent);
+  gst_trace_add_entry (NULL, 0, buf, "tee buffer");
+
+  for (i=0; i<tee->numsrcpads-1; i++)
+    gst_buffer_ref (buf);
+  
+  srcpads = tee->srcpads;
+  while (srcpads) {
+    gst_pad_push (GST_PAD (srcpads->data), buf);
+    srcpads = g_slist_next (srcpads);
+  }
+}
+
+gboolean
+gst_tee_factory_init (GstElementFactory *factory)
+{
+  gst_tee_src_template = gst_padtemplate_new (&tee_src_factory);
+  gst_elementfactory_add_padtemplate (factory, gst_tee_src_template);
+
+  return TRUE;
+}
+
similarity index 91%
rename from gst/gsttee.h
rename to gst/elements/gsttee.h
index 3d9a90a..f7f3979 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef __GST_TEE_H__
 #define __GST_TEE_H__
 
-#include "gstelement.h"
+#include <gst/gst.h>
 
 
 #ifdef __cplusplus
@@ -62,10 +62,7 @@ struct _GstTeeClass {
 
 GtkType        gst_tee_get_type        (void);
 
-GstElement*    gst_tee_new             (gchar *name);
-
-gchar*         gst_tee_new_pad         (GstTee *tee);
-void           gst_tee_chain           (GstPad *pad, GstBuffer *buf);
+gboolean       gst_tee_factory_init    (GstElementFactory *factory);
 
 #ifdef __cplusplus
 }
index 633fba5..1b98c5d 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -31,7 +31,6 @@
 #include "gstbin.h"
 #include "gstpipeline.h"
 #include "gstthread.h"
-#include "gsttee.h"
 
 
 
@@ -77,7 +76,6 @@ gst_init (int *argc, char **argv[])
   gst_elementfactory_new ("bin", gst_bin_get_type (), &gst_bin_details);
   gst_elementfactory_new ("pipeline", gst_pipeline_get_type (), &gst_pipeline_details);
   gst_elementfactory_new ("thread", gst_thread_get_type (), &gst_thread_details);
-  gst_elementfactory_new ("tee", gst_tee_get_type (), &gst_tee_details);
 
   _gst_trace_on = 0;
   if (_gst_trace_on) {
index a47b2e2..a2d98c6 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -45,7 +45,6 @@
 #include <gst/gstutils.h>
 #include <gst/gsttrace.h>
 #include <gst/gstxml.h>
-#include <gst/gsttee.h>
 #include <gst/cothreads.h>
 
 #include <gst/gstparse.h>
index 31c4cb2..5f24ac9 100644 (file)
@@ -304,6 +304,75 @@ gst_element_get_padtemplate_list (GstElement *element)
 }
 
 /**
+ * gst_element_get_padtemplate_by_name:
+ * @element: element to get padtemplate of
+ * @name: the name of the padtemplate to get.
+ *
+ * Retrieve a padtemplate from this element with the
+ * given name.
+ *
+ * Returns: the padtemplate with the given name
+ */
+GstPadTemplate*
+gst_element_get_padtemplate_by_name (GstElement *element, const guchar *name)
+{
+  GList *padlist;
+
+  g_return_val_if_fail (element != NULL, NULL);
+  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+
+  padlist = gst_element_get_padtemplate_list (element);
+
+  while (padlist) {
+    GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
+
+    if (!strcmp (padtempl->name_template, name))
+      return padtempl;
+       
+    padlist = g_list_next (padlist);
+  }
+
+  return NULL;
+}
+
+GstPad*
+gst_element_request_pad (GstElement *element, GstPadTemplate *temp)
+{
+  GstPad *newpad = NULL;
+  GstElementClass *oclass;
+
+  g_return_val_if_fail (element != NULL, NULL);
+  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+  g_return_val_if_fail (temp != NULL, NULL);
+
+  /* call the state change function so it can set the state */
+  oclass = GST_ELEMENT_CLASS (GTK_OBJECT (element)->klass);
+  if (oclass->request_new_pad)
+    newpad = (oclass->request_new_pad)(element, temp);
+
+  return newpad; 
+}
+
+GstPad*
+gst_element_request_pad_by_name (GstElement *element, const gchar *name)
+{
+  GstPadTemplate *templ;
+  GstPad *pad;
+
+  g_return_val_if_fail (element != NULL, NULL);
+  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+
+  templ = gst_element_get_padtemplate_by_name (element, name);
+  g_return_val_if_fail (templ != NULL, NULL);
+
+  pad = gst_element_request_pad (element, templ);
+
+  return pad;
+}
+
+/**
  * gst_element_connect:
  * @src: element containing source pad
  * @srcpadname: name of pad in source element
index 28e739e..7f463a3 100644 (file)
@@ -158,7 +158,9 @@ struct _GstElementClass {
   void (*eos)          (GstElement *element);
 
   /* change the element state */
-  GstElementStateReturn (*change_state) (GstElement *element);
+  GstElementStateReturn (*change_state)        (GstElement *element);
+  /* request a new pad */
+  GstPad*              (*request_new_pad)      (GstElement *element, GstPadTemplate *temp);
 
   /* create or read XML representation of self */
   xmlNodePtr   (*save_thyself)         (GstElement *element, xmlNodePtr parent);
@@ -201,9 +203,13 @@ void                       gst_element_add_pad             (GstElement *element, GstPad *pad);
 GstPad*                        gst_element_get_pad             (GstElement *element, const gchar *name);
 GList*                 gst_element_get_pad_list        (GstElement *element);
 GList*                 gst_element_get_padtemplate_list        (GstElement *element);
+GstPadTemplate*                gst_element_get_padtemplate_by_name     (GstElement *element, const guchar *name);
 void                   gst_element_add_ghost_pad       (GstElement *element, GstPad *pad);
 void                   gst_element_remove_ghost_pad    (GstElement *element, GstPad *pad);
 
+GstPad*                        gst_element_request_pad         (GstElement *element, GstPadTemplate *temp);
+GstPad*                        gst_element_request_pad_by_name (GstElement *element, const gchar *name);
+
 void                   gst_element_connect             (GstElement *src, const gchar *srcpadname,
                                                         GstElement *dest, const gchar *destpadname);
 void                   gst_element_disconnect          (GstElement *src, const gchar *srcpadname,
@@ -234,12 +240,12 @@ GstElementFactory*        gst_elementfactory_new                  (const gchar *name,GtkType type,
                                                                 GstElementDetails *details);
 void                   gst_elementfactory_destroy              (GstElementFactory *elementfactory);
 
-void                   gst_elementfactory_add_padtemplate      (GstElementFactory *elementfactory, 
-                                                                GstPadTemplate *temp);
-
 GstElementFactory*     gst_elementfactory_find                 (const gchar *name);
 GList*                 gst_elementfactory_get_list             (void);
 
+void                   gst_elementfactory_add_padtemplate      (GstElementFactory *elementfactory, 
+                                                                GstPadTemplate *temp);
+
 gboolean               gst_elementfactory_can_src_caps         (GstElementFactory *factory,
                                                                 GstCaps *caps);
 gboolean               gst_elementfactory_can_sink_caps        (GstElementFactory *factory,
index b2ce44f..727988e 100644 (file)
@@ -977,10 +977,26 @@ gst_padtemplate_save_thyself (GstPadTemplate *pad, xmlNodePtr parent)
 {
   xmlNodePtr subtree;
   GList *caps;
+  guchar *presence;
 
   xmlNewChild(parent,NULL,"nametemplate", pad->name_template);
   xmlNewChild(parent,NULL,"direction", (pad->direction == GST_PAD_SINK? "sink":"src"));
-  xmlNewChild(parent,NULL,"presence", (pad->presence == GST_PAD_ALWAYS? "always":"sometimes"));
+
+  switch (pad->presence) {
+    case GST_PAD_ALWAYS:
+      presence = "always";
+      break;
+    case GST_PAD_SOMETIMES:
+      presence = "sometimes";
+      break;
+    case GST_PAD_REQUEST:
+      presence = "request";
+      break;
+    default:
+      presence = "unknown";
+      break;
+  }
+  xmlNewChild(parent,NULL,"presence", presence);
 
   caps = pad->caps;
   while (caps) {
@@ -1034,6 +1050,9 @@ gst_padtemplate_load_thyself (xmlNodePtr parent)
       else if (!strcmp(value, "sometimes")) {
         factory->presence = GST_PAD_SOMETIMES;
       }
+      else if (!strcmp(value, "request")) {
+        factory->presence = GST_PAD_REQUEST;
+      }
       g_free (value);
     }
     else if (!strcmp(field->name, "caps")) {
index d3e0008..795eed1 100644 (file)
@@ -137,6 +137,7 @@ struct _GstPadClass {
 typedef enum {
   GST_PAD_ALWAYS,
   GST_PAD_SOMETIMES,
+  GST_PAD_REQUEST,
 } GstPadPresence;
 
 struct _GstPadTemplate {
@@ -162,6 +163,7 @@ typedef GstPadFactoryEntry GstPadFactory[];
 
 #define GST_PAD_FACTORY_ALWAYS                 GINT_TO_POINTER(GST_PAD_ALWAYS)
 #define GST_PAD_FACTORY_SOMETIMES      GINT_TO_POINTER(GST_PAD_SOMETIMES)
+#define GST_PAD_FACTORY_REQUEST        GINT_TO_POINTER(GST_PAD_REQUEST)
 
 #define GST_PAD_FACTORY_SRC            GINT_TO_POINTER(GST_PAD_SRC)
 #define GST_PAD_FACTORY_SINK           GINT_TO_POINTER(GST_PAD_SINK)
diff --git a/gst/gsttee.c b/gst/gsttee.c
deleted file mode 100644 (file)
index be5ed02..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/* GStreamer
- * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- *                    2000 Wim Taymans <wtay@chello.be>
- *
- * gsttee.c: Tee element, one in N out
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "gst_private.h"
-
-#include "gsttee.h"
-
-
-GstElementDetails gst_tee_details = {
-  "Tee pipe fitting",
-  "Tee",
-  "1-to-N pipe fitting",
-  VERSION,
-  "Erik Walthinsen <omega@cse.ogi.edu>",
-  "(C) 1999",
-};
-
-/* Tee signals and args */
-enum {
-  /* FILL ME */
-  LAST_SIGNAL
-};
-
-enum {
-  ARG_0,
-  /* FILL ME */
-};
-
-
-static void gst_tee_class_init(GstTeeClass *klass);
-static void gst_tee_init(GstTee *tee);
-
-//static xmlNodePtr gst_tee_save_thyself(GstElement *element,xmlNodePtr parent);
-
-static GstElementClass *parent_class = NULL;
-//static guint gst_tee_signals[LAST_SIGNAL] = { 0 };
-
-GtkType
-gst_tee_get_type(void) {
-  static GtkType tee_type = 0;
-
-  if (!tee_type) {
-    static const GtkTypeInfo tee_info = {
-      "GstTee",
-      sizeof(GstTee),
-      sizeof(GstTeeClass),
-      (GtkClassInitFunc)gst_tee_class_init,
-      (GtkObjectInitFunc)gst_tee_init,
-      (GtkArgSetFunc)NULL,
-      (GtkArgGetFunc)NULL,
-      (GtkClassInitFunc)NULL,
-    };
-    tee_type = gtk_type_unique(GST_TYPE_ELEMENT,&tee_info);
-  }
-  return tee_type;
-}
-
-static void
-gst_tee_class_init(GstTeeClass *klass) {
-  GstElementClass *gstelement_class;
-
-  gstelement_class = (GstElementClass*)klass;
-
-  parent_class = gtk_type_class(GST_TYPE_ELEMENT);
-}
-
-static void gst_tee_init(GstTee *tee) {
-  tee->sinkpad = gst_pad_new("sink",GST_PAD_SINK);
-  gst_element_add_pad(GST_ELEMENT(tee),tee->sinkpad);
-  gst_pad_set_chain_function(tee->sinkpad,gst_tee_chain);
-
-  tee->numsrcpads = 0;
-  tee->srcpads = NULL;
-}
-
-/**
- * gst_tee_new:
- * @name: the name of the new tee
- *
- * Create a new tee element.
- *
- * Returns: the new tee element
- */
-GstElement *gst_tee_new(gchar *name) {
-  return gst_elementfactory_make ("tee", name);
-}
-
-/**
- * gst_tee_new_pad:
- * @tee: the tee to create the new pad on
- *
- * Create a new pad on a given tee.
- *
- * Returns: the name of the new pad
- */
-gchar *gst_tee_new_pad(GstTee *tee) {
-  gchar *name;
-  GstPad *srcpad;
-
-  g_return_val_if_fail(tee != NULL, NULL);
-  g_return_val_if_fail(GST_IS_TEE(tee), NULL);
-
-  name = g_strdup_printf("src%d",tee->numsrcpads);
-  srcpad = gst_pad_new(name,GST_PAD_SRC);
-  gst_element_add_pad(GST_ELEMENT(tee),srcpad);
-  tee->srcpads = g_slist_prepend(tee->srcpads,srcpad);
-  tee->numsrcpads++;
-  return name;
-}
-
-/**
- * gst_tee_chain:
- * @pad: the pad to follow
- * @buf: the buffer to pass
- *
- * Chain a buffer on a pad.
- */
-void gst_tee_chain(GstPad *pad,GstBuffer *buf) {
-  GstTee *tee;
-  GSList *srcpads;
-  int i;
-
-  g_return_if_fail(pad != NULL);
-  g_return_if_fail(GST_IS_PAD(pad));
-  g_return_if_fail(buf != NULL);
-
-  tee = GST_TEE(pad->parent);
-  gst_trace_add_entry(NULL,0,buf,"tee buffer");
-  for (i=0;i<tee->numsrcpads-1;i++)
-    gst_buffer_ref(buf);
-  srcpads = tee->srcpads;
-  while (srcpads) {
-    gst_pad_push(GST_PAD(srcpads->data),buf);
-    srcpads = g_slist_next(srcpads);
-  }
-}
index 2078a21..3a14027 100644 (file)
@@ -22,6 +22,7 @@ libgstelements_la_SOURCES =   \
        gstfdsink.c             \
        gstpipefilter.c         \
        gstqueue.c              \
+       gsttee.c                \
        gsttypefind.c           \
        gstsinesrc.c            \
        $(GSTHTTPSRC)
@@ -39,6 +40,7 @@ noinst_HEADERS =              \
        gstfdsink.h             \
        gstpipefilter.h         \
        gstqueue.h              \
+       gsttee.h                \
        gsttypefind.h           \
        gstsinesrc.h
 
index 15091a0..da7c0f6 100644 (file)
 
 #include <gst/gst.h>
 
-#include <gstasyncdisksrc.h>
-#include <gstaudiosink.h>
-#include <gstaudiosrc.h>
-#include <gstdisksrc.h>
-#include <gstidentity.h>
-#include <gstfakesink.h>
-#include <gstfakesrc.h>
-#include <gstfdsink.h>
-#include <gstfdsrc.h>
-#include <gstpipefilter.h>
-#include <gstqueue.h>
-#include <gstsinesrc.h>
-#include <gsttypefind.h>
+#include "gstasyncdisksrc.h"
+#include "gstaudiosink.h"
+#include "gstaudiosrc.h"
+#include "gstdisksrc.h"
+#include "gstidentity.h"
+#include "gstfakesink.h"
+#include "gstfakesrc.h"
+#include "gstfdsink.h"
+#include "gstfdsrc.h"
+#include "gstpipefilter.h"
+#include "gstqueue.h"
+#include "gstsinesrc.h"
+#include "gsttee.h"
+#include "gsttypefind.h"
 
 #if HAVE_LIBGHTTP
 #include <gsthttpsrc.h>
@@ -62,6 +63,7 @@ static struct _elements_entry _elements[] = {
   { "pipefilter",   gst_pipefilter_get_type,   &gst_pipefilter_details,   NULL },
   { "queue",       gst_queue_get_type,         &gst_queue_details,        NULL },
   { "sinesrc",             gst_sinesrc_get_type,       &gst_sinesrc_details,      NULL },
+  { "tee",                 gst_tee_get_type,           &gst_tee_details,          gst_tee_factory_init },
   { "typefind",     gst_typefind_get_type,     &gst_typefind_details,     NULL },
 
 #if HAVE_LIBGHTTP
diff --git a/plugins/elements/gsttee.c b/plugins/elements/gsttee.c
new file mode 100644 (file)
index 0000000..ffb0ed0
--- /dev/null
@@ -0,0 +1,205 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wim.taymans@chello.be>
+ *
+ * gsttee.c: Tee element, one in N out
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gsttee.h"
+
+
+GstElementDetails gst_tee_details = {
+  "Tee pipe fitting",
+  "Tee",
+  "1-to-N pipe fitting",
+  VERSION,
+  "Erik Walthinsen <omega@cse.ogi.edu>\n"
+  "Wim Taymans <wim.taymans@chello.be>",
+  "(C) 1999, 2000",
+};
+
+/* Tee signals and args */
+enum {
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  ARG_NUM_PADS,
+  /* FILL ME */
+};
+
+static GstPadFactory tee_src_factory = {
+  "src%d",
+  GST_PAD_FACTORY_SRC,
+  GST_PAD_FACTORY_REQUEST,
+  NULL,                        /* no caps */
+  NULL,
+};
+
+
+static void    gst_tee_class_init      (GstTeeClass *klass);
+static void    gst_tee_init            (GstTee *tee);
+
+static GstPad*         gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp);
+
+static void    gst_tee_get_arg         (GtkObject *object, GtkArg *arg, guint id);
+
+static void    gst_tee_chain           (GstPad *pad, GstBuffer *buf);
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_tee_signals[LAST_SIGNAL] = { 0 };
+static GstPadTemplate *gst_tee_src_template;
+
+GtkType
+gst_tee_get_type(void) {
+  static GtkType tee_type = 0;
+
+  if (!tee_type) {
+    static const GtkTypeInfo tee_info = {
+      "GstTee",
+      sizeof(GstTee),
+      sizeof(GstTeeClass),
+      (GtkClassInitFunc)gst_tee_class_init,
+      (GtkObjectInitFunc)gst_tee_init,
+      (GtkArgSetFunc)NULL,
+      (GtkArgGetFunc)NULL,
+      (GtkClassInitFunc)NULL,
+    };
+    tee_type = gtk_type_unique (GST_TYPE_ELEMENT, &tee_info);
+  }
+  return tee_type;
+}
+
+static void
+gst_tee_class_init (GstTeeClass *klass) 
+{
+  GtkObjectClass *gtkobject_class;
+  GstElementClass *gstelement_class;
+
+  gtkobject_class = (GtkObjectClass*)klass;
+  gstelement_class = (GstElementClass*)klass;
+
+  parent_class = gtk_type_class(GST_TYPE_ELEMENT);
+
+  gtk_object_add_arg_type ("GstTee::num_pads", GTK_TYPE_INT,
+                            GTK_ARG_READABLE, ARG_NUM_PADS);
+
+  gtkobject_class->get_arg = gst_tee_get_arg;
+
+  gstelement_class->request_new_pad = gst_tee_request_new_pad;
+}
+
+static void 
+gst_tee_init (GstTee *tee) 
+{
+  tee->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
+  gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad);
+  gst_pad_set_chain_function (tee->sinkpad, gst_tee_chain);
+
+  tee->numsrcpads = 0;
+  tee->srcpads = NULL;
+}
+
+static GstPad*
+gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ) 
+{
+  gchar *name;
+  GstPad *srcpad;
+  GstTee *tee;
+
+  g_return_val_if_fail (GST_IS_TEE (element), NULL);
+
+  if (templ->direction != GST_PAD_SRC) {
+    g_warning ("gsttee: request new pad that is not a SRC pad\n");
+    return NULL;
+  }
+
+  tee = GST_TEE (element);
+
+  name = g_strdup_printf ("src%d",tee->numsrcpads);
+  
+  srcpad = gst_pad_new_from_template (templ, name);
+  gst_element_add_pad (GST_ELEMENT (tee), srcpad);
+  
+  tee->srcpads = g_slist_prepend (tee->srcpads, srcpad);
+  tee->numsrcpads++;
+  
+  return srcpad;
+}
+
+static void
+gst_tee_get_arg (GtkObject *object, GtkArg *arg, guint id)
+{
+  GstTee *tee;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_TEE (object));
+
+  tee = GST_TEE (object);
+
+  switch(id) {
+    case ARG_NUM_PADS:
+      GTK_VALUE_INT (*arg) = tee->numsrcpads;
+      break;
+    default:
+      break;
+  }
+}
+
+/**
+ * gst_tee_chain:
+ * @pad: the pad to follow
+ * @buf: the buffer to pass
+ *
+ * Chain a buffer on a pad.
+ */
+static void 
+gst_tee_chain (GstPad *pad, GstBuffer *buf) 
+{
+  GstTee *tee;
+  GSList *srcpads;
+  int i;
+
+  g_return_if_fail (pad != NULL);
+  g_return_if_fail (GST_IS_PAD (pad));
+  g_return_if_fail (buf != NULL);
+
+  tee = GST_TEE (pad->parent);
+  gst_trace_add_entry (NULL, 0, buf, "tee buffer");
+
+  for (i=0; i<tee->numsrcpads-1; i++)
+    gst_buffer_ref (buf);
+  
+  srcpads = tee->srcpads;
+  while (srcpads) {
+    gst_pad_push (GST_PAD (srcpads->data), buf);
+    srcpads = g_slist_next (srcpads);
+  }
+}
+
+gboolean
+gst_tee_factory_init (GstElementFactory *factory)
+{
+  gst_tee_src_template = gst_padtemplate_new (&tee_src_factory);
+  gst_elementfactory_add_padtemplate (factory, gst_tee_src_template);
+
+  return TRUE;
+}
+
diff --git a/plugins/elements/gsttee.h b/plugins/elements/gsttee.h
new file mode 100644 (file)
index 0000000..f7f3979
--- /dev/null
@@ -0,0 +1,72 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gsttee.h: Header for GstTee element
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_TEE_H__
+#define __GST_TEE_H__
+
+#include <gst/gst.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+extern GstElementDetails gst_tee_details;
+
+#define GST_TYPE_TEE \
+  (gst_tee_get_type())
+#define GST_TEE(obj) \
+  (GTK_CHECK_CAST((obj),GST_TYPE_TEE,GstTee))
+#define GST_TEE_CLASS(klass) \
+  (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_TEE,GstTeeClass))
+#define GST_IS_TEE(obj) \
+  (GTK_CHECK_TYPE((obj),GST_TYPE_TEE))
+#define GST_IS_TEE_CLASS(obj) \
+  (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_TEE))
+
+typedef struct _GstTee                 GstTee;
+typedef struct _GstTeeClass    GstTeeClass;
+
+struct _GstTee {
+  GstElement element;
+
+  GstPad *sinkpad;
+
+  gint numsrcpads;
+  GSList *srcpads;
+};
+
+struct _GstTeeClass {
+  GstElementClass parent_class;
+};
+
+GtkType        gst_tee_get_type        (void);
+
+gboolean       gst_tee_factory_init    (GstElementFactory *factory);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_TEE_H__ */