diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2002-02-01 19:28:30 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2002-02-01 19:28:30 +0000 |
commit | 4d3b1472e78ac7c12460b26914c9a294a3de573a (patch) | |
tree | 4d9b1f0a6698385b086e37381b75b2d93bf85e39 /gst/goom/gstgoom.c | |
parent | e5faa112b67c7681f653949413799180c7382451 (diff) |
Added a goom plugin (goom.sourceforge.net) to test: ./gst-launch filesrc location=/opt/data/south.mp3 ! mad ! tee sil...
Original commit message from CVS:
Added a goom plugin (goom.sourceforge.net)
to test:
./gst-launch filesrc location=/opt/data/south.mp3 ! mad ! tee silent=true src%d! goom ! colorspace ! xvideosink tee0.src%d! osssink
Diffstat (limited to 'gst/goom/gstgoom.c')
-rw-r--r-- | gst/goom/gstgoom.c | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/gst/goom/gstgoom.c b/gst/goom/gstgoom.c new file mode 100644 index 00000000..c0513524 --- /dev/null +++ b/gst/goom/gstgoom.c @@ -0,0 +1,341 @@ +/* gstgoom.c: implementation of goom drawing element + * Copyright (C) <2001> Richard Boulton <richard@tartarus.org> + * + * 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 <config.h> +#include <gst/gst.h> + +#include "goom_core.h" + +#define GST_TYPE_GOOM (gst_goom_get_type()) +#define GST_GOOM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GOOM,GstGOOM)) +#define GST_GOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GOOM,GstGOOM)) +#define GST_IS_GOOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GOOM)) +#define GST_IS_GOOM_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GOOM)) + +typedef struct _GstGOOM GstGOOM; +typedef struct _GstGOOMClass GstGOOMClass; + +struct _GstGOOM { + GstElement element; + + /* pads */ + GstPad *sinkpad,*srcpad; + GstBufferPool *peerpool; + + // the timestamp of the next frame + guint64 next_time; + + // video state + gint bpp; + gint depth; + gint width; + gint height; + gboolean first_buffer; + + gint samplerate; + gint framerate; // desired frame rate + gint samples_between_frames; // number of samples between start of successive frames + gint samples_since_last_frame; // number of samples between start of successive frames +}; + +struct _GstGOOMClass { + GstElementClass parent_class; +}; + +GType gst_goom_get_type(void); + + +/* elementfactory information */ +static GstElementDetails gst_goom_details = { + "GOOM: what a GOOM!", + "Filter/Visualization", + "Takes frames of data and outputs video frames using the GOOM filter", + VERSION, + "Wim Taymans <wim.taymans@chello.be>", + "(C) 2002", +}; + +/* signals and args */ +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +enum { + ARG_0, + /* FILL ME */ +}; + +GST_PADTEMPLATE_FACTORY (src_template, + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "goomsrc", + "video/raw", + "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), + "bpp", GST_PROPS_INT (32), + "depth", GST_PROPS_INT (32), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "red_mask", GST_PROPS_INT (0xff0000), + "green_mask", GST_PROPS_INT (0xff00), + "blue_mask", GST_PROPS_INT (0xff), + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096) + ) +) + +GST_PADTEMPLATE_FACTORY (sink_template, + "sink", /* the name of the pads */ + GST_PAD_SINK, /* type of the pad */ + GST_PAD_ALWAYS, /* ALWAYS/SOMETIMES */ + GST_CAPS_NEW ( + "goomsink", /* the name of the caps */ + "audio/raw", /* the mime type of the caps */ + /* Properties follow: */ + "format", GST_PROPS_STRING ("int"), + "law", GST_PROPS_INT (0), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "signed", GST_PROPS_BOOLEAN (TRUE), + "width", GST_PROPS_INT (16), + "depth", GST_PROPS_INT (16), + "rate", GST_PROPS_INT_RANGE (8000, 96000), + "channels", GST_PROPS_INT (1) + ) +) + + +static void gst_goom_class_init (GstGOOMClass *klass); +static void gst_goom_init (GstGOOM *goom); + +static void gst_goom_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_goom_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); + +static void gst_goom_chain (GstPad *pad, GstBuffer *buf); + +static GstPadConnectReturn + gst_goom_sinkconnect (GstPad *pad, GstCaps *caps); + +static GstElementClass *parent_class = NULL; + +GType +gst_goom_get_type (void) +{ + static GType type = 0; + + if (!type) { + static const GTypeInfo info = { + sizeof (GstGOOMClass), + NULL, + NULL, + (GClassInitFunc) gst_goom_class_init, + NULL, + NULL, + sizeof (GstGOOM), + 0, + (GInstanceInitFunc) gst_goom_init, + }; + type = g_type_register_static (GST_TYPE_ELEMENT, "GstGOOM", &info, 0); + } + return type; +} + +static void +gst_goom_class_init(GstGOOMClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass*) klass; + gstelement_class = (GstElementClass*) klass; + + parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + + gobject_class->set_property = gst_goom_set_property; + gobject_class->get_property = gst_goom_get_property; +} + +static void +gst_goom_init (GstGOOM *goom) +{ + /* create the sink and src pads */ + goom->sinkpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (sink_template ), "sink"); + goom->srcpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (src_template ), "src"); + gst_element_add_pad (GST_ELEMENT (goom), goom->sinkpad); + gst_element_add_pad (GST_ELEMENT (goom), goom->srcpad); + + gst_pad_set_chain_function (goom->sinkpad, gst_goom_chain); + gst_pad_set_connect_function (goom->sinkpad, gst_goom_sinkconnect); + + goom->next_time = 0; + goom->peerpool = NULL; + + // reset the initial video state + goom->bpp = 32; + goom->depth = 32; + goom->first_buffer = TRUE; + goom->width = 320; + goom->height = 200; + + goom->samplerate = -1; + goom->framerate = 25; // desired frame rate + goom->samples_between_frames = 0; // number of samples between start of successive frames + goom->samples_since_last_frame = 0; + + goom_init (goom->width, goom->height); +} + +static GstPadConnectReturn +gst_goom_sinkconnect (GstPad *pad, GstCaps *caps) +{ + GstGOOM *goom; + goom = GST_GOOM (gst_pad_get_parent (pad)); + + if (!GST_CAPS_IS_FIXED (caps)) { + return GST_PAD_CONNECT_DELAYED; + } + + goom->samplerate = gst_caps_get_int (caps, "rate"); + goom->samples_between_frames = goom->samplerate / goom->framerate; + + GST_DEBUG (0, "GOOM: new sink caps: rate %d\n", + goom->samplerate); + + return GST_PAD_CONNECT_OK; +} + +static void +gst_goom_chain (GstPad *pad, GstBuffer *bufin) +{ + GstGOOM *goom; + GstBuffer *bufout; + guint32 samples_in; + gint16 datain[2][512]; + + goom = GST_GOOM (gst_pad_get_parent (pad)); + + GST_DEBUG (0, "GOOM: chainfunc called\n"); + + samples_in = GST_BUFFER_SIZE (bufin) / sizeof (gint16); + + GST_DEBUG (0, "input buffer has %d samples\n", samples_in); + + if (goom->next_time <= GST_BUFFER_TIMESTAMP (bufin)) { + goom->next_time = GST_BUFFER_TIMESTAMP (bufin); + GST_DEBUG (0, "in: %lld\n", GST_BUFFER_TIMESTAMP (bufin)); + } + if (goom->first_buffer) { + GstCaps *caps; + + GST_DEBUG (0, "making new pad\n"); + + caps = GST_CAPS_NEW ( + "goomsrc", + "video/raw", + "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), + "bpp", GST_PROPS_INT (goom->bpp), + "depth", GST_PROPS_INT (goom->depth), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "red_mask", GST_PROPS_INT (0xff0000), + "green_mask", GST_PROPS_INT (0x00ff00), + "blue_mask", GST_PROPS_INT (0x0000ff), + "width", GST_PROPS_INT (goom->width), + "height", GST_PROPS_INT (goom->height) + ); + + if (!gst_pad_try_set_caps (goom->srcpad, caps)) { + gst_element_error (GST_ELEMENT (goom), "could not set caps"); + return; + } + goom->first_buffer = FALSE; + } + + memcpy (&datain[0][0], GST_BUFFER_DATA (bufin), 512); + memcpy (&datain[1][0], GST_BUFFER_DATA (bufin), 512); + + bufout = gst_buffer_new (); + GST_BUFFER_DATA (bufout) = (guchar *) goom_update (datain); + GST_BUFFER_SIZE (bufout) = goom->width * goom->height * 4; + GST_BUFFER_FLAG_SET (bufout, GST_BUFFER_DONTFREE); + + gst_pad_push (goom->srcpad, bufout); + + gst_buffer_unref (bufin); + + GST_DEBUG (0, "GOOM: exiting chainfunc\n"); +} + +static void +gst_goom_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstGOOM *goom; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_GOOM (object)); + goom = GST_GOOM (object); + + switch (prop_id) { + default: + break; + } +} + +static void +gst_goom_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstGOOM *goom; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_GOOM (object)); + goom = GST_GOOM (object); + + switch (prop_id) { + default: + break; + } +} + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + GstElementFactory *factory; + + /* create an elementfactory for the goom element */ + factory = gst_elementfactory_new("goom",GST_TYPE_GOOM, + &gst_goom_details); + g_return_val_if_fail(factory != NULL, FALSE); + + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_template)); + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_template)); + + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); + + return TRUE; +} + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "goom", + plugin_init +}; |