changeset 16682:5f98b89262c4

hqdn3d: 2.5x faster temporal-only, 1.6x faster spatial-only.
author lorenm
date Thu, 06 Oct 2005 06:05:38 +0000
parents d2644619e364
children 7720dfea43ec
files libmpcodecs/vf_hqdn3d.c
diffstat 1 files changed, 76 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/vf_hqdn3d.c	Wed Oct 05 19:52:13 2005 +0000
+++ b/libmpcodecs/vf_hqdn3d.c	Thu Oct 06 06:05:38 2005 +0000
@@ -73,6 +73,68 @@
     return CurrMul + Coef[d];
 }
 
+static void deNoiseTemporal(
+                    unsigned char *Frame,        // mpi->planes[x]
+                    unsigned char *FrameDest,    // dmpi->planes[x]
+                    unsigned short *FrameAnt,
+                    int W, int H, int sStride, int dStride,
+                    int *Temporal)
+{
+    int X, Y;
+    int PixelDst;
+
+    for (Y = 0; Y < H; Y++){
+        for (X = 0; X < W; X++){
+            PixelDst = LowPassMul(FrameAnt[X]<<8, Frame[X]<<16, Temporal);
+            FrameAnt[X] = ((PixelDst+0x1000007F)/256);
+            FrameDest[X]= ((PixelDst+0x10007FFF)/65536);
+        }
+        Frame += sStride;
+        FrameDest += dStride;
+        FrameAnt += W;
+    }
+}
+
+static void deNoiseSpacial(
+                    unsigned char *Frame,        // mpi->planes[x]
+                    unsigned char *FrameDest,    // dmpi->planes[x]
+                    unsigned int *LineAnt,       // vf->priv->Line (width bytes)
+                    int W, int H, int sStride, int dStride,
+                    int *Horizontal, int *Vertical)
+{
+    int X, Y;
+    int sLineOffs = 0, dLineOffs = 0;
+    unsigned int PixelAnt;
+    int PixelDst;
+    
+    /* First pixel has no left nor top neightbour. */
+    PixelDst = LineAnt[0] = PixelAnt = Frame[0]<<16;
+    FrameDest[0]= ((PixelDst+0x10007FFF)/65536);
+
+    /* Fist line has no top neightbour, only left. */
+    for (X = 1; X < W; X++){
+        PixelDst = LineAnt[X] = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal);
+	FrameDest[X]= ((PixelDst+0x10007FFF)/65536);
+    }
+
+    for (Y = 1; Y < H; Y++){
+	unsigned int PixelAnt;
+	sLineOffs += sStride, dLineOffs += dStride;
+        /* First pixel on each line doesn't have previous pixel */
+        PixelAnt = Frame[sLineOffs]<<16;
+        PixelDst = LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical);
+	FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)/65536);
+
+        for (X = 1; X < W; X++){
+	    int PixelDst;
+            /* The rest are normal */
+            PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal);
+            PixelDst = LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical);
+	    FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)/65536);
+        }
+    }
+}
+
 static void deNoise(unsigned char *Frame,        // mpi->planes[x]
                     unsigned char *FrameDest,    // dmpi->planes[x]
                     unsigned int *LineAnt,      // vf->priv->Line (width bytes)
@@ -95,6 +157,17 @@
 	}
     }
 
+    if(!Horizontal[0] && !Vertical[0]){
+        deNoiseTemporal(Frame, FrameDest, FrameAnt,
+                        W, H, sStride, dStride, Temporal);
+        return;
+    }
+    if(!Temporal[0]){
+        deNoiseSpacial(Frame, FrameDest, LineAnt,
+                       W, H, sStride, dStride, Horizontal, Vertical);
+        return;
+    }
+
     /* First pixel has no left nor top neightbour. Only previous frame */
     LineAnt[0] = PixelAnt = Frame[0]<<16;
     PixelDst = LowPassMul(FrameAnt[0]<<8, PixelAnt, Temporal);
@@ -194,12 +267,14 @@
 
     Gamma = log(0.25) / log(1.0 - Dist25/255.0 - 0.00001);
 
-    for (i = -256*16; i < 256*16; i++)
+    for (i = -255*16; i <= 255*16; i++)
     {
         Simil = 1.0 - ABS(i) / (16*255.0);
         C = pow(Simil, Gamma) * 65536.0 * (double)i / 16.0;
         Ct[16*256+i] = (C<0) ? (C-0.5) : (C+0.5);
     }
+
+    Ct[0] = (Dist25 != 0);
 }