summaryrefslogtreecommitdiffstats
path: root/gst/goom2k1
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2008-02-23 01:51:37 +0000
committerBastien Nocera <hadess@hadess.net>2008-02-23 01:51:37 +0000
commita7bc7485b1a4d7e1b1a12ff593ca4ccb1d59e466 (patch)
treeffba99ad38c7616d089c5e728c75a6bd5f736c6c /gst/goom2k1
parent7f0745bb7f26c69766bb0c64458c6543588cc4dc (diff)
configure.ac: Add checks for Flex/Yacc/Bison and other furry animals, for the new goom 2k4 based plugin
Original commit message from CVS: 2008-02-23 Bastien Nocera <hadess@hadess.net> * configure.ac: Add checks for Flex/Yacc/Bison and other furry animals, for the new goom 2k4 based plugin * gst/goom/*: Update to use goom 2k4, uses liboil to detect CPU optimisations (not working yet), move the old plugin to... * gst/goom2k1/*: ... here, in case somebody is sick enough Fixes #515073
Diffstat (limited to 'gst/goom2k1')
-rw-r--r--gst/goom2k1/Makefile.am14
-rw-r--r--gst/goom2k1/README5
-rw-r--r--gst/goom2k1/filters.c606
-rw-r--r--gst/goom2k1/filters.h83
-rw-r--r--gst/goom2k1/filters_mmx.s130
-rw-r--r--gst/goom2k1/goom.vcproj172
-rw-r--r--gst/goom2k1/goom_core.c412
-rw-r--r--gst/goom2k1/goom_core.h43
-rw-r--r--gst/goom2k1/goom_tools.h24
-rw-r--r--gst/goom2k1/graphic.c14
-rw-r--r--gst/goom2k1/graphic.h23
-rw-r--r--gst/goom2k1/gstgoom.c602
-rw-r--r--gst/goom2k1/gstgoom.h91
-rw-r--r--gst/goom2k1/lines.c107
-rw-r--r--gst/goom2k1/lines.h16
15 files changed, 2342 insertions, 0 deletions
diff --git a/gst/goom2k1/Makefile.am b/gst/goom2k1/Makefile.am
new file mode 100644
index 00000000..4f4abb76
--- /dev/null
+++ b/gst/goom2k1/Makefile.am
@@ -0,0 +1,14 @@
+plugin_LTLIBRARIES = libgstgoom.la
+
+GOOM_FILTER_FILES = filters.c
+GOOM_FILTER_CFLAGS = -UMMX -UUSE_ASM
+
+noinst_HEADERS = gstgoom.h filters.h goom_core.h goom_tools.h graphic.h lines.h
+
+libgstgoom_la_SOURCES = gstgoom.c goom_core.c $(GOOM_FILTER_FILES) graphic.c lines.c
+
+libgstgoom_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS)
+libgstgoom_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM)
+libgstgoom_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+
+EXTRA_DIST = filters.c
diff --git a/gst/goom2k1/README b/gst/goom2k1/README
new file mode 100644
index 00000000..f12cf1b5
--- /dev/null
+++ b/gst/goom2k1/README
@@ -0,0 +1,5 @@
+The Goom plugin is based on the Goom visualization code from
+the Goom homepage found at:
+http://ios.free.fr/?page=projet&quoi=1
+
+Like the original library so is the Goom plugin available under the LGPL license
diff --git a/gst/goom2k1/filters.c b/gst/goom2k1/filters.c
new file mode 100644
index 00000000..b898e89c
--- /dev/null
+++ b/gst/goom2k1/filters.c
@@ -0,0 +1,606 @@
+/* filter.c version 0.7
+ * contient les filtres applicable a un buffer
+ * creation : 01/10/2000
+ * -ajout de sinFilter()
+ * -ajout de zoomFilter()
+ * -copie de zoomFilter() en zoomFilterRGB(), gérant les 3 couleurs
+ * -optimisation de sinFilter (utilisant une table de sin)
+ * -asm
+ * -optimisation de la procedure de génération du buffer de transformation
+ * la vitesse est maintenant comprise dans [0..128] au lieu de [0..100]
+*/
+
+/*#define _DEBUG_PIXEL; */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "filters.h"
+#include "graphic.h"
+#include "goom_tools.h"
+#include "goom_core.h"
+#include <stdlib.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifdef MMX
+#define USE_ASM
+#endif
+#ifdef POWERPC
+#define USE_ASM
+#endif
+
+#ifdef USE_ASM
+#define EFFECT_DISTORS 4
+#else
+#define EFFECT_DISTORS 10
+#endif
+
+
+#ifdef USE_ASM
+
+#ifdef MMX
+int mmx_zoom ();
+guint32 mmx_zoom_size;
+#endif /* MMX */
+
+#ifdef POWERPC
+extern unsigned int useAltivec;
+extern void ppc_zoom (void);
+extern void ppc_zoom_altivec (void);
+unsigned int ppcsize4;
+#endif /* PowerPC */
+
+
+unsigned int *coeffs = 0, *freecoeffs = 0;
+guint32 *expix1 = 0; /* pointeur exporte vers p1 */
+guint32 *expix2 = 0; /* pointeur exporte vers p2 */
+guint32 zoom_width;
+#endif /* ASM */
+
+
+static int firstTime = 1;
+static int sintable[0xffff];
+
+ZoomFilterData *
+zoomFilterNew ()
+{
+ ZoomFilterData *zf = malloc (sizeof (ZoomFilterData));
+
+ zf->vitesse = 128;
+ zf->pertedec = 8;
+ zf->sqrtperte = 16;
+ zf->middleX = 1;
+ zf->middleY = 1;
+ zf->reverse = 0;
+ zf->mode = WAVE_MODE;
+ zf->hPlaneEffect = 0;
+ zf->vPlaneEffect = 0;
+ zf->noisify = 0;
+ zf->buffsize = 0;
+ zf->res_x = 0;
+ zf->res_y = 0;
+
+ zf->buffer = NULL;
+ zf->firedec = NULL;
+
+ zf->wave = 0;
+ zf->wavesp = 0;
+
+ return zf;
+}
+
+/* retourne x>>s , en testant le signe de x */
+static inline int
+ShiftRight (int x, const unsigned char s)
+{
+ if (x < 0)
+ return -(-x >> s);
+ else
+ return x >> s;
+}
+
+/*
+ calculer px et py en fonction de x,y,middleX,middleY et theMode
+ px et py indique la nouvelle position (en sqrtperte ieme de pixel)
+ (valeur * 16)
+*/
+void
+calculatePXandPY (GoomData * gd, int x, int y, int *px, int *py)
+{
+ ZoomFilterData *zf = gd->zfd;
+ int middleX, middleY;
+ guint32 resoly = zf->res_y;
+ int vPlaneEffect = zf->vPlaneEffect;
+ int hPlaneEffect = zf->hPlaneEffect;
+ int vitesse = zf->vitesse;
+ char theMode = zf->mode;
+
+ if (theMode == WATER_MODE) {
+ int wavesp = zf->wavesp;
+ int wave = zf->wave;
+ int yy = y + RAND (gd) % 4 + wave / 10;
+
+ yy -= RAND (gd) % 4;
+ if (yy < 0)
+ yy = 0;
+ if (yy >= resoly)
+ yy = resoly - 1;
+
+ *px = (x << 4) + zf->firedec[yy] + (wave / 10);
+ *py = (y << 4) + 132 - ((vitesse < 132) ? vitesse : 131);
+
+ wavesp += RAND (gd) % 3;
+ wavesp -= RAND (gd) % 3;
+ if (wave < -10)
+ wavesp += 2;
+ if (wave > 10)
+ wavesp -= 2;
+ wave += (wavesp / 10) + RAND (gd) % 3;
+ wave -= RAND (gd) % 3;
+ if (wavesp > 100)
+ wavesp = (wavesp * 9) / 10;
+
+ zf->wavesp = wavesp;
+ zf->wave = wave;
+ } else {
+ int dist;
+ register int vx, vy;
+ int fvitesse = vitesse << 4;
+
+ middleX = zf->middleX;
+ middleY = zf->middleY;
+
+ if (zf->noisify) {
+ x += RAND (gd) % zf->noisify;
+ x -= RAND (gd) % zf->noisify;
+ y += RAND (gd) % zf->noisify;
+ y -= RAND (gd) % zf->noisify;
+ }
+
+ if (hPlaneEffect)
+ vx = ((x - middleX) << 9) + hPlaneEffect * (y - middleY);
+ else
+ vx = (x - middleX) << 9;
+
+ if (vPlaneEffect)
+ vy = ((y - middleY) << 9) + vPlaneEffect * (x - middleX);
+ else
+ vy = (y - middleY) << 9;
+
+ switch (theMode) {
+ case WAVE_MODE:
+ dist =
+ ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
+ 9) * ShiftRight (vy, 9);
+ fvitesse *=
+ 1024 +
+ ShiftRight (sintable[(unsigned short) (0xffff * dist *
+ EFFECT_DISTORS)], 6);
+ fvitesse /= 1024;
+ break;
+ case CRYSTAL_BALL_MODE:
+ dist =
+ ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
+ 9) * ShiftRight (vy, 9);
+ fvitesse += (dist * EFFECT_DISTORS >> 10);
+ break;
+ case AMULETTE_MODE:
+ dist =
+ ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
+ 9) * ShiftRight (vy, 9);
+ fvitesse -= (dist * EFFECT_DISTORS >> 4);
+ break;
+ case SCRUNCH_MODE:
+ dist =
+ ShiftRight (vx, 9) * ShiftRight (vx, 9) + ShiftRight (vy,
+ 9) * ShiftRight (vy, 9);
+ fvitesse -= (dist * EFFECT_DISTORS >> 9);
+ break;
+ }
+ if (vx < 0)
+ *px = (middleX << 4) - (-(vx * fvitesse) >> 16);
+ else
+ *px = (middleX << 4) + ((vx * fvitesse) >> 16);
+ if (vy < 0)
+ *py = (middleY << 4) - (-(vy * fvitesse) >> 16);
+ else
+ *py = (middleY << 4) + ((vy * fvitesse) >> 16);
+ }
+}
+
+/*#define _DEBUG */
+
+static inline void
+setPixelRGB (Uint * buffer, Uint x, Uint y, Color c,
+ guint32 resolx, guint32 resoly)
+{
+/* buffer[ y*WIDTH + x ] = (c.r<<16)|(c.v<<8)|c.b */
+#ifdef _DEBUG_PIXEL
+ if (x + y * resolx >= resolx * resoly) {
+ fprintf (stderr, "setPixel ERROR : hors du tableau... %i, %i\n", x, y);
+ /*exit (1) ; */
+ }
+#endif
+
+#ifdef USE_DGA
+ buffer[y * resolx + x] = (c.b << 16) | (c.v << 8) | c.r;
+#else
+ buffer[y * resolx + x] = (c.r << 16) | (c.v << 8) | c.b;
+#endif
+}
+
+
+static inline void
+setPixelRGB_ (Uint * buffer, Uint x, Color c, guint32 resolx, guint32 resoly)
+{
+#ifdef _DEBUG
+ if (x >= resolx * resoly) {
+ printf ("setPixel ERROR : hors du tableau... %i >= %i*%i (%i)\n", x, resolx,
+ resoly, resolx * resoly);
+ exit (1);
+ }
+#endif
+
+#ifdef USE_DGA
+ buffer[x] = (c.b << 16) | (c.v << 8) | c.r;
+#else
+ buffer[x] = (c.r << 16) | (c.v << 8) | c.b;
+#endif
+}
+
+
+
+static inline void
+getPixelRGB (Uint * buffer, Uint x, Uint y, Color * c,
+ guint32 resolx, guint32 resoly)
+{
+ register unsigned char *tmp8;
+
+#ifdef _DEBUG
+ if (x + y * resolx >= resolx * resoly) {
+ printf ("getPixel ERROR : hors du tableau... %i, %i\n", x, y);
+ exit (1);
+ }
+#endif
+
+#ifdef __BIG_ENDIAN__
+ c->b = *(unsigned char *) (tmp8 =
+ (unsigned char *) (buffer + (x + y * resolx)));
+ c->r = *(unsigned char *) (++tmp8);
+ c->v = *(unsigned char *) (++tmp8);
+ c->b = *(unsigned char *) (++tmp8);
+
+#else
+ /* ATTENTION AU PETIT INDIEN */
+ c->b = *(unsigned char *) (tmp8 =
+ (unsigned char *) (buffer + (x + y * resolx)));
+ c->v = *(unsigned char *) (++tmp8);
+ c->r = *(unsigned char *) (++tmp8);
+/* *c = (Color) buffer[x+y*WIDTH] ; */
+#endif
+}
+
+
+static inline void
+getPixelRGB_ (Uint * buffer, Uint x, Color * c, guint32 resolx, guint32 resoly)
+{
+ register unsigned char *tmp8;
+
+#ifdef _DEBUG
+ if (x >= resolx * resoly) {
+ printf ("getPixel ERROR : hors du tableau... %i\n", x);
+ exit (1);
+ }
+#endif
+
+#ifdef __BIG_ENDIAN__
+ c->b = *(unsigned char *) (tmp8 = (unsigned char *) (buffer + x));
+ c->r = *(unsigned char *) (++tmp8);
+ c->v = *(unsigned char *) (++tmp8);
+ c->b = *(unsigned char *) (++tmp8);
+
+#else
+ /* ATTENTION AU PETIT INDIEN */
+ tmp8 = (unsigned char *) (buffer + x);
+ c->b = *(unsigned char *) (tmp8++);
+ c->v = *(unsigned char *) (tmp8++);
+ c->r = *(unsigned char *) (tmp8);
+/* *c = (Color) buffer[x+y*WIDTH] ; */
+#endif
+}
+
+static void
+zoomFilterSetResolution (GoomData * gd, ZoomFilterData * zf)
+{
+ unsigned short us;
+
+ if (zf->buffsize >= gd->buffsize) {
+ zf->res_x = gd->resolx;
+ zf->res_y = gd->resoly;
+ zf->middleX = gd->resolx / 2;
+ zf->middleY = gd->resoly - 1;
+
+ return;
+ }
+#ifndef USE_ASM
+ if (zf->buffer)
+ free (zf->buffer);
+ zf->buffer = 0;
+#else
+ if (coeffs)
+ free (freecoeffs);
+ coeffs = 0;
+#endif
+ zf->middleX = gd->resolx / 2;
+ zf->middleY = gd->resoly - 1;
+ zf->res_x = gd->resolx;
+ zf->res_y = gd->resoly;
+
+ if (zf->firedec)
+ free (zf->firedec);
+ zf->firedec = 0;
+
+ zf->buffsize = gd->resolx * gd->resoly * sizeof (unsigned int);
+
+#ifdef USE_ASM
+ freecoeffs = (unsigned int *)
+ malloc (resx * resy * 2 * sizeof (unsigned int) + 128);
+ coeffs = (guint32 *) ((1 + ((unsigned int) (freecoeffs)) / 128) * 128);
+
+#else
+ zf->buffer = calloc (sizeof (guint32), zf->buffsize * 5);
+ zf->pos10 = zf->buffer;
+ zf->c[0] = zf->pos10 + zf->buffsize;
+ zf->c[1] = zf->c[0] + zf->buffsize;
+ zf->c[2] = zf->c[1] + zf->buffsize;
+ zf->c[3] = zf->c[2] + zf->buffsize;
+#endif
+ zf->firedec = (int *) malloc (zf->res_y * sizeof (int));
+
+ if (firstTime) {
+ firstTime = 0;
+
+ /* generation d'une table de sinus */
+ for (us = 0; us < 0xffff; us++) {
+ sintable[us] = (int) (1024.0f * sin (us * 2 * 3.31415f / 0xffff));
+ }
+ }
+
+ {
+ int loopv;
+
+ for (loopv = zf->res_y; loopv != 0;) {
+ int decc = 0;
+ int spdc = 0;
+ int accel = 0;
+
+ loopv--;
+ zf->firedec[loopv] = decc;
+ decc += spdc / 10;
+ spdc += RAND (gd) % 3;
+ spdc -= RAND (gd) % 3;
+
+ if (decc > 4)
+ spdc -= 1;
+ if (decc < -4)
+ spdc += 1;
+
+ if (spdc > 30)
+ spdc = spdc - RAND (gd) % 3 + accel / 10;
+ if (spdc < -30)
+ spdc = spdc + RAND (gd) % 3 + accel / 10;
+
+ if (decc > 8 && spdc > 1)
+ spdc -= RAND (gd) % 3 - 2;
+
+ if (decc < -8 && spdc < -1)
+ spdc += RAND (gd) % 3 + 2;
+
+ if (decc > 8 || decc < -8)
+ decc = decc * 8 / 9;
+
+ accel += RAND (gd) % 2;
+ accel -= RAND (gd) % 2;
+ if (accel > 20)
+ accel -= 2;
+ if (accel < -20)
+ accel += 2;
+ }
+ }
+}
+
+void
+zoomFilterDestroy (ZoomFilterData * zf)
+{
+ if (zf) {
+ if (zf->firedec)
+ free (zf->firedec);
+ if (zf->buffer)
+ free (zf->buffer);
+ free (zf);
+ }
+}
+
+/*===============================================================*/
+void
+zoomFilterFastRGB (GoomData * goomdata, ZoomFilterData * zf, int zfd_update)
+{
+ guint32 prevX = goomdata->resolx;
+ guint32 prevY = goomdata->resoly;
+
+ guint32 *pix1 = goomdata->p1;
+ guint32 *pix2 = goomdata->p2;
+ unsigned int *pos10;
+ unsigned int **c;
+
+ Uint x, y;
+
+/* static unsigned int prevX = 0, prevY = 0; */
+
+#ifdef USE_ASM
+ expix1 = pix1;
+ expix2 = pix2;
+#else
+ Color couleur;
+ Color col1, col2, col3, col4;
+ Uint position;
+#endif
+
+ if ((goomdata->resolx != zf->res_x) || (goomdata->resoly != zf->res_y)) {
+ zoomFilterSetResolution (goomdata, zf);
+ }
+
+ pos10 = zf->pos10;
+ c = zf->c;
+
+ if (zfd_update) {
+ guchar sqrtperte = zf->sqrtperte;
+ gint start_y = 0;
+
+ if (zf->reverse)
+ zf->vitesse = 256 - zf->vitesse;
+
+ /* generation du buffer */
+ for (y = 0; y < zf->res_y; y++) {
+ gint y_16 = y << 4;
+ gint max_px = (prevX - 1) * sqrtperte;
+ gint max_py = (prevY - 1) * sqrtperte;
+
+ for (x = 0; x < zf->res_x; x++) {
+ gint px, py;
+ guchar coefv, coefh;
+
+ /* calculer px et py en fonction de */
+ /* x,y,middleX,middleY et theMode */
+ calculatePXandPY (goomdata, x, y, &px, &py);
+
+ if ((px == x << 4) && (py == y_16))
+ py += 8;
+
+ if ((py < 0) || (px < 0) || (py >= max_py) || (px >= max_px)) {
+#ifdef USE_ASM
+ coeffs[(y * prevX + x) * 2] = 0;
+ coeffs[(y * prevX + x) * 2 + 1] = 0;
+#else
+ pos10[start_y + x] = 0;
+ c[0][start_y + x] = 0;
+ c[1][start_y + x] = 0;
+ c[2][start_y + x] = 0;
+ c[3][start_y + x] = 0;
+#endif
+ } else {
+ int npx10;
+ int npy10;
+ int pos;
+
+ npx10 = (px / sqrtperte);
+ npy10 = (py / sqrtperte);
+
+/* if (npx10 >= prevX) fprintf(stderr,"error npx:%d",npx10);
+ if (npy10 >= prevY) fprintf(stderr,"error npy:%d",npy10);
+*/
+ coefh = px % sqrtperte;
+ coefv = py % sqrtperte;
+#ifdef USE_ASM
+ pos = (y * prevX + x) * 2;
+ coeffs[pos] = (npx10 + prevX * npy10) * 4;
+
+ if (!(coefh || coefv))
+ coeffs[pos + 1] = (sqrtperte * sqrtperte - 1);
+ else
+ coeffs[pos + 1] = ((sqrtperte - coefh) * (sqrtperte - coefv));
+
+ coeffs[pos + 1] |= (coefh * (sqrtperte - coefv)) << 8;
+ coeffs[pos + 1] |= ((sqrtperte - coefh) * coefv) << 16;
+ coeffs[pos + 1] |= (coefh * coefv) << 24;
+#else
+ pos = start_y + x;
+ pos10[pos] = npx10 + prevX * npy10;
+
+ if (!(coefh || coefv))
+ c[0][pos] = sqrtperte * sqrtperte - 1;
+ else
+ c[0][pos] = (sqrtperte - coefh) * (sqrtperte - coefv);
+
+ c[1][pos] = coefh * (sqrtperte - coefv);
+ c[2][pos] = (sqrtperte - coefh) * coefv;
+ c[3][pos] = coefh * coefv;
+#endif
+ }
+ }
+ /* Advance start of line index */
+ start_y += prevX;
+ }
+ }
+#ifdef USE_ASM
+#ifdef MMX
+ zoom_width = prevX;
+ mmx_zoom_size = prevX * prevY;
+ mmx_zoom ();
+#endif
+
+#ifdef POWERPC
+ zoom_width = prevX;
+ if (useAltivec) {
+ ppcsize4 = ((unsigned int) (prevX * prevY)) / 4;
+ ppc_zoom_altivec ();
+ } else {
+ ppcsize4 = ((unsigned int) (prevX * prevY));
+ ppc_zoom ();
+ }
+#endif
+#else
+ for (position = 0; position < prevX * prevY; position++) {
+ getPixelRGB_ (pix1, pos10[position], &col1, goomdata->resolx,
+ goomdata->resoly);
+ getPixelRGB_ (pix1, pos10[position] + 1, &col2, goomdata->resolx,
+ goomdata->resoly);
+ getPixelRGB_ (pix1, pos10[position] + prevX, &col3, goomdata->resolx,
+ goomdata->resoly);
+ getPixelRGB_ (pix1, pos10[position] + prevX + 1, &col4, goomdata->resolx,
+ goomdata->resoly);
+
+ couleur.r = col1.r * c[0][position]
+ + col2.r * c[1][position]
+ + col3.r * c[2][position]
+ + col4.r * c[3][position];
+ couleur.r >>= zf->pertedec;
+
+ couleur.v = col1.v * c[0][position]
+ + col2.v * c[1][position]
+ + col3.v * c[2][position]
+ + col4.v * c[3][position];
+ couleur.v >>= zf->pertedec;
+
+ couleur.b = col1.b * c[0][position]
+ + col2.b * c[1][position]
+ + col3.b * c[2][position]
+ + col4.b * c[3][position];
+ couleur.b >>= zf->pertedec;
+
+ setPixelRGB_ (pix2, position, couleur, goomdata->resolx, goomdata->resoly);
+ }
+#endif
+}
+
+
+void
+pointFilter (GoomData * goomdata, Color c,
+ float t1, float t2, float t3, float t4, Uint cycle)
+{
+ Uint *pix1 = goomdata->p1;
+ ZoomFilterData *zf = goomdata->zfd;
+ Uint x = (Uint) (zf->middleX + (int) (t1 * cos ((float) cycle / t3)));
+ Uint y = (Uint) (zf->middleY + (int) (t2 * sin ((float) cycle / t4)));
+
+ if ((x > 1) && (y > 1) && (x < goomdata->resolx - 2)
+ && (y < goomdata->resoly - 2)) {
+ setPixelRGB (pix1, x + 1, y, c, goomdata->resolx, goomdata->resoly);
+ setPixelRGB (pix1, x, y + 1, c, goomdata->resolx, goomdata->resoly);
+ setPixelRGB (pix1, x + 1, y + 1, WHITE, goomdata->resolx, goomdata->resoly);
+ setPixelRGB (pix1, x + 2, y + 1, c, goomdata->resolx, goomdata->resoly);
+ setPixelRGB (pix1, x + 1, y + 2, c, goomdata->resolx, goomdata->resoly);
+ }
+}
diff --git a/gst/goom2k1/filters.h b/gst/goom2k1/filters.h
new file mode 100644
index 00000000..65eb3e25
--- /dev/null
+++ b/gst/goom2k1/filters.h
@@ -0,0 +1,83 @@
+#ifndef FILTERS_H
+#define FILTERS_H
+
+#include <glib.h>
+
+#include "graphic.h"
+#include "goom_core.h"
+
+#define NORMAL_MODE 0
+#define WAVE_MODE 1
+#define CRYSTAL_BALL_MODE 2
+#define SCRUNCH_MODE 3
+#define AMULETTE_MODE 4
+#define WATER_MODE 5
+
+struct ZoomFilterData
+{
+ int vitesse;
+ unsigned char pertedec;
+ unsigned char sqrtperte;
+ int middleX;
+ int middleY;
+ char reverse;
+ char mode;
+ /** @since June 2001 */
+ int hPlaneEffect;
+ int vPlaneEffect;
+ char noisify;
+
+ guint32 res_x;
+ guint32 res_y;
+ guint32 buffsize;
+
+ guint32 *buffer;
+ guint32 *pos10;
+ guint32 *c[4];
+ int *firedec;
+
+ int wave;
+ int wavesp;
+};
+
+void pointFilter(GoomData *goomdata, Color c,
+ float t1, float t2, float t3, float t4,
+ guint32 cycle);
+
+/* filtre de zoom :
+ le contenu de pix1 est copie dans pix2, avec l'effet appliqué
+ midx et midy represente le centre du zoom
+
+void zoomFilter(Uint *pix1, Uint *pix2, Uint middleX, Uint middleY);
+void zoomFilterRGB(Uint *pix1,
+Uint *pix2,
+Uint middleX,
+Uint middleY);
+*/
+
+ZoomFilterData *zoomFilterNew ();
+void zoomFilterDestroy (ZoomFilterData *zf);
+void zoomFilterFastRGB (GoomData *goomdata, ZoomFilterData *zf,
+ int zfd_update);
+
+/* filtre sin :
+ le contenu de pix1 est copie dans pix2, avec l'effet appliqué
+ cycle est la variable de temps.
+ mode vaut SIN_MUL ou SIN_ADD
+ rate est le pourcentage de l'effet appliqué
+ lenght : la longueur d'onde (1..10) [5]
+ speed : la vitesse (1..100) [10]
+*/
+/*
+void sinFilter(Uint *pix1,Uint *pix2,
+ Uint cycle,
+ Uint mode,
+ Uint rate,
+ char lenght,
+ Uint speed);
+*/
+
+#define SIN_MUL 1
+#define SIN_ADD 2
+
+#endif
diff --git a/gst/goom2k1/filters_mmx.s b/gst/goom2k1/filters_mmx.s
new file mode 100644
index 00000000..337de56c
--- /dev/null
+++ b/gst/goom2k1/filters_mmx.s
@@ -0,0 +1,130 @@
+;// file : mmx_zoom.s
+;// author : JC Hoelt <jeko@free.fr>
+;//
+;// history
+;// 07/01/2001 : Changing FEMMS to EMMS : slower... but run on intel machines
+;// 03/01/2001 : WIDTH and HEIGHT are now variable
+;// 28/12/2000 : adding comments to the code, suppress some useless lines
+;// 27/12/2000 : reducing memory access... improving performance by 20%
+;// coefficients are now on 1 byte
+;// 22/12/2000 : Changing data structure
+;// 16/12/2000 : AT&T version
+;// 14/12/2000 : unrolling loop
+;// 12/12/2000 : 64 bits memory access
+
+
+.data
+
+thezero:
+ .long 0x00000000
+ .long 0x00000000
+
+
+.text
+
+.globl mmx_zoom ;// name of the function to call by C program
+.extern coeffs ;// the transformation buffer
+.extern expix1,expix2 ;// the source and destination buffer
+.extern mmx_zoom_size, zoom_width ;// size of the buffers
+
+.align 16
+mmx_zoom:
+
+push %ebp
+push %esp
+
+;// initialisation du mm7 à zero
+movq (thezero), %mm7
+
+movl zoom_width, %eax
+movl $4, %ebx
+mull %ebx
+movl %eax, %ebp
+
+movl (coeffs), %eax
+movl (expix1), %edx
+movl (expix2), %ebx
+movl $10, %edi
+movl mmx_zoom_size, %ecx
+
+.while:
+ ;// esi <- nouvelle position
+ movl (%eax), %esi
+ leal (%edx, %esi), %esi
+
+ ;// recuperation des deux premiers pixels dans mm0 et mm1
+ movq (%esi), %mm0 /* b1-v1-r1-a1-b2-v2-r2-a2 */
+ movq %mm0, %mm1 /* b1-v1-r1-a1-b2-v2-r2-a2 */
+
+ ;// recuperation des 4 coefficients
+ movd 4(%eax), %mm6 /* ??-??-??-??-c4-c3-c2-c1 */
+ ;// depackage du premier pixel
+ punpcklbw %mm7, %mm0 /* 00-b2-00-v2-00-r2-00-a2 */
+
+ movq %mm6, %mm5 /* ??-??-??-??-c4-c3-c2-c1 */
+ ;// depackage du 2ieme pixel
+ punpckhbw %mm7, %mm1 /* 00-b1-00-v1-00-r1-00-a1 */
+
+ ;// extraction des coefficients...
+ punpcklbw %mm5, %mm6 /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ movq %mm6, %mm4 /* c4-c4-c3-c3-c2-c2-c1-c1 */
+ movq %mm6, %mm5 /* c4-c4-c3-c3-c2-c2-c1-c1 */
+
+ punpcklbw %mm5, %mm6 /* c2-c2-c2-c2-c1-c1-c1-c1 */
+ punpckhbw %mm5, %mm4 /* c4-c4-c4-c4-c3-c3-c3-c3 */
+
+ movq %mm6, %mm3 /* c2-c2-c2-c2-c1-c1-c1-c1 */
+ punpcklbw %mm7, %mm6 /* 00-c1-00-c1-00-c1-00-c1 */
+ punpckhbw %mm7, %mm3 /* 00-c2-00-c2-00-c2-00-c2 */
+
+ ;// multiplication des pixels par les coefficients
+ pmullw %mm6, %mm0 /* c1*b2-c1*v2-c1*r2-c1*a2 */
+ pmullw %mm3, %mm1 /* c2*b1-c2*v1-c2*r1-c2*a1 */
+ paddw %mm1, %mm0
+
+ ;// ...extraction des 2 derniers coefficients
+ movq %mm4, %mm5 /* c4-c4-c4-c4-c3-c3-c3-c3 */
+ punpcklbw %mm7, %mm4 /* 00-c3-00-c3-00-c3-00-c3 */
+ punpckhbw %mm7, %mm5 /* 00-c4-00-c4-00-c4-00-c4 */
+
+ ;// recuperation des 2 derniers pixels
+ movq (%esi,%ebp), %mm1
+ movq %mm1, %mm2
+
+ ;// depackage des pixels
+ punpcklbw %mm7, %mm1
+ punpckhbw %mm7, %mm2
+
+ ;// multiplication pas les coeffs
+ pmullw %mm4, %mm1
+ pmullw %mm5, %mm2
+
+ ;// ajout des valeurs obtenues à la valeur finale
+ paddw %mm1, %mm0
+ paddw %mm2, %mm0
+
+ ;// division par 256 = 16+16+16+16, puis repackage du pixel final
+ psrlw $8, %mm0
+ packuswb %mm7, %mm0
+
+ ;// passage au suivant
+ leal 8(%eax), %eax
+
+ decl %ecx
+ ;// enregistrement du resultat
+ movd %mm0, (%ebx)
+ leal 4(%ebx), %ebx
+
+ ;// test de fin du tantque
+ cmpl $0, %ecx ;// 400x300
+
+jz .fin_while
+jmp .while
+
+.fin_while:
+emms
+
+pop %esp
+pop %ebp
+
+ret ;//The End
diff --git a/gst/goom2k1/goom.vcproj b/gst/goom2k1/goom.vcproj
new file mode 100644
index 00000000..7d4c1efa
--- /dev/null
+++ b/gst/goom2k1/goom.vcproj
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="goom"
+ ProjectGUID="{979C216F-0ACF-4956-AE00-055A42D678B4}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../win32/Debug"
+ IntermediateDirectory="../../win32/Debug"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;&quot;../../gst-libs&quot;;../../../popt/include;../../../libxml2/include/libxml2"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;goom_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib"
+ OutputFile="$(OutDir)/gstgoom2k1.dll"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="../../../gstreamer/win32/Debug;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib"
+ ModuleDefinitionFile=""
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/goom.pdb"
+ SubSystem="2"
+ OptimizeReferences="2"
+ ImportLibrary="$(OutDir)/gstgoom2k1.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="../../win32/Release"
+ IntermediateDirectory="../../win32/Release"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../../gstreamer/win32;../../../gstreamer;../../../gstreamer/libs;../../../glib;../../../glib/glib;../../../glib/gmodule;&quot;../../gst-libs&quot;;../../../popt/include;../../../libxml2/include/libxml2"
+ PreprocessorDefinitions="WIN32;NDEBUG;GST_DISABLE_GST_DEBUG;_WINDOWS;_USRDLL;goom_EXPORTS;HAVE_CONFIG_H;_USE_MATH_DEFINES"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="glib-2.0.lib gmodule-2.0.lib gthread-2.0.lib gobject-2.0.lib libgstreamer.lib gstbytestream.lib iconv.lib intl.lib"
+ OutputFile="$(OutDir)/gstgoom2k1.dll"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="../../../gstreamer/win32/Release;../../../glib/glib;../../../glib/gmodule;../../../glib/gthread;../../../glib/gobject;../../../gettext/lib;../../../libiconv/lib"
+ ModuleDefinitionFile=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary="$(OutDir)/gstgoom2k1.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy /Y $(TargetPath) c:\gstreamer\plugins"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\gstgoom2k1.c">
+ </File>
+ <File
+ RelativePath=".\goom_core.c">
+ </File>
+ <File
+ RelativePath=".\graphic.c">
+ </File>
+ <File
+ RelativePath=".\lines.c">
+ </File>
+ <File
+ RelativePath=".\filters.c">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\filters.h">
+ </File>
+ <File
+ RelativePath=".\goom_core.h">
+ </File>
+ <File
+ RelativePath=".\goom_tools.h">
+ </File>
+ <File
+ RelativePath=".\graphic.h">
+ </File>
+ <File
+ RelativePath=".\lines.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/gst/goom2k1/goom_core.c b/gst/goom2k1/goom_core.c
new file mode 100644
index 00000000..d66ffe25
--- /dev/null
+++ b/gst/goom2k1/goom_core.c
@@ -0,0 +1,412 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <glib.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include "goom_core.h"
+#include "goom_tools.h"
+#include "filters.h"
+#include "lines.h"
+
+/*#define VERBOSE */
+
+#ifdef VERBOSE
+#include <stdio.h>
+#endif
+
+#define STOP_SPEED 128
+
+void
+goom_init (GoomData * goomdata, guint32 resx, guint32 resy)
+{
+#ifdef VERBOSE
+ printf ("GOOM: init (%d, %d);\n", resx, resy);
+#endif
+ goomdata->resolx = 0;
+ goomdata->resoly = 0;
+ goomdata->buffsize = 0;
+
+ goomdata->pixel = NULL;
+ goomdata->back = NULL;
+ goomdata->p1 = NULL;
+ goomdata->p2 = NULL;
+
+ goom_set_resolution (goomdata, resx, resy);
+ RAND_INIT (goomdata, GPOINTER_TO_INT (goomdata->pixel));
+ goomdata->cycle = 0;
+
+
+ goomdata->goomlimit = 2; /* sensibilité du goom */
+ goomdata->zfd = zoomFilterNew ();
+ goomdata->lockvar = 0; /* pour empecher de nouveaux changements */
+ goomdata->goomvar = 0; /* boucle des gooms */
+ goomdata->totalgoom = 0; /* nombre de gooms par seconds */
+ goomdata->agoom = 0; /* un goom a eu lieu.. */
+ goomdata->loopvar = 0; /* mouvement des points */
+ goomdata->speedvar = 0; /* vitesse des particules */
+ goomdata->lineMode = 0; /* l'effet lineaire a dessiner */
+}
+
+void
+goom_set_resolution (GoomData * goomdata, guint32 resx, guint32 resy)
+{
+ guint32 buffsize = resx * resy;
+
+ if ((goomdata->resolx == resx) && (goomdata->resoly == resy))
+ return;
+
+ if (goomdata->buffsize < buffsize) {
+ if (goomdata->pixel)
+ free (goomdata->pixel);
+ if (goomdata->back)
+ free (goomdata->back);
+ goomdata->pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
+ goomdata->back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
+ goomdata->buffsize = buffsize;
+
+ goomdata->p1 =
+ (void *) (((unsigned long) goomdata->pixel + 0x7f) & (~0x7f));
+ goomdata->p2 = (void *) (((unsigned long) goomdata->back + 0x7f) & (~0x7f));
+ }
+
+ goomdata->resolx = resx;
+ goomdata->resoly = resy;
+
+ memset (goomdata->pixel, 0, buffsize * sizeof (guint32) + 128);
+ memset (goomdata->back, 0, buffsize * sizeof (guint32) + 128);
+}
+
+guint32 *
+goom_update (GoomData * goomdata, gint16 data[2][512])
+{
+ guint32 *return_val;
+ guint32 pointWidth;
+ guint32 pointHeight;
+ int incvar; /* volume du son */
+ int accelvar; /* acceleration des particules */
+ int i;
+ float largfactor; /* elargissement de l'intervalle d'évolution des points */
+ int zfd_update = 0;
+ int resolx = goomdata->resolx;
+ int resoly = goomdata->resoly;
+ ZoomFilterData *pzfd = goomdata->zfd;
+ guint32 *tmp;
+
+ /* test if the config has changed, update it if so */
+
+ pointWidth = (resolx * 2) / 5;
+ pointHeight = (resoly * 2) / 5;
+
+ /* ! etude du signal ... */
+ incvar = 0;
+ for (i = 0; i < 512; i++) {
+ if (incvar < data[0][i])
+ incvar = data[0][i];
+ }
+
+ accelvar = incvar / 5000;
+ if (goomdata->speedvar > 5) {
+ accelvar--;
+ if (goomdata->speedvar > 20)
+ accelvar--;
+ if (goomdata->speedvar > 40)
+ goomdata->speedvar = 40;
+ }
+ accelvar--;
+ goomdata->speedvar += accelvar;
+
+ if (goomdata->speedvar < 0)
+ goomdata->speedvar = 0;
+ if (goomdata->speedvar > 40)
+ goomdata->speedvar = 40;
+
+
+ /* ! calcul du deplacement des petits points ... */
+
+ largfactor =
+ ((float) goomdata->speedvar / 40.0f + (float) incvar / 50000.0f) / 1.5f;
+ if (largfactor > 1.5f)
+ largfactor = 1.5f;
+
+ for (i = 1; i * 15 <= goomdata->speedvar + 15; i++) {
+ goomdata->loopvar += goomdata->speedvar + 1;
+
+ pointFilter (goomdata,
+ YELLOW,
+ ((pointWidth - 6.0f) * largfactor + 5.0f),
+ ((pointHeight - 6.0f) * largfactor + 5.0f),
+ i * 152.0f, 128.0f, goomdata->loopvar + i * 2032);
+ pointFilter (goomdata, ORANGE,
+ ((pointWidth / 2) * largfactor) / i + 10.0f * i,
+ ((pointHeight / 2) * largfactor) / i + 10.0f * i,
+ 96.0f, i * 80.0f, goomdata->loopvar / i);
+ pointFilter (goomdata, VIOLET,
+ ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
+ ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
+ i + 122.0f, 134.0f, goomdata->loopvar / i);
+ pointFilter (goomdata, BLACK,
+ ((pointHeight / 3) * largfactor + 20.0f),
+ ((pointHeight / 3) * largfactor + 20.0f),
+ 58.0f, i * 66.0f, goomdata->loopvar / i);
+ pointFilter (goomdata, WHITE,
+ (pointHeight * largfactor + 10.0f * i) / i,
+ (pointHeight * largfactor + 10.0f * i) / i,
+ 66.0f, 74.0f, goomdata->loopvar + i * 500);
+ }
+
+ /* diminuer de 1 le temps de lockage */
+ /* note pour ceux qui n'ont pas suivis : le lockvar permet d'empecher un */
+ /* changement d'etat du plugins juste apres un autre changement d'etat. oki ? */
+ if (--goomdata->lockvar < 0)
+ goomdata->lockvar = 0;
+
+ /* temps du goom */
+ if (--goomdata->agoom < 0)
+ goomdata->agoom = 0;
+
+ /* on verifie qu'il ne se pas un truc interressant avec le son. */
+ if ((accelvar > goomdata->goomlimit) || (accelvar < -goomdata->goomlimit)) {
+ /* UN GOOM !!! YAHOO ! */
+ goomdata->totalgoom++;
+ goomdata->agoom = 20; /* mais pdt 20 cycles, il n'y en aura plus. */
+ goomdata->lineMode = (goomdata->lineMode + 1) % 20; /* Tous les 10 gooms on change de mode lineaire */
+
+ /* changement eventuel de mode */
+ switch (iRAND (goomdata, 10)) {
+ case 0:
+ case 1:
+ case 2:
+ pzfd->mode = WAVE_MODE;
+ pzfd->vitesse = STOP_SPEED - 1;
+ pzfd->reverse = 0;
+ break;
+ case 3:
+ case 4:
+ pzfd->mode = CRYSTAL_BALL_MODE;
+ break;
+ case 5:
+ pzfd->mode = AMULETTE_MODE;
+ break;
+ case 6:
+ pzfd->mode = WATER_MODE;
+ break;
+ case 7:
+ pzfd->mode = SCRUNCH_MODE;
+ break;
+ default:
+ pzfd->mode = NORMAL_MODE;
+ }
+ }
+
+ /* tout ceci ne sera fait qu'en cas de non-blocage */
+ if (goomdata->lockvar == 0) {
+ /* reperage de goom (acceleration forte de l'acceleration du volume) */
+ /* -> coup de boost de la vitesse si besoin.. */
+ if ((accelvar > goomdata->goomlimit) || (accelvar < -goomdata->goomlimit)) {
+ goomdata->goomvar++;
+ /*if (goomvar % 1 == 0) */
+ {
+ guint32 vtmp;
+ guint32 newvit;
+
+ newvit = STOP_SPEED - goomdata->speedvar / 2;
+ /* retablir le zoom avant.. */
+ if ((pzfd->reverse) && (!(goomdata->cycle % 12)) && (rand () % 3 == 0)) {
+ pzfd->reverse = 0;
+ pzfd->vitesse = STOP_SPEED - 2;
+ goomdata->lockvar = 50;
+ }
+ if (iRAND (goomdata, 10) == 0) {
+ pzfd->reverse = 1;
+ goomdata->lockvar = 100;
+ }
+
+ /* changement de milieu.. */
+ switch (iRAND (goomdata, 20)) {
+ case 0:
+ pzfd->middleY = resoly - 1;
+ pzfd->middleX = resolx / 2;
+ break;
+ case 1:
+ pzfd->middleX = resolx - 1;
+ break;
+ case 2:
+ pzfd->middleX = 1;
+ break;
+ default:
+ pzfd->middleY = resoly / 2;
+ pzfd->middleX = resolx / 2;
+ }
+
+ if (pzfd->mode == WATER_MODE) {
+ pzfd->middleX = resolx / 2;
+ pzfd->middleY = resoly / 2;
+ }
+
+ switch (vtmp = (iRAND (goomdata, 27))) {
+ case 0:
+ pzfd->vPlaneEffect = iRAND (goomdata, 3);
+ pzfd->vPlaneEffect -= iRAND (goomdata, 3);
+ pzfd->hPlaneEffect = iRAND (goomdata, 3);
+ pzfd->hPlaneEffect -= iRAND (goomdata, 3);
+ break;
+ case 3:
+ pzfd->vPlaneEffect = 0;
+ pzfd->hPlaneEffect = iRAND (goomdata, 8);
+ pzfd->hPlaneEffect -= iRAND (goomdata, 8);
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ pzfd->vPlaneEffect = iRAND (goomdata, 5);
+ pzfd->vPlaneEffect -= iRAND (goomdata, 5);
+ pzfd->hPlaneEffect = -pzfd->vPlaneEffect;
+ break;
+ case 8:
+ pzfd->hPlaneEffect = 5 + iRAND (goomdata, 8);
+ pzfd->vPlaneEffect = -pzfd->hPlaneEffect;
+ break;
+ case 9:
+ pzfd->vPlaneEffect = 5 + iRAND (goomdata, 8);
+ pzfd->hPlaneEffect = -pzfd->hPlaneEffect;
+ break;
+ case 13:
+ pzfd->hPlaneEffect = 0;
+ pzfd->vPlaneEffect = iRAND (goomdata, 10);
+ pzfd->vPlaneEffect -= iRAND (goomdata, 10);
+ break;
+ default:
+ if (vtmp < 10) {
+ pzfd->vPlaneEffect = 0;
+ pzfd->hPlaneEffect = 0;
+ }
+ }
+
+ if (iRAND (goomdata, 3) != 0)
+ pzfd->noisify = 0;
+ else {
+ pzfd->noisify = iRAND (goomdata, 3) + 2;
+ goomdata->lockvar *= 3;
+ }
+
+ if (pzfd->mode == AMULETTE_MODE) {
+ pzfd->vPlaneEffect = 0;
+ pzfd->hPlaneEffect = 0;
+ pzfd->noisify = 0;
+ }
+
+ if ((pzfd->middleX == 1) || (pzfd->middleX == resolx - 1)) {
+ pzfd->vPlaneEffect = 0;
+ pzfd->hPlaneEffect = iRAND (goomdata, 2) ? 0 : pzfd->hPlaneEffect;
+ }
+
+ if (newvit < pzfd->vitesse) { /* on accelere */
+ zfd_update = 1;
+ if (((newvit < STOP_SPEED - 7) &&
+ (pzfd->vitesse < STOP_SPEED - 6) &&
+ (goomdata->cycle % 3 == 0)) || (iRAND (goomdata, 40) == 0)) {
+ pzfd->vitesse = STOP_SPEED - 1;
+ pzfd->reverse = !pzfd->reverse;
+ } else {
+ pzfd->vitesse = (newvit + pzfd->vitesse * 4) / 5;
+ }
+ goomdata->lockvar += 50;
+ }
+ }
+ }
+ /* mode mega-lent */
+ if (iRAND (goomdata, 1000) == 0) {
+ /*
+ printf ("coup du sort...\n") ;
+ */
+ zfd_update = 1;
+ pzfd->vitesse = STOP_SPEED - 1;
+ pzfd->pertedec = 8;
+ pzfd->sqrtperte = 16;
+ goomdata->goomvar = 1;
+ goomdata->lockvar += 70;
+ }
+ }
+
+ /* gros frein si la musique est calme */
+ if ((goomdata->speedvar < 1) && (pzfd->vitesse < STOP_SPEED - 4)
+ && (goomdata->cycle % 16 == 0)) {
+ /*
+ printf ("++slow part... %i\n", zfd.vitesse) ;
+ */
+ zfd_update = 1;
+ pzfd->vitesse += 3;
+ pzfd->pertedec = 8;
+ pzfd->sqrtperte = 16;
+ goomdata->goomvar = 0;
+ /*
+ printf ("--slow part... %i\n", zfd.vitesse) ;
+ */
+ }
+
+ /* baisser regulierement la vitesse... */
+ if ((goomdata->cycle % 73 == 0) && (pzfd->vitesse < STOP_SPEED - 5)) {
+ /*
+ printf ("slow down...\n") ;
+ */
+ zfd_update = 1;
+ pzfd->vitesse++;
+ }
+
+ /* arreter de decrémenter au bout d'un certain temps */
+ if ((goomdata->cycle % 101 == 0) && (pzfd->pertedec == 7)) {
+ zfd_update = 1;
+ pzfd->pertedec = 8;
+ pzfd->sqrtperte = 16;
+ }
+
+ /* Zoom here ! */
+ zoomFilterFastRGB (goomdata, pzfd, zfd_update);
+
+ /* si on est dans un goom : afficher les lignes... */
+ if (goomdata->agoom > 15)
+ goom_lines (goomdata, data, ((pzfd->middleX == resolx / 2)
+ && (pzfd->middleY == resoly / 2)
+ && (pzfd->mode != WATER_MODE))
+ ? (goomdata->lineMode / 10) : 0, goomdata->p2, goomdata->agoom - 15);
+
+ return_val = goomdata->p2;
+ tmp = goomdata->p1;
+ goomdata->p1 = goomdata->p2;
+ goomdata->p2 = tmp;
+
+ /* affichage et swappage des buffers.. */
+ goomdata->cycle++;
+
+ /* tous les 100 cycles : vérifier si le taux de goom est correct */
+ /* et le modifier sinon.. */
+ if (!(goomdata->cycle % 100)) {
+ if (goomdata->totalgoom > 15) {
+ /* printf ("less gooms\n") ; */
+ goomdata->goomlimit++;
+ } else {
+ if ((goomdata->totalgoom == 0) && (goomdata->goomlimit > 1))
+ goomdata->goomlimit--;
+ }
+ goomdata->totalgoom = 0;
+ }
+ return return_val;
+}
+
+void
+goom_close (GoomData * goomdata)
+{
+ if (goomdata->pixel != NULL)
+ free (goomdata->pixel);
+ if (goomdata->back != NULL)
+ free (goomdata->back);
+ if (goomdata->zfd != NULL) {
+ zoomFilterDestroy (goomdata->zfd);
+ goomdata->zfd = NULL;
+ }
+ goomdata->pixel = goomdata->back = NULL;
+ RAND_CLOSE (goomdata);
+}
diff --git a/gst/goom2k1/goom_core.h b/gst/goom2k1/goom_core.h
new file mode 100644
index 00000000..1fbc0ee8
--- /dev/null
+++ b/gst/goom2k1/goom_core.h
@@ -0,0 +1,43 @@
+#ifndef _GOOMCORE_H
+#define _GOOMCORE_H
+
+#include <glib.h>
+
+typedef struct ZoomFilterData ZoomFilterData;
+
+typedef struct
+{
+/**-----------------------------------------------------**
+ ** SHARED DATA **
+ **-----------------------------------------------------**/
+ guint32 *pixel;
+ guint32 *back;
+ guint32 *p1, *p2;
+ guint32 cycle;
+
+ guint32 resolx, resoly, buffsize;
+
+ int lockvar; /* pour empecher de nouveaux changements */
+ int goomvar; /* boucle des gooms */
+ int totalgoom; /* nombre de gooms par seconds */
+ int agoom; /* un goom a eu lieu.. */
+ int loopvar; /* mouvement des points */
+ int speedvar; /* vitesse des particules */
+ int lineMode; /* l'effet lineaire a dessiner */
+ char goomlimit; /* sensibilité du goom */
+
+ ZoomFilterData *zfd;
+
+ /* Random table */
+ gint *rand_tab;
+ guint rand_pos;
+} GoomData;
+
+void goom_init (GoomData *goomdata, guint32 resx, guint32 resy);
+void goom_set_resolution (GoomData *goomdata, guint32 resx, guint32 resy);
+
+guint32 *goom_update (GoomData *goomdata, gint16 data [2][512]);
+
+void goom_close (GoomData *goomdata);
+
+#endif
diff --git a/gst/goom2k1/goom_tools.h b/gst/goom2k1/goom_tools.h
new file mode 100644
index 00000000..6178dbaf
--- /dev/null
+++ b/gst/goom2k1/goom_tools.h
@@ -0,0 +1,24 @@
+#ifndef _GOOMTOOLS_H
+#define _GOOMTOOLS_H
+
+#define NB_RAND 0x10000
+
+#define RAND_INIT(gd,i) \
+ srand (i); \
+ if (gd->rand_tab == NULL) \
+ gd->rand_tab = g_malloc (NB_RAND * sizeof(gint)) ;\
+ gd->rand_pos = 0; \
+ while (gd->rand_pos < NB_RAND) \
+ gd->rand_tab [gd->rand_pos++] = rand ();
+
+#define RAND(gd) \
+ (gd->rand_tab[gd->rand_pos = ((gd->rand_pos + 1) % NB_RAND)])
+
+#define RAND_CLOSE(gd) \
+ g_free (gd->rand_tab); \
+ gd->rand_tab = NULL;
+
+/*#define iRAND(i) ((guint32)((float)i * RAND()/RAND_MAX)) */
+#define iRAND(gd,i) (RAND(gd) % i)
+
+#endif
diff --git a/gst/goom2k1/graphic.c b/gst/goom2k1/graphic.c
new file mode 100644
index 00000000..c20f987d
--- /dev/null
+++ b/gst/goom2k1/graphic.c
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "graphic.h"
+
+const Color BLACK = { 0, 0, 0 };
+const Color WHITE = { 0xff, 0xff, 0xff };
+const Color RED = { 0xff, 0, 0 };
+const Color GREEN = { 0, 0xff, 0 };
+const Color BLUE = { 0, 0, 0xff };
+const Color YELLOW = { 0xff, 0xff, 0x33 };
+const Color ORANGE = { 0xff, 0xcc, 0x00 };
+const Color VIOLET = { 0x55, 0x00, 0xff };
diff --git a/gst/goom2k1/graphic.h b/gst/goom2k1/graphic.h
new file mode 100644
index 00000000..4154d7fd
--- /dev/null
+++ b/gst/goom2k1/graphic.h
@@ -0,0 +1,23 @@
+#ifndef GRAPHIC_H
+#define GRAPHIC_H
+
+#include <glib.h> /* defines inline for better portability */
+
+typedef unsigned int Uint;
+
+typedef struct
+{
+ unsigned short r,v,b;
+}
+Color;
+
+extern const Color BLACK;
+extern const Color WHITE;
+extern const Color RED;
+extern const Color BLUE;
+extern const Color GREEN;
+extern const Color YELLOW;
+extern const Color ORANGE;
+extern const Color VIOLET;
+
+#endif /*GRAPHIC_H*/
diff --git a/gst/goom2k1/gstgoom.c b/gst/goom2k1/gstgoom.c
new file mode 100644
index 00000000..812d4239
--- /dev/null
+++ b/gst/goom2k1/gstgoom.c
@@ -0,0 +1,602 @@
+/* gstgoom.c: implementation of goom drawing element
+ * Copyright (C) <2001> Richard Boulton <richard@tartarus.org>
+ * (C) <2006> Wim Taymans <wim at fluendo dot com>
+ *
+ * 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.
+ */
+
+/**
+ * SECTION:element-goom
+ * @see_also: synaesthesia
+ *
+ * <refsect2>
+ * <para>
+ * Goom is an audio visualisation element. It creates warping structures
+ * based on the incomming audio signal.
+ * </para>
+ * <title>Example launch line</title>
+ * <para>
+ * <programlisting>
+ * gst-launch -v audiotestsrc ! goom2k1 ! ffmpegcolorspace ! xvimagesink
+ * </programlisting>
+ * </para>
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <gst/gst.h>
+#include "gstgoom.h"
+#include <gst/video/video.h>
+#include "goom_core.h"
+
+GST_DEBUG_CATEGORY_STATIC (goom_debug);
+#define GST_CAT_DEFAULT goom_debug
+
+/* elementfactory information */
+static const GstElementDetails gst_goom_details =
+GST_ELEMENT_DETAILS ("GOOM: what a GOOM! 2k1",
+ "Visualization",
+ "Takes frames of data and outputs video frames using the GOOM 2k1 filter",
+ "Wim Taymans <wim@fluendo.com>");
+
+/* signals and args */
+enum
+{
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum
+{
+ ARG_0
+ /* FILL ME */
+};
+
+static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_xRGB_HOST_ENDIAN)
+ );
+
+static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", /* the name of the pads */
+ GST_PAD_SINK, /* type of the pad */
+ GST_PAD_ALWAYS, /* ALWAYS/SOMETIMES */
+ GST_STATIC_CAPS ("audio/x-raw-int, "
+ "endianness = (int) BYTE_ORDER, "
+ "signed = (boolean) TRUE, "
+ "width = (int) 16, "
+ "depth = (int) 16, "
+ "rate = (int) [ 8000, 96000 ], " "channels = (int) { 1, 2 }")
+ );
+
+
+static void gst_goom_class_init (GstGoomClass * klass);
+static void gst_goom_base_init (GstGoomClass * klass);
+static void gst_goom_init (GstGoom * goom);
+static void gst_goom_finalize (GObject * object);
+
+static GstStateChangeReturn gst_goom_change_state (GstElement * element,
+ GstStateChange transition);
+
+static GstFlowReturn gst_goom_chain (GstPad * pad, GstBuffer * buffer);
+static gboolean gst_goom_src_event (GstPad * pad, GstEvent * event);
+static gboolean gst_goom_sink_event (GstPad * pad, GstEvent * event);
+
+static gboolean gst_goom_sink_setcaps (GstPad * pad, GstCaps * caps);
+static gboolean gst_goom_src_setcaps (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),
+ (GBaseInitFunc) gst_goom_base_init,
+ 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_base_init (GstGoomClass * klass)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+
+ gst_element_class_set_details (element_class, &gst_goom_details);
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_template));
+}
+
+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_peek_parent (klass);
+
+ gobject_class->finalize = gst_goom_finalize;
+
+ gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_goom_change_state);
+
+ GST_DEBUG_CATEGORY_INIT (goom_debug, "goom", 0, "goom visualisation element");
+}
+
+static void
+gst_goom_init (GstGoom * goom)
+{
+ /* create the sink and src pads */
+ goom->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
+ gst_pad_set_chain_function (goom->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_goom_chain));
+ gst_pad_set_event_function (goom->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_goom_sink_event));
+ gst_pad_set_setcaps_function (goom->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_goom_sink_setcaps));
+ gst_element_add_pad (GST_ELEMENT (goom), goom->sinkpad);
+
+ goom->srcpad = gst_pad_new_from_static_template (&src_template, "src");
+ gst_pad_set_setcaps_function (goom->srcpad,
+ GST_DEBUG_FUNCPTR (gst_goom_src_setcaps));
+ gst_pad_set_event_function (goom->srcpad,
+ GST_DEBUG_FUNCPTR (gst_goom_src_event));
+ gst_element_add_pad (GST_ELEMENT (goom), goom->srcpad);
+
+ goom->adapter = gst_adapter_new ();
+
+ goom->width = 320;
+ goom->height = 200;
+ goom->fps_n = 25; /* desired frame rate */
+ goom->fps_d = 1; /* desired frame rate */
+ goom->channels = 0;
+ goom->rate = 0;
+ goom->duration = 0;
+
+ goom_init (&(goom->goomdata), goom->width, goom->height);
+}
+
+static void
+gst_goom_finalize (GObject * object)
+{
+ GstGoom *goom = GST_GOOM (object);
+
+ goom_close (&(goom->goomdata));
+
+ g_object_unref (goom->adapter);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_goom_reset (GstGoom * goom)
+{
+ goom->next_ts = -1;
+ gst_adapter_clear (goom->adapter);
+ gst_segment_init (&goom->segment, GST_FORMAT_UNDEFINED);
+
+ GST_OBJECT_LOCK (goom);
+ goom->proportion = 1.0;
+ goom->earliest_time = -1;
+ GST_OBJECT_UNLOCK (goom);
+}
+
+static gboolean
+gst_goom_sink_setcaps (GstPad * pad, GstCaps * caps)
+{
+ GstGoom *goom;
+ GstStructure *structure;
+ gboolean res;
+
+ goom = GST_GOOM (GST_PAD_PARENT (pad));
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ res = gst_structure_get_int (structure, "channels", &goom->channels);
+ res &= gst_structure_get_int (structure, "rate", &goom->rate);
+
+ goom->bps = goom->channels * sizeof (gint16);
+
+ return res;
+}
+
+static gboolean
+gst_goom_src_setcaps (GstPad * pad, GstCaps * caps)
+{
+ GstGoom *goom;
+ GstStructure *structure;
+
+ goom = GST_GOOM (GST_PAD_PARENT (pad));
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ if (!gst_structure_get_int (structure, "width", &goom->width) ||
+ !gst_structure_get_int (structure, "height", &goom->height) ||
+ !gst_structure_get_fraction (structure, "framerate", &goom->fps_n,
+ &goom->fps_d))
+ return FALSE;
+
+ goom_set_resolution (&(goom->goomdata), goom->width, goom->height);
+
+ /* size of the output buffer in bytes, depth is always 4 bytes */
+ goom->outsize = goom->width * goom->height * 4;
+ goom->duration =
+ gst_util_uint64_scale_int (GST_SECOND, goom->fps_d, goom->fps_n);
+ goom->spf = gst_util_uint64_scale_int (goom->rate, goom->fps_d, goom->fps_n);
+ goom->bpf = goom->spf * goom->bps;
+
+ GST_DEBUG_OBJECT (goom, "dimension %dx%d, framerate %d/%d, spf %d",
+ goom->width, goom->height, goom->fps_n, goom->fps_d, goom->spf);
+
+ return TRUE;
+}
+
+static gboolean
+gst_goom_src_negotiate (GstGoom * goom)
+{
+ GstCaps *othercaps, *target, *intersect;
+ GstStructure *structure;
+ const GstCaps *templ;
+
+ templ = gst_pad_get_pad_template_caps (goom->srcpad);
+
+ GST_DEBUG_OBJECT (goom, "performing negotiation");
+
+ /* see what the peer can do */
+ othercaps = gst_pad_peer_get_caps (goom->srcpad);
+ if (othercaps) {
+ intersect = gst_caps_intersect (othercaps, templ);
+ gst_caps_unref (othercaps);
+
+ if (gst_caps_is_empty (intersect))
+ goto no_format;
+
+ target = gst_caps_copy_nth (intersect, 0);
+ gst_caps_unref (intersect);
+ } else {
+ target = gst_caps_ref ((GstCaps *) templ);
+ }
+
+ structure = gst_caps_get_structure (target, 0);
+ gst_structure_fixate_field_nearest_int (structure, "width", 320);
+ gst_structure_fixate_field_nearest_int (structure, "height", 240);
+ gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
+
+ gst_pad_set_caps (goom->srcpad, target);
+ gst_caps_unref (target);
+
+ return TRUE;
+
+no_format:
+ {
+ gst_caps_unref (intersect);
+ return FALSE;
+ }
+}
+
+static gboolean
+gst_goom_src_event (GstPad * pad, GstEvent * event)
+{
+ gboolean res;
+ GstGoom *goom;
+
+ goom = GST_GOOM (gst_pad_get_parent (pad));
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_QOS:
+ {
+ gdouble proportion;
+ GstClockTimeDiff diff;
+ GstClockTime timestamp;
+
+ gst_event_parse_qos (event, &proportion, &diff, &timestamp);
+
+ /* save stuff for the _chain() function */
+ GST_OBJECT_LOCK (goom);
+ goom->proportion = proportion;
+ if (diff >= 0)
+ /* we're late, this is a good estimate for next displayable
+ * frame (see part-qos.txt) */
+ goom->earliest_time = timestamp + 2 * diff + goom->duration;
+ else
+ goom->earliest_time = timestamp + diff;
+ GST_OBJECT_UNLOCK (goom);
+
+ res = gst_pad_push_event (goom->sinkpad, event);
+ break;
+ }
+ default:
+ res = gst_pad_push_event (goom->sinkpad, event);
+ break;
+ }
+ gst_object_unref (goom);
+
+ return res;
+}
+
+static gboolean
+gst_goom_sink_event (GstPad * pad, GstEvent * event)
+{
+ gboolean res;
+ GstGoom *goom;
+
+ goom = GST_GOOM (gst_pad_get_parent (pad));
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_FLUSH_START:
+ res = gst_pad_push_event (goom->srcpad, event);
+ break;
+ case GST_EVENT_FLUSH_STOP:
+ gst_goom_reset (goom);
+ res = gst_pad_push_event (goom->srcpad, event);
+ break;
+ case GST_EVENT_NEWSEGMENT:
+ {
+ GstFormat format;
+ gdouble rate, arate;
+ gint64 start, stop, time;
+ gboolean update;
+
+ /* the newsegment values are used to clip the input samples
+ * and to convert the incomming timestamps to running time so
+ * we can do QoS */
+ gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
+ &start, &stop, &time);
+
+ /* now configure the values */
+ gst_segment_set_newsegment_full (&goom->segment, update,
+ rate, arate, format, start, stop, time);
+
+ res = gst_pad_push_event (goom->srcpad, event);
+ break;
+ }
+ default:
+ res = gst_pad_push_event (goom->srcpad, event);
+ break;
+ }
+ gst_object_unref (goom);
+
+ return res;
+}
+
+static GstFlowReturn
+get_buffer (GstGoom * goom, GstBuffer ** outbuf)
+{
+ GstFlowReturn ret;
+
+ if (GST_PAD_CAPS (goom->srcpad) == NULL) {
+ if (!gst_goom_src_negotiate (goom))
+ return GST_FLOW_NOT_NEGOTIATED;
+ }
+
+ GST_DEBUG_OBJECT (goom, "allocating output buffer with caps %"
+ GST_PTR_FORMAT, GST_PAD_CAPS (goom->srcpad));
+
+ ret =
+ gst_pad_alloc_buffer_and_set_caps (goom->srcpad,
+ GST_BUFFER_OFFSET_NONE, goom->outsize,
+ GST_PAD_CAPS (goom->srcpad), outbuf);
+ if (ret != GST_FLOW_OK)
+ return ret;
+
+ return GST_FLOW_OK;
+}
+
+static GstFlowReturn
+gst_goom_chain (GstPad * pad, GstBuffer * buffer)
+{
+ GstGoom *goom;
+ GstFlowReturn ret;
+ GstBuffer *outbuf = NULL;
+
+ goom = GST_GOOM (gst_pad_get_parent (pad));
+
+ /* If we don't have an output format yet, preallocate a buffer to try and
+ * set one */
+ if (GST_PAD_CAPS (goom->srcpad) == NULL) {
+ ret = get_buffer (goom, &outbuf);
+ if (ret != GST_FLOW_OK) {
+ gst_buffer_unref (buffer);
+ goto beach;
+ }
+ }
+
+ /* don't try to combine samples from discont buffer */
+ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
+ gst_adapter_clear (goom->adapter);
+ goom->next_ts = -1;
+ }
+
+ /* Match timestamps from the incoming audio */
+ if (GST_BUFFER_TIMESTAMP (buffer) != GST_CLOCK_TIME_NONE)
+ goom->next_ts = GST_BUFFER_TIMESTAMP (buffer);
+
+ GST_DEBUG_OBJECT (goom,
+ "Input buffer has %d samples, time=%" G_GUINT64_FORMAT,
+ GST_BUFFER_SIZE (buffer) / goom->bps, GST_BUFFER_TIMESTAMP (buffer));
+
+ /* Collect samples until we have enough for an output frame */
+ gst_adapter_push (goom->adapter, buffer);
+
+ ret = GST_FLOW_OK;
+
+ while (TRUE) {
+ const guint16 *data;
+ gboolean need_skip;
+ guchar *out_frame;
+ gint i;
+ guint avail, to_flush;
+
+ avail = gst_adapter_available (goom->adapter);
+ GST_DEBUG_OBJECT (goom, "avail now %u", avail);
+
+ /* we need GOOM_SAMPLES to get a meaningful result from goom. */
+ if (avail < (GOOM_SAMPLES * goom->bps))
+ break;
+
+ /* we also need enough samples to produce one frame at least */
+ if (avail < goom->bpf)
+ break;
+
+ GST_DEBUG_OBJECT (goom, "processing buffer");
+
+ if (goom->next_ts != -1) {
+ gint64 qostime;
+
+ qostime = gst_segment_to_running_time (&goom->segment, GST_FORMAT_TIME,
+ goom->next_ts);
+
+ GST_OBJECT_LOCK (goom);
+ /* check for QoS, don't compute buffers that are known to be late */
+ need_skip = goom->earliest_time != -1 && qostime <= goom->earliest_time;
+ GST_OBJECT_UNLOCK (goom);
+
+ if (need_skip) {
+ GST_WARNING_OBJECT (goom,
+ "QoS: skip ts: %" GST_TIME_FORMAT ", earliest: %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (qostime), GST_TIME_ARGS (goom->earliest_time));
+ goto skip;
+ }
+ }
+
+ /* get next GOOM_SAMPLES, we have at least this amount of samples */
+ data =
+ (const guint16 *) gst_adapter_peek (goom->adapter,
+ GOOM_SAMPLES * goom->bps);
+
+ if (goom->channels == 2) {
+ for (i = 0; i < GOOM_SAMPLES; i++) {
+ goom->datain[0][i] = *data++;
+ goom->datain[1][i] = *data++;
+ }
+ } else {
+ for (i = 0; i < GOOM_SAMPLES; i++) {
+ goom->datain[0][i] = *data;
+ goom->datain[1][i] = *data++;
+ }
+ }
+
+ /* alloc a buffer if we don't have one yet, this happens
+ * when we pushed a buffer in this while loop before */
+ if (outbuf == NULL) {
+ ret = get_buffer (goom, &outbuf);
+ if (ret != GST_FLOW_OK) {
+ goto beach;
+ }
+ }
+
+ GST_BUFFER_TIMESTAMP (outbuf) = goom->next_ts;
+ GST_BUFFER_DURATION (outbuf) = goom->duration;
+ GST_BUFFER_SIZE (outbuf) = goom->outsize;
+
+ out_frame = (guchar *) goom_update (&(goom->goomdata), goom->datain);
+ memcpy (GST_BUFFER_DATA (outbuf), out_frame, goom->outsize);
+
+ GST_DEBUG ("Pushing frame with time=%" GST_TIME_FORMAT ", duration=%"
+ GST_TIME_FORMAT, GST_TIME_ARGS (goom->next_ts),
+ GST_TIME_ARGS (goom->duration));
+
+ ret = gst_pad_push (goom->srcpad, outbuf);
+ outbuf = NULL;
+
+ skip:
+ /* interpollate next timestamp */
+ if (goom->next_ts != -1)
+ goom->next_ts += goom->duration;
+
+ /* Now flush the samples we needed for this frame, which might be more than
+ * the samples we used (GOOM_SAMPLES). */
+ to_flush = goom->bpf;
+
+ GST_DEBUG_OBJECT (goom, "finished frame, flushing %u bytes from input",
+ to_flush);
+ gst_adapter_flush (goom->adapter, to_flush);
+
+ if (ret != GST_FLOW_OK)
+ break;
+ }
+
+ if (outbuf != NULL)
+ gst_buffer_unref (outbuf);
+
+beach:
+ gst_object_unref (goom);
+
+ return ret;
+}
+
+static GstStateChangeReturn
+gst_goom_change_state (GstElement * element, GstStateChange transition)
+{
+ GstGoom *goom = GST_GOOM (element);
+ GstStateChangeReturn ret;
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ gst_goom_reset (goom);
+ break;
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ return gst_element_register (plugin, "goom2k1", GST_RANK_NONE, GST_TYPE_GOOM);
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "goom2k1",
+ "GOOM 2k1 visualization filter",
+ plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/gst/goom2k1/gstgoom.h b/gst/goom2k1/gstgoom.h
new file mode 100644
index 00000000..9c25f453
--- /dev/null
+++ b/gst/goom2k1/gstgoom.h
@@ -0,0 +1,91 @@
+/* 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.
+ */
+
+#ifndef __GST_GOOM_H__
+#define __GST_GOOM_H__
+
+G_BEGIN_DECLS
+
+#include <gst/gst.h>
+#include <gst/base/gstadapter.h>
+#include "goom_core.h"
+
+#define GOOM_SAMPLES 512
+
+#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,GstGoomClass))
+#define GST_IS_GOOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GOOM))
+#define GST_IS_GOOM_CLASS(klass) (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;
+ GstAdapter *adapter;
+
+ /* input tracking */
+ gint rate;
+ gint channels;
+ guint bps;
+
+ /* video state */
+ gint fps_n;
+ gint fps_d;
+ gint width;
+ gint height;
+ GstClockTime duration;
+ guint outsize;
+
+ /* samples per frame */
+ guint spf;
+ /* bytes per frame */
+ guint bpf;
+
+ /* goom stuff */
+ gint16 datain[2][GOOM_SAMPLES];
+ GoomData goomdata;
+
+ /* segment state */
+ GstSegment segment;
+
+ /* the timestamp of the next frame */
+ GstClockTime next_ts;
+
+ /* QoS stuff *//* with LOCK */
+ gdouble proportion;
+ GstClockTime earliest_time;
+};
+
+struct _GstGoomClass
+{
+ GstElementClass parent_class;
+};
+
+GType gst_goom_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_GOOM_H__ */
+
diff --git a/gst/goom2k1/lines.c b/gst/goom2k1/lines.c
new file mode 100644
index 00000000..3214e1db
--- /dev/null
+++ b/gst/goom2k1/lines.c
@@ -0,0 +1,107 @@
+/*
+ * lines.c
+ * iTunesXPlugIn
+ *
+ * Created by guillaum on Tue Aug 14 2001.
+ * Copyright (c) 2001 __CompanyName__. All rights reserved.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "lines.h"
+#include <math.h>
+
+static inline unsigned char
+lighten (unsigned char value, unsigned char power)
+{
+ unsigned char i;
+
+ for (i = 0; i < power; i++)
+ value += (255 - value) / 5;
+ return value;
+}
+
+void
+goom_lines (GoomData * goomdata, gint16 data[2][512], unsigned int ID,
+ unsigned int *p, guint32 power)
+{
+ guint32 color1;
+ guint32 color2;
+ guint32 resolx = goomdata->resolx;
+ guint32 resoly = goomdata->resoly;
+ unsigned char *color = 1 + (unsigned char *) &color1;
+
+ switch (ID) {
+ case 0: /* Horizontal stereo lines */
+ {
+ color1 = 0x0000AA00;
+ color2 = 0x00AA0000;
+ break;
+ }
+
+ case 1: /* Stereo circles */
+ {
+ color1 = 0x00AA33DD;
+ color2 = 0x00AA33DD;
+ break;
+ }
+ }
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color = 1 + (unsigned char *) &color2;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+ color++;
+ *color = lighten (*color, power);
+
+ switch (ID) {
+ case 0: /* Horizontal stereo lines */
+ {
+ unsigned int i;
+
+ for (i = 0; i < 512; i++) {
+ guint32 plot;
+
+ plot = i * resolx / 512 + (resoly / 4 + data[0][i] / 1600) * resolx;
+ p[plot] = color1;
+ p[plot + 1] = color1;
+ plot = i * resolx / 512 + (resoly * 3 / 4 - data[1][i] / 1600) * resolx;
+ p[plot] = color2;
+ p[plot + 1] = color2;
+ }
+ break;
+ }
+
+ case 1: /* Stereo circles */
+ {
+ float z;
+ unsigned int monX = resolx / 2;
+ float monY = resoly / 4;
+ float monY2 = resoly / 2;
+
+ for (z = 0; z < 6.2832f; z += 1.0f / monY) {
+ /* float offset1 = 128+data[1][(unsigned int)(z*81.33f)])/200000; */
+ p[monX + (unsigned int) ((monY + ((float) resoly) * (128 +
+ data[1][(unsigned int) (z * 81.33f)]) / 200000) *
+ cos (z) + resolx * (unsigned int) (monY2 + (monY +
+ ((float) resoly) * (128 +
+ data[1][(unsigned int) (z * 81.33f)]) / 400000) *
+ sin (z)))] = color1;
+ p[monX + (unsigned int) ((monY - ((float) resoly) * (128 +
+ data[0][(unsigned int) (z * 81.33f)]) / 200000) *
+ cos (z) + resolx * (unsigned int) (monY2 + (monY -
+ ((float) resoly) * (128 +
+ data[0][(unsigned int) (z * 81.33f)]) / 400000) *
+ sin (z)))] = color2;
+ }
+ break;
+ }
+ }
+}
diff --git a/gst/goom2k1/lines.h b/gst/goom2k1/lines.h
new file mode 100644
index 00000000..548f339a
--- /dev/null
+++ b/gst/goom2k1/lines.h
@@ -0,0 +1,16 @@
+/*
+ * lines.h
+ * iGoom
+ *
+ * Created by guillaum on Tue Aug 14 2001.
+ * Copyright (c) 2001 ios. All rights reserved.
+ *
+ */
+#include <glib.h>
+
+#include "graphic.h"
+#include "goom_core.h"
+
+void goom_lines(GoomData *goomdata, gint16 data [2][512], unsigned int ID,unsigned int* p, guint32 power);
+
+