diff --git a/vp8/encoder/denoising.c b/vp8/encoder/denoising.c index 0c98eb1a5..d4f68a9da 100644 --- a/vp8/encoder/denoising.c +++ b/vp8/encoder/denoising.c @@ -412,12 +412,27 @@ int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height, vp8_denoiser_set_parameters(denoiser, mode); denoiser->nmse_source_diff = 0; denoiser->nmse_source_diff_count = 0; + denoiser->qp_avg = 0; + // QP threshold below which we can go up to aggressive mode. + denoiser->qp_threshold_up = 80; + // QP threshold above which we can go back down to normal mode. + // For now keep this second threshold high, so not used currently. + denoiser->qp_threshold_down = 128; + // Bitrate thresholds and noise metric (nmse) thresholds for switching to + // aggressive mode. // TODO(marpan): Adjust thresholds, including effect on resolution. + denoiser->bitrate_threshold = 200000; // (bits/sec). denoiser->threshold_aggressive_mode = 35; - if (width * height > 640 * 480) + if (width * height > 640 * 480) { + denoiser->bitrate_threshold = 500000; + denoiser->threshold_aggressive_mode = 100; + } else if (width * height > 960 * 540) { + denoiser->bitrate_threshold = 800000; denoiser->threshold_aggressive_mode = 150; - else if (width * height > 1280 * 720) + } else if (width * height > 1280 * 720) { + denoiser->bitrate_threshold = 2000000; denoiser->threshold_aggressive_mode = 1400; + } return 0; } diff --git a/vp8/encoder/denoising.h b/vp8/encoder/denoising.h index e1844f18a..bb0c2ce8d 100644 --- a/vp8/encoder/denoising.h +++ b/vp8/encoder/denoising.h @@ -19,7 +19,7 @@ extern "C" { #endif #define SUM_DIFF_THRESHOLD (16 * 16 * 2) -#define SUM_DIFF_THRESHOLD_HIGH (16 * 16 * 3) +#define SUM_DIFF_THRESHOLD_HIGH (600) #define MOTION_MAGNITUDE_THRESHOLD (8*3) #define SUM_DIFF_THRESHOLD_UV (96) // (8 * 8 * 1.5) @@ -81,6 +81,10 @@ typedef struct vp8_denoiser int threshold_aggressive_mode; int nmse_source_diff; int nmse_source_diff_count; + int qp_avg; + int qp_threshold_up; + int qp_threshold_down; + int bitrate_threshold; denoise_params denoise_pars; } VP8_DENOISER; diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 74e75c4cf..791a4858d 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -3370,33 +3370,43 @@ static void process_denoiser_mode_change(VP8_COMP *cpi) { if (total > 0 && (num_blocks > (tot_num_blocks >> 4))) { // Update the recursive mean square source_diff. - if (cpi->denoiser.nmse_source_diff_count == 0) + if (cpi->denoiser.nmse_source_diff_count == 0) { // First sample in new interval. cpi->denoiser.nmse_source_diff = total; - else + cpi->denoiser.qp_avg = cm->base_qindex; + } else { // For subsequent samples, use average with weight ~1/4 for new sample. cpi->denoiser.nmse_source_diff = (int)((total >> 2) + 3 * (cpi->denoiser.nmse_source_diff >> 2)); + cpi->denoiser.qp_avg = (int)((cm->base_qindex >> 2) + + 3 * (cpi->denoiser.qp_avg >> 2)); + } cpi->denoiser.nmse_source_diff_count++; } // Check for changing the denoiser mode, when we have obtained #samples = - // num_mode_change. + // num_mode_change. Condition the change also on the bitrate and QP. if (cpi->denoiser.nmse_source_diff_count == num_mode_change) { // Check for going up: from normal to aggressive mode. if ((cpi->denoiser.denoiser_mode == kDenoiserOnYUV) && (cpi->denoiser.nmse_source_diff > - cpi->denoiser.threshold_aggressive_mode)) { + cpi->denoiser.threshold_aggressive_mode) && + (cpi->denoiser.qp_avg < cpi->denoiser.qp_threshold_up && + cpi->target_bandwidth > cpi->denoiser.bitrate_threshold)) { vp8_denoiser_set_parameters(&cpi->denoiser, kDenoiserOnYUVAggressive); } else { // Check for going down: from aggressive to normal mode. - if ((cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) && + if (((cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) && (cpi->denoiser.nmse_source_diff < - cpi->denoiser.threshold_aggressive_mode)) { + cpi->denoiser.threshold_aggressive_mode)) || + ((cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) && + (cpi->denoiser.qp_avg > cpi->denoiser.qp_threshold_down || + cpi->target_bandwidth < cpi->denoiser.bitrate_threshold))) { vp8_denoiser_set_parameters(&cpi->denoiser, kDenoiserOnYUV); } } // Reset metric and counter for next interval. cpi->denoiser.nmse_source_diff = 0; + cpi->denoiser.qp_avg = 0; cpi->denoiser.nmse_source_diff_count = 0; } }