diff --git a/gst/elements/gstpipefilter.c b/gst/elements/gstpipefilter.c new file mode 100644 index 0000000000..b054c93e11 --- /dev/null +++ b/gst/elements/gstpipefilter.c @@ -0,0 +1,296 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen + * + * 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 +#include +#include +#include +#include +#include + +//#define DEBUG_ENABLED +#include "gstpipefilter.h" + + +GstElementDetails gst_pipefilter_details = { + "Pipefilter", + "Filter", + "Pass data without modification", + VERSION, + "Erik Walthinsen ", + "(C) 1999", +}; + + +/* Pipefilter signals and args */ +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_CONTROL +}; + + +static void gst_pipefilter_class_init(GstPipefilterClass *klass); +static void gst_pipefilter_init(GstPipefilter *pipefilter); +static void gst_pipefilter_set_arg(GtkObject *object,GtkArg *arg,guint id); +static void gst_pipefilter_get_arg(GtkObject *object,GtkArg *arg,guint id); + +void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf); + +static gboolean gst_pipefilter_change_state(GstElement *element, + GstElementState state); + +static GstFilterClass *parent_class = NULL; +//static guint gst_pipefilter_signals[LAST_SIGNAL] = { 0 }; + +GtkType +gst_pipefilter_get_type(void) { + static GtkType pipefilter_type = 0; + + if (!pipefilter_type) { + static const GtkTypeInfo pipefilter_info = { + "GstPipefilter", + sizeof(GstPipefilter), + sizeof(GstPipefilterClass), + (GtkClassInitFunc)gst_pipefilter_class_init, + (GtkObjectInitFunc)gst_pipefilter_init, + (GtkArgSetFunc)gst_pipefilter_set_arg, + (GtkArgGetFunc)gst_pipefilter_get_arg, + (GtkClassInitFunc)NULL, + }; + pipefilter_type = gtk_type_unique(GST_TYPE_FILTER,&pipefilter_info); + } + return pipefilter_type; +} + +static void gst_pipefilter_class_init(GstPipefilterClass *klass) { + GtkObjectClass *gtkobject_class; + GstFilterClass *gstfilter_class; + GstElementClass *gstelement_class; + + gtkobject_class = (GtkObjectClass*)klass; + gstfilter_class = (GstFilterClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = gtk_type_class(GST_TYPE_FILTER); + + gstelement_class->change_state = gst_pipefilter_change_state; + + //gtk_object_add_arg_type("GstPipefilter::control", GTK_TYPE_INT, + // GTK_ARG_READWRITE, ARG_CONTROL); + + //gtkobject_class->set_arg = gst_pipefilter_set_arg; + //gtkobject_class->get_arg = gst_pipefilter_get_arg; +} + +static void gst_pipefilter_init(GstPipefilter *pipefilter) { + pipefilter->sinkpad = gst_pad_new("sink",GST_PAD_SINK); + gst_element_add_pad(GST_ELEMENT(pipefilter),pipefilter->sinkpad); + gst_pad_set_chain_function(pipefilter->sinkpad,gst_pipefilter_chain); + pipefilter->srcpad = gst_pad_new("src",GST_PAD_SRC); + gst_element_add_pad(GST_ELEMENT(pipefilter),pipefilter->srcpad); + + pipefilter->control = 0; + pipefilter->curoffset = 0; + pipefilter->bytes_per_read = 4096; + pipefilter->seq = 0; +} + +GstElement *gst_pipefilter_new(gchar *name) { + GstElement *pipefilter = GST_ELEMENT(gtk_type_new(GST_TYPE_PIPEFILTER)); + gst_element_set_name(GST_ELEMENT(pipefilter),name); + return pipefilter; +} + +void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) { + GstPipefilter *pipefilter; + GstBuffer *newbuf; + glong readbytes, writebytes; + guchar *data; + gulong size; + + g_return_if_fail(pad != NULL); + g_return_if_fail(GST_IS_PAD(pad)); + g_return_if_fail(buf != NULL); + + pipefilter = GST_PIPEFILTER(pad->parent); + + data = GST_BUFFER_DATA(buf); + size = GST_BUFFER_SIZE(buf); + + DEBUG("attemting to write %d bytes\n", size); + writebytes = write(pipefilter->fdin[1],data,size); + DEBUG("written %d bytes\n", writebytes); + if (writebytes < 0) { + perror("write"); + gst_element_error(GST_ELEMENT(pipefilter),"writing"); + return; + } + gst_buffer_unref(buf); + + + /* create the buffer */ + // FIXME: should eventually use a bufferpool for this + newbuf = gst_buffer_new(); + g_return_if_fail(newbuf); + + /* allocate the space for the buffer data */ + GST_BUFFER_DATA(newbuf) = g_malloc(pipefilter->bytes_per_read); + g_return_if_fail(GST_BUFFER_DATA(newbuf) != NULL); + + /* read it in from the file */ + DEBUG("attemting to read %d bytes\n", pipefilter->bytes_per_read); + readbytes = read(pipefilter->fdout[0],GST_BUFFER_DATA(newbuf),pipefilter->bytes_per_read); + DEBUG("read %d bytes\n", readbytes); + if (readbytes < 0) { + if (errno == EAGAIN) { + DEBUG("no input yet\n"); + gst_buffer_unref(newbuf); + return; + } + else { + perror("read"); + gst_element_error(GST_ELEMENT(pipefilter),"reading"); + return; + } + } + if (readbytes == 0) { + gst_buffer_unref(newbuf); + return; + } + /* if we didn't get as many bytes as we asked for, we're at EOF */ + if (readbytes < pipefilter->bytes_per_read) + GST_BUFFER_FLAG_SET(newbuf,GST_BUFFER_EOS); + GST_BUFFER_OFFSET(newbuf) = pipefilter->curoffset; + GST_BUFFER_SIZE(newbuf) = readbytes; + pipefilter->curoffset += readbytes; + + /* we're done, push the buffer off now */ + gst_pad_push(pipefilter->srcpad,newbuf); +} + +static void gst_pipefilter_set_arg(GtkObject *object,GtkArg *arg,guint id) { + GstPipefilter *pipefilter; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_PIPEFILTER(object)); + pipefilter = GST_PIPEFILTER(object); + + switch(id) { + case ARG_CONTROL: + pipefilter->control = GTK_VALUE_INT(*arg); + break; + default: + break; + } +} + +static void gst_pipefilter_get_arg(GtkObject *object,GtkArg *arg,guint id) { + GstPipefilter *pipefilter; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_PIPEFILTER(object)); + pipefilter = GST_PIPEFILTER(object); + + switch (id) { + case ARG_CONTROL: + GTK_VALUE_INT(*arg) = pipefilter->control; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +/* open the file, necessary to go to RUNNING state */ +static gboolean gst_pipefilter_open_file(GstPipefilter *src) { + g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_PIPEFILTER_OPEN), FALSE); + + pipe(src->fdin); + pipe(src->fdout); + + if (fcntl(src->fdout[0], F_SETFL, O_NONBLOCK) < 0) { + perror("fcntl"); + gst_element_error(GST_ELEMENT(src),"fcntl"); + return FALSE; + } + + if((src->childpid = fork()) == -1) + { + perror("fork"); + gst_element_error(GST_ELEMENT(src),"forking"); + return FALSE; + } + + if(src->childpid == 0) + { + close(1); + dup(src->fdout[1]); /* set the childs output stream */ + close(0); + dup(src->fdin[0]); /* set the childs output stream */ + execlp("lame", "lame", "-x", "-", "-", NULL); + } + + GST_FLAG_SET(src,GST_PIPEFILTER_OPEN); + return TRUE; +} + +/* close the file */ +static void gst_pipefilter_close_file(GstPipefilter *src) { + g_return_if_fail(GST_FLAG_IS_SET(src,GST_PIPEFILTER_OPEN)); + + /* close the file */ + close(src->fdout[0]); + close(src->fdout[1]); + close(src->fdin[0]); + close(src->fdin[1]); + + /* zero out a lot of our state */ + src->curoffset = 0; + src->seq = 0; + + GST_FLAG_UNSET(src,GST_PIPEFILTER_OPEN); +} + +static gboolean gst_pipefilter_change_state(GstElement *element, + GstElementState state) { + g_return_val_if_fail(GST_IS_PIPEFILTER(element), FALSE); + + switch (state) { + case GST_STATE_RUNNING: + if (!gst_pipefilter_open_file(GST_PIPEFILTER(element))) + return FALSE; + break; + case ~GST_STATE_RUNNING: + gst_pipefilter_close_file(GST_PIPEFILTER(element)); + break; + default: + break; + } + + if (GST_ELEMENT_CLASS(parent_class)->change_state) + return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); + return TRUE; +} diff --git a/gst/elements/gstpipefilter.h b/gst/elements/gstpipefilter.h new file mode 100644 index 0000000000..4e20e2bb48 --- /dev/null +++ b/gst/elements/gstpipefilter.h @@ -0,0 +1,88 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen + * + * 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_PIPEFILTER_H__ +#define __GST_PIPEFILTER_H__ + +#include +#include + +#include "config.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +GstElementDetails gst_pipefilter_details; + +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_PIPEFILTER_OPEN = (1 << 16), +} GstPipefilterFlags; + +#define GST_TYPE_PIPEFILTER \ + (gst_pipefilter_get_type()) +#define GST_PIPEFILTER(obj) \ + (GTK_CHECK_CAST((obj),GST_TYPE_PIPEFILTER,GstPipefilter)) +#define GST_PIPEFILTER_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_PIPEFILTER,GstPipefilterClass)) +#define GST_IS_PIPEFILTER(obj) \ + (GTK_CHECK_TYPE((obj),GST_TYPE_PIPEFILTER)) +#define GST_IS_PIPEFILTER_CLASS(obj) \ + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_PIPEFILTER)) + +typedef struct _GstPipefilter GstPipefilter; +typedef struct _GstPipefilterClass GstPipefilterClass; + +struct _GstPipefilter { + GstFilter filter; + + GstPad *sinkpad; + GstPad *srcpad; + + /* filename */ + gchar *filename; + /* fd */ + gint fdout[2]; + gint fdin[2]; + pid_t childpid; + + gulong curoffset; /* current offset in file */ + gulong bytes_per_read; /* bytes per read */ + + gulong seq; /* buffer sequence number */ + + gint control; +}; + +struct _GstPipefilterClass { + GstFilterClass parent_class; +}; + +GtkType gst_pipefilter_get_type(void); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_PIPEFILTER_H__ */ diff --git a/plugins/elements/gstpipefilter.c b/plugins/elements/gstpipefilter.c new file mode 100644 index 0000000000..b054c93e11 --- /dev/null +++ b/plugins/elements/gstpipefilter.c @@ -0,0 +1,296 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen + * + * 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 +#include +#include +#include +#include +#include + +//#define DEBUG_ENABLED +#include "gstpipefilter.h" + + +GstElementDetails gst_pipefilter_details = { + "Pipefilter", + "Filter", + "Pass data without modification", + VERSION, + "Erik Walthinsen ", + "(C) 1999", +}; + + +/* Pipefilter signals and args */ +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_CONTROL +}; + + +static void gst_pipefilter_class_init(GstPipefilterClass *klass); +static void gst_pipefilter_init(GstPipefilter *pipefilter); +static void gst_pipefilter_set_arg(GtkObject *object,GtkArg *arg,guint id); +static void gst_pipefilter_get_arg(GtkObject *object,GtkArg *arg,guint id); + +void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf); + +static gboolean gst_pipefilter_change_state(GstElement *element, + GstElementState state); + +static GstFilterClass *parent_class = NULL; +//static guint gst_pipefilter_signals[LAST_SIGNAL] = { 0 }; + +GtkType +gst_pipefilter_get_type(void) { + static GtkType pipefilter_type = 0; + + if (!pipefilter_type) { + static const GtkTypeInfo pipefilter_info = { + "GstPipefilter", + sizeof(GstPipefilter), + sizeof(GstPipefilterClass), + (GtkClassInitFunc)gst_pipefilter_class_init, + (GtkObjectInitFunc)gst_pipefilter_init, + (GtkArgSetFunc)gst_pipefilter_set_arg, + (GtkArgGetFunc)gst_pipefilter_get_arg, + (GtkClassInitFunc)NULL, + }; + pipefilter_type = gtk_type_unique(GST_TYPE_FILTER,&pipefilter_info); + } + return pipefilter_type; +} + +static void gst_pipefilter_class_init(GstPipefilterClass *klass) { + GtkObjectClass *gtkobject_class; + GstFilterClass *gstfilter_class; + GstElementClass *gstelement_class; + + gtkobject_class = (GtkObjectClass*)klass; + gstfilter_class = (GstFilterClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = gtk_type_class(GST_TYPE_FILTER); + + gstelement_class->change_state = gst_pipefilter_change_state; + + //gtk_object_add_arg_type("GstPipefilter::control", GTK_TYPE_INT, + // GTK_ARG_READWRITE, ARG_CONTROL); + + //gtkobject_class->set_arg = gst_pipefilter_set_arg; + //gtkobject_class->get_arg = gst_pipefilter_get_arg; +} + +static void gst_pipefilter_init(GstPipefilter *pipefilter) { + pipefilter->sinkpad = gst_pad_new("sink",GST_PAD_SINK); + gst_element_add_pad(GST_ELEMENT(pipefilter),pipefilter->sinkpad); + gst_pad_set_chain_function(pipefilter->sinkpad,gst_pipefilter_chain); + pipefilter->srcpad = gst_pad_new("src",GST_PAD_SRC); + gst_element_add_pad(GST_ELEMENT(pipefilter),pipefilter->srcpad); + + pipefilter->control = 0; + pipefilter->curoffset = 0; + pipefilter->bytes_per_read = 4096; + pipefilter->seq = 0; +} + +GstElement *gst_pipefilter_new(gchar *name) { + GstElement *pipefilter = GST_ELEMENT(gtk_type_new(GST_TYPE_PIPEFILTER)); + gst_element_set_name(GST_ELEMENT(pipefilter),name); + return pipefilter; +} + +void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf) { + GstPipefilter *pipefilter; + GstBuffer *newbuf; + glong readbytes, writebytes; + guchar *data; + gulong size; + + g_return_if_fail(pad != NULL); + g_return_if_fail(GST_IS_PAD(pad)); + g_return_if_fail(buf != NULL); + + pipefilter = GST_PIPEFILTER(pad->parent); + + data = GST_BUFFER_DATA(buf); + size = GST_BUFFER_SIZE(buf); + + DEBUG("attemting to write %d bytes\n", size); + writebytes = write(pipefilter->fdin[1],data,size); + DEBUG("written %d bytes\n", writebytes); + if (writebytes < 0) { + perror("write"); + gst_element_error(GST_ELEMENT(pipefilter),"writing"); + return; + } + gst_buffer_unref(buf); + + + /* create the buffer */ + // FIXME: should eventually use a bufferpool for this + newbuf = gst_buffer_new(); + g_return_if_fail(newbuf); + + /* allocate the space for the buffer data */ + GST_BUFFER_DATA(newbuf) = g_malloc(pipefilter->bytes_per_read); + g_return_if_fail(GST_BUFFER_DATA(newbuf) != NULL); + + /* read it in from the file */ + DEBUG("attemting to read %d bytes\n", pipefilter->bytes_per_read); + readbytes = read(pipefilter->fdout[0],GST_BUFFER_DATA(newbuf),pipefilter->bytes_per_read); + DEBUG("read %d bytes\n", readbytes); + if (readbytes < 0) { + if (errno == EAGAIN) { + DEBUG("no input yet\n"); + gst_buffer_unref(newbuf); + return; + } + else { + perror("read"); + gst_element_error(GST_ELEMENT(pipefilter),"reading"); + return; + } + } + if (readbytes == 0) { + gst_buffer_unref(newbuf); + return; + } + /* if we didn't get as many bytes as we asked for, we're at EOF */ + if (readbytes < pipefilter->bytes_per_read) + GST_BUFFER_FLAG_SET(newbuf,GST_BUFFER_EOS); + GST_BUFFER_OFFSET(newbuf) = pipefilter->curoffset; + GST_BUFFER_SIZE(newbuf) = readbytes; + pipefilter->curoffset += readbytes; + + /* we're done, push the buffer off now */ + gst_pad_push(pipefilter->srcpad,newbuf); +} + +static void gst_pipefilter_set_arg(GtkObject *object,GtkArg *arg,guint id) { + GstPipefilter *pipefilter; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_PIPEFILTER(object)); + pipefilter = GST_PIPEFILTER(object); + + switch(id) { + case ARG_CONTROL: + pipefilter->control = GTK_VALUE_INT(*arg); + break; + default: + break; + } +} + +static void gst_pipefilter_get_arg(GtkObject *object,GtkArg *arg,guint id) { + GstPipefilter *pipefilter; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_PIPEFILTER(object)); + pipefilter = GST_PIPEFILTER(object); + + switch (id) { + case ARG_CONTROL: + GTK_VALUE_INT(*arg) = pipefilter->control; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +/* open the file, necessary to go to RUNNING state */ +static gboolean gst_pipefilter_open_file(GstPipefilter *src) { + g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_PIPEFILTER_OPEN), FALSE); + + pipe(src->fdin); + pipe(src->fdout); + + if (fcntl(src->fdout[0], F_SETFL, O_NONBLOCK) < 0) { + perror("fcntl"); + gst_element_error(GST_ELEMENT(src),"fcntl"); + return FALSE; + } + + if((src->childpid = fork()) == -1) + { + perror("fork"); + gst_element_error(GST_ELEMENT(src),"forking"); + return FALSE; + } + + if(src->childpid == 0) + { + close(1); + dup(src->fdout[1]); /* set the childs output stream */ + close(0); + dup(src->fdin[0]); /* set the childs output stream */ + execlp("lame", "lame", "-x", "-", "-", NULL); + } + + GST_FLAG_SET(src,GST_PIPEFILTER_OPEN); + return TRUE; +} + +/* close the file */ +static void gst_pipefilter_close_file(GstPipefilter *src) { + g_return_if_fail(GST_FLAG_IS_SET(src,GST_PIPEFILTER_OPEN)); + + /* close the file */ + close(src->fdout[0]); + close(src->fdout[1]); + close(src->fdin[0]); + close(src->fdin[1]); + + /* zero out a lot of our state */ + src->curoffset = 0; + src->seq = 0; + + GST_FLAG_UNSET(src,GST_PIPEFILTER_OPEN); +} + +static gboolean gst_pipefilter_change_state(GstElement *element, + GstElementState state) { + g_return_val_if_fail(GST_IS_PIPEFILTER(element), FALSE); + + switch (state) { + case GST_STATE_RUNNING: + if (!gst_pipefilter_open_file(GST_PIPEFILTER(element))) + return FALSE; + break; + case ~GST_STATE_RUNNING: + gst_pipefilter_close_file(GST_PIPEFILTER(element)); + break; + default: + break; + } + + if (GST_ELEMENT_CLASS(parent_class)->change_state) + return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); + return TRUE; +} diff --git a/plugins/elements/gstpipefilter.h b/plugins/elements/gstpipefilter.h new file mode 100644 index 0000000000..4e20e2bb48 --- /dev/null +++ b/plugins/elements/gstpipefilter.h @@ -0,0 +1,88 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen + * + * 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_PIPEFILTER_H__ +#define __GST_PIPEFILTER_H__ + +#include +#include + +#include "config.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +GstElementDetails gst_pipefilter_details; + +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_PIPEFILTER_OPEN = (1 << 16), +} GstPipefilterFlags; + +#define GST_TYPE_PIPEFILTER \ + (gst_pipefilter_get_type()) +#define GST_PIPEFILTER(obj) \ + (GTK_CHECK_CAST((obj),GST_TYPE_PIPEFILTER,GstPipefilter)) +#define GST_PIPEFILTER_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_PIPEFILTER,GstPipefilterClass)) +#define GST_IS_PIPEFILTER(obj) \ + (GTK_CHECK_TYPE((obj),GST_TYPE_PIPEFILTER)) +#define GST_IS_PIPEFILTER_CLASS(obj) \ + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_PIPEFILTER)) + +typedef struct _GstPipefilter GstPipefilter; +typedef struct _GstPipefilterClass GstPipefilterClass; + +struct _GstPipefilter { + GstFilter filter; + + GstPad *sinkpad; + GstPad *srcpad; + + /* filename */ + gchar *filename; + /* fd */ + gint fdout[2]; + gint fdin[2]; + pid_t childpid; + + gulong curoffset; /* current offset in file */ + gulong bytes_per_read; /* bytes per read */ + + gulong seq; /* buffer sequence number */ + + gint control; +}; + +struct _GstPipefilterClass { + GstFilterClass parent_class; +}; + +GtkType gst_pipefilter_get_type(void); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_PIPEFILTER_H__ */ diff --git a/test/pipetest.c b/test/pipetest.c new file mode 100644 index 0000000000..7f77e83fa4 --- /dev/null +++ b/test/pipetest.c @@ -0,0 +1,65 @@ +#include +#include +#include + +#include + + +void eof(GstSrc *src) { + g_print("have eof, quitting\n"); + exit(0); +} + +int main(int argc,char *argv[]) { + GstPipeline *pipeline; + GstElementFactory *srcfactory, *pipefactory, *sinkfactory; + GstElement *src, *pipe, *sink; + GstPad *infopad; + int fd; + + g_print("have %d args\n",argc); + + gst_init(&argc,&argv); + + pipeline = gst_pipeline_new("pipeline"); + g_return_if_fail(pipeline != NULL); + + srcfactory = gst_elementfactory_find("disksrc"); + g_return_if_fail(srcfactory != NULL); + pipefactory = gst_elementfactory_find("pipefilter"); + g_return_if_fail(pipefactory != NULL); + sinkfactory = gst_elementfactory_find("fdsink"); + g_return_if_fail(sinkfactory != NULL); + + src = gst_elementfactory_create(srcfactory,"src"); + g_return_if_fail(src != NULL); + gtk_object_set(GTK_OBJECT(src),"location",argv[1],NULL); + g_print("should be using file '%s'\n",argv[1]); + pipe = gst_elementfactory_create(pipefactory,"pipe"); + g_return_if_fail(pipe != NULL); + sink = gst_elementfactory_create(sinkfactory,"fdsink"); + g_return_if_fail(sink != NULL); + + fd = open(argv[2],O_CREAT|O_RDWR|O_TRUNC); + gtk_object_set(GTK_OBJECT(sink),"fd",fd,NULL); + + gtk_signal_connect(GTK_OBJECT(src),"eos", + GTK_SIGNAL_FUNC(eof),NULL); + + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(src)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(pipe)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(sink)); + + gst_pad_connect(gst_element_get_pad(src,"src"), + gst_element_get_pad(pipe,"sink")); + gst_pad_connect(gst_element_get_pad(pipe,"src"), + gst_element_get_pad(sink,"sink")); + + g_print("setting to RUNNING state\n"); + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_RUNNING); + + g_print("about to enter loop\n"); + while (1) { + gst_src_push(GST_SRC(src)); + } +}