[MPlayer-dev-eng] New noise filter from ffdshow

Jindrich Makovicka makovick at KMLinux.fjfi.cvut.cz
Sun Aug 11 18:25:00 CEST 2002


On Sun, Aug 11, 2002 at 12:36:38PM +0200, Michael Niedermayer wrote:
> Hi
> 
> [...]
> > On Sunday 11 August 2002 10:01, Jindrich Makovicka wrote:
> > > On Sat, Aug 10, 2002 at 12:36:16PM +0200, Arpi wrote:
> > > > Hi,
> > > >
> > > > > I tried to modify vf_noise to add a moving temporal average of the
> > > > > noise from several consecutive timesteps and for about three or four
> > > > > steps the noise looks (imo) very similar to the dx50 film effect.
> > > > > It's pretty cpu-intensive though.
> > > >
> > > > where is the patch? :)
> > >
> > > ok, i cleaned it a bit, here it goes. it doesn't look completely the same
> > > as dx50 but i think it's better than the original temporal noise. there
> > > are no mmx optimizations, as i don't know to code it (and especially the
> > > twisted at&t syntax)
> ok mmx and c versions optimized, rounding is a bit different now though, 
> perhaps u want to check that the quality is still ok after my optimizations 
> ...
> 

btw, here is a little bit different version yet. this one adds also a "p"
option, which enables mixing of the noise with a pattern (just try and see).
the mixing function is a bit modified too, to suppress the noise in the
light/dark regions.

-- 
Jindrich Makovicka
-------------- next part --------------
diff -ur --exclude-from dontdiff vanilla/main/DOCS/mplayer.1 main/DOCS/mplayer.1
--- vanilla/main/DOCS/mplayer.1	Mon Aug  5 18:57:02 2002
+++ main/DOCS/mplayer.1	Sun Aug 11 14:03:40 2002
@@ -518,13 +518,15 @@
                         DVB_HEIGHT*ASPECTRATIO)
     cropdetect[=limit]  black border detection
                         (print crop values)
