Added a goom plugin (goom.sourceforge.net) to test: ./gst-launch filesrc location...
authorWim Taymans <wim.taymans@gmail.com>
Fri, 1 Feb 2002 19:28:30 +0000 (19:28 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Fri, 1 Feb 2002 19:28:30 +0000 (19:28 +0000)
Original commit message from CVS:
Added a goom plugin (goom.sourceforge.net)

to test:
./gst-launch filesrc location=/opt/data/south.mp3 ! mad ! tee silent=true src%d! goom ! colorspace ! xvideosink  tee0.src%d! osssink

12 files changed:
gst/goom/Makefile.am [new file with mode: 0644]
gst/goom/filters.c [new file with mode: 0644]
gst/goom/filters.h [new file with mode: 0644]
gst/goom/filters_mmx.s [new file with mode: 0644]
gst/goom/goom_core.c [new file with mode: 0644]
gst/goom/goom_core.h [new file with mode: 0644]
gst/goom/goom_tools.h [new file with mode: 0644]
gst/goom/graphic.c [new file with mode: 0644]
gst/goom/graphic.h [new file with mode: 0644]
gst/goom/gstgoom.c [new file with mode: 0644]
gst/goom/lines.c [new file with mode: 0644]
gst/goom/lines.h [new file with mode: 0644]

diff --git a/gst/goom/Makefile.am b/gst/goom/Makefile.am
new file mode 100644 (file)
index 0000000..26bc05a
--- /dev/null
@@ -0,0 +1,13 @@
+plugindir = $(libdir)/gst
+
+plugin_LTLIBRARIES = libgstgoom.la
+
+libgstgoom_la_SOURCES = gstgoom.c goom_core.c filters.c filters_mmx.s graphic.c lines.c
+
+noinst_HEADERS = filters.h goom_core.h goom_tools.h graphic.h lines.h 
+
+#CFLAGS += -Wall -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions -ffast-math -DNDEBUG
+libgstgoom_la_CFLAGS = -O2 -ffast-math $(GST_CFLAGS) -DMMX
+libgstgoom_la_LIBADD = $(GST_LIBS)
+libgstgoom_la_LDFLAGS = @GST_PLUGIN_LDFLAGS@
+
diff --git a/gst/goom/filters.c b/gst/goom/filters.c
new file mode 100644 (file)
index 0000000..bd26795
--- /dev/null
@@ -0,0 +1,528 @@
+/* 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;
+
+#include "filters.h"
+#include "graphic.h"
+#include "goom_tools.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
+
+
+extern volatile guint32 resolx;
+extern volatile guint32 resoly;
+
+#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 sintable [0xffff] ;
+static int vitesse = 127;
+static char theMode = AMULETTE_MODE ;
+static int vPlaneEffect = 0;
+static int hPlaneEffect = 0;
+static char noisify = 2;
+static int middleX , middleY ;
+static unsigned char sqrtperte = 16 ;
+
+static int * firedec = 0 ;
+
+
+// retourne x>>s , en testant le signe de x
+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)
+*/
+inline void calculatePXandPY (int x, int y, int *px, int *py)
+{
+    if (theMode == WATER_MODE)
+    {
+        static int wave = 0 ;
+        static int wavesp = 0 ;
+        int yy ;
+
+        yy = y + RAND () % 4 - RAND () % 4 + wave / 10 ;
+        if (yy < 0) yy = 0 ;
+        if (yy >= resoly) yy = resoly - 1 ;
+         
+        *px = (x<<4) + firedec [yy] + (wave / 10) ;
+        *py = (y<<4) + 132 - ((vitesse < 132) ? vitesse : 131) ;
+
+        wavesp += RAND () % 3 - RAND () % 3 ;
+        if (wave < -10) wavesp += 2 ;
+        if (wave > 10) wavesp -= 2 ;
+        wave += (wavesp / 10) + RAND () % 3 - RAND () % 3 ;
+        if (wavesp > 100) wavesp = (wavesp * 9) / 10  ;
+    }
+    else
+    {
+        int dist ;
+        register int vx,vy ;
+        int fvitesse = vitesse << 4 ;
+
+        if (noisify)
+        {
+            x += RAND() % noisify - RAND() % noisify ;
+            y += RAND() % noisify - RAND() % 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
+
+inline void setPixelRGB(Uint *buffer, Uint x, Uint y, Color c)
+{
+//             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
+}
+
+
+inline void setPixelRGB_ (Uint *buffer, Uint x, Color c)
+{
+#ifdef _DEBUG
+  if ( x >= resolx*resoly )
+       {
+         printf ("setPixel ERROR : hors du tableau... %i, %i\n", x,y) ;
+         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
+}
+
+
+
+inline void getPixelRGB (Uint *buffer, Uint x, Uint y, Color *c)
+{
+       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
+}
+
+
+inline void getPixelRGB_ (Uint *buffer, Uint x, Color *c)
+{
+       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  */
+       c->b = *(unsigned char *)(tmp8 = (unsigned char*)(buffer + x));
+       c->v = *(unsigned char *)(++tmp8);
+       c->r = *(unsigned char *)(++tmp8);
+//     *c = (Color) buffer[x+y*WIDTH] ;
+#endif
+}
+
+
+/*===============================================================*/
+void zoomFilterFastRGB (Uint *pix1,
+                                               Uint *pix2,
+                                               ZoomFilterData *zf,
+                                               Uint resx, Uint resy)
+{
+  static guint32 prevX = 0, prevY = 0;
+
+  static char reverse = 0 ; //vitesse inversé..(zoom out)
+  //   static int perte = 100; // 100 = normal
+  static unsigned char pertedec = 8 ;
+  static char firstTime = 1;
+  
+  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 ;
+
+  static unsigned int *pos10 = 0;
+  static unsigned int *c1 = 0,
+       *c2 = 0,
+       *c3 = 0,
+       *c4 = 0;
+#endif
+  
+  if ((prevX != resx) || (prevY != resy))
+       {
+         prevX = resx;
+         prevY = resy;
+#ifndef USE_ASM
+         if (c1) free (c1) ;
+         if (c2) free (c2) ;
+         if (c3) free (c3) ;
+         if (c4) free (c4) ;
+         if (pos10) free (pos10) ;
+         c1=c2=c3=c4=pos10=0;
+#else
+         if (coeffs) free (freecoeffs) ;
+         coeffs = 0;
+#endif
+         middleX = resx / 2 ;
+         middleY = resy - 1;
+         firstTime = 1 ;
+         if (firedec) free (firedec);
+         firedec=0;
+       }
+       
+       if (zf)
+         {
+               reverse = zf->reverse ;
+               vitesse = zf->vitesse ;
+               if (reverse)
+                 vitesse = 256 - vitesse ;
+#ifndef USE_ASM
+               sqrtperte = zf->sqrtperte ;
+#endif
+               pertedec = zf->pertedec ;
+               middleX = zf->middleX ;
+               middleY = zf->middleY ;
+               theMode = zf->mode ;
+               hPlaneEffect = zf->hPlaneEffect;
+               vPlaneEffect = zf->vPlaneEffect;
+               noisify = zf->noisify;
+         }
+       
+       if (firstTime || zf)
+         {
+               
+               // generation d'une table de sinus
+               if (firstTime)
+                 {
+                       unsigned short us ;
+
+                       firstTime = 0;
+#ifdef USE_ASM
+                       freecoeffs = (unsigned int *)
+                         malloc (resx*resy*2*sizeof(unsigned int)+128);
+                        coeffs = (guint32 *)((1+((unsigned int)(freecoeffs))/128)*128);
+
+#else
+                       pos10 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+                       c1 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+                       c2 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+                       c3 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+                       c4 = (unsigned int *) malloc (resx*resy*sizeof(unsigned int)) ;
+#endif
+                       for (us=0; us<0xffff; us++)
+                         {
+                               sintable [us] = (int)(1024.0f * sin (us*2*3.31415f/0xffff)) ;
+                         }
+                       
+                       {
+                         int loopv ;
+                         firedec = (int *) malloc (prevY * sizeof(int)) ;
+                         for (loopv = prevY ; loopv != 0 ;)
+                               {
+                                 static int decc = 0 ;
+                                 static int spdc = 0 ;
+                                 static int accel = 0 ;
+                                 loopv -- ;
+                                 firedec [loopv] = decc ;
+                                 decc += spdc / 10 ;
+                                 spdc = spdc + RAND () % 3 - RAND () % 3 ;
+                                 
+                                 if (decc > 4)
+                                       spdc -= 1 ;
+                                 if (decc < -4)
+                                       spdc += 1 ;
+                                 
+                                 if (spdc > 30)
+                                       spdc = spdc - RAND () % 3 + accel / 10 ;
+                                 if (spdc < -30)
+                                       spdc = spdc + RAND () % 3 + accel / 10 ;
+                                 
+                                 if (decc > 8 && spdc > 1 )
+                                       spdc -= RAND () % 3 - 2 ;
+                                 
+                                 if (decc < -8 && spdc < -1 )
+                                       spdc += RAND () % 3 + 2 ;
+                                 
+                                 if (decc > 8 || decc < -8)
+                                       decc = decc * 8 / 9 ;
+                                 
+                                 accel += RAND () % 2 - RAND () % 2 ;
+                                 if (accel > 20)
+                                       accel -= 2 ;
+                                 if (accel < -20)
+                                       accel += 2 ;
+                               }
+                       }
+                 }
+               
+               
+               // generation du buffer
+               for (y = 0 ; y < prevY ; y++)
+                 for (x = 0; x < prevX ; x++)
+                       {
+                         int px,py;
+                         unsigned char coefv,coefh;
+                         
+                         // calculer px et py en fonction de
+                         //   x,y,middleX,middleY et theMode
+                         calculatePXandPY (x,y,&px, &py) ;
+                         if ((px == x << 4) && (py == y << 4))
+                               py += 8 ;
+
+                         if ( (py<0) || (px<0) ||
+                                  (py>=(prevY-1)*sqrtperte) ||
+                                  (px>=(prevX-1)*sqrtperte))
+                               {
+#ifdef USE_ASM
+                                 coeffs[(y*prevX+x)*2]=0 ;
+                                 coeffs[(y*prevX+x)*2+1]=0;
+#else
+                                 pos10[y*prevX+x]=0 ;
+                                 c1[y*prevX+x] = 0 ;
+                                 c2[y*prevX+x] = 0 ;
+                                 c3[y*prevX+x] = 0 ;
+                                 c4[y*prevX+x] = 0 ;
+#endif
+                               }
+                         else
+                               {
+                                 int npx10 ;
+                                 int npy10 ;
+                                  int pos = (y*prevX+x)*2;
+
+                                 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
+                                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
+                               pos10[y*prevX+x]= npx10 + prevX * npy10 ;
+
+                               if (!(coefh || coefv))
+                                       c1[y*prevX+x] = sqrtperte*sqrtperte-1 ;
+                               else
+                                       c1[y*prevX+x] = (sqrtperte-coefh) * (sqrtperte-coefv);
+                               
+                               c2[y*prevX+x] = coefh * (sqrtperte-coefv) ;
+                               c3[y*prevX+x] = (sqrtperte-coefh) * coefv ;
+                               c4[y*prevX+x] = coefh * coefv ;
+#endif
+                               }
+                       }
+         }
+       
+#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);
+               getPixelRGB_(pix1,pos10[position]+1,&col2);
+               getPixelRGB_(pix1,pos10[position]+prevX,&col3);
+               getPixelRGB_(pix1,pos10[position]+prevX+1,&col4);
+               
+               couleur.r = col1.r * c1[position]
+                    + col2.r * c2[position]
+                    + col3.r * c3[position]
+                    + col4.r * c4[position];
+               couleur.r >>= pertedec ;
+
+               couleur.v = col1.v * c1[position]
+                    + col2.v * c2[position]
+                    + col3.v * c3[position]
+                    + col4.v * c4[position];
+               couleur.v >>= pertedec ;
+               
+               couleur.b = col1.b * c1[position]
+                    + col2.b * c2[position]
+                    + col3.b * c3[position]
+                    + col4.b * c4[position];
+               couleur.b >>= pertedec ;
+               
+               setPixelRGB_(pix2,position,couleur);
+       }
+#endif
+}
+
+
+void pointFilter(Uint *pix1, Color c,
+                                float t1, float t2, float t3, float t4,
+                                Uint cycle)
+{
+  Uint x = (Uint)((int)middleX + (int)(t1*cos((float)cycle/t3)));
+  Uint y = (Uint)((int)middleY + (int)(t2*sin((float)cycle/t4)));
+  if ((x>1) && (y>1) && (x<resolx-2) && (y<resoly-2))
+       {
+         setPixelRGB(pix1, x+1, y, c);
+         setPixelRGB(pix1, x, y+1, c);
+         setPixelRGB(pix1, x+1, y+1, WHITE);
+         setPixelRGB(pix1, x+2, y+1, c);
+         setPixelRGB(pix1, x+1, y+2, c);
+       }
+}
diff --git a/gst/goom/filters.h b/gst/goom/filters.h
new file mode 100644 (file)
index 0000000..33784c2
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef FILTERS_H
+#define FILTERS_H
+
+#include <glib.h>
+
+#include "graphic.h"
+
+typedef struct
+{
+       int vitesse ;
+       unsigned char pertedec ;
+       unsigned char sqrtperte ;
+       int middleX,middleY ;
+       char reverse ;
+       char mode ;
+       /** @since June 2001 */
+       int hPlaneEffect ;
+       int vPlaneEffect ;
+       char noisify ;
+} ZoomFilterData ;
+
+
+#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
+
+void pointFilter(guint32 *pix1, 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);
+*/
+
+void zoomFilterFastRGB (guint32 *pix1,
+                                               guint32 *pix2,
+                                               ZoomFilterData *zf,
+                                               guint32 resx, guint32 resy);
+
+
+/* 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/goom/filters_mmx.s b/gst/goom/filters_mmx.s
new file mode 100644 (file)
index 0000000..337de56
--- /dev/null
@@ -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/goom/goom_core.c b/gst/goom/goom_core.c
new file mode 100644 (file)
index 0000000..245c280
--- /dev/null
@@ -0,0 +1,420 @@
+#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
+
+
+/**-----------------------------------------------------**
+ **  SHARED DATA                                        **
+ **-----------------------------------------------------**/
+static guint32 *pixel ;
+static guint32 *back ;
+static guint32 *p1,*p2,*tmp;
+static guint32 cycle;
+
+guint32 resolx, resoly, buffsize;
+
+void goom_init (guint32 resx, guint32 resy)
+{
+#ifdef VERBOSE
+    printf ("GOOM: init (%d, %d);\n", resx,resy);
+#endif
+    resolx = resx;
+    resoly = resy;
+    buffsize = resx * resy;
+
+    pixel = (guint32 *) malloc (buffsize * sizeof(guint32) + 128);
+    back = (guint32 *) malloc (buffsize * sizeof(guint32) + 128);
+    RAND_INIT ((guint32)pixel) ;
+    cycle = 0 ;
+
+    p1 = (guint32 *)((1+((unsigned int)(pixel))/128)*128);
+    p2 = (guint32 *)((1+((unsigned int)(back))/128)*128);
+}
+
+
+void goom_set_resolution (guint32 resx, guint32 resy)
+{
+    free (pixel);
+    free (back);
+
+    resolx = resx;
+    resoly = resy;
+    buffsize = resx * resy;
+
+    pixel = (guint32 *) malloc (buffsize * sizeof(guint32) + 128);
+    bzero(pixel,buffsize * sizeof(guint32) + 128);
+    back = (guint32 *) malloc (buffsize * sizeof(guint32) + 128);
+    bzero(back,buffsize * sizeof(guint32) + 128);
+    p1 = (guint32 *)((1+((unsigned int)(pixel))/128)*128);
+    p2 = (guint32 *)((1+((unsigned int)(back))/128)*128);
+}
+
+
+guint32 * goom_update (gint16 data [2][512])
+{
+    static int lockvar = 0 ; // pour empecher de nouveaux changements
+    static int         goomvar = 0 ; // boucle des gooms
+    static int         totalgoom = 0 ; // nombre de gooms par seconds
+    static int         agoom = 0 ; // un goom a eu lieu..      
+    static int         loopvar = 0 ; // mouvement des points
+    static int         speedvar = 0 ; // vitesse des particules
+    static int lineMode = 0 ; // l'effet lineaire a dessiner
+    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
+    static char        goomlimit = 2 ; // sensibilité du goom
+    static     ZoomFilterData zfd =
+    {
+       128,    8,      16,
+       1,      1,      0,      WAVE_MODE,
+       0,      0,      0};
+
+    ZoomFilterData *pzfd;
+
+    /* 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 (speedvar>5)
+    {
+        accelvar-- ;
+        if (speedvar>20) accelvar -- ;
+        if (speedvar>40) speedvar = 40 ;
+    }
+    accelvar -- ;
+    speedvar += accelvar ;
+       
+    if (speedvar<0) speedvar=0;
+    if (speedvar>40) speedvar = 40 ;
+
+
+  /* ! calcul du deplacement des petits points ... */
+
+  largfactor = ((float)speedvar / 40.0f + (float)incvar / 50000.0f) / 1.5f ;
+  if (largfactor>1.5f) largfactor = 1.5f ;
+
+  for (i = 1 ; i*15 <= speedvar + 15; i ++) {
+       loopvar += speedvar + 1 ;
+               
+       pointFilter(p1,
+                               YELLOW,
+                               ((pointWidth - 6.0f) * largfactor + 5.0f),
+                               ((pointHeight - 6.0f) * largfactor + 5.0f),
+                               i * 152.0f, 128.0f,
+                               loopvar + i*2032);
+       pointFilter(p1, ORANGE,
+                               ((pointWidth / 2) * largfactor) / i + 10.0f * i,
+                               ((pointHeight / 2) * largfactor) / i + 10.0f * i,
+                               96.0f, i * 80.0f, loopvar / i);
+       pointFilter(p1, VIOLET,
+                               ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
+                               ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
+                               i + 122.0f, 134.0f, loopvar / i);
+       pointFilter(p1, BLACK,
+                               ((pointHeight / 3) * largfactor + 20.0f),
+                               ((pointHeight / 3) * largfactor + 20.0f),
+                               58.0f, i * 66.0f, loopvar / i);
+       pointFilter(p1, WHITE,
+                               (pointHeight * largfactor + 10.0f * i) / i,
+                               (pointHeight * largfactor + 10.0f * i) / i,
+                               66.0f, 74.0f, loopvar + i * 500);
+  }
+
+    // par défaut pas de changement de zoom
+    pzfd = NULL ;
+       
+    // 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 (--lockvar < 0) lockvar = 0 ;
+
+    // temps du goom
+    if (--agoom < 0) agoom = 0 ;
+
+    // on verifie qu'il ne se pas un truc interressant avec le son.
+    if ((accelvar>goomlimit) || (accelvar<-goomlimit))
+    {
+        // UN GOOM !!! YAHOO !
+        totalgoom ++ ;
+        agoom = 20 ; // mais pdt 20 cycles, il n'y en aura plus.
+        lineMode = (lineMode + 1)%20; // Tous les 10 gooms on change de mode lineaire
+
+        // changement eventuel de mode
+        switch (iRAND(10))
+        {
+        case 0:
+        case 1:
+        case 2:
+            zfd.mode=WAVE_MODE;
+            zfd.vitesse=STOP_SPEED-1;
+            zfd.reverse=0;
+            break;
+        case 3:
+        case 4:
+            zfd.mode=CRYSTAL_BALL_MODE;
+            break;
+        case 5:
+            zfd.mode=AMULETTE_MODE;
+            break;
+        case 6:
+            zfd.mode = WATER_MODE ;
+            break;
+        case 7:
+            zfd.mode=SCRUNCH_MODE;
+            break;
+        default:
+            zfd.mode=NORMAL_MODE;
+        }
+    }
+
+    // tout ceci ne sera fait qu'en cas de non-blocage
+    if (lockvar == 0)
+    {
+        // reperage de goom (acceleration forte de l'acceleration du volume)
+        // -> coup de boost de la vitesse si besoin..
+        if ( (accelvar>goomlimit) || (accelvar<-goomlimit) )
+        {
+            goomvar ++ ;
+            //if (goomvar % 1 == 0)
+            {
+                guint32 vtmp ;
+                guint32 newvit ;
+                newvit = STOP_SPEED - speedvar / 2 ;
+                // retablir le zoom avant..
+                if ((zfd.reverse) &&
+                        (!(cycle%12)) &&
+                        (rand ()%3==0))
+                {
+                    zfd.reverse = 0 ;
+                    zfd.vitesse = STOP_SPEED - 2 ;
+                    lockvar = 50 ;
+                }
+                if (iRAND (10) == 0)
+                {
+                    zfd.reverse = 1;
+                    lockvar = 100;
+                }
+
+                // changement de milieu..
+                switch (iRAND(20))
+                {
+                    case 0:
+                        zfd.middleY = resoly - 1 ;
+                        zfd.middleX = resolx / 2 ;
+                        break ;
+                    case 1:
+                        zfd.middleX = resolx - 1 ;
+                        break ;
+                    case 2:
+                        zfd.middleX = 1 ;
+                        break ;
+                    default:
+                        zfd.middleY = resoly / 2 ;
+                        zfd.middleX = resolx / 2 ;
+                }
+
+                if (zfd.mode == WATER_MODE)
+                {
+                    zfd.middleX = resolx / 2;
+                    zfd.middleY = resoly / 2;
+                }
+
+                switch (vtmp = (iRAND (27)))
+                {
+                    case 0:
+                        zfd.vPlaneEffect = iRAND(3) - iRAND(3);
+                        zfd.hPlaneEffect = iRAND(3) - iRAND(3);
+                        break;
+                    case 3:
+                        zfd.vPlaneEffect = 0 ;
+                        zfd.hPlaneEffect = iRAND(8) - iRAND(8);
+                        break;
+                    case 4:
+                    case 5:
+                    case 6:
+                    case 7:
+                        zfd.vPlaneEffect = iRAND(5) - iRAND (5);
+                        zfd.hPlaneEffect = - zfd.vPlaneEffect;
+                        break;
+                    case 8:
+                        zfd.hPlaneEffect = 5 + iRAND (8);
+                        zfd.vPlaneEffect = - zfd.hPlaneEffect ;
+                        break;
+                    case 9:
+                        zfd.vPlaneEffect = 5 + iRAND (8);
+                        zfd.hPlaneEffect = - zfd.hPlaneEffect ;
+                        break;
+                    case 13:
+                        zfd.hPlaneEffect = 0;
+                        zfd.vPlaneEffect = iRAND(10) - iRAND(10);
+                        break;
+                    default:
+                        if (vtmp < 10)
+                        {
+                            zfd.vPlaneEffect = 0;
+                            zfd.hPlaneEffect = 0;
+                        }
+                    }
+
+                if (iRAND (3) != 0) zfd.noisify = 0 ;
+                else
+                {
+                    zfd.noisify = iRAND (3) + 2 ;
+                    lockvar *= 3;
+                }
+                       
+                if (zfd.mode == AMULETTE_MODE)
+                {
+                    zfd.vPlaneEffect = 0;
+                    zfd.hPlaneEffect = 0;
+                    zfd.noisify = 0;
+                }
+
+                if ((zfd.middleX == 1) || (zfd.middleX == resolx - 1))
+                {
+                    zfd.vPlaneEffect = 0 ;
+                    zfd.hPlaneEffect = iRAND (2) ? 0 : zfd.hPlaneEffect;
+                }
+
+                if (newvit < zfd.vitesse) // on accelere
+                {
+                    pzfd = &zfd;
+                    if ( ( (newvit < STOP_SPEED - 7) &&
+                                (zfd.vitesse < STOP_SPEED - 6) &&
+                                (cycle % 3 == 0)) ||
+                                (iRAND (40) == 0))
+                    {
+                        zfd.vitesse = STOP_SPEED - 1 ;
+                        zfd.reverse = ! zfd.reverse ;
+                    }
+                    else
+                    {
+                        zfd.vitesse = (newvit + zfd.vitesse * 4) / 5 ;
+                    }
+                    lockvar += 50 ;
+                }
+            }
+        }
+         // mode mega-lent
+         if (iRAND(1000) == 0)
+               {
+                 /* 
+                        printf ("coup du sort...\n") ;
+                 */
+                 pzfd = &zfd ;
+                 zfd.vitesse = STOP_SPEED - 1 ;
+                 zfd.pertedec = 8 ;
+                 zfd.sqrtperte = 16 ;
+                 goomvar = 1 ;
+                 lockvar += 70 ;
+               }
+       }
+       
+  // gros frein si la musique est calme
+  if ((speedvar < 1) && (zfd.vitesse < STOP_SPEED - 4) && (cycle % 16 == 0))
+       {
+         /*
+               printf ("++slow part... %i\n", zfd.vitesse) ;
+         */
+         pzfd = &zfd ;
+         zfd.vitesse += 3 ;
+         zfd.pertedec = 8 ;
+         zfd.sqrtperte = 16 ;
+         goomvar = 0 ;
+         /*
+               printf ("--slow part... %i\n", zfd.vitesse) ;
+         */
+       }
+       
+  // baisser regulierement la vitesse...
+  if ( (cycle % 73 == 0) && (zfd.vitesse < STOP_SPEED - 5))
+       {
+         /*
+               printf ("slow down...\n") ;
+         */
+         pzfd = &zfd ;
+         zfd.vitesse ++ ;
+       }
+       
+  // arreter de decrémenter au bout d'un certain temps
+  if ((cycle % 101 == 0) && (zfd.pertedec == 7))
+       {
+         pzfd = &zfd ;
+         zfd.pertedec=8 ;
+         zfd.sqrtperte=16 ;
+       }
+       
+#ifdef VERBOSE
+  if (pzfd)
+       {
+         printf ("GOOM: pzfd->mode = %d\n", pzfd->mode);
+       }
+#endif
+
+    // Zoom here !
+    zoomFilterFastRGB (p1, p2, pzfd, resolx, resoly) ;
+
+    // si on est dans un goom : afficher les lignes...
+    if (agoom > 15) goom_lines
+                                         (data,
+                                          ((zfd.middleX==resolx/2) && (zfd.middleY==resoly/2) && (zfd.mode!=WATER_MODE))
+                                            ? (lineMode/10) : 0,
+                                          p2,agoom-15);
+
+    return_val = p2 ;
+    tmp=p1;
+    p1=p2;
+    p2=tmp;
+
+    // affichage et swappage des buffers..
+    cycle++;
+       
+    // tous les 100 cycles : vérifier si le taux de goom est correct
+    // et le modifier sinon..
+    if (!(cycle%100))
+    {
+        if (totalgoom>15)
+        {
+            // printf ("less gooms\n") ;
+            goomlimit ++ ;
+        }
+        else
+        {
+            if ((totalgoom==0) && (goomlimit>1))
+                goomlimit -- ;
+        }        
+        totalgoom = 0 ;
+    }
+    return return_val;
+}
+
+void goom_close ()
+{
+  if (pixel!=NULL) free (pixel) ;
+  if (back!=NULL) free (back) ;
+       pixel = back = NULL;
+  RAND_CLOSE();
+}
diff --git a/gst/goom/goom_core.h b/gst/goom/goom_core.h
new file mode 100644 (file)
index 0000000..15f942d
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _GOOMCORE_H
+#define _GOOMCORE_H
+
+#include <glib.h>
+
+void goom_init (guint32 resx, guint32 resy);
+void goom_set_resolution (guint32 resx, guint32 resy);
+
+guint32 * goom_update (gint16 data [2][512]);
+
+void goom_close ();
+
+#endif
diff --git a/gst/goom/goom_tools.h b/gst/goom/goom_tools.h
new file mode 100644 (file)
index 0000000..d077c0c
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _GOOMTOOLS_H
+#define _GOOMTOOLS_H
+
+#define NB_RAND 0x10000
+
+/* in graphic.c */
+extern int * rand_tab ;
+extern unsigned short rand_pos ;
+
+#define RAND_INIT(i) \
+       srand (i) ;\
+       if (!rand_tab)\
+               rand_tab = (int *) malloc (NB_RAND * sizeof(int)) ;\
+       rand_pos = 1 ;\
+       while (rand_pos != 0)\
+               rand_tab [rand_pos++] = rand () ;
+
+#define RAND()\
+       (rand_tab[rand_pos = rand_pos + 1])
+
+#define RAND_CLOSE()\
+       free (rand_tab);\
+       rand_tab = 0;
+
+
+//#define iRAND(i) ((guint32)((float)i * RAND()/RAND_MAX))
+#define iRAND(i) (RAND()%i)
+       
+#endif
diff --git a/gst/goom/graphic.c b/gst/goom/graphic.c
new file mode 100644 (file)
index 0000000..4223c67
--- /dev/null
@@ -0,0 +1,17 @@
+#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} ;
+
+unsigned int SIZE ;
+unsigned int HEIGHT ;
+unsigned int WIDTH ;
+
+int * rand_tab = 0 ;
+unsigned short int rand_pos = 0 ;
diff --git a/gst/goom/graphic.h b/gst/goom/graphic.h
new file mode 100644 (file)
index 0000000..415dde7
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef GRAPHIC_H
+#define GRAPHIC_H
+
+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;
+
+inline void setPixelRGB (Uint *buffer, Uint x, Uint y, Color c) ;
+inline void getPixelRGB (Uint *buffer, Uint x, Uint y, Color *c) ;
+
+#endif /*GRAPHIC_H*/
diff --git a/gst/goom/gstgoom.c b/gst/goom/gstgoom.c
new file mode 100644 (file)
index 0000000..c051352
--- /dev/null
@@ -0,0 +1,341 @@
+/* gstgoom.c: implementation of goom drawing element
+ * Copyright (C) <2001> Richard Boulton <richard@tartarus.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gst/gst.h>
+
+#include "goom_core.h"
+
+#define GST_TYPE_GOOM (gst_goom_get_type())
+#define GST_GOOM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GOOM,GstGOOM))
+#define GST_GOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GOOM,GstGOOM))
+#define GST_IS_GOOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GOOM))
+#define GST_IS_GOOM_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GOOM))
+
+typedef struct _GstGOOM GstGOOM;
+typedef struct _GstGOOMClass GstGOOMClass;
+
+struct _GstGOOM {
+  GstElement element;
+
+  /* pads */
+  GstPad *sinkpad,*srcpad;
+  GstBufferPool *peerpool;
+
+  // the timestamp of the next frame
+  guint64 next_time;
+
+  // video state
+  gint bpp;
+  gint depth;
+  gint width;
+  gint height;
+  gboolean first_buffer;
+
+  gint samplerate;
+  gint framerate; // desired frame rate
+  gint samples_between_frames; // number of samples between start of successive frames
+  gint samples_since_last_frame; // number of samples between start of successive frames
+};
+
+struct _GstGOOMClass {
+  GstElementClass parent_class;
+};
+
+GType gst_goom_get_type(void);
+
+
+/* elementfactory information */
+static GstElementDetails gst_goom_details = {
+  "GOOM: what a GOOM!",
+  "Filter/Visualization",
+  "Takes frames of data and outputs video frames using the GOOM filter",
+  VERSION,
+  "Wim Taymans <wim.taymans@chello.be>",
+  "(C) 2002",
+};
+
+/* signals and args */
+enum {
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  /* FILL ME */
+};
+
+GST_PADTEMPLATE_FACTORY (src_template,
+  "src",
+  GST_PAD_SRC,
+  GST_PAD_ALWAYS,
+  GST_CAPS_NEW (
+    "goomsrc",
+    "video/raw",
+      "format",                GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")),
+      "bpp",           GST_PROPS_INT (32),
+      "depth",         GST_PROPS_INT (32),
+      "endianness",    GST_PROPS_INT (G_BYTE_ORDER),
+      "red_mask",      GST_PROPS_INT (0xff0000),
+      "green_mask",    GST_PROPS_INT (0xff00),
+      "blue_mask",     GST_PROPS_INT (0xff),
+      "width",         GST_PROPS_INT_RANGE (16, 4096),
+      "height",                GST_PROPS_INT_RANGE (16, 4096)
+  )
+)
+
+GST_PADTEMPLATE_FACTORY (sink_template,
+  "sink",                                      /* the name of the pads */
+  GST_PAD_SINK,                                /* type of the pad */
+  GST_PAD_ALWAYS,                              /* ALWAYS/SOMETIMES */
+  GST_CAPS_NEW (
+    "goomsink",                                /* the name of the caps */
+    "audio/raw",                               /* the mime type of the caps */
+       /* Properties follow: */
+      "format",     GST_PROPS_STRING ("int"),
+      "law",        GST_PROPS_INT (0),
+      "endianness", GST_PROPS_INT (G_BYTE_ORDER),
+      "signed",     GST_PROPS_BOOLEAN (TRUE),
+      "width",      GST_PROPS_INT (16),
+      "depth",      GST_PROPS_INT (16),
+      "rate",       GST_PROPS_INT_RANGE (8000, 96000),
+      "channels",   GST_PROPS_INT (1)
+  )
+)
+
+
+static void            gst_goom_class_init     (GstGOOMClass *klass);
+static void            gst_goom_init           (GstGOOM *goom);
+
+static void            gst_goom_set_property   (GObject *object, guint prop_id, 
+                                                const GValue *value, GParamSpec *pspec);
+static void            gst_goom_get_property   (GObject *object, guint prop_id, 
+                                                GValue *value, GParamSpec *pspec);
+
+static void            gst_goom_chain          (GstPad *pad, GstBuffer *buf);
+
+static GstPadConnectReturn 
+                       gst_goom_sinkconnect    (GstPad *pad, GstCaps *caps);
+
+static GstElementClass *parent_class = NULL;
+
+GType
+gst_goom_get_type (void)
+{
+  static GType type = 0;
+
+  if (!type) {
+    static const GTypeInfo info = {
+      sizeof (GstGOOMClass),      
+      NULL,      
+      NULL,      
+      (GClassInitFunc) gst_goom_class_init,
+      NULL,
+      NULL,
+      sizeof (GstGOOM),
+      0,
+      (GInstanceInitFunc) gst_goom_init,
+    };
+    type = g_type_register_static (GST_TYPE_ELEMENT, "GstGOOM", &info, 0);
+  }
+  return type;
+}
+
+static void
+gst_goom_class_init(GstGOOMClass *klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass*) klass;
+  gstelement_class = (GstElementClass*) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  gobject_class->set_property = gst_goom_set_property;
+  gobject_class->get_property = gst_goom_get_property;
+}
+
+static void
+gst_goom_init (GstGOOM *goom)
+{
+  /* create the sink and src pads */
+  goom->sinkpad = gst_pad_new_from_template (
+                 GST_PADTEMPLATE_GET (sink_template ), "sink");
+  goom->srcpad = gst_pad_new_from_template (
+                 GST_PADTEMPLATE_GET (src_template ), "src");
+  gst_element_add_pad (GST_ELEMENT (goom), goom->sinkpad);
+  gst_element_add_pad (GST_ELEMENT (goom), goom->srcpad);
+
+  gst_pad_set_chain_function (goom->sinkpad, gst_goom_chain);
+  gst_pad_set_connect_function (goom->sinkpad, gst_goom_sinkconnect);
+
+  goom->next_time = 0;
+  goom->peerpool = NULL;
+
+  // reset the initial video state
+  goom->bpp = 32;
+  goom->depth = 32;
+  goom->first_buffer = TRUE;
+  goom->width = 320;
+  goom->height = 200;
+
+  goom->samplerate = -1;
+  goom->framerate = 25; // desired frame rate
+  goom->samples_between_frames = 0; // number of samples between start of successive frames
+  goom->samples_since_last_frame = 0;
+
+  goom_init (goom->width, goom->height);
+}
+
+static GstPadConnectReturn
+gst_goom_sinkconnect (GstPad *pad, GstCaps *caps)
+{
+  GstGOOM *goom;
+  goom = GST_GOOM (gst_pad_get_parent (pad));
+
+  if (!GST_CAPS_IS_FIXED (caps)) {
+    return GST_PAD_CONNECT_DELAYED;
+  }
+
+  goom->samplerate = gst_caps_get_int (caps, "rate");
+  goom->samples_between_frames = goom->samplerate / goom->framerate;
+
+  GST_DEBUG (0, "GOOM: new sink caps: rate %d\n",
+            goom->samplerate);
+
+  return GST_PAD_CONNECT_OK;
+}
+
+static void
+gst_goom_chain (GstPad *pad, GstBuffer *bufin)
+{
+  GstGOOM *goom;
+  GstBuffer *bufout;
+  guint32 samples_in;
+  gint16 datain[2][512];
+
+  goom = GST_GOOM (gst_pad_get_parent (pad));
+
+  GST_DEBUG (0, "GOOM: chainfunc called\n");
+
+  samples_in = GST_BUFFER_SIZE (bufin) / sizeof (gint16);
+
+  GST_DEBUG (0, "input buffer has %d samples\n", samples_in);
+
+  if (goom->next_time <= GST_BUFFER_TIMESTAMP (bufin)) {
+    goom->next_time = GST_BUFFER_TIMESTAMP (bufin);
+    GST_DEBUG (0, "in:  %lld\n", GST_BUFFER_TIMESTAMP (bufin));
+  }
+  if (goom->first_buffer) {
+    GstCaps *caps;
+       
+    GST_DEBUG (0, "making new pad\n");
+
+    caps = GST_CAPS_NEW (
+                    "goomsrc",
+                    "video/raw",
+                      "format",        GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")), 
+                      "bpp",           GST_PROPS_INT (goom->bpp), 
+                      "depth",         GST_PROPS_INT (goom->depth), 
+                      "endianness",    GST_PROPS_INT (G_BYTE_ORDER), 
+                      "red_mask",      GST_PROPS_INT (0xff0000), 
+                      "green_mask",    GST_PROPS_INT (0x00ff00), 
+                      "blue_mask",     GST_PROPS_INT (0x0000ff), 
+                      "width",         GST_PROPS_INT (goom->width), 
+                      "height",        GST_PROPS_INT (goom->height)
+                  );
+
+    if (!gst_pad_try_set_caps (goom->srcpad, caps)) {
+      gst_element_error (GST_ELEMENT (goom), "could not set caps");
+      return;
+    }
+    goom->first_buffer = FALSE;
+  }
+
+  memcpy (&datain[0][0], GST_BUFFER_DATA (bufin), 512);
+  memcpy (&datain[1][0], GST_BUFFER_DATA (bufin), 512);
+
+  bufout = gst_buffer_new ();
+  GST_BUFFER_DATA (bufout) = (guchar *) goom_update (datain);
+  GST_BUFFER_SIZE (bufout) = goom->width * goom->height * 4;
+  GST_BUFFER_FLAG_SET (bufout, GST_BUFFER_DONTFREE);
+
+  gst_pad_push (goom->srcpad, bufout);
+
+  gst_buffer_unref (bufin);
+
+  GST_DEBUG (0, "GOOM: exiting chainfunc\n");
+}
+
+static void
+gst_goom_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+  GstGOOM *goom;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_GOOM (object));
+  goom = GST_GOOM (object);
+
+  switch (prop_id) {
+    default:
+      break;
+  }
+}
+
+static void
+gst_goom_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+  GstGOOM *goom;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_GOOM (object));
+  goom = GST_GOOM (object);
+
+  switch (prop_id) {
+    default:
+      break;
+  }
+}
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+  GstElementFactory *factory;
+
+  /* create an elementfactory for the goom element */
+  factory = gst_elementfactory_new("goom",GST_TYPE_GOOM,
+                                   &gst_goom_details);
+  g_return_val_if_fail(factory != NULL, FALSE);
+
+  gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (src_template));
+  gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sink_template));
+
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+  return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "goom",
+  plugin_init
+};
diff --git a/gst/goom/lines.c b/gst/goom/lines.c
new file mode 100644 (file)
index 0000000..fbab8b1
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  lines.c
+ *  iTunesXPlugIn
+ *
+ *  Created by guillaum on Tue Aug 14 2001.
+ *  Copyright (c) 2001 __CompanyName__. All rights reserved.
+ *
+ */
+
+#include "lines.h"
+#include <math.h>
+
+extern unsigned int resolx,resoly;
+
+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(gint16 data [2][512], unsigned int ID,unsigned int* p, guint32 power)
+{
+    guint32 color1;
+    guint32 color2;
+    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/goom/lines.h b/gst/goom/lines.h
new file mode 100644 (file)
index 0000000..3582d38
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ *  lines.h
+ *  iGoom
+ *
+ *  Created by guillaum on Tue Aug 14 2001.
+ *  Copyright (c) 2001 ios. All rights reserved.
+ *
+ */
+#include <glib.h>
+
+#include "graphic.h"
+
+void goom_lines(gint16 data [2][512], unsigned int ID,unsigned int* p, guint32 power);
+void goom_lines_conf(gint16 config [25]);
+