From: Marco Paniconi Date: Tue, 15 Jul 2014 01:15:39 +0000 (-0700) Subject: vp8: Allow for on/off control of UV temporal denoiser. X-Git-Tag: v1.4.0~1220^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=21042c7154c87048fd1b056d8c905ddf2352185f;p=libvpx vp8: Allow for on/off control of UV temporal denoiser. Use noise_sensitivity level for enabling UV denoiser. Change-Id: Ib208786a6fdf654981bcd96a3cf44e8e678025c1 --- diff --git a/examples/vpx_temporal_svc_encoder.c b/examples/vpx_temporal_svc_encoder.c index 9f32bd8fe..e4616ef69 100644 --- a/examples/vpx_temporal_svc_encoder.c +++ b/examples/vpx_temporal_svc_encoder.c @@ -32,6 +32,14 @@ void usage_exit() { exit(EXIT_FAILURE); } +// Denoiser states, for temporal denoising. +enum denoiserState { + kDenoiserOff, + kDenoiserOnYOnly, + kDenoiserOnYUV, + kDenoiserOnYUVAggressive // Aggressive mode not implemented currently. +}; + static int mode_to_num_layers[12] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3}; // For rate control encoding stats. @@ -571,7 +579,7 @@ int main(int argc, char **argv) { if (strncmp(encoder->name, "vp8", 3) == 0) { vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed); - vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, 1); + vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOnYUV); } else if (strncmp(encoder->name, "vp9", 3) == 0) { vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed); vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h index 119e40cdc..7d9441d54 100644 --- a/vp8/common/onyx.h +++ b/vp8/common/onyx.h @@ -104,7 +104,17 @@ extern "C" struct vpx_rational timebase; unsigned int target_bandwidth; /* kilobits per second */ - /* parameter used for applying pre processing blur: recommendation 0 */ + /* Parameter used for applying denoiser. + * For temporal denoiser: noise_sensitivity = 0 means off, + * noise_sensitivity = 1 means temporal denoiser on for Y channel only, + * noise_sensitivity = 2 means temporal denoiser on for all channels. + * noise_sensitivity = 3 will be used for aggressive mode in future. + * Temporal denoiser is enabled via the build option + * CONFIG_TEMPORAL_DENOISING. + * For spatial denoiser: noise_sensitivity controls the amount of + * pre-processing blur: noise_sensitivity = 0 means off. + * Spatial denoiser invoked under !CONFIG_TEMPORAL_DENOISING. + */ int noise_sensitivity; /* parameter used for sharpening output: recommendation 0: */ diff --git a/vp8/encoder/denoising.c b/vp8/encoder/denoising.c index 94aa2ca24..0f0a36a61 100644 --- a/vp8/encoder/denoising.c +++ b/vp8/encoder/denoising.c @@ -396,15 +396,14 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, loop_filter_info_n *lfi_n, int mb_row, int mb_col, - int block_index) + int block_index, + int uv_denoise) { int mv_row; int mv_col; unsigned int motion_magnitude2; unsigned int sse_thresh; int sse_diff_thresh = 0; - // Denoise the UV channel. - int apply_color_denoise = 0; // Spatial loop filter: only applied selectively based on // temporal filter state of block relative to top/left neighbors. int apply_spatial_loop_filter = 1; @@ -529,7 +528,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, denoiser->denoise_state[block_index] = motion_magnitude2 > 0 ? kFilterNonZeroMV : kFilterZeroMV; // Only denoise UV for zero motion, and if y channel was denoised. - if (apply_color_denoise && + if (uv_denoise && motion_magnitude2 == 0 && decision == FILTER_BLOCK) { unsigned char *mc_running_avg_u = @@ -566,7 +565,7 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, denoiser->yv12_running_avg[INTRA_FRAME].y_stride); denoiser->denoise_state[block_index] = kNoFilter; } - if (apply_color_denoise) { + if (uv_denoise) { if (decision_u == COPY_BLOCK) { vp8_copy_mem8x8( x->block[16].src + *x->block[16].base_src, x->block[16].src_stride, diff --git a/vp8/encoder/denoising.h b/vp8/encoder/denoising.h index 8f1bfa51d..a1f195b72 100644 --- a/vp8/encoder/denoising.h +++ b/vp8/encoder/denoising.h @@ -61,7 +61,8 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, loop_filter_info_n *lfi_n, int mb_row, int mb_col, - int block_index); + int block_index, + int uv_denoise); #ifdef __cplusplus } // extern "C" diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c index 3a78ee9ba..86108b70a 100644 --- a/vp8/encoder/pickinter.c +++ b/vp8/encoder/pickinter.c @@ -1168,6 +1168,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, #if CONFIG_TEMPORAL_DENOISING if (cpi->oxcf.noise_sensitivity) { + int uv_denoise = (cpi->oxcf.noise_sensitivity == 2) ? 1 : 0; int block_index = mb_row * cpi->common.mb_cols + mb_col; if (x->best_sse_inter_mode == DC_PRED) { @@ -1182,7 +1183,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse, recon_yoffset, recon_uvoffset, &cpi->common.lf_info, mb_row, mb_col, - block_index); + block_index, uv_denoise); /* Reevaluate ZEROMV after denoising. */ diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 4465b5e98..98d60160c 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -2511,6 +2511,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, #if CONFIG_TEMPORAL_DENOISING if (cpi->oxcf.noise_sensitivity) { + int uv_denoise = (cpi->oxcf.noise_sensitivity == 2) ? 1 : 0; int block_index = mb_row * cpi->common.mb_cols + mb_col; if (x->best_sse_inter_mode == DC_PRED) { @@ -2524,7 +2525,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse, recon_yoffset, recon_uvoffset, &cpi->common.lf_info, mb_row, mb_col, - block_index); + block_index, uv_denoise); /* Reevaluate ZEROMV after denoising. */