From 4d3b1472e78ac7c12460b26914c9a294a3de573a Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 1 Feb 2002 19:28:30 +0000 Subject: [PATCH] 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 --- gst/goom/Makefile.am | 13 ++ gst/goom/filters.c | 528 +++++++++++++++++++++++++++++++++++++++++++++++++ gst/goom/filters.h | 71 +++++++ gst/goom/filters_mmx.s | 130 ++++++++++++ gst/goom/goom_core.c | 420 +++++++++++++++++++++++++++++++++++++++ gst/goom/goom_core.h | 13 ++ gst/goom/goom_tools.h | 29 +++ gst/goom/graphic.c | 17 ++ gst/goom/graphic.h | 24 +++ gst/goom/gstgoom.c | 341 ++++++++++++++++++++++++++++++++ gst/goom/lines.c | 90 +++++++++ gst/goom/lines.h | 15 ++ 12 files changed, 1691 insertions(+) create mode 100644 gst/goom/Makefile.am create mode 100644 gst/goom/filters.c create mode 100644 gst/goom/filters.h create mode 100644 gst/goom/filters_mmx.s create mode 100644 gst/goom/goom_core.c create mode 100644 gst/goom/goom_core.h create mode 100644 gst/goom/goom_tools.h create mode 100644 gst/goom/graphic.c create mode 100644 gst/goom/graphic.h create mode 100644 gst/goom/gstgoom.c create mode 100644 gst/goom/lines.c create mode 100644 gst/goom/lines.h diff --git a/gst/goom/Makefile.am b/gst/goom/Makefile.am new file mode 100644 index 0000000..26bc05a --- /dev/null +++ b/gst/goom/Makefile.am @@ -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 index 0000000..bd26795 --- /dev/null +++ b/gst/goom/filters.c @@ -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 +#include +#include + +#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>= 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 + +#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 index 0000000..337de56 --- /dev/null +++ b/gst/goom/filters_mmx.s @@ -0,0 +1,130 @@ +;// file : mmx_zoom.s +;// author : JC Hoelt +;// +;// 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 index 0000000..245c280 --- /dev/null +++ b/gst/goom/goom_core.c @@ -0,0 +1,420 @@ +#include +#include +#include "goom_core.h" +#include "goom_tools.h" +#include "filters.h" +#include "lines.h" + +//#define VERBOSE + +#ifdef VERBOSE +#include +#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 index 0000000..15f942d --- /dev/null +++ b/gst/goom/goom_core.h @@ -0,0 +1,13 @@ +#ifndef _GOOMCORE_H +#define _GOOMCORE_H + +#include + +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 index 0000000..d077c0c --- /dev/null +++ b/gst/goom/goom_tools.h @@ -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 index 0000000..4223c67 --- /dev/null +++ b/gst/goom/graphic.c @@ -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 index 0000000..415dde7 --- /dev/null +++ b/gst/goom/graphic.h @@ -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 index 0000000..c051352 --- /dev/null +++ b/gst/goom/gstgoom.c @@ -0,0 +1,341 @@ +/* gstgoom.c: implementation of goom drawing element + * Copyright (C) <2001> Richard Boulton + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "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 ", + "(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 index 0000000..fbab8b1 --- /dev/null +++ b/gst/goom/lines.c @@ -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 + +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 index 0000000..3582d38 --- /dev/null +++ b/gst/goom/lines.h @@ -0,0 +1,15 @@ +/* + * lines.h + * iGoom + * + * Created by guillaum on Tue Aug 14 2001. + * Copyright (c) 2001 ios. All rights reserved. + * + */ +#include + +#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]); + -- 2.7.4