-    noise[=lumaNoise[u][t][h]:chromaNoise[u][t][h]
+    noise[=lumaNoise[u][t|a][h][p]:chromaNoise[u][t|a][h][p]
                         add noise
                           <0-100>  lumaNoise
                           <0-100>  chromaNoise
                           u        uniform noise
                           t        temporal noise
+                          a        averaged temporal noise
                           h        high quality
+                          p        mix with a pattern
 
 .I parameters:
 .br
diff -ur --exclude-from dontdiff vanilla/main/DOCS/tech/vop.txt main/DOCS/tech/vop.txt
--- vanilla/main/DOCS/tech/vop.txt	Sun Aug  4 13:14:21 2002
+++ main/DOCS/tech/vop.txt	Sun Aug 11 14:04:24 2002
@@ -154,11 +154,13 @@
     generate various test patterns
     MPI: TEMP, accepts stride
 
--vop noise[=lumaNoise[u][t][h]:chromaNoise[u][t][h]
+-vop noise[=lumaNoise[u][t|a][h]:chromaNoise[u][t|a][h]
     add noise
     0<= lumaNoise, chromaNoise <=100
     u uniform noise (gaussian otherwise)
     t temporal noise (noise pattern changes between frames)
+    a averaged temporal (smoother, but a lot slower)
     h high quality (slightly better looking, slightly slower)
+    p mix the noise with a (semi)regular patern
     MPI: DR (if possible) or TEMP, accepts stride
 
diff -ur --exclude-from dontdiff vanilla/main/libmpcodecs/vf_noise.c main/libmpcodecs/vf_noise.c
--- vanilla/main/libmpcodecs/vf_noise.c	Sun Jun 16 15:54:36 2002
+++ main/libmpcodecs/vf_noise.c	Sun Aug 11 16:48:50 2002
@@ -42,14 +42,19 @@
 //===========================================================================//
 
 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 FilterParam{
 	int strength;
 	int uniform;
 	int temporal;
 	int quality;
+        int averaged;
+        int pattern;
+        int shiftptr;
 	int8_t *noise;
 }FilterParam;
 
@@ -61,21 +66,41 @@
 };
 
 static int nonTempRandShift[MAX_RES]= {-1};
+static int8_t *prev_shift[MAX_RES][3];
+
+static int patt[4] = {
+    -1,0,1,0
+};
 
 static int8_t *initNoise(FilterParam *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;
+	int i, j;
 
 	srand(123457);
 
 	for(i=0; i<MAX_NOISE; i++)
 	{
-		if(uniform)
-			noise[i]= ((rand()/11)%strength) - strength/2;
-		else
-		{
+	        if(uniform) {
+		        if (averaged) {
+			    if (pattern) {
+				noise[i]= (((rand()/11)%strength) - strength/2)/6
+				    +patt[(i+((int) (3.0*rand()/(RAND_MAX+1.0))?1:0))%4]*strength*0.125/3;
+			    } else {
+				noise[i]= ((int) ((double)strength*rand()/(RAND_MAX+1.0)) - strength/2)/3;
+			    }
+		        } else {
+			    if (pattern) {
+				noise[i]= ((int) ((double)strength*rand()/(RAND_MAX+1.0))) - strength/2
+				    +patt[(i+((int) (3.0*rand()/(RAND_MAX+1.0))?1:0))%4]*strength*0.125;
+			    } else {
+			        noise[i]= ((int) ((double)strength*rand()/(RAND_MAX+1.0))) - strength/2;
+			    }
+		        }
+                } else {
 			double x1, x2, w, y1;
 			do {
 				x1 = 2.0 * rand()/(float)RAND_MAX - 1.0;
@@ -86,12 +111,22 @@
 			w = sqrt( (-2.0 * log( w ) ) / w );
 			y1= x1 * w;
 
-			y1*= strength / sqrt(3.0); 
+			y1*= strength / sqrt(3.0);
+			if (pattern) {
+			    y1 /= 2;
+			    y1 += patt[(i+((int) (3.0*rand()/(RAND_MAX+1.0))?1:0))%4]*strength*0.35;
+			}
 			if     (y1<-128) y1=-128;
 			else if(y1> 127) y1= 127;
+			if (averaged) y1 /= 3.0;
 			noise[i]= (int)y1;
 		}
 	}
+	
+
+	for (i = 0; i < MAX_RES; i++)
+	    for (j = 0; j < 3; j++)
+		prev_shift[i][j] = noise + (rand()&(MAX_SHIFT-1));
 
 	if(nonTempRandShift[0]==-1){
 		for(i=0; i<MAX_RES; i++){
@@ -100,9 +135,12 @@
 	}
 
 	fp->noise= noise;
+	fp->shiftptr= 0;
 	return noise;
 }
 
+/***************************************************************************/
+
 #ifdef HAVE_MMX
 static inline void lineNoise_MMX(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift){
 	int mmx_len= len&(~7);
@@ -172,6 +210,21 @@
 	}
 }
 
+/***************************************************************************/
+
+static inline void lineNoiseAvg_C(uint8_t *dst, uint8_t *src, int len, int8_t **shift){
+	int i, j, n;
+	
+	for(i=0; i<len; i++)
+	{
+	    for(j=0,n=0;j<3;j++)
+		n+=shift[j][i];
+	    dst[i]= src[i]+n*(128-abs(128-src[i]))/128;
+	}
+}
+
+/***************************************************************************/
+
 static void noise(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height, FilterParam *fp){
 	int8_t *noise= fp->noise;
 	int y;
@@ -200,10 +253,17 @@
 		else			shift= nonTempRandShift[y];
 
 		if(fp->quality==0) shift&= ~7;
-		lineNoise(dst, src, noise, width, shift);
+		if (fp->averaged) {
+		    lineNoiseAvg(dst, src, width, prev_shift[y]);
+		    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;
 }
 
 static int config(struct vf_instance_s* vf,
@@ -301,6 +361,13 @@
 	if(pos && pos<max) fp->temporal=1;
 	pos= strchr(args, 'h');
 	if(pos && pos<max) fp->quality=1;
+	pos= strchr(args, 'p');
+	if(pos && pos<max) fp->pattern=1;
+	pos= strchr(args, 'a');
+	if(pos && pos<max) {
+	    fp->temporal=1;
+	    fp->averaged=1;
+	}
 
 	if(fp->strength) initNoise(fp);
 }
@@ -338,9 +405,11 @@
  
 #ifdef HAVE_MMX
     if(gCpuCaps.hasMMX) lineNoise= lineNoise_MMX;
+//    if(gCpuCaps.hasMMX) lineNoiseAvg= lineNoiseAvg_MMX;
 #endif
 #ifdef HAVE_MMX2
     if(gCpuCaps.hasMMX2) lineNoise= lineNoise_MMX2;
+//    if(gCpuCaps.hasMMX) lineNoiseAvg= lineNoiseAvg_MMX2;
 #endif
     
     return 1;


More information about the MPlayer-dev-eng mailing list