shithub: libvpx

Download patch

ref: 9c9922df972b543631e3d88680c5aac87860e9c0
parent: 49741fee9feca9695424818a2e63b194696d03b1
author: Tim Kopp <tkopp@google.com>
date: Tue Jul 1 07:05:16 EDT 2014

VP9 denoising enabled by noise_sensitivity param

As in VP8.

Currently, this parameter is set with the VP8E_SET_NOISE_SENSITIVITY flag.
The flag was not renamed so that we don't break the interface for webrtc. This
should probably be changed at some point in the future.

Change-Id: Ic73fcb0dde9d1d019e9d042050b617333ac65472

--- a/vp9/encoder/vp9_denoiser.c
+++ b/vp9/encoder/vp9_denoiser.c
@@ -15,6 +15,17 @@
 #include "vp9/common/vp9_reconinter.h"
 #include "vp9/encoder/vp9_denoiser.h"
 
+/* The VP9 denoiser is a work-in-progress. It currently is only designed to work
+ * with speed 6, though it (inexplicably) seems to also work with speed 5 (one
+ * would need to modify the source code in vp9_pickmode.c and vp9_encoder.c to
+ * make the calls to the vp9_denoiser_* functions when in speed 5).
+ *
+ * The implementation is very similar to that of the VP8 denoiser. While
+ * choosing the motion vectors / reference frames, the denoiser is run, and if
+ * it did not modify the signal to much, the denoised block is copied to the
+ * signal.
+ */
+
 #ifdef OUTPUT_YUV_DENOISED
 static void make_grayscale(YV12_BUFFER_CONFIG *yuv);
 #endif
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -65,7 +65,7 @@
 // #define OUTPUT_YUV_REC
 
 #ifdef OUTPUT_YUV_DENOISED
-FILE *yuv_denoised_file;
+FILE *yuv_denoised_file = NULL;
 #endif
 #ifdef OUTPUT_YUV_SRC
 FILE *yuv_file;
@@ -657,9 +657,11 @@
   cpi->ext_refresh_frame_context_pending = 0;
 
 #if CONFIG_DENOISING
-  vp9_denoiser_alloc(&(cpi->denoiser), cm->width, cm->height,
-                     cm->subsampling_x, cm->subsampling_y,
-                     VP9_ENC_BORDER_IN_PIXELS);
+  if (cpi->oxcf.noise_sensitivity > 0) {
+    vp9_denoiser_alloc(&(cpi->denoiser), cm->width, cm->height,
+                       cm->subsampling_x, cm->subsampling_y,
+                       VP9_ENC_BORDER_IN_PIXELS);
+  }
 #endif
 }
 
@@ -839,9 +841,13 @@
   cpi->mb.nmvsadcost_hp[1] = &cpi->mb.nmvsadcosts_hp[1][MV_MAX];
   cal_nmvsadcosts_hp(cpi->mb.nmvsadcost_hp);
 
+#if CONFIG_DENOISING
 #ifdef OUTPUT_YUV_DENOISED
-  yuv_denoised_file = fopen("denoised.yuv", "ab");
+  if (cpi->oxcf.noise_sensitivity > 0) {
+    yuv_denoised_file = fopen("denoised.yuv", "ab");
+  }
 #endif
+#endif
 #ifdef OUTPUT_YUV_SRC
   yuv_file = fopen("bd.yuv", "ab");
 #endif
@@ -1079,7 +1085,9 @@
   }
 
 #if CONFIG_DENOISING
-  vp9_denoiser_free(&(cpi->denoiser));
+  if (cpi->oxcf.noise_sensitivity > 0) {
+    vp9_denoiser_free(&(cpi->denoiser));
+  }
 #endif
 
   dealloc_compressor_data(cpi);
@@ -1093,9 +1101,13 @@
   vp9_remove_common(&cpi->common);
   vpx_free(cpi);
 
+#if CONFIG_DENOISING
 #ifdef OUTPUT_YUV_DENOISED
-  fclose(yuv_denoised_file);
+  if (cpi->oxcf.noise_sensitivity > 0) {
+    fclose(yuv_denoised_file);
+  }
 #endif
+#endif
 #ifdef OUTPUT_YUV_SRC
   fclose(yuv_file);
 #endif
@@ -1305,6 +1317,7 @@
 }
 #endif
 
+#if CONFIG_DENOISING
 #if defined(OUTPUT_YUV_DENOISED)
 // The denoiser buffer is allocated as a YUV 440 buffer. This function writes it
 // as YUV 420. We simply use the top-left pixels of the UV buffers, since we do
@@ -1336,6 +1349,7 @@
   } while (--h);
 }
 #endif
+#endif
 
 #ifdef OUTPUT_YUV_REC
 void vp9_write_yuv_rec_frame(VP9_COMMON *cm) {
@@ -1574,12 +1588,14 @@
                &cm->ref_frame_map[cpi->lst_fb_idx], cm->new_fb_idx);
   }
 #if CONFIG_DENOISING
-  vp9_denoiser_update_frame_info(&cpi->denoiser,
-                                *cpi->Source,
-                                cpi->common.frame_type,
-                                cpi->refresh_alt_ref_frame,
-                                cpi->refresh_golden_frame,
-                                cpi->refresh_last_frame);
+  if (cpi->oxcf.noise_sensitivity > 0) {
+    vp9_denoiser_update_frame_info(&cpi->denoiser,
+                                   *cpi->Source,
+                                   cpi->common.frame_type,
+                                   cpi->refresh_alt_ref_frame,
+                                   cpi->refresh_golden_frame,
+                                   cpi->refresh_last_frame);
+  }
 #endif
 }
 
@@ -2171,15 +2187,20 @@
   }
 #endif
 
-#ifdef OUTPUT_YUV_DENOISED
-  vp9_write_yuv_frame_420(&cpi->denoiser.running_avg_y[INTRA_FRAME],
-                      yuv_denoised_file);
-#endif
 #ifdef OUTPUT_YUV_SRC
   vp9_write_yuv_frame(cpi->Source, yuv_file);
 #endif
 
   set_speed_features(cpi);
+
+#if CONFIG_DENOISING
+#ifdef OUTPUT_YUV_DENOISED
+  if (cpi->oxcf.noise_sensitivity > 0) {
+    vp9_write_yuv_frame_420(&cpi->denoiser.running_avg_y[INTRA_FRAME],
+                            yuv_denoised_file);
+  }
+#endif
+#endif
 
   // Decide q and q bounds.
   q = vp9_rc_pick_q_and_bounds(cpi, &bottom_index, &top_index);
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -440,7 +440,9 @@
   int i;
 
 #if CONFIG_DENOISING
-  vp9_denoiser_reset_frame_stats(&cpi->denoiser);
+  if (cpi->oxcf.noise_sensitivity > 0) {
+    vp9_denoiser_reset_frame_stats(&cpi->denoiser);
+  }
 #endif
 
   if (cpi->sf.reuse_inter_pred_sby) {
@@ -658,7 +660,9 @@
       }
 
 #if CONFIG_DENOISING
-      vp9_denoiser_update_frame_stats(&cpi->denoiser, mbmi, sse_y, this_mode);
+      if (cpi->oxcf.noise_sensitivity > 0) {
+        vp9_denoiser_update_frame_stats(&cpi->denoiser, mbmi, sse_y, this_mode);
+      }
 #endif
 
       if (this_rd < best_rd || x->skip) {
@@ -774,7 +778,9 @@
   }
 
 #if CONFIG_DENOISING
-  vp9_denoiser_denoise(&cpi->denoiser, x, mi_row, mi_col, bsize);
+  if (cpi->oxcf.noise_sensitivity > 0) {
+    vp9_denoiser_denoise(&cpi->denoiser, x, mi_row, mi_col, bsize);
+  }
 #endif
 
   return INT64_MAX;