Commit 4d3b1472 authored by Wim Taymans's avatar Wim Taymans

Added a goom plugin (goom.sourceforge.net) to test: ./gst-launch filesrc...

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
parent e5faa112
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@
This diff is collapsed.
#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
;// 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
This diff is collapsed.
#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
#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
#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 ;
#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*/
/* 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
};
/*
* 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;
}
}
}
/*
* 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);