move smoothwave to gst

Original commit message from CVS:
move smoothwave to gst
This commit is contained in:
Thomas Vander Stichele 2005-12-30 15:41:21 +00:00
parent 3f88a353d4
commit 691b10ff8e
6 changed files with 0 additions and 601 deletions

View file

@ -1 +0,0 @@
demo-osssrc

View file

@ -1,18 +0,0 @@
plugin_LTLIBRARIES = libgstsmoothwave.la
libgstsmoothwave_la_SOURCES = gstsmoothwave.c
libgstsmoothwave_la_CFLAGS = $(GST_CFLAGS)
libgstsmoothwave_la_LIBADD =
libgstsmoothwave_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gstsmoothwave.h
if HAVE_GTK
noinst_PROGRAMS = demo-osssrc
demo_osssrc_SOURCES = demo-osssrc.c
demo_osssrc_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS)
demo_osssrc_LDFLAGS = $(GST_LIBS) $(GTK_LIBS)
endif
EXTRA_DIST = README

View file

@ -1,6 +0,0 @@
This is a home-grown visualization, with a couple lines of code copied
from synaesthesia. It draws the waveform in the bitmap, then fades out
the entire bitmap so older waveforms disappear. It looks OK, but it's
grayscale so far (haven't solved the cmap problems, note all the commented
out code). I'm going to try to make a much better version as time goes
on.

View file

@ -1,52 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gtk/gtk.h>
#include <gst/gst.h>
extern gboolean _gst_plugin_spew;
gboolean idle_func (gpointer data);
GtkWidget *drawingarea;
int
main (int argc, char *argv[])
{
GstElement *bin;
GstElement *src;
GstElement *wave;
GstElement *ximage;
gst_init (&argc, &argv);
gst_plugin_load ("libsmoothwave.so");
gtk_init (&argc, &argv);
bin = gst_pipeline_new ("bin");
src = gst_element_factory_make ("sinesrc", "src");
wave = gst_element_factory_make ("smoothwave", "wave");
ximage = gst_element_factory_make (DEFAULT_VIDEOSINK, "sink");
g_return_val_if_fail (src != NULL, -1);
g_return_val_if_fail (wave != NULL, -1);
g_return_val_if_fail (ximage != NULL, -1);
gst_bin_add_many (GST_BIN (bin), src, wave, ximage, NULL);
g_return_val_if_fail (gst_element_link_many (src, wave, ximage,
NULL) != FALSE, -1);
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
g_idle_add (idle_func, bin);
gtk_main ();
return 0;
}
gboolean
idle_func (gpointer data)
{
gst_bin_iterate (GST_BIN (data));
return TRUE;
}

View file

@ -1,446 +0,0 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/audio/audio.h>
#include "gstsmoothwave.h"
static GstElementDetails gst_smoothwave_details =
GST_ELEMENT_DETAILS ("Smooth waveform",
"Visualization",
"Fading grayscale waveform display",
"Erik Walthinsen <omega@cse.ogi.edu>");
/* SmoothWave signals and args */
enum
{
/* FILL ME */
LAST_SIGNAL
};
static void gst_smoothwave_base_init (gpointer g_class);
static void gst_smoothwave_class_init (GstSmoothWaveClass * klass);
static void gst_smoothwave_init (GstSmoothWave * smoothwave);
static void gst_smoothwave_dispose (GObject * object);
static GstStateChangeReturn gst_sw_change_state (GstElement * element,
GstStateChange transition);
static void gst_smoothwave_chain (GstPad * pad, GstData * _data);
static GstPadLinkReturn gst_sw_sinklink (GstPad * pad, const GstCaps * caps);
static GstPadLinkReturn gst_sw_srclink (GstPad * pad, const GstCaps * caps);
static GstElementClass *parent_class = NULL;
/*static guint gst_smoothwave_signals[LAST_SIGNAL] = { 0 }; */
#if G_BYTE_ORDER == G_BIG_ENDIAN
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-rgb, "
"bpp = (int) 32, "
"depth = (int) 24, "
"endianness = (int) BIG_ENDIAN, "
"red_mask = (int) " GST_VIDEO_BYTE2_MASK_32 ", "
"green_mask = (int) " GST_VIDEO_BYTE3_MASK_32 ", "
"blue_mask = (int) " GST_VIDEO_BYTE4_MASK_32 ", "
"width = (int)512, "
"height = (int)256, " "framerate = " GST_VIDEO_FPS_RANGE)
);
#else
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("video/x-raw-rgb, "
"bpp = (int) 32, "
"depth = (int) 24, "
"endianness = (int) BIG_ENDIAN, "
"red_mask = (int) " GST_VIDEO_BYTE3_MASK_32 ", "
"green_mask = (int) " GST_VIDEO_BYTE2_MASK_32 ", "
"blue_mask = (int) " GST_VIDEO_BYTE1_MASK_32 ", "
"width = (int)512, "
"height = (int)256, " "framerate = " GST_VIDEO_FPS_RANGE)
);
#endif
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("audio/x-raw-int, "
"rate = (int) [ 1, MAX ], "
"channels = (int) [ 1, 2 ], "
"endianness = (int) BYTE_ORDER, "
"width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true")
);
GType
gst_smoothwave_get_type (void)
{
static GType smoothwave_type = 0;
if (!smoothwave_type) {
static const GTypeInfo smoothwave_info = {
sizeof (GstSmoothWaveClass),
gst_smoothwave_base_init,
NULL,
(GClassInitFunc) gst_smoothwave_class_init,
NULL,
NULL,
sizeof (GstSmoothWave),
0,
(GInstanceInitFunc) gst_smoothwave_init,
};
smoothwave_type =
g_type_register_static (GST_TYPE_ELEMENT, "GstSmoothWave",
&smoothwave_info, 0);
}
return smoothwave_type;
}
static void
gst_smoothwave_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (element_class, &gst_smoothwave_details);
}
static void
gst_smoothwave_class_init (GstSmoothWaveClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *element_class;
gobject_class = (GObjectClass *) klass;
element_class = (GstElementClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
gobject_class->dispose = gst_smoothwave_dispose;
element_class->change_state = gst_sw_change_state;
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&src_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template));
}
static void
gst_smoothwave_init (GstSmoothWave * smoothwave)
{
int i;
smoothwave->sinkpad =
gst_pad_new_from_template (gst_static_pad_template_get (&sink_template),
"sink");
smoothwave->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get (&src_template),
"src");
gst_element_add_pad (GST_ELEMENT (smoothwave), smoothwave->sinkpad);
gst_pad_set_chain_function (smoothwave->sinkpad, gst_smoothwave_chain);
gst_pad_set_link_function (smoothwave->sinkpad, gst_sw_sinklink);
gst_element_add_pad (GST_ELEMENT (smoothwave), smoothwave->srcpad);
gst_pad_set_link_function (smoothwave->srcpad, gst_sw_srclink);
GST_OBJECT_FLAG_SET (smoothwave, GST_ELEMENT_EVENT_AWARE);
smoothwave->adapter = gst_adapter_new ();
smoothwave->width = 512;
smoothwave->height = 256;
#define SPLIT_PT 96
/* Fade in blue up to the split point */
for (i = 0; i < SPLIT_PT; i++)
smoothwave->palette[i] = (255 * i / SPLIT_PT);
/* After the split point, fade out blue and fade in red */
for (; i < 256; i++) {
gint val = (i - SPLIT_PT) * 255 / (255 - SPLIT_PT);
smoothwave->palette[i] = (255 - val) | (val << 16);
}
smoothwave->imagebuffer = g_malloc (smoothwave->width * smoothwave->height);
memset (smoothwave->imagebuffer, 0, smoothwave->width * smoothwave->height);
smoothwave->fps = 0;
smoothwave->sample_rate = 0;
smoothwave->audio_basetime = GST_CLOCK_TIME_NONE;
smoothwave->samples_consumed = 0;
}
inline guchar *
draw_line (guchar * cur_pos, gint diff_y, gint stride)
{
gint j;
if (diff_y > 0) {
for (j = diff_y; j > 0; j--) {
cur_pos += stride;
*cur_pos = 0xff;
}
} else if (diff_y < 0) {
for (j = diff_y; j < 0; j++) {
cur_pos -= stride;
*cur_pos = 0xff;
}
} else {
*cur_pos = 0xff;
}
return cur_pos;
}
static void
gst_smoothwave_dispose (GObject * object)
{
GstSmoothWave *sw = GST_SMOOTHWAVE (object);
if (sw->adapter != NULL) {
g_object_unref (sw->adapter);
sw->adapter = NULL;
}
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static GstPadLinkReturn
gst_sw_sinklink (GstPad * pad, const GstCaps * caps)
{
GstSmoothWave *sw = GST_SMOOTHWAVE (GST_OBJECT_PARENT (pad));
GstStructure *structure;
g_return_val_if_fail (sw != NULL, GST_PAD_LINK_REFUSED);
structure = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (structure, "channels", &sw->channels) ||
!gst_structure_get_int (structure, "rate", &sw->sample_rate))
return GST_PAD_LINK_REFUSED;
return GST_PAD_LINK_OK;
}
static GstPadLinkReturn
gst_sw_srclink (GstPad * pad, const GstCaps * caps)
{
GstSmoothWave *sw = GST_SMOOTHWAVE (GST_OBJECT_PARENT (pad));
GstStructure *structure;
g_return_val_if_fail (sw != NULL, GST_PAD_LINK_REFUSED);
structure = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (structure, "width", &sw->width) ||
!gst_structure_get_int (structure, "height", &sw->height) ||
!gst_structure_get_double (structure, "framerate", &sw->fps))
return GST_PAD_LINK_REFUSED;
return GST_PAD_LINK_OK;
}
static void
gst_smoothwave_chain (GstPad * pad, GstData * _data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstSmoothWave *smoothwave;
guint32 bytesperread;
gint samples_per_frame;
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (buf != NULL);
smoothwave = GST_SMOOTHWAVE (GST_OBJECT_PARENT (pad));
if (GST_IS_EVENT (_data)) {
GstEvent *event = GST_EVENT (_data);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_DISCONTINUOUS:
{
gint64 value = 0;
gst_event_discont_get_value (event, GST_FORMAT_TIME, &value);
gst_adapter_clear (smoothwave->adapter);
smoothwave->audio_basetime = value;
smoothwave->samples_consumed = 0;
}
default:
gst_pad_event_default (pad, event);
break;
}
return;
}
if (!GST_PAD_IS_USABLE (smoothwave->srcpad)) {
gst_buffer_unref (buf);
return;
}
if (smoothwave->audio_basetime == GST_CLOCK_TIME_NONE)
smoothwave->audio_basetime = GST_BUFFER_TIMESTAMP (buf);
if (smoothwave->audio_basetime == GST_CLOCK_TIME_NONE)
smoothwave->audio_basetime = 0;
bytesperread = smoothwave->width * smoothwave->channels * sizeof (gint16);
samples_per_frame = smoothwave->sample_rate / smoothwave->fps;
gst_adapter_push (smoothwave->adapter, buf);
while (gst_adapter_available (smoothwave->adapter) > MAX (bytesperread,
samples_per_frame * smoothwave->channels * sizeof (gint16))) {
guint32 *ptr;
gint i;
gint qheight;
const gint16 *samples =
(const guint16 *) gst_adapter_peek (smoothwave->adapter, bytesperread);
gint stride = smoothwave->width;
/* First draw the new waveform */
if (smoothwave->channels == 2) {
guchar *cur_pos[2];
gint prev_y[2];
qheight = smoothwave->height / 4;
prev_y[0] = (gint32) (*samples) * qheight / 32768;
samples++;
prev_y[1] = (gint32) (*samples) * qheight / 32768;
samples++;
cur_pos[0] = smoothwave->imagebuffer + ((prev_y[0] + qheight) * stride);
cur_pos[1] =
smoothwave->imagebuffer + ((prev_y[1] +
(3 * smoothwave->height / 4)) * stride);
*(cur_pos[0]) = 0xff;
*(cur_pos[1]) = 0xff;
for (i = 1; i < smoothwave->width; i++) {
gint diff_y = (gint) (*samples) * qheight / 32768 - prev_y[0];
samples++;
cur_pos[0] = draw_line (cur_pos[0], diff_y, stride);
cur_pos[0]++;
prev_y[0] += diff_y;
diff_y = (gint) (*samples) * qheight / 32768 - prev_y[1];
samples++;
cur_pos[1] = draw_line (cur_pos[1], diff_y, stride);
cur_pos[1]++;
prev_y[1] += diff_y;
}
} else {
qheight = smoothwave->height / 2;
guchar *cur_pos;
gint prev_y;
prev_y = (gint32) (*samples) * qheight / 32768;
samples++;
cur_pos = smoothwave->imagebuffer + ((prev_y + qheight) * stride);
*cur_pos = 0xff;
for (i = 1; i < smoothwave->width; i++) {
gint diff_y = (gint) (*samples) * qheight / 32768 - prev_y;
samples++;
cur_pos = draw_line (cur_pos, diff_y, stride);
cur_pos++;
prev_y += diff_y;
}
}
/* Now fade stuff out */
ptr = (guint32 *) smoothwave->imagebuffer;
for (i = 0; i < (smoothwave->width * smoothwave->height) / 4; i++) {
if (*ptr)
*ptr -= ((*ptr & 0xf0f0f0f0ul) >> 4) + ((*ptr & 0xe0e0e0e0ul) >> 5);
ptr++;
}
{
guint32 *out;
guchar *in;
GstBuffer *bufout;
bufout =
gst_buffer_new_and_alloc (smoothwave->width * smoothwave->height * 4);
GST_BUFFER_TIMESTAMP (bufout) =
smoothwave->audio_basetime +
(GST_SECOND * smoothwave->samples_consumed / smoothwave->sample_rate);
GST_BUFFER_DURATION (bufout) = GST_SECOND / smoothwave->fps;
out = (guint32 *) GST_BUFFER_DATA (bufout);
in = smoothwave->imagebuffer;
for (i = 0; i < (smoothwave->width * smoothwave->height); i++) {
*out++ = smoothwave->palette[*in++]; // t | (t << 8) | (t << 16) | (t << 24);
}
gst_pad_push (smoothwave->srcpad, GST_DATA (bufout));
}
smoothwave->samples_consumed += samples_per_frame;
gst_adapter_flush (smoothwave->adapter,
samples_per_frame * smoothwave->channels * sizeof (gint16));
}
}
static GstStateChangeReturn
gst_sw_change_state (GstElement * element, GstStateChange transition)
{
GstSmoothWave *sw = GST_SMOOTHWAVE (element);
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
break;
case GST_STATE_CHANGE_READY_TO_NULL:
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
sw->audio_basetime = GST_CLOCK_TIME_NONE;
gst_adapter_clear (sw->adapter);
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
sw->channels = 0;
break;
default:
break;
}
return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
}
static gboolean
plugin_init (GstPlugin * plugin)
{
if (!gst_library_load ("gstbytestream"))
return FALSE;
if (!gst_element_register (plugin, "smoothwave", GST_RANK_NONE,
GST_TYPE_SMOOTHWAVE))
return FALSE;
return TRUE;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"smoothwave",
"Fading greyscale waveform display",
plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN)

View file

@ -1,78 +0,0 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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_SMOOTHWAVE_H__
#define __GST_SMOOTHWAVE_H__
#include <gst/gst.h>
#include <gst/bytestream/adapter.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define GST_TYPE_SMOOTHWAVE \
(gst_smoothwave_get_type())
#define GST_SMOOTHWAVE(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SMOOTHWAVE,GstSmoothWave))
#define GST_SMOOTHWAVE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SMOOTHWAVE,GstSmoothWave))
#define GST_IS_SMOOTHWAVE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SMOOTHWAVE))
#define GST_IS_SMOOTHWAVE_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SMOOTHWAVE))
typedef struct _GstSmoothWave GstSmoothWave;
typedef struct _GstSmoothWaveClass GstSmoothWaveClass;
struct _GstSmoothWave
{
GstElement element;
GstPad *sinkpad, *srcpad;
GstAdapter *adapter;
guchar *imagebuffer;
GstClockTime audio_basetime;
guint64 samples_consumed;
gint sample_rate;
gint width, height;
gdouble fps;
gint channels;
guint32 palette[256];
};
struct _GstSmoothWaveClass
{
GstElementClass parent_class;
};
GType gst_smoothwave_get_type (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_SMOOTHWAVE_H__ */