summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/post/planar/Makefile.am2
-rw-r--r--src/post/planar/noise.c605
-rw-r--r--src/post/planar/planar.c6
3 files changed, 611 insertions, 2 deletions
diff --git a/src/post/planar/Makefile.am b/src/post/planar/Makefile.am
index 998e1210f..61a7c7956 100644
--- a/src/post/planar/Makefile.am
+++ b/src/post/planar/Makefile.am
@@ -20,7 +20,7 @@ libdir = $(XINE_PLUGINDIR)/post
lib_LTLIBRARIES = xineplug_post_planar.la
xineplug_post_planar_la_SOURCES = planar.c invert.c expand.c fill.c boxblur.c \
- denoise3d.c eq.c eq2.c unsharp.c pp.c
+ denoise3d.c eq.c eq2.c unsharp.c pp.c noise.c
xineplug_post_planar_la_DEPENDENCIES = $(postproc_dep)
xineplug_post_planar_la_LIBADD = $(XINE_LIB) $(postproc_lib) -lm $(THREAD_LIBS)
xineplug_post_planar_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
diff --git a/src/post/planar/noise.c b/src/post/planar/noise.c
new file mode 100644
index 000000000..bf7ef7a9b
--- /dev/null
+++ b/src/post/planar/noise.c
@@ -0,0 +1,605 @@
+/*
+ * Copyright (C) 2000-2004 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: noise.c,v 1.1 2006/02/05 21:07:54 miguelfreitas Exp $
+ *
+ * mplayer's noise filter, ported by Jason Tackaberry. Original filter
+ * is copyright 2002 Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#include "xine_internal.h"
+#include "post.h"
+#include "xineutils.h"
+#include <math.h>
+#include <pthread.h>
+
+
+#ifdef ARCH_X86_64
+# define REG_a "rax"
+#else
+# define REG_a "eax"
+#endif
+
+#define MAX_NOISE 4096
+#define MAX_SHIFT 1024
+#define MAX_RES (MAX_NOISE-MAX_SHIFT)
+
+static inline void lineNoise_C(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift);
+static inline void lineNoiseAvg_C(uint8_t *dst, uint8_t *src, int len, int8_t **shift);
+
+static void (*lineNoise)(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift) = lineNoise_C;
+static void (*lineNoiseAvg)(uint8_t *dst, uint8_t *src, int len, int8_t **shift) = lineNoiseAvg_C;
+
+
+typedef struct noise_param_t {
+ int strength,
+ uniform,
+ temporal,
+ quality,
+ averaged,
+ pattern,
+ shiftptr;
+ int8_t *noise,
+ *prev_shift[MAX_RES][3];
+} noise_param_t;
+
+static int nonTempRandShift[MAX_RES]= {-1};
+
+static int patt[4] = {
+ -1,0,1,0
+};
+
+#define RAND_N(range) ((int) ((double)range*rand()/(RAND_MAX+1.0)))
+static int8_t *initNoise(noise_param_t *fp){
+ int strength= fp->strength;
+ int uniform= fp->uniform;
+ int averaged= fp->averaged;
+ int pattern= fp->pattern;
+ int8_t *noise= memalign(16, MAX_NOISE*sizeof(int8_t));
+ int i, j;
+
+ srand(123457);
+
+ for(i=0,j=0; i<MAX_NOISE; i++,j++)
+ {
+ if(uniform) {
+ if (averaged) {
+ if (pattern) {
+ noise[i]= (RAND_N(strength) - strength/2)/6
+ +patt[j%4]*strength*0.25/3;
+ } else {
+ noise[i]= (RAND_N(strength) - strength/2)/3;
+ }
+ } else {
+ if (pattern) {
+ noise[i]= (RAND_N(strength) - strength/2)/2
+ + patt[j%4]*strength*0.25;
+ } else {
+ noise[i]= RAND_N(strength) - strength/2;
+ }
+ }
+ } else {
+ double x1, x2, w, y1;
+ do {
+ x1 = 2.0 * rand()/(float)RAND_MAX - 1.0;
+ x2 = 2.0 * rand()/(float)RAND_MAX - 1.0;
+ w = x1 * x1 + x2 * x2;
+ } while ( w >= 1.0 );
+
+ w = sqrt( (-2.0 * log( w ) ) / w );
+ y1= x1 * w;
+ y1*= strength / sqrt(3.0);
+ if (pattern) {
+ y1 /= 2;
+ y1 += patt[j%4]*strength*0.35;
+ }
+ if (y1<-128) y1=-128;
+ else if(y1> 127) y1= 127;
+ if (averaged) y1 /= 3.0;
+ noise[i]= (int)y1;
+ }
+ if (RAND_N(6) == 0) j--;
+ }
+
+
+ for (i = 0; i < MAX_RES; i++)
+ for (j = 0; j < 3; j++)
+ fp->prev_shift[i][j] = noise + (rand()&(MAX_SHIFT-1));
+
+ if(nonTempRandShift[0]==-1){
+ for(i=0; i<MAX_RES; i++){
+ nonTempRandShift[i]= rand()&(MAX_SHIFT-1);
+ }
+ }
+
+ fp->noise= noise;
+ fp->shiftptr= 0;
+ return noise;
+}
+
+
+#ifdef ARCH_X86
+static inline void lineNoise_MMX(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift){
+ long mmx_len= len&(~7);
+ noise+=shift;
+
+ asm volatile(
+ "mov %3, %%"REG_a" \n\t"
+ "pcmpeqb %%mm7, %%mm7 \n\t"
+ "psllw $15, %%mm7 \n\t"
+ "packsswb %%mm7, %%mm7 \n\t"
+ ".balign 16 \n\t"
+ "1: \n\t"
+ "movq (%0, %%"REG_a"), %%mm0 \n\t"
+ "movq (%1, %%"REG_a"), %%mm1 \n\t"
+ "pxor %%mm7, %%mm0 \n\t"
+ "paddsb %%mm1, %%mm0 \n\t"
+ "pxor %%mm7, %%mm0 \n\t"
+ "movq %%mm0, (%2, %%"REG_a") \n\t"
+ "add $8, %%"REG_a" \n\t"
+ " js 1b \n\t"
+ :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len)
+ : "%"REG_a
+ );
+ if(mmx_len!=len)
+ lineNoise_C(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0);
+}
+
+//duplicate of previous except movntq
+static inline void lineNoise_MMX2(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift){
+ long mmx_len= len&(~7);
+ noise+=shift;
+
+ asm volatile(
+ "mov %3, %%"REG_a" \n\t"
+ "pcmpeqb %%mm7, %%mm7 \n\t"
+ "psllw $15, %%mm7 \n\t"
+ "packsswb %%mm7, %%mm7 \n\t"
+ ".balign 16 \n\t"
+ "1: \n\t"
+ "movq (%0, %%"REG_a"), %%mm0 \n\t"
+ "movq (%1, %%"REG_a"), %%mm1 \n\t"
+ "pxor %%mm7, %%mm0 \n\t"
+ "paddsb %%mm1, %%mm0 \n\t"
+ "pxor %%mm7, %%mm0 \n\t"
+ "movntq %%mm0, (%2, %%"REG_a") \n\t"
+ "add $8, %%"REG_a" \n\t"
+ " js 1b \n\t"
+ :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len)
+ : "%"REG_a
+ );
+ if(mmx_len!=len)
+ lineNoise_C(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0);
+}
+
+#endif
+
+static inline void lineNoise_C(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift){
+ int i;
+ noise+= shift;
+ for(i=0; i<len; i++)
+ {
+ int v= src[i]+ noise[i];
+ if(v>255) dst[i]=255; //FIXME optimize
+ else if(v<0) dst[i]=0;
+ else dst[i]=v;
+ }
+}
+
+/***************************************************************************/
+
+#ifdef ARCH_X86
+
+static inline void lineNoiseAvg_MMX(uint8_t *dst, uint8_t *src, int len, int8_t **shift){
+ long mmx_len= len&(~7);
+
+ asm volatile(
+ "mov %5, %%"REG_a" \n\t"
+ ".balign 16 \n\t"
+ "1: \n\t"
+ "movq (%1, %%"REG_a"), %%mm1 \n\t"
+ "movq (%0, %%"REG_a"), %%mm0 \n\t"
+ "paddb (%2, %%"REG_a"), %%mm1 \n\t"
+ "paddb (%3, %%"REG_a"), %%mm1 \n\t"
+ "movq %%mm0, %%mm2 \n\t"
+ "movq %%mm1, %%mm3 \n\t"
+ "punpcklbw %%mm0, %%mm0 \n\t"
+ "punpckhbw %%mm2, %%mm2 \n\t"
+ "punpcklbw %%mm1, %%mm1 \n\t"
+ "punpckhbw %%mm3, %%mm3 \n\t"
+ "pmulhw %%mm0, %%mm1 \n\t"
+ "pmulhw %%mm2, %%mm3 \n\t"
+ "paddw %%mm1, %%mm1 \n\t"
+ "paddw %%mm3, %%mm3 \n\t"
+ "paddw %%mm0, %%mm1 \n\t"
+ "paddw %%mm2, %%mm3 \n\t"
+ "psrlw $8, %%mm1 \n\t"
+ "psrlw $8, %%mm3 \n\t"
+ "packuswb %%mm3, %%mm1 \n\t"
+ "movq %%mm1, (%4, %%"REG_a") \n\t"
+ "add $8, %%"REG_a" \n\t"
+ " js 1b \n\t"
+ :: "r" (src+mmx_len), "r" (shift[0]+mmx_len), "r" (shift[1]+mmx_len), "r" (shift[2]+mmx_len),
+ "r" (dst+mmx_len), "g" (-mmx_len)
+ : "%"REG_a
+ );
+
+ if(mmx_len!=len){
+ int8_t *shift2[3]={shift[0]+mmx_len, shift[1]+mmx_len, shift[2]+mmx_len};
+ lineNoiseAvg_C(dst+mmx_len, src+mmx_len, len-mmx_len, shift2);
+ }
+}
+#endif
+
+static inline void lineNoiseAvg_C(uint8_t *dst, uint8_t *src, int len, int8_t **shift){
+ int i;
+ int8_t *src2= (int8_t*)src;
+
+ for(i=0; i<len; i++)
+ {
+ const int n= shift[0][i] + shift[1][i] + shift[2][i];
+ dst[i]= src2[i]+((n*src2[i])>>7);
+ }
+}
+
+
+/***************************************************************************/
+
+static void noise(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height, noise_param_t *fp)
+{
+ int8_t *noise= fp->noise;
+ int y;
+ int shift=0;
+
+ if(!noise)
+ {
+ if(src==dst) return;
+
+ if(dstStride==srcStride) memcpy(dst, src, srcStride*height);
+ else
+ {
+ for(y=0; y<height; y++)
+ {
+ memcpy(dst, src, width);
+ dst+= dstStride;
+ src+= srcStride;
+ }
+ }
+ return;
+ }
+
+ for(y=0; y<height; y++)
+ {
+ if(fp->temporal) shift= rand()&(MAX_SHIFT -1);
+ else shift= nonTempRandShift[y];
+
+ if(fp->quality==0) shift&= ~7;
+ if (fp->averaged) {
+ lineNoiseAvg(dst, src, width, fp->prev_shift[y]);
+ fp->prev_shift[y][fp->shiftptr] = noise + shift;
+ } else {
+ lineNoise(dst, src, noise, width, shift);
+ }
+ dst+= dstStride;
+ src+= srcStride;
+ }
+ fp->shiftptr++;
+ if (fp->shiftptr == 3) fp->shiftptr = 0;
+}
+
+
+
+/* plugin class initialization function */
+void *noise_init_plugin(xine_t *xine, void *);
+
+typedef struct post_plugin_noise_s post_plugin_noise_t;
+
+/*
+ * this is the struct used by "parameters api"
+ */
+typedef struct noise_parameters_s {
+ int luma_strength, chroma_strength,
+ type, quality, pattern;
+} noise_parameters_t;
+
+static char *enum_types[] = {"uniform", "gaussian", NULL};
+static char *enum_quality[] = {"fixed", "temporal", "averaged temporal", NULL};
+
+/*
+ * description of params struct
+ */
+START_PARAM_DESCR( noise_parameters_t )
+PARAM_ITEM( POST_PARAM_TYPE_INT, luma_strength, NULL, 0, 100, 0,
+ "Amount of noise to add to luma channel" )
+PARAM_ITEM( POST_PARAM_TYPE_INT, chroma_strength, NULL, 0, 100, 0,
+ "Amount of noise to add to chroma channel" )
+PARAM_ITEM( POST_PARAM_TYPE_INT, quality, enum_quality, 0, 0, 0,
+ "Quality level of noise" )
+PARAM_ITEM( POST_PARAM_TYPE_INT, type, enum_types, 0, 0, 0,
+ "Type of noise" )
+PARAM_ITEM( POST_PARAM_TYPE_BOOL, pattern, NULL, 0, 1, 0,
+ "Mix random noise with a (semi)regular pattern" )
+END_PARAM_DESCR( param_descr )
+
+
+/* plugin structure */
+struct post_plugin_noise_s {
+ post_plugin_t post;
+
+ /* private data */
+ noise_param_t params[2]; // luma and chroma
+ xine_post_in_t params_input;
+
+ pthread_mutex_t lock;
+};
+
+
+static int set_parameters (xine_post_t *this_gen, void *param_gen)
+{
+ post_plugin_noise_t *this = (post_plugin_noise_t *)this_gen;
+ noise_parameters_t *param = (noise_parameters_t *)param_gen;
+ int i;
+
+ pthread_mutex_lock (&this->lock);
+ for (i = 0; i < 2; i++) {
+ this->params[i].uniform = (param->type == 0);
+ this->params[i].temporal = (param->quality >= 1);
+ this->params[i].averaged = (param->quality == 2);
+ this->params[i].quality = 1;
+ this->params[i].pattern = param->pattern;
+ }
+ this->params[0].strength = param->luma_strength;
+ this->params[1].strength = param->chroma_strength;
+ pthread_mutex_unlock (&this->lock);
+ initNoise(&this->params[0]);
+ initNoise(&this->params[1]);
+ return 1;
+}
+
+static int get_parameters (xine_post_t *this_gen, void *param_gen)
+{
+ post_plugin_noise_t *this = (post_plugin_noise_t *)this_gen;
+ noise_parameters_t *param = (noise_parameters_t *)param_gen;
+
+ pthread_mutex_lock (&this->lock);
+ param->type = (this->params[0].uniform == 0);
+ if (this->params[0].averaged)
+ param->quality = 2;
+ else if (this->params[0].temporal)
+ param->quality = 1;
+ else
+ param->quality = 0;
+ param->pattern = this->params[0].pattern;
+ param->luma_strength = this->params[0].strength;
+ param->chroma_strength = this->params[1].strength;
+ pthread_mutex_unlock (&this->lock);
+ return 1;
+}
+
+static xine_post_api_descr_t *get_param_descr (void) {
+ return &param_descr;
+}
+
+static char *get_help (void) {
+ return _("Adds random noise to the video.\n"
+ "\n"
+ "Parameters:\n"
+ " luma_strength: strength of noise added to luma channel "
+ "(0-100, default: 8)\n"
+ " chroma_strength: strength of noise added to chroma channel "
+ "(0-100, default: 5)\n"
+ " quality: quality level of the noise. fixed: constant noise "
+ "pattern; temporal: noise pattern changes between frames; "
+ "averaged temporal: smoother noise pattern that changes between "
+ "frames. (default: averaged temporal)\n"
+ " type: Type of noise: uniform or gaussian. (default: "
+ "gaussian)\n"
+ " pattern: Mix random noise with a (semi)regular pattern. "
+ "(default: False)\n"
+ "\n"
+ "* mplayer's noise (C) Michael Niedermayer\n"
+ );
+}
+
+static xine_post_api_t post_api = {
+ set_parameters,
+ get_parameters,
+ get_param_descr,
+ get_help,
+};
+
+
+/* plugin class functions */
+static post_plugin_t *noise_open_plugin(post_class_t *class_gen, int inputs,
+ xine_audio_port_t **audio_target,
+ xine_video_port_t **video_target);
+static char *noise_get_identifier(post_class_t *class_gen);
+static char *noise_get_description(post_class_t *class_gen);
+static void noise_class_dispose(post_class_t *class_gen);
+
+/* plugin instance functions */
+static void noise_dispose(post_plugin_t *this_gen);
+
+/* frame intercept check */
+static int noise_intercept_frame(post_video_port_t *port, vo_frame_t *frame);
+
+/* replaced vo_frame functions */
+static int noise_draw(vo_frame_t *frame, xine_stream_t *stream);
+
+
+void *noise_init_plugin(xine_t *xine, void *data)
+{
+ post_class_t *class = (post_class_t *)malloc(sizeof(post_class_t));
+
+ if (!class)
+ return NULL;
+
+ class->open_plugin = noise_open_plugin;
+ class->get_identifier = noise_get_identifier;
+ class->get_description = noise_get_description;
+ class->dispose = noise_class_dispose;
+
+#ifdef ARCH_X86
+ if (xine_mm_accel() & MM_ACCEL_X86_MMX) {
+ lineNoise = lineNoise_MMX;
+ lineNoiseAvg = lineNoiseAvg_MMX;
+ } else if (xine_mm_accel() & MM_ACCEL_X86_MMXEXT) {
+ lineNoise = lineNoise_MMX2;
+ }
+#endif
+ return class;
+}
+
+
+static post_plugin_t *noise_open_plugin(post_class_t *class_gen, int inputs,
+ xine_audio_port_t **audio_target,
+ xine_video_port_t **video_target)
+{
+ post_plugin_noise_t *this = (post_plugin_noise_t *)xine_xmalloc(sizeof(post_plugin_noise_t));
+ post_in_t *input;
+ xine_post_in_t *input_api;
+ post_out_t *output;
+ post_video_port_t *port;
+ noise_parameters_t params;
+
+ if (!this || !video_target || !video_target[0]) {
+ free(this);
+ return NULL;
+ }
+
+ _x_post_init(&this->post, 0, 1);
+
+ memset(&params, 0, sizeof(noise_parameters_t));
+ params.luma_strength = 8;
+ params.chroma_strength = 5;
+ params.type = 1;
+ params.quality = 2;
+
+ pthread_mutex_init(&this->lock, NULL);
+
+ port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output);
+ port->intercept_frame = noise_intercept_frame;
+ port->new_frame->draw = noise_draw;
+
+ input_api = &this->params_input;
+ input_api->name = "parameters";
+ input_api->type = XINE_POST_DATA_PARAMETERS;
+ input_api->data = &post_api;
+ xine_list_push_back(this->post.input, input_api);
+
+ input->xine_in.name = "video";
+ output->xine_out.name = "filtered video";
+
+ this->post.xine_post.video_input[0] = &port->new_port;
+
+ this->post.dispose = noise_dispose;
+
+ set_parameters ((xine_post_t *)this, &params);
+
+ return &this->post;
+}
+
+static char *noise_get_identifier(post_class_t *class_gen)
+{
+ return "noise";
+}
+
+static char *noise_get_description(post_class_t *class_gen)
+{
+ return "Adds noise";
+}
+
+static void noise_class_dispose(post_class_t *class_gen)
+{
+ free(class_gen);
+}
+
+
+static void noise_dispose(post_plugin_t *this_gen)
+{
+ post_plugin_noise_t *this = (post_plugin_noise_t *)this_gen;
+
+ if (_x_post_dispose(this_gen)) {
+ pthread_mutex_destroy(&this->lock);
+ free(this);
+ }
+}
+
+
+static int noise_intercept_frame(post_video_port_t *port, vo_frame_t *frame)
+{
+ return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2);
+}
+
+
+static int noise_draw(vo_frame_t *frame, xine_stream_t *stream)
+{
+ post_video_port_t *port = (post_video_port_t *)frame->port;
+ post_plugin_noise_t *this = (post_plugin_noise_t *)port->post;
+ vo_frame_t *out_frame;
+ int skip;
+
+ if (frame->bad_frame ||
+ (this->params[0].strength == 0 && this->params[1].strength == 0)) {
+ _x_post_frame_copy_down(frame, frame->next);
+ skip = frame->next->draw(frame->next, stream);
+ _x_post_frame_copy_up(frame, frame->next);
+ return skip;
+ }
+
+ frame->lock(frame);
+ out_frame = port->original_port->get_frame(port->original_port,
+ frame->width, frame->height, frame->ratio, frame->format,
+ frame->flags | VO_BOTH_FIELDS);
+
+ _x_post_frame_copy_down(frame, out_frame);
+ pthread_mutex_lock (&this->lock);
+
+ if (frame->format == XINE_IMGFMT_YV12) {
+ noise(out_frame->base[0], frame->base[0],
+ out_frame->pitches[0], frame->pitches[0],
+ frame->width, frame->height, &this->params[0]);
+ noise(out_frame->base[1], frame->base[1],
+ out_frame->pitches[1], frame->pitches[1],
+ frame->width/2, frame->height/2, &this->params[1]);
+ noise(out_frame->base[2], frame->base[2],
+ out_frame->pitches[2], frame->pitches[2],
+ frame->width/2, frame->height/2, &this->params[1]);
+ } else {
+ // Chroma strength is ignored for YUY2.
+ noise(out_frame->base[0], frame->base[0],
+ out_frame->pitches[0], frame->pitches[0],
+ frame->width * 2, frame->height, &this->params[0]);
+ }
+
+#ifdef ARCH_X86
+ if (xine_mm_accel() & MM_ACCEL_X86_MMX)
+ asm volatile ("emms\n\t");
+ if (xine_mm_accel() & MM_ACCEL_X86_MMXEXT)
+ asm volatile ("sfence\n\t");
+#endif
+
+ pthread_mutex_unlock (&this->lock);
+ skip = out_frame->draw(out_frame, stream);
+ _x_post_frame_copy_up(frame, out_frame);
+
+ out_frame->free(out_frame);
+ frame->free(frame);
+ return skip;
+}
diff --git a/src/post/planar/planar.c b/src/post/planar/planar.c
index 2d2c76767..8600c482a 100644
--- a/src/post/planar/planar.c
+++ b/src/post/planar/planar.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: planar.c,v 1.9 2005/07/18 18:02:51 jstembridge Exp $
+ * $Id: planar.c,v 1.10 2006/02/05 21:07:54 miguelfreitas Exp $
*
* catalog for planar post plugins
*/
@@ -53,6 +53,9 @@ post_info_t unsharp_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
extern void *pp_init_plugin(xine_t *xine, void *);
post_info_t pp_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
+extern void *noise_init_plugin(xine_t *xine, void *);
+post_info_t noise_special_info = { XINE_POST_TYPE_VIDEO_FILTER };
+
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
{ PLUGIN_POST, 9, "expand", XINE_VERSION_CODE, &expand_special_info, &expand_init_plugin },
@@ -64,5 +67,6 @@ plugin_info_t xine_plugin_info[] = {
{ PLUGIN_POST, 9, "eq2", XINE_VERSION_CODE, &eq2_special_info, &eq2_init_plugin },
{ PLUGIN_POST, 9, "unsharp", XINE_VERSION_CODE, &unsharp_special_info, &unsharp_init_plugin },
{ PLUGIN_POST, 9, "pp", XINE_VERSION_CODE, &pp_special_info, &pp_init_plugin },
+ { PLUGIN_POST, 9, "noise", XINE_VERSION_CODE, &noise_special_info, &noise_init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};