gstplugin.c \
gstprops.c \
gstscheduler.c \
- gsttee.c \
gstthread.c \
gsttrace.c \
gsttype.c \
gstplugin.h \
gstprops.h \
gstscheduler.h \
- gsttee.h \
gstthread.h \
gsttrace.h \
gsttype.h \
gstfdsink.c \
gstpipefilter.c \
gstqueue.c \
+ gsttee.c \
gsttypefind.c \
gstsinesrc.c \
$(GSTHTTPSRC)
gstfdsink.h \
gstpipefilter.h \
gstqueue.h \
+ gsttee.h \
gsttypefind.h \
gstsinesrc.h
#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>
{ "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
--- /dev/null
+/* 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;
+}
+
#ifndef __GST_TEE_H__
#define __GST_TEE_H__
-#include "gstelement.h"
+#include <gst/gst.h>
#ifdef __cplusplus
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
}
#include "gstbin.h"
#include "gstpipeline.h"
#include "gstthread.h"
-#include "gsttee.h"
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) {
#include <gst/gstutils.h>
#include <gst/gsttrace.h>
#include <gst/gstxml.h>
-#include <gst/gsttee.h>
#include <gst/cothreads.h>
#include <gst/gstparse.h>
}
/**
+ * 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
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);
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,
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,
{
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) {
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")) {
typedef enum {
GST_PAD_ALWAYS,
GST_PAD_SOMETIMES,
+ GST_PAD_REQUEST,
} GstPadPresence;
struct _GstPadTemplate {
#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)
+++ /dev/null
-/* 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);
- }
-}
gstfdsink.c \
gstpipefilter.c \
gstqueue.c \
+ gsttee.c \
gsttypefind.c \
gstsinesrc.c \
$(GSTHTTPSRC)
gstfdsink.h \
gstpipefilter.h \
gstqueue.h \
+ gsttee.h \
gsttypefind.h \
gstsinesrc.h
#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>
{ "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
--- /dev/null
+/* 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;
+}
+
--- /dev/null
+/* 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__ */