mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
Added mthodes to request an element to create pads: gst_element_request_pad*
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).
This commit is contained in:
parent
82769bcae9
commit
90f82b6840
16 changed files with 619 additions and 196 deletions
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -23,19 +23,20 @@
|
|||
|
||||
#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
|
||||
|
|
205
gst/elements/gsttee.c
Normal file
205
gst/elements/gsttee.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -303,6 +303,75 @@ gst_element_get_padtemplate_list (GstElement *element)
|
|||
return oclass->elementfactory->padtemplates;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -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,
|
||||
|
|
21
gst/gstpad.c
21
gst/gstpad.c
|
@ -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")) {
|
||||
|
|
|
@ -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)
|
||||
|
|
155
gst/gsttee.c
155
gst/gsttee.c
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -23,19 +23,20 @@
|
|||
|
||||
#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
|
||||
|
|
205
plugins/elements/gsttee.c
Normal file
205
plugins/elements/gsttee.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
72
plugins/elements/gsttee.h
Normal file
72
plugins/elements/gsttee.h
Normal file
|
@ -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__ */
|
Loading…
Reference in a new issue