Attached is a small patch that I put together today that based on my
measurements produces about a 6-7% speedup of yuvdenoise if the
luminance contrast option is used.  I got the idea for the change
from the yuvcorrect sources, the optimization is to pre-compute the
contrasted values for pixel values 0->255 during initialization time,
and then simply do a table lookup in the luma contrast frame inner
loop on the pre-computed pixel value table.  The change saves one
subtract, one multiplication, two additions, one division, and a pair
of comparisons inside the inner luma contrast loop for each pixel. 
That's all replaced by a memory read and the necessary address
calculation to index the lookup table.  And at 256 bytes in length,
the entire table should be in L1 cache after several pixels worth of
lookups in most instances.

I ran about 25 different frames through the unpatched and patch
denoiser with the same options and compared the results, all compared
identical.  I don't see any obvious mistakes in my implementation,
but comments are welcome.

I also made a couple tiny documentation edits to the yuvdenoise help
screen and man page, these changes are unrelated to the table lookup
change.

The group may ask why I didn't also implement a table lookup for the
chrominance contrast pass.  Well, the simple answer right now is that
I don't use the chrominance contrast option and so it wasn't an itch
that needed scratching yet.  However, the exact same optimization
applies there as well.
diff -ur mjpegtools-1.6.1.90.orig/docs/yuvdenoise.1 
mjpegtools-1.6.1.90/docs/yuvdenoise.1
--- mjpegtools-1.6.1.90.orig/docs/yuvdenoise.1  Sat Apr  5 07:29:01 2003
+++ mjpegtools-1.6.1.90/docs/yuvdenoise.1       Mon Sep 29 20:31:26 2003
@@ -61,16 +61,20 @@
 
 .TP 4
 .BI \-L " [0..255] luminance contrast"
-Set luminance (Y Contrast) in percent. (default=100)
+Set luminance (Y Contrast) in percent. (default=100)  The default value of
+100 skips performing luminance contrast adjustment entirely.
 
 .TP 4
 .BI \-C " [0..255] chrominance contrast"
 Set chrominance (Cr/Cb Contrast) in percent. AKA "Saturation" (default=100)
+The default value of 100 skips performing chroninance contract adjustment
+entirely.
 
 .TP 4
 .BI \-S " [0..255] sharpness in percent"
 Set sharpness in percent. WARNING: do not set too high
-as this will gain bit-noise. (default=125)
+as this will gain bit-noise. (default=125)  A sharpness value of 0 will skip
+performing the sharpening pass.
 
 .TP 4
 .BI \-F " deinterlacing"
diff -ur mjpegtools-1.6.1.90.orig/yuvdenoise/denoise.c 
mjpegtools-1.6.1.90/yuvdenoise/denoise.c
--- mjpegtools-1.6.1.90.orig/yuvdenoise/denoise.c       Sat Aug 23 09:14:42 2003
+++ mjpegtools-1.6.1.90/yuvdenoise/denoise.c    Mon Sep 29 12:55:48 2003
@@ -69,6 +69,30 @@
 
 }
 
+/* lookup table implimentation of luma_contrast */
+/* idea from yuvcorrect */
+
+void init_luma_contrast_vector (void)
+{
+  int c;
+  int value;
+
+  for(c=0;c<256;c++)
+    {
+      value=c;
+         
+      value-=128;
+      value*=denoiser.luma_contrast;
+      value=(value+50)/100;
+      value+=128;
+         
+      value=(value>Y_HI_LIMIT)? Y_HI_LIMIT:value;
+      value=(value<Y_LO_LIMIT)? Y_LO_LIMIT:value;
+         
+      luma_contrast_vector[c]=value;
+  }
+}  
+
 void contrast_frame (void)
 {
   register int c;
@@ -81,17 +105,7 @@
     {
       for(c=0;c<(W*H);c++)
        {
-         value=*(p);
-         
-         value-=128;
-         value*=denoiser.luma_contrast;
-         value=(value+50)/100;
-         value+=128;
-         
-         value=(value>Y_HI_LIMIT)? Y_HI_LIMIT:value;
-         value=(value<Y_LO_LIMIT)? Y_LO_LIMIT:value;
-         
-         *(p++)=value;
+         *(p++)=luma_contrast_vector[*(p)];
        }
     }
 
diff -ur mjpegtools-1.6.1.90.orig/yuvdenoise/denoise.h 
mjpegtools-1.6.1.90/yuvdenoise/denoise.h
--- mjpegtools-1.6.1.90.orig/yuvdenoise/denoise.h       Sat Apr  5 07:29:36 2003
+++ mjpegtools-1.6.1.90/yuvdenoise/denoise.h    Mon Sep 29 12:56:59 2003
@@ -8,3 +8,4 @@
 void correct_frame2 (void);
 void denoise_frame_pass2 (void);
 void sharpen_frame(void);
+void init_luma_contrast_vector(void);
diff -ur mjpegtools-1.6.1.90.orig/yuvdenoise/global.h 
mjpegtools-1.6.1.90/yuvdenoise/global.h
--- mjpegtools-1.6.1.90.orig/yuvdenoise/global.h        Sat Aug 23 09:14:42 2003
+++ mjpegtools-1.6.1.90/yuvdenoise/global.h     Mon Sep 29 12:50:14 2003
@@ -104,4 +104,6 @@
   uint32_t SAD;
 };
 
+uint8_t luma_contrast_vector[255];
+
 #endif
diff -ur mjpegtools-1.6.1.90.orig/yuvdenoise/main.c 
mjpegtools-1.6.1.90/yuvdenoise/main.c
--- mjpegtools-1.6.1.90.orig/yuvdenoise/main.c  Sat Aug 23 09:14:42 2003
+++ mjpegtools-1.6.1.90/yuvdenoise/main.c       Mon Sep 29 13:02:10 2003
@@ -187,6 +187,9 @@
   /* turn on accelerations if any */
   turn_on_accels();
   
+  /* precompute luma contrast values for lookup table */
+  init_luma_contrast_vector();
+  
   /* read every single frame until the end of the input stream */
   while 
     (
@@ -609,12 +612,14 @@
   "                   on 4:3 (VCD and SVCD) (default=%i,%i,%i,%i)\n"
   "\n"
   "-L <0...255>       Set luminance contrast in percent. (default=%i)\n"
+  "                   100 = no effect\n"
   "\n"
   "-C <0...255>       Set chrominance contrast in percent. AKA \"Saturation\"\n"
-  "                   (default=%i)"
+  "                   (default=%i) 100 = no effect\n"
   "\n"
   "-S <0...255>       Set sharpness in percent. WARNING: do not set too high\n"
   "                   as this will gain bit-noise. (default=%i)\n"
+  "                   0 = no effect\n"
   "\n"
   "-F                 Force deinterlacing. By default denoise interlaced.\n"
   "\n"

Reply via email to