mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-14 02:05:39 +00:00
Added a goom plugin (goom.sourceforge.net) to test: ./gst-launch filesrc location=/opt/data/south.mp3 ! mad ! tee sil...
Original commit message from CVS: Added a goom plugin (goom.sourceforge.net) to test: ./gst-launch filesrc location=/opt/data/south.mp3 ! mad ! tee silent=true src%d! goom ! colorspace ! xvideosink tee0.src%d! osssink
This commit is contained in:
parent
e5faa112b6
commit
4d3b1472e7
12 changed files with 1691 additions and 0 deletions
13
gst/goom/Makefile.am
Normal file
13
gst/goom/Makefile.am
Normal file
|
@ -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@
|
||||
|
528
gst/goom/filters.c
Normal file
528
gst/goom/filters.c
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
71
gst/goom/filters.h
Normal file
71
gst/goom/filters.h
Normal file
|
@ -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
|
130
gst/goom/filters_mmx.s
Normal file
130
gst/goom/filters_mmx.s
Normal file
|
@ -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
|
420
gst/goom/goom_core.c
Normal file
420
gst/goom/goom_core.c
Normal file
|
@ -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();
|
||||
}
|
13
gst/goom/goom_core.h
Normal file
13
gst/goom/goom_core.h
Normal file
|
@ -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
|
29
gst/goom/goom_tools.h
Normal file
29
gst/goom/goom_tools.h
Normal file
|
@ -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
|
17
gst/goom/graphic.c
Normal file
17
gst/goom/graphic.c
Normal file
|
@ -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 ;
|
24
gst/goom/graphic.h
Normal file
24
gst/goom/graphic.h
Normal file
|
@ -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*/
|
341
gst/goom/gstgoom.c
Normal file
341
gst/goom/gstgoom.c
Normal file
|
@ -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
|
||||
};
|
90
gst/goom/lines.c
Normal file
90
gst/goom/lines.c
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
gst/goom/lines.h
Normal file
15
gst/goom/lines.h
Normal file
|
@ -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]);
|
||||
|
Loading…
Reference in a new issue