diff -r -u -N xawtv-3.88.orig/libng/plugins/Subdir.mk xawtv-3.88/libng/plugins/Subdir.mk
--- xawtv-3.88.orig/libng/plugins/Subdir.mk	2003-02-14 15:14:05.000000000 +0100
+++ xawtv-3.88/libng/plugins/Subdir.mk	2003-08-17 16:50:17.000000000 +0200
@@ -4,6 +4,7 @@
 	libng/plugins/flt-gamma.so \
 	libng/plugins/flt-invert.so \
 	libng/plugins/flt-disor.so \
+	libng/plugins/fir.so \
 	libng/plugins/conv-mjpeg.so \
 	libng/plugins/read-avi.so \
 	libng/plugins/write-avi.so
@@ -60,6 +61,7 @@
 libng/plugins/flt-disor.so:  libng/plugins/flt-disor.o
 libng/plugins/flt-gamma.so:  libng/plugins/flt-gamma.o
 libng/plugins/flt-invert.so: libng/plugins/flt-invert.o
+libng/plugins/fir.so: libng/plugins/fir.o
 libng/plugins/read-avi.so:   libng/plugins/read-avi.o
 libng/plugins/read-dv.so:    libng/plugins/read-dv.o
 libng/plugins/read-qt.so:    libng/plugins/read-qt.o
diff -r -u -N xawtv-3.88.orig/libng/plugins/fir.c xawtv-3.88/libng/plugins/fir.c
--- xawtv-3.88.orig/libng/plugins/fir.c	1970-01-01 01:00:00.000000000 +0100
+++ xawtv-3.88/libng/plugins/fir.c	2003-08-24 19:16:36.000000000 +0200
@@ -0,0 +1,352 @@
+/* FIR-filter
+ *
+ * plugin for xawtv and co.
+ * to denoise video frames with FIR filter
+ *
+ * (c)2001/2003 by Andreas Romeyke
+ * distributed under terms of GNU General Public License
+ * please check file COPYING or http://www.fsf.org or http://gnu.org for details
+ *
+ * original used in yet another wormz (c) 2001 by Andreas Romeyke
+ * Algorithm description:
+ *  - p[i]=k*p[i-1]+(1-k)*o[i]
+ *  - k - strength of filtering in 0..1, should be 0.5
+ *  - must used on every column and every row
+ *  - converts sequence of o[0..i..n] to p[0..i..n]
+ *
+ *
+ * works in all YUV-Modi, RGB24, RGB32 and Gray, packed RGB not supported yet
+ * to use YUV, try to start motv this way "motv -xvport 56", on 24 Bit X11 try "motv -noxv"
+ *
+ * The normalize-stuff is there, because the FIR tends to darken the image, not useful in adaptive mode
+ * The YUV modus filters only the Y-channel (b/w-channel).
+ *
+ * The adaptive mode does a edge detection. Best use for animation. Try a horizontal value about 80%, vertical
+ * about 50% and adaptive to 10-12.
+ *
+ * For normal usage set horizontal and vertical value to 50%, adaptive off or to 2-6
+ * If you have suggestions, a patch or you find a bug, please do not hesitate to contact me
+ * via eMail: mailto:andreas.romeyke@web.de
+ *
+ */
+
+/* TODO: correct filter to work on per Channel basis in 15/16bit RGB mode*/
+/* TODO: adaptive filterinbg in RGB-modi */
+
+#include <stdlib.h>
+#include "grab-ng.h"
+
+static int fircoeffh = (int) 1000/2;
+static int fircoeffv = (int) 1000/2;
+static int firnormalize = 0;
+static int firadaptive = 0;
+static int fircoeffa=10;
+#define FIRCOEFF(v) ((double) (v)/1000)
+#define PIX(x,y) (frame->data[((y) * frame->fmt.bytesperline) + (x)])
+static void inline
+fir(struct ng_video_buf *frame) {
+	int x,y;
+	unsigned char maxY=0; unsigned char maxR=0; unsigned char maxG=0; unsigned char maxB=0;
+	unsigned char maxpY=0; unsigned char maxpR=0; unsigned char maxpG=0; unsigned char maxpB=0;
+	switch (frame->fmt.fmtid) {
+		case VIDEO_GRAY: /* 8 bit Gray */
+			if (firadaptive>0) {
+				for (y = 2; y < frame->fmt.height-2; y++) {
+					for (x = 2; x < frame->fmt.width-2 ; x++) {
+						if ((maxpY<255) && (maxpY<PIX(x,y))) maxpY=PIX(x,y);
+						if (
+							abs(
+							((PIX(x-2,y)+PIX(x-1,y)+PIX(x,y))/3) -
+							((PIX(x,y)+PIX(x+1,y)+PIX(x+2,y))/3)) < fircoeffa) {
+								PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-1),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+						}
+						if (
+							abs(
+							((PIX(x,y-2)+PIX(x,y-1)+PIX(x,y))/3) -
+							((PIX(x,y)+PIX(x,y+1)+PIX(x,y+2))/3)) < fircoeffa) {
+								PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+						}
+						if ((maxY<255) && (maxY<PIX(x,y))) maxY=PIX(x,y);
+					}
+				}
+			} else {
+				for (y = 1; y < frame->fmt.height; y++) {
+					for (x = 1; x < frame->fmt.width ; x++) {
+						if ((maxpY<255) && (maxpY<PIX(x,y))) maxpY=PIX(x,y);
+						PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-1),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+						PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+						if ((maxY<255) && (maxY<PIX(x,y))) maxY=PIX(x,y);
+					}
+				}
+			}
+			if (firnormalize==1) {
+				for (y = 1; y < frame->fmt.height; y++) {
+					for (x = 1; x < frame->fmt.width ; x++) {
+						PIX(x,y)=PIX(x,y)*maxpY/maxY;
+					}
+				}
+			}
+
+			break;
+		case VIDEO_YUYV: /* only Y channel will be denoised, 16bit */
+			if (firadaptive>0) {
+				for (y = 3; y < frame->fmt.height; y++) {
+					for (x = 6; x < frame->fmt.bytesperline ; x+=2) {
+						if ((maxpY<255) && (maxpY<PIX(x,y))) maxpY=PIX(x,y);
+						if (
+							abs(
+							((PIX(x-6,y)+PIX(x-4,y)+PIX(x-2,y))/3) -
+							((PIX(x-4,y)+PIX(x-2,y)+PIX(x,y))/3)) < fircoeffa) {
+								PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-2),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+						}
+						if (
+							abs(
+							((PIX(x,y-3)+PIX(x,y-2)+PIX(x,y-1))/3) -
+							((PIX(x,y-2)+PIX(x,y-1)+PIX(x,y))/3)) < fircoeffa) {
+								PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+						}
+						if ((maxY<255) && (maxY<PIX(x,y))) maxY=PIX(x,y);
+					}
+				}
+			} else {
+				for (y = 1; y < frame->fmt.height; y++) {
+					for (x = 2; x < frame->fmt.bytesperline ; x+=2) {
+						if ((maxpY<255) && (maxpY<PIX(x,y))) maxpY=PIX(x,y);
+						PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-2),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+						PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+						if ((maxY<255) && (maxY<PIX(x,y))) maxY=PIX(x,y);
+					}
+				}
+			}
+			if (firnormalize==1) {
+				for (y = 1; y < frame->fmt.height; y++) {
+					for (x = 2; x < frame->fmt.bytesperline ; x+=2) {
+						PIX(x,y)=PIX(x,y)*maxpY/maxY;
+					}
+				}
+			}
+
+			break;
+		case VIDEO_BGR24:
+		case VIDEO_RGB24: /* all channels will be denoised, 24bit */
+			for (y = 1; y < frame->fmt.height; y++) {
+				for (x = 3; x < frame->fmt.bytesperline ; x+=3) {
+					if ((maxpR<255) && (maxpR<PIX(x,y))) maxpR=PIX(x,y);
+					PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-3),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+					PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+					if ((maxR<255) && (maxR<PIX(x,y))) maxR=PIX(x,y);
+				}
+				for (x = 4; x < frame->fmt.bytesperline ; x+=3) {
+					if ((maxpG<255) && (maxpG<PIX(x,y))) maxpG=PIX(x,y);
+					PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-3),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+					PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+					if ((maxG<255) && (maxG<PIX(x,y))) maxG=PIX(x,y);
+				}
+				for (x = 5; x < frame->fmt.bytesperline ; x+=3) {
+					if ((maxpB<255) && (maxpB<PIX(x,y))) maxpB=PIX(x,y);
+					PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-3),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+					PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+					if ((maxB<255) && (maxB<PIX(x,y))) maxB=PIX(x,y);
+				}
+			}
+			if (firnormalize==1) {
+				for (y = 1; y < frame->fmt.height; y++) {
+					for (x = 3; x < frame->fmt.bytesperline ; x+=3) {
+						PIX(x,y)=PIX(x,y)*maxpR/maxR;
+					}
+					for (x = 4; x < frame->fmt.bytesperline ; x+=3) {
+						PIX(x,y)=PIX(x,y)*maxpG/maxG;
+					}
+					for (x = 5; x < frame->fmt.bytesperline ; x+=3) {
+						PIX(x,y)=PIX(x,y)*maxpB/maxB;
+					}
+				}
+			}
+			break;
+		case VIDEO_BGR32:
+		case VIDEO_RGB32: /* all channels will be denoised, 32bit */
+			for (y = 1; y < frame->fmt.height; y++) {
+				for (x = 4; x < frame->fmt.bytesperline ; x+=4) {
+					PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-4),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+					PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+					if ((maxR<255) && (maxR<PIX(x,y))) maxR=PIX(x,y);
+				}
+				for (x = 5; x < frame->fmt.bytesperline ; x+=4) {
+					PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-4),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+					PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+					if ((maxG<255) && (maxG<PIX(x,y))) maxG=PIX(x,y);
+				}
+				for (x = 6; x < frame->fmt.bytesperline ; x+=4) {
+					PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-4),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+					PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+					if ((maxB<255) && (maxB<PIX(x,y))) maxB=PIX(x,y);
+				}
+			}
+			if (firnormalize==1) {
+				for (y = 1; y < frame->fmt.height; y++) {
+					for (x = 4; x < frame->fmt.bytesperline ; x+=4) {
+						PIX(x,y)=PIX(x,y)*maxpR/maxR;
+					}
+					for (x = 5; x < frame->fmt.bytesperline ; x+=4) {
+						PIX(x,y)=PIX(x,y)*maxpG/maxG;
+					}
+					for (x = 6; x < frame->fmt.bytesperline ; x+=4) {
+						PIX(x,y)=PIX(x,y)*maxpB/maxB;
+					}
+				}
+			}
+			break;
+
+		default:
+			for (y = 1; y < frame->fmt.height; y++) {
+				for (x = 1; x < frame->fmt.bytesperline ; x++) {
+					PIX(x,y) = FIRCOEFF(fircoeffh) *PIX((x-1),y)+(1-FIRCOEFF(fircoeffh))*PIX(x,y); /* horiz. FIR */
+					PIX(x,y) = FIRCOEFF(fircoeffv) *PIX(x,(y-1))+(1-FIRCOEFF(fircoeffv))*PIX(x,y); /* vert. FIR */
+				}
+			}
+			break;
+	}
+}
+
+
+
+static void *init(struct ng_video_fmt *out) {
+    /* don't have to carry around status info */
+    static int dummy;
+    return &dummy;
+}
+
+
+static struct ng_video_buf*
+frame(void *handle, struct ng_video_buf *frame) {
+   fir(frame); // In hindsight, we may not have needed the function ;)
+					   // Added clarity when we make it more complicated.
+   return frame;
+}
+
+
+static void fini(void *handle) {
+    /* nothing to clean up */
+}
+
+
+/* ------------------------------------------------------------------- */
+static int read_attr(struct ng_attribute *attr)
+{
+    switch (attr->id) {
+		case 0:
+			return fircoeffh;
+			break;
+		case 1:
+			return fircoeffv;
+			break;
+		case 2:
+			return firnormalize;
+			break;
+		case 3:
+			return firadaptive;
+			break;
+		case 4:
+			return fircoeffa;
+			break;
+	}
+	return 0;
+}
+
+
+static void write_attr(struct ng_attribute *attr, int value)
+{
+    switch (attr->id) {
+		case 0:
+			fircoeffh = value;
+			break;
+		case 1:
+			fircoeffv = value;
+			break;
+		case 2:
+			firnormalize = value;
+			break;
+		case 3:
+			firadaptive = value;
+			break;
+		case 4:
+			fircoeffa = value;
+	}
+}
+
+
+static struct ng_attribute attrs[] = {
+    {
+	id:       0,
+	name:     "FIR coefficent horiz",
+	type:     ATTR_TYPE_INTEGER,
+	defval:   (int) 10000/2,
+	min:      0,
+	max:      1000,
+	points:   1,
+	read:     read_attr,
+	write:    write_attr,
+    },{
+	id:       1,
+	name:     "FIR coefficent vert",
+	type:     ATTR_TYPE_INTEGER,
+	defval:   (int) 1000/2,
+	min:      0,
+	max:      1000,
+	points:   1,
+	read:     read_attr,
+	write:    write_attr,
+    },{
+	id:       2,
+	name:     "FIR normalize",
+	type:     ATTR_TYPE_BOOL,
+	defval:   (int) 1,
+	read:     read_attr,
+	write:    write_attr,
+    },{
+	id:       3,
+	name:     "FIR adaptive",
+	type:     ATTR_TYPE_BOOL,
+	defval:   (int) 0,
+	min:      0,
+	max:      1,
+	read:     read_attr,
+	write:    write_attr,
+    },{
+	id:       4,
+	name:     "FIR adaptive",
+	type:     ATTR_TYPE_INTEGER,
+	defval:   (int) 0,
+	min:      0,
+	max:      100,
+	read:     read_attr,
+	write:    write_attr,
+    },{
+	/* end of list */
+    }
+};
+
+
+static struct ng_filter filter = {
+    name:    "FIR denoiser",
+    attrs:   attrs,
+    fmts:
+    (1 << VIDEO_GRAY)         |
+    (1 << VIDEO_BGR24)        |
+    (1 << VIDEO_RGB24)        |
+    (1 << VIDEO_BGR32)        |
+    (1 << VIDEO_RGB32)        |
+    (1 << VIDEO_YUYV)         |
+    (1 << VIDEO_UYVY),
+
+    init:    init,
+    frame:   frame,
+    fini:    fini,
+};
+
+
+
+extern void ng_plugin_init(void);
+void ng_plugin_init(void) {
+	ng_filter_register(NG_PLUGIN_MAGIC,__FILE__,&filter);
+}

