From 92d4e11782aac4cf054edc89c9f65fdeceff77dc Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sat, 22 Dec 2001 23:27:17 +0000 Subject: [PATCH] Initial revision Original commit message from CVS: Initial revision --- gst/videoscale/.gitignore | 7 + gst/videoscale/Makefile.am | 20 ++ gst/videoscale/gstvideoscale.c | 355 ++++++++++++++++++++++++++++++++++ gst/videoscale/gstvideoscale.h | 91 +++++++++ gst/videoscale/videoscale.c | 370 +++++++++++++++++++++++++++++++++++ gst/videoscale/videoscale_x86.c | 80 ++++++++ gst/videoscale/videoscale_x86.h | 30 +++ gst/videoscale/videoscale_x86_asm.s | 53 +++++ gst/volume/Makefile.am | 8 + gst/volume/filter.func | 25 +++ gst/volume/gstvolume.c | 373 ++++++++++++++++++++++++++++++++++++ gst/volume/gstvolume.h | 98 ++++++++++ 12 files changed, 1510 insertions(+) create mode 100644 gst/videoscale/.gitignore create mode 100644 gst/videoscale/Makefile.am create mode 100644 gst/videoscale/gstvideoscale.c create mode 100644 gst/videoscale/gstvideoscale.h create mode 100644 gst/videoscale/videoscale.c create mode 100644 gst/videoscale/videoscale_x86.c create mode 100644 gst/videoscale/videoscale_x86.h create mode 100644 gst/videoscale/videoscale_x86_asm.s create mode 100644 gst/volume/Makefile.am create mode 100644 gst/volume/filter.func create mode 100644 gst/volume/gstvolume.c create mode 100644 gst/volume/gstvolume.h diff --git a/gst/videoscale/.gitignore b/gst/videoscale/.gitignore new file mode 100644 index 0000000..08f5ed3 --- /dev/null +++ b/gst/videoscale/.gitignore @@ -0,0 +1,7 @@ +Makefile +Makefile.in +*.o +*.lo +*.la +.deps +.libs diff --git a/gst/videoscale/Makefile.am b/gst/videoscale/Makefile.am new file mode 100644 index 0000000..e2ca13d --- /dev/null +++ b/gst/videoscale/Makefile.am @@ -0,0 +1,20 @@ +filterdir = $(libdir)/gst + +filter_LTLIBRARIES = libgstvideoscale.la + +if HAVE_CPU_I386 +ARCHSRCS = \ + videoscale_x86.c \ + videoscale_x86_asm.s +else +ARCHSRCS = +endif + +libgstvideoscale_la_SOURCES = \ + gstvideoscale.c \ + videoscale.c \ + $(ARCHSRCS) +libvideoscale_la_CFLAGS = -O2 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math $(GST_CFLAGS) + +noinst_HEADERS = gstvideoscale.h videoscale_x86.h + diff --git a/gst/videoscale/gstvideoscale.c b/gst/videoscale/gstvideoscale.c new file mode 100644 index 0000000..5d5da45 --- /dev/null +++ b/gst/videoscale/gstvideoscale.c @@ -0,0 +1,355 @@ +/* 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. + */ + + +//#define DEBUG_ENABLED +#include + + + +/* elementfactory information */ +static GstElementDetails videoscale_details = { + "Video scaler", + "Filter/Video/Scaler", + "Resizes video", + VERSION, + "Wim Taymans ", + "(C) 2000", +}; + +/* GstVideoscale signals and args */ +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_WIDTH, + ARG_HEIGHT, + ARG_METHOD, + /* FILL ME */ +}; + +GST_PADTEMPLATE_FACTORY (sink_templ, + "sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "videoscale_caps", + "video/raw", + "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')) + ) +) + +GST_PADTEMPLATE_FACTORY (src_templ, + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_CAPS_NEW ( + "videoscale_caps", + "video/raw", + "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')) + ) +) + +#define GST_TYPE_VIDEOSCALE_METHOD (gst_videoscale_method_get_type()) +static GType +gst_videoscale_method_get_type (void) +{ + static GType videoscale_method_type = 0; + static GEnumValue videoscale_methods[] = { + { GST_VIDEOSCALE_POINT_SAMPLE, "0", "Point Sample" }, + { GST_VIDEOSCALE_NEAREST, "1", "Nearest" }, + { GST_VIDEOSCALE_BILINEAR, "2", "Bilinear" }, + { GST_VIDEOSCALE_BICUBIC, "3", "Bicubic" }, + { 0, NULL, NULL }, + }; + if (!videoscale_method_type) { + videoscale_method_type = g_enum_register_static ("GstVideoscaleMethod", videoscale_methods); + } + return videoscale_method_type; +} + +static void gst_videoscale_class_init (GstVideoscaleClass *klass); +static void gst_videoscale_init (GstVideoscale *videoscale); + +static void gst_videoscale_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gst_videoscale_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + +static void gst_videoscale_chain (GstPad *pad, GstBuffer *buf); + +static GstElementClass *parent_class = NULL; +//static guint gst_videoscale_signals[LAST_SIGNAL] = { 0 }; + +GType +gst_videoscale_get_type (void) +{ + static GType videoscale_type = 0; + + if (!videoscale_type) { + static const GTypeInfo videoscale_info = { + sizeof(GstVideoscaleClass), NULL, + NULL, + (GClassInitFunc)gst_videoscale_class_init, + NULL, + NULL, + sizeof(GstVideoscale), + 0, + (GInstanceInitFunc)gst_videoscale_init, + }; + videoscale_type = g_type_register_static(GST_TYPE_ELEMENT, "GstVideoscale", &videoscale_info, 0); + } + return videoscale_type; +} + +static void +gst_videoscale_class_init (GstVideoscaleClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_WIDTH, + g_param_spec_int("width","width","width", + G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HEIGHT, + g_param_spec_int("height","height","height", + G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_METHOD, + g_param_spec_enum("method","method","method", + GST_TYPE_VIDEOSCALE_METHOD,0,G_PARAM_READWRITE)); // CHECKME! + + parent_class = g_type_class_ref(GST_TYPE_ELEMENT); + + gobject_class->set_property = gst_videoscale_set_property; + gobject_class->get_property = gst_videoscale_get_property; + +} + +static GstPadNegotiateReturn +videoscale_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GstVideoscale *videoscale = GST_VIDEOSCALE (gst_pad_get_parent (pad)); + + GST_DEBUG(0,"videoscale_negotiate_src\n"); + + if(*caps==NULL){ + return GST_PAD_NEGOTIATE_FAIL; + } + + *caps = GST_CAPS_NEW ( "videoscale_caps", + "video/raw", + "format", GST_PROPS_FOURCC (videoscale->format), + "width", GST_PROPS_INT (videoscale->targetwidth), + "height", GST_PROPS_INT (videoscale->targetheight) + ); + + return GST_PAD_NEGOTIATE_AGREE; +} + +static GstPadNegotiateReturn +videoscale_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GST_DEBUG(0,"videoscale_negotiate_sink\n"); + + if (*caps==NULL) + return GST_PAD_NEGOTIATE_FAIL; + + return GST_PAD_NEGOTIATE_AGREE; +} + +static void +gst_videoscale_newcaps (GstPad *pad, GstCaps *caps) +{ + GstVideoscale *videoscale; + + GST_DEBUG(0,"gst_videoscale_newcaps\n"); + videoscale = GST_VIDEOSCALE (gst_pad_get_parent (pad)); + + videoscale->width = gst_caps_get_int (caps, "width"); + videoscale->height = gst_caps_get_int (caps, "height"); + videoscale->format = gst_caps_get_int (caps, "format"); + + gst_videoscale_setup(videoscale); + + GST_DEBUG (0,"target size %d x %d\n",videoscale->targetwidth, + videoscale->targetheight); + + GST_DEBUG(0,"width %d\n",videoscale->targetwidth); + gst_pad_set_caps (videoscale->srcpad, + GST_CAPS_NEW ( + "videoscale_src", + "video/raw", + "format", GST_PROPS_FOURCC (videoscale->format), + "width", GST_PROPS_INT (videoscale->targetwidth), + "height", GST_PROPS_INT (videoscale->targetheight) + )); +} + +static void +gst_videoscale_init (GstVideoscale *videoscale) +{ + GST_DEBUG(0,"gst_videoscale_init\n"); + videoscale->sinkpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (sink_templ), "sink"); + gst_pad_set_negotiate_function(videoscale->sinkpad,videoscale_negotiate_sink); + gst_element_add_pad(GST_ELEMENT(videoscale),videoscale->sinkpad); + gst_pad_set_chain_function(videoscale->sinkpad,gst_videoscale_chain); + gst_pad_set_newcaps_function(videoscale->sinkpad,gst_videoscale_newcaps); + + videoscale->srcpad = gst_pad_new_from_template ( + GST_PADTEMPLATE_GET (src_templ), "src"); + gst_pad_set_negotiate_function(videoscale->srcpad,videoscale_negotiate_src); + gst_element_add_pad(GST_ELEMENT(videoscale),videoscale->srcpad); + + videoscale->targetwidth = -1; + videoscale->targetheight = -1; + videoscale->method = GST_VIDEOSCALE_NEAREST; + //videoscale->method = GST_VIDEOSCALE_BILINEAR; + //videoscale->method = GST_VIDEOSCALE_POINT_SAMPLE; +} + + +static void +gst_videoscale_chain (GstPad *pad, GstBuffer *buf) +{ + GstVideoscale *videoscale; + guchar *data; + gulong size; + GstBuffer *outbuf; + + GST_DEBUG (0,"gst_videoscale_chain\n"); + + g_return_if_fail (pad != NULL); + g_return_if_fail (GST_IS_PAD (pad)); + g_return_if_fail (buf != NULL); + + videoscale = GST_VIDEOSCALE (gst_pad_get_parent (pad)); + data = GST_BUFFER_DATA(buf); + size = GST_BUFFER_SIZE(buf); + + if(!videoscale->scale_cc){ + videoscale->format = gst_caps_get_int (gst_pad_get_caps(pad), "format"); + gst_videoscale_setup(videoscale); + } + GST_DEBUG (0,"gst_videoscale_chain: got buffer of %ld bytes in '%s'\n",size, + GST_OBJECT_NAME (videoscale)); + +GST_DEBUG(0,"size=%ld from=%dx%d to=%dx%d newsize=%d\n", + size, + videoscale->width, videoscale->height, + videoscale->targetwidth, videoscale->targetheight, + videoscale->targetwidth*videoscale->targetheight + videoscale->targetwidth*videoscale->targetheight/2); + + outbuf = gst_buffer_new(); + /* XXX this is wrong for anything but I420 */ + GST_BUFFER_SIZE(outbuf) = videoscale->targetwidth*videoscale->targetheight + + videoscale->targetwidth*videoscale->targetheight/2; + GST_BUFFER_DATA(outbuf) = g_malloc (videoscale->targetwidth*videoscale->targetheight*2); + GST_BUFFER_TIMESTAMP(outbuf) = GST_BUFFER_TIMESTAMP(buf); + + //g_return_if_fail(videoscale->scale_cc != NULL); + videoscale->scale_cc(videoscale, data, GST_BUFFER_DATA(outbuf)); + + GST_DEBUG (0,"gst_videoscale_chain: pushing buffer of %d bytes in '%s'\n",GST_BUFFER_SIZE(outbuf), + GST_OBJECT_NAME (videoscale)); + + gst_pad_push(videoscale->srcpad, outbuf); + + gst_buffer_unref(buf); +} + +static void +gst_videoscale_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstVideoscale *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_VIDEOSCALE(object)); + src = GST_VIDEOSCALE(object); + + GST_DEBUG(0,"gst_videoscale_set_property\n"); + switch (prop_id) { + case ARG_WIDTH: + src->targetwidth = g_value_get_int (value); + break; + case ARG_HEIGHT: + src->targetheight = g_value_get_int (value); + break; + case ARG_METHOD: + src->method = g_value_get_int (value); + break; + default: + break; + } +} + +static void +gst_videoscale_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstVideoscale *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_VIDEOSCALE(object)); + src = GST_VIDEOSCALE(object); + + switch (prop_id) { + case ARG_WIDTH: + g_value_set_int (value, src->targetwidth); + break; + case ARG_HEIGHT: + g_value_set_int (value, src->targetheight); + break; + case ARG_METHOD: + g_value_set_int (value, src->method); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + GstElementFactory *factory; + + /* create an elementfactory for the videoscale element */ + factory = gst_elementfactory_new("videoscale",GST_TYPE_VIDEOSCALE, + &videoscale_details); + g_return_val_if_fail(factory != NULL, FALSE); + + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_templ)); + gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_templ)); + + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); + + return TRUE; +} + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "videoscale", + plugin_init +}; diff --git a/gst/videoscale/gstvideoscale.h b/gst/videoscale/gstvideoscale.h new file mode 100644 index 0000000..657d22f --- /dev/null +++ b/gst/videoscale/gstvideoscale.h @@ -0,0 +1,91 @@ +/* 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_VIDEOSCALE_H__ +#define __GST_VIDEOSCALE_H__ + + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GST_TYPE_VIDEOSCALE \ + (gst_videoscale_get_type()) +#define GST_VIDEOSCALE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VIDEOSCALE,GstVideoscale)) +#define GST_VIDEOSCALE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VIDEOSCALE,GstVideoscale)) +#define GST_IS_VIDEOSCALE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEOSCALE)) +#define GST_IS_VIDEOSCALE_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEOSCALE)) + +typedef enum { + GST_VIDEOSCALE_POINT_SAMPLE, + GST_VIDEOSCALE_NEAREST, + GST_VIDEOSCALE_BILINEAR, + GST_VIDEOSCALE_BICUBIC +} GstVideoScaleMethod; + +typedef struct _GstVideoscale GstVideoscale; +typedef struct _GstVideoscaleClass GstVideoscaleClass; + +struct _GstVideoscale { + GstElement element; + + GstPad *sinkpad,*srcpad; + + // video state + gint format; + gint width; + gint height; + gint targetwidth; + gint targetheight; + GstVideoScaleMethod method; + guint scale_bytes; + + /* private */ + guchar *temp; + void (*scale_cc) (GstVideoscale *scale, guchar *src, guchar *dest); + void (*scaler) (GstVideoscale *scale, guchar *src, guchar *dest,int,int,int,int); + guchar (*filter) (guchar *src, gdouble x, gdouble y, gint sw, gint sh); + guchar copy_row[8192]; +}; + +struct _GstVideoscaleClass { + GstElementClass parent_class; +}; + +GType gst_videoscale_get_type(void); + +void gst_videoscale_setup(GstVideoscale *); +#define gst_videoscale_scale(scale, src, dest) (scale)->scale_cc((scale), (src), (dest)) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_VIDEOSCALE_H__ */ diff --git a/gst/videoscale/videoscale.c b/gst/videoscale/videoscale.c new file mode 100644 index 0000000..d33aab6 --- /dev/null +++ b/gst/videoscale/videoscale.c @@ -0,0 +1,370 @@ +/* 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. + */ + +#define DEBUG_ENABLED +#include +#include + +#include "config.h" +#include "gstvideoscale.h" +#undef HAVE_CPU_I386 +#ifdef HAVE_CPU_I386 +#include "videoscale_x86.h" +#endif + +static void gst_videoscale_scale_yuv (Videoscale *scale, unsigned char *src, unsigned char *dest); +static void gst_videoscale_scale_rgb (Videoscale *scale, unsigned char *src, unsigned char *dest); + +/* scalers */ +static void gst_videoscale_scale_nearest (Videoscale *scale, unsigned char *src, unsigned char *dest, + int sw, int sh, int dw, int dh); +static void gst_videoscale_scale_plane_slow (Videoscale *scale, unsigned char *src, unsigned char *dest, + int sw, int sh, int dw, int dh); +static void gst_videoscale_scale_point_sample (Videoscale *scale, unsigned char *src, unsigned char *dest, + int sw, int sh, int dw, int dh); + +/* filters */ +static unsigned char gst_videoscale_bilinear (unsigned char *src, double x, double y, int sw, int sh); +static unsigned char gst_videoscale_bicubic (unsigned char *src, double x, double y, int sw, int sh); + +void +gst_videoscale_setup (Videoscale *scale) +{ + switch (scale->format) { + case GST_MAKE_FOURCC('I','4','2','0'): + scale->scale_cc = gst_videoscale_scale_yuv; + scale->scale_bytes = 1; + break; + case GST_MAKE_FOURCC('R','G','B',' '): + scale->scale_cc = gst_videoscale_scale_rgb; + /* XXX */ + //scale->scale_bytes = gst_caps_get_int(scale->srcpad->caps,"bpp")/8; + break; + default: + g_print("videoscale: unsupported video format %08x\n", scale->format); + return; /* XXX */ + } + + switch (scale->method) { + case GST_VIDEOSCALE_POINT_SAMPLE: + scale->scaler = gst_videoscale_scale_point_sample; + GST_DEBUG (0,"videoscale: scaling method POINT_SAMPLE\n"); + break; + case GST_VIDEOSCALE_NEAREST: +#ifdef HAVE_CPU_I386 + gst_videoscale_generate_rowbytes_x86 (scale->copy_row, scale->width, + scale->targetwidth, scale->scale_bytes); + scale->scaler = gst_videoscale_scale_nearest_x86; +#else + scale->scaler = gst_videoscale_scale_nearest; +#endif + GST_DEBUG (0,"videoscale: scaling method NEAREST\n"); + break; + case GST_VIDEOSCALE_BILINEAR: + scale->scaler = gst_videoscale_scale_plane_slow; + scale->filter = gst_videoscale_bilinear; + GST_DEBUG (0,"videoscale: scaling method BILINEAR\n"); + break; + case GST_VIDEOSCALE_BICUBIC: + scale->scaler = gst_videoscale_scale_plane_slow; + scale->filter = gst_videoscale_bicubic; + GST_DEBUG (0,"videoscale: scaling method BICUBIC\n"); + break; + default: + g_print("videoscale: unsupported scaling method %d\n", scale->method); + return; /* XXX */ + } + + return; /* XXX */ +} + +static void +gst_videoscale_scale_rgb (Videoscale *scale, unsigned char *src, unsigned char *dest) +{ + int sw = scale->width; + int sh = scale->height; + int dw = scale->targetwidth; + int dh = scale->targetheight; + GST_DEBUG (0,"videoscale: scaling RGB %dx%d to %dx%d\n", sw, sh, dw, dh); + + switch (scale->scale_bytes) { + case 2: + dw = ((dw + 1) & ~1) << 1; + sw = sw<<1; + break; + case 4: + dw = ((dw + 2) & ~3) << 2; + sw = sw<<2; + break; + default: + break; + } + + GST_DEBUG (0,"videoscale: %p %p\n", src, dest); + scale->scaler(scale, src, dest, sw, sh, dw, dh); +} + +static void +gst_videoscale_scale_yuv (Videoscale *scale, unsigned char *src, unsigned char *dest) +{ + int sw = scale->width; + int sh = scale->height; + int dw = scale->targetwidth; + int dh = scale->targetheight; + + GST_DEBUG (0,"videoscale: scaling YUV420P %dx%d to %dx%d\n", sw, sh, dw, dh); + + scale->scaler(scale, src, dest, sw, sh, dw, dh); + + src += sw*sh; + dest += dw*dh; + + dh = dh>>1; + dw = dw>>1; + sh = sh>>1; + sw = sw>>1; + + scale->scaler(scale, src, dest, sw, sh, dw, dh); + + src += sw*sh; + dest += dw*dh; + + scale->scaler(scale, src, dest, sw, sh, dw, dh); +} + +#define RC(x,y) *(src+(int)(x)+(int)((y)*sw)) + +static unsigned char +gst_videoscale_bilinear (unsigned char *src, double x, double y, int sw, int sh) +{ + int j=floor(x); + int k=floor(y); + double a=x-j; + double b=y-k; + double dest; + int color; + + GST_DEBUG(0,"videoscale: scaling bilinear %f %f %dx%d\n", x, y, sw, sh); + + dest=(1-a)*(1-b)*RC(j,k)+ + a*(1-b)*RC(j+1,k); + + k = MIN(sh-1, k); + dest+= b*(1-a)*RC(j,k+1)+ + a*b*RC(j+1,k+1); + + color=rint(dest); + if (color<0) color=abs(color); // cannot have negative values ! + //if (color<0) color=0; // cannot have negative values ! + if (color>255) color=255; + + return (unsigned char) color; +} + +static unsigned char +gst_videoscale_bicubic (unsigned char *src, double x, double y, int sw, int sh) +{ + int j=floor(x); + int k=floor(y), k2; + double a=x-j; + double b=y-k; + double dest; + int color; + double t1, t2, t3, t4; + double a1, a2, a3, a4; + + GST_DEBUG (0,"videoscale: scaling bicubic %dx%d\n", sw, sh); + + a1 = -a*(1-a)*(1-a); + a2 = (1-2*a*a+a*a*a); + a3 = a*(1+a-a*a); + a4 = a*a*(1-a); + + k2 = MAX(0, k-1); + t1=a1*RC(j-1,k2)+ a2*RC(j,k2)+ a3*RC(j+1,k2)- a4*RC(j+2,k2); + t2=a1*RC(j-1,k)+ a2*RC(j,k)+ a3*RC(j+1,k)- a4*RC(j+2,k); + k2 = MIN(sh, k+1); + t3=a1*RC(j-1,k2)+ a2*RC(j,k2)+ a3*RC(j+1,k2)- a4*RC(j+2,k2); + k2 = MIN(sh, k+2); + t4=a1*RC(j-1,k2)+ a2*RC(j,k2)+ a3*RC(j+1,k2)- a4*RC(j+2,k2); + + dest= -b*(1-b)*(1-b)*t1+ (1-2*b*b+b*b*b)*t2+ b*(1+b-b*b)*t3+ b*b*(b-1)*t4; + + color=rint(dest); + if (color<0) color=abs(color); // cannot have negative values ! + if (color>255) color=255; + + return (unsigned char) color; +} + +static void +gst_videoscale_scale_plane_slow (Videoscale *scale, unsigned char *src, unsigned char *dest, + int sw, int sh, int dw, int dh) +{ + double zoomx = ((double)dw)/(double)sw; + double zoomy = ((double)dh)/(double)sh; + double xr, yr; + int x, y; + + GST_DEBUG (0,"videoscale: scale plane slow %dx%d %dx%d %g %g %p %p\n", sw, sh, dw, dh, zoomx, zoomy, src, dest); + + for (y=0; yfilter(src, xr, yr, sw, sh); + //*dest++ = gst_videoscale_bicubic(src, xr, yr, sw, sh); + } + } + } +} + +static void +gst_videoscale_scale_point_sample (Videoscale *scale, unsigned char *src, unsigned char *dest, + int sw, int sh, int dw, int dh) +{ + int ypos, yinc, y; + int xpos, xinc, x; + int sum, xcount, ycount, loop; + unsigned char *srcp, *srcp2; + + GST_DEBUG (0,"videoscale: scaling nearest point sample %p %p %d\n", src, dest, dw); + + ypos = 0x10000; + yinc = (sh<<16)/dh; + xinc = (sw<<16)/dw; + + for (y = dh; y; y--) { + + ycount = 1; + srcp = src; + while (ypos >0x10000) { + ycount++; + ypos-=0x10000; + src += sw; + } + + xpos = 0x10000; + for ( x=dw; x; x-- ) { + xcount = 0; + sum=0; + while ( xpos >= 0x10000L ) { + loop = ycount; + srcp2 = srcp; + while (loop--) { + sum += *srcp2; + srcp2 += sw; + } + srcp++; + xcount++; + xpos -= 0x10000L; + } + *dest++ = sum/(xcount*ycount); + xpos += xinc; + } + + ypos += yinc; + } +} + +static void +gst_videoscale_scale_nearest (Videoscale *scale, + unsigned char *src, + unsigned char *dest, + int sw, int sh, int dw, int dh) +{ + int ypos, yinc, y; + int xpos, xinc, x; + + GST_DEBUG (0, "videoscale: scaling nearest %p %p %d %d\n", src, dest, dw, scale->scale_bytes); + + + ypos = 0x10000; + yinc = (sh<<16)/dh; + xinc = (sw<<16)/dw; + + for (y = dh; y; y--) { + + while (ypos >0x10000) { + ypos-=0x10000; + src += sw; + } + + xpos = 0x10000; + + switch (scale->scale_bytes) { + case 4: + { + guint32 *destp = (guint32 *)dest; + guint32 *srcp = (guint32 *)src; + + for ( x=dw>>2; x; x-- ) { + while ( xpos >= 0x10000L ) { + srcp++; + xpos -= 0x10000L; + } + *destp++ = *srcp; + xpos += xinc; + } + break; + } + case 2: + { + guint16 *destp = (guint16 *)dest; + guint16 *srcp = (guint16 *)src; + + for ( x=dw>>1; x; x-- ) { + while ( xpos >= 0x10000L ) { + srcp++; + xpos -= 0x10000L; + } + *destp++ = *srcp; + xpos += xinc; + } + break; + } + case 1: + { + guchar *destp = dest; + guchar *srcp = src; + + for ( x=dw; x; x-- ) { + while ( xpos >= 0x10000L ) { + srcp++; + xpos -= 0x10000L; + } + *destp++ = *srcp; + xpos += xinc; + } + } + } + dest += dw; + + ypos += yinc; + } +} + diff --git a/gst/videoscale/videoscale_x86.c b/gst/videoscale/videoscale_x86.c new file mode 100644 index 0000000..1704d6e --- /dev/null +++ b/gst/videoscale/videoscale_x86.c @@ -0,0 +1,80 @@ +/* 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. + */ + +//#define DEBUG_ENABLED + +#include "gstvideoscale.h" + +/* scalers */ +void gst_videoscale_generate_rowbytes_x86 (unsigned char *copy_row, int src_w, int dst_w, int bpp); +void gst_videoscale_scale_nearest_x86 (Videoscale *scale, + unsigned char *src, unsigned char *dest, + int sw, int sh, int dw, int dh); + +#define PREFIX16 0x66 +#define STORE_BYTE 0xAA +#define STORE_WORD 0xAB +#define LOAD_BYTE 0xAC +#define LOAD_WORD 0xAD +#define RETURN 0xC3 + +void +gst_videoscale_generate_rowbytes_x86 (unsigned char *copy_row, int src_w, int dst_w, int bpp) +{ + int i; + int pos, inc; + unsigned char *eip; + unsigned char load, store; + + GST_DEBUG (0,"videoscale: setup scaling %p\n", copy_row); + + switch (bpp) { + case 1: + load = LOAD_BYTE; + store = STORE_BYTE; + break; + case 2: + case 4: + load = LOAD_WORD; + store = STORE_WORD; + break; + default: + return; + } + pos = 0x10000; + inc = (src_w << 16) / dst_w; + eip = copy_row; + for ( i=0; i= 0x10000L ) { + if ( bpp == 2 ) { + *eip++ = PREFIX16; + } + *eip++ = load; + pos -= 0x10000L; + } + if ( bpp == 2 ) { + *eip++ = PREFIX16; + } + *eip++ = store; + pos += inc; + } + *eip++ = RETURN; + GST_DEBUG (0,"scaler start/end %p %p %p\n", copy_row, eip, (void*)(eip-copy_row)); +} + diff --git a/gst/videoscale/videoscale_x86.h b/gst/videoscale/videoscale_x86.h new file mode 100644 index 0000000..efff5e2 --- /dev/null +++ b/gst/videoscale/videoscale_x86.h @@ -0,0 +1,30 @@ +/* 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_VIDEOSCALE__X86_H__ +#define __GST_VIDEOSCALE__X86_H__ + + +/* scalers */ +void gst_videoscale_generate_rowbytes_x86 (unsigned char *copy_row, int src_w, int dst_w, int bpp); +void gst_videoscale_scale_nearest_x86 (GstVideoscale *scale, + unsigned char *src, unsigned char *dest, + int sw, int sh, int dw, int dh); +#endif /* __GST_VIDEOSCALE__X86_H__ */ diff --git a/gst/videoscale/videoscale_x86_asm.s b/gst/videoscale/videoscale_x86_asm.s new file mode 100644 index 0000000..9ec9785 --- /dev/null +++ b/gst/videoscale/videoscale_x86_asm.s @@ -0,0 +1,53 @@ +.text + .align 4 +.globl gst_videoscale_scale_nearest_x86 + .type gst_videoscale_scale_nearest_x86,@function +gst_videoscale_scale_nearest_x86: + + subl $8,%esp + pushl %ebp + pushl %edi + pushl %esi + movl 28(%esp),%ebp + movl 24(%esp),%edx + addl $28,%edx + movl 24(%esp),%eax + movl %edx,8220(%eax) + movl $65536,12(%esp) + movl 40(%esp),%ecx + sall $16,%ecx + movl %ecx,%eax + cltd + idivl 48(%esp) + movl %eax,%ecx + movl 48(%esp),%eax + movl %eax,16(%esp) + testl %eax,%eax + jle .L92 + jmp .L100 + .p2align 4,,7 +.L97: + addl 36(%esp),%ebp + addl $-65536,12(%esp) +.L100: + cmpl $65536,12(%esp) + jg .L97 + movl 32(%esp),%edi + movl %ebp,%esi + movl 24(%esp),%edx + + movl 8220(%edx), %eax + call *%eax + + movl 44(%esp),%eax + addl %eax,32(%esp) + addl %ecx,12(%esp) + decl 16(%esp) + cmpl $0,16(%esp) + jg .L100 +.L92: + popl %esi + popl %edi + popl %ebp + addl $8,%esp + ret diff --git a/gst/volume/Makefile.am b/gst/volume/Makefile.am new file mode 100644 index 0000000..2caed5e --- /dev/null +++ b/gst/volume/Makefile.am @@ -0,0 +1,8 @@ +filterdir = $(libdir)/gst + +filter_LTLIBRARIES = libgstvolume.la + +libgstvolume_la_SOURCES = gstvolume.c +libgstvolume_la_CFLAGS = $(GST_CFLAGS) + +noinst_HEADERS = gstvolume.h filter.func diff --git a/gst/volume/filter.func b/gst/volume/filter.func new file mode 100644 index 0000000..430bc1c --- /dev/null +++ b/gst/volume/filter.func @@ -0,0 +1,25 @@ +{ + guint j; + gint16 vol_i = filter->volume_i; + gfloat vol_f = filter->volume_f; + + switch (filter->format) { + case GST_VOLUME_FORMAT_INT: + if (filter->muted) vol_i = 0; + + for (j = 0; j < num_samples; j++) { + data[j] = (gint16) (((gint32)vol_i) * ((gint32)data[j]) / 8192); + } + break; + case GST_VOLUME_FORMAT_FLOAT: + if (filter->muted) vol_f = 0; + + for (j = 0; j < num_samples; j++) { + data[j] *= vol_f; + } + break; + default: + g_warning("volume: filter.func: no format, aborting"); + break; + } +} diff --git a/gst/volume/gstvolume.c b/gst/volume/gstvolume.c new file mode 100644 index 0000000..2cd7dbb --- /dev/null +++ b/gst/volume/gstvolume.c @@ -0,0 +1,373 @@ +/* -*- c-basic-offset: 2 -*- + * GStreamer + * Copyright (C) 1999-2001 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 "gstvolume.h" + + + +static GstElementDetails volume_details = { + "Volume", + "Filter/Effect", + "Set volume on audio/raw streams", + VERSION, + "Andy Wingo ", + "(C) 2001" +}; + + +/* Filter signals and args */ +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_SILENT, + ARG_MUTED, + ARG_VOLUME +}; + +static GstPadTemplate* +volume_sink_factory (void) +{ + static GstPadTemplate *template = NULL; + + if (!template) { + template = gst_padtemplate_new + ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, + gst_caps_append(gst_caps_new ("sink_int", "audio/raw", + GST_AUDIO_INT_PAD_TEMPLATE_PROPS), + gst_caps_new ("sink_float", "audio/raw", + GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS)), + NULL); + } + return template; +} + +static GstPadTemplate* +volume_src_factory (void) +{ + static GstPadTemplate *template = NULL; + + if (!template) + template = gst_padtemplate_new + ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + gst_caps_append (gst_caps_new ("src_float", "audio/raw", + GST_AUDIO_FLOAT_MONO_PAD_TEMPLATE_PROPS), + gst_caps_new ("src_int", "audio/raw", + GST_AUDIO_INT_PAD_TEMPLATE_PROPS)), + NULL); + + return template; +} + +static void volume_class_init (GstVolumeClass *klass); +static void volume_init (GstVolume *filter); + +static void volume_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void volume_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + +static gint volume_parse_caps (GstVolume *filter, GstCaps *caps); + +static void volume_chain (GstPad *pad, GstBuffer *buf); +static void inline volume_fast_float_chain (gfloat* data, guint numsamples, GstVolume *filter); +static void inline volume_fast_8bit_chain (gint8* data, guint numsamples, GstVolume *filter); +static void inline volume_fast_16bit_chain (gint16* data, guint numsamples, GstVolume *filter); + +static GstElementClass *parent_class = NULL; +//static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; + +static GstBufferPool* +volume_get_bufferpool (GstPad *pad) +{ + GstVolume *filter; + + filter = GST_VOLUME (gst_pad_get_parent (pad)); + + return gst_pad_get_bufferpool (filter->srcpad); +} + +static GstPadNegotiateReturn +volume_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GstVolume* filter = GST_VOLUME (gst_pad_get_parent (pad)); + + if (*caps==NULL) + return GST_PAD_NEGOTIATE_FAIL; + + if (volume_parse_caps(filter, *caps)) + return GST_PAD_NEGOTIATE_FAIL; + + return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps); +} + +static GstPadNegotiateReturn +volume_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GstVolume* filter = GST_VOLUME (gst_pad_get_parent (pad)); + + if (*caps==NULL) + return GST_PAD_NEGOTIATE_FAIL; + + if (volume_parse_caps(filter, *caps)) + return GST_PAD_NEGOTIATE_FAIL; + + return gst_pad_negotiate_proxy(pad,filter->srcpad,caps); +} + +static gint +volume_parse_caps (GstVolume *filter, GstCaps *caps) +{ + const gchar *format; + + g_return_val_if_fail(filter!=NULL,-1); + g_return_val_if_fail(caps!=NULL,-1); + + format = gst_caps_get_string(caps, "format"); + + filter->rate = gst_caps_get_int (caps, "rate"); + filter->channels = gst_caps_get_int (caps, "channels"); + + if (strcmp(format, "int")==0) { + filter->format = GST_VOLUME_FORMAT_INT; + filter->width = gst_caps_get_int (caps, "width"); + filter->depth = gst_caps_get_int (caps, "depth"); + filter->law = gst_caps_get_int (caps, "law"); + filter->endianness = gst_caps_get_int (caps, "endianness"); + filter->is_signed = gst_caps_get_int (caps, "signed"); + if (!filter->silent) { + g_print ("Volume : channels %d, rate %d\n", + filter->channels, filter->rate); + g_print ("Volume : format int, bit width %d, endianness %d, signed %s\n", + filter->width, filter->endianness, filter->is_signed ? "yes" : "no"); + } + } else if (strcmp(format, "float")==0) { + filter->format = GST_VOLUME_FORMAT_FLOAT; + filter->layout = gst_caps_get_string(caps, "layout"); + filter->intercept = gst_caps_get_float(caps, "intercept"); + filter->slope = gst_caps_get_float(caps, "slope"); + if (!filter->silent) { + g_print ("Volume : channels %d, rate %d\n", + filter->channels, filter->rate); + g_print ("Volume : format float, layout %s, intercept %f, slope %f\n", + filter->layout, filter->intercept, filter->slope); + } + } else { + return -1; + } + return 0; +} + + +GType +gst_volume_get_type(void) { + static GType volume_type = 0; + + if (!volume_type) { + static const GTypeInfo volume_info = { + sizeof(GstVolumeClass), NULL, + NULL, + (GClassInitFunc)volume_class_init, + NULL, + NULL, + sizeof(GstVolume), + 0, + (GInstanceInitFunc)volume_init, + }; + volume_type = g_type_register_static(GST_TYPE_ELEMENT, "GstVolume", &volume_info, 0); + } + return volume_type; +} + +static void +volume_class_init (GstVolumeClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = g_type_class_ref(GST_TYPE_ELEMENT); + + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SILENT, + g_param_spec_boolean("silent","silent","silent", + TRUE,G_PARAM_READWRITE)); // CHECKME + + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MUTED, + g_param_spec_boolean("muted","muted","muted", + FALSE,G_PARAM_READWRITE)); + + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VOLUME, + g_param_spec_float("volume","volume","volume", + -4.0,4.0,1.0,G_PARAM_READWRITE)); + + gobject_class->set_property = volume_set_property; + gobject_class->get_property = volume_get_property; +} + +static void +volume_init (GstVolume *filter) +{ + filter->sinkpad = gst_pad_new_from_template(volume_sink_factory (),"sink"); + gst_pad_set_negotiate_function(filter->sinkpad,volume_negotiate_sink); + gst_pad_set_bufferpool_function(filter->sinkpad,volume_get_bufferpool); + filter->srcpad = gst_pad_new_from_template(volume_src_factory (),"src"); + gst_pad_set_negotiate_function(filter->srcpad,volume_negotiate_src); + + gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad); + gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad); + gst_pad_set_chain_function(filter->sinkpad,volume_chain); + filter->silent = FALSE; + filter->muted = FALSE; + filter->volume_i = 8192; + filter->volume_f = 1.0; +} + +static void +volume_chain (GstPad *pad, GstBuffer *buf) +{ + GstVolume *filter; + gint16 *int_data; + gfloat *float_data; + + g_return_if_fail(pad != NULL); + g_return_if_fail(GST_IS_PAD(pad)); + g_return_if_fail(buf != NULL); + + filter = GST_VOLUME(GST_OBJECT_PARENT (pad)); + g_return_if_fail(filter != NULL); + g_return_if_fail(GST_IS_VOLUME(filter)); + + switch (filter->format) { + case GST_VOLUME_FORMAT_INT: + int_data = (gint16 *)GST_BUFFER_DATA(buf); + + switch (filter->width) { + case 16: + volume_fast_16bit_chain(int_data,GST_BUFFER_SIZE(buf)/2, filter); + break; + case 8: + volume_fast_8bit_chain((gint8*)int_data,GST_BUFFER_SIZE(buf), filter); + break; + } + + break; + case GST_VOLUME_FORMAT_FLOAT: + float_data = (gfloat *)GST_BUFFER_DATA(buf); + + volume_fast_float_chain(float_data,GST_BUFFER_SIZE(buf)/sizeof(float), filter); + + break; + } + + gst_pad_push(filter->srcpad,buf); +} + +static void inline +volume_fast_float_chain(gfloat* data, guint num_samples, GstVolume *filter) +#include "filter.func" + +static void inline +volume_fast_16bit_chain(gint16* data, guint num_samples, GstVolume *filter) +#include "filter.func" + +static void inline +volume_fast_8bit_chain(gint8* data, guint num_samples, GstVolume *filter) +#include "filter.func" + +static void +volume_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstVolume *filter; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_VOLUME(object)); + filter = GST_VOLUME(object); + + switch (prop_id) + { + case ARG_SILENT: + filter->silent = g_value_get_boolean (value); + break; + case ARG_MUTED: + filter->muted = g_value_get_boolean (value); + break; + case ARG_VOLUME: + filter->volume_f = g_value_get_float (value); + filter->volume_i = filter->volume_f*8192; + break; + default: + break; + } +} + +static void +volume_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstVolume *filter; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_VOLUME(object)); + filter = GST_VOLUME(object); + + switch (prop_id) { + case ARG_SILENT: + g_value_set_boolean (value, filter->silent); + break; + case ARG_MUTED: + g_value_set_boolean (value, filter->muted); + break; + case ARG_VOLUME: + g_value_set_float (value, filter->volume_f); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +plugin_init (GModule *module, GstPlugin *plugin) +{ + GstElementFactory *factory; + + factory = gst_elementfactory_new("volume",GST_TYPE_VOLUME, + &volume_details); + g_return_val_if_fail(factory != NULL, FALSE); + + gst_elementfactory_add_padtemplate (factory, volume_src_factory ()); + gst_elementfactory_add_padtemplate (factory, volume_sink_factory ()); + + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); + + return TRUE; +} + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "volume", + plugin_init +}; diff --git a/gst/volume/gstvolume.h b/gst/volume/gstvolume.h new file mode 100644 index 0000000..0f7d427 --- /dev/null +++ b/gst/volume/gstvolume.h @@ -0,0 +1,98 @@ +/* -*- c-basic-offset: 2 -*- + * GStreamer + * 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_VOLUME_H__ +#define __GST_VOLUME_H__ + + +#include +#include +// #include + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GST_TYPE_VOLUME \ + (gst_volume_get_type()) +#define GST_VOLUME(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VOLUME,GstVolume)) +#define GST_VOLUME_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstVolume)) +#define GST_IS_VOLUME(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VOLUME)) +#define GST_IS_VOLUME_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VOLUME)) + +typedef struct _GstVolume GstVolume; +typedef struct _GstVolumeClass GstVolumeClass; +typedef enum _GstVolumeFormat GstVolumeFormat; + +enum _GstVolumeFormat { + GST_VOLUME_FORMAT_INT=1, + GST_VOLUME_FORMAT_FLOAT +}; + +struct _GstVolume { + GstElement element; + + GstPad *sinkpad, *srcpad; + + gboolean silent; + gboolean muted; + gint16 volume_i; + gfloat volume_f; + + /* the next three are valid for both int and float */ + + GstVolumeFormat format; + guint rate; + guint channels; + + /* the next five are valid only for format==GST_VOLUME_FORMAT_INT */ + + guint width; + guint depth; + guint endianness; + guint law; + gboolean is_signed; + + /* the next three are valid only for format==GST_VOLUME_FORMAT_FLOAT */ + + const gchar *layout; + gfloat slope; + gfloat intercept; +}; + +struct _GstVolumeClass { + GstElementClass parent_class; +}; + +GType gst_volume_get_type(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_VOLUME_H__ */ -- 2.7.4