/* * Copyright (c) 2012 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include <limits.h> #include "denoising.h" #include "vp8/common/reconinter.h" #include "vpx/vpx_integer.h" #include "vpx_mem/vpx_mem.h" #include "vp8_rtcd.h" static const unsigned int NOISE_MOTION_THRESHOLD = …; /* SSE_DIFF_THRESHOLD is selected as ~95% confidence assuming * var(noise) ~= 100. */ static const unsigned int SSE_DIFF_THRESHOLD = …; static const unsigned int SSE_THRESHOLD = …; static const unsigned int SSE_THRESHOLD_HIGH = …; /* * The filter function was modified to reduce the computational complexity. * Step 1: * Instead of applying tap coefficients for each pixel, we calculated the * pixel adjustments vs. pixel diff value ahead of time. * adjustment = filtered_value - current_raw * = (filter_coefficient * diff + 128) >> 8 * where * filter_coefficient = (255 << 8) / (256 + ((absdiff * 330) >> 3)); * filter_coefficient += filter_coefficient / * (3 + motion_magnitude_adjustment); * filter_coefficient is clamped to 0 ~ 255. * * Step 2: * The adjustment vs. diff curve becomes flat very quick when diff increases. * This allowed us to use only several levels to approximate the curve without * changing the filtering algorithm too much. * The adjustments were further corrected by checking the motion magnitude. * The levels used are: * diff adjustment w/o motion correction adjustment w/ motion correction * [-255, -16] -6 -7 * [-15, -8] -4 -5 * [-7, -4] -3 -4 * [-3, 3] diff diff * [4, 7] 3 4 * [8, 15] 4 5 * [16, 255] 6 7 */ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, unsigned char *running_avg_y, int avg_y_stride, unsigned char *sig, int sig_stride, unsigned int motion_magnitude, int increase_denoising) { … } int vp8_denoiser_filter_uv_c(unsigned char *mc_running_avg, int mc_avg_stride, unsigned char *running_avg, int avg_stride, unsigned char *sig, int sig_stride, unsigned int motion_magnitude, int increase_denoising) { … } void vp8_denoiser_set_parameters(VP8_DENOISER *denoiser, int mode) { … } int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height, int num_mb_rows, int num_mb_cols, int mode) { … } void vp8_denoiser_free(VP8_DENOISER *denoiser) { … } void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, MACROBLOCK *x, unsigned int best_sse, unsigned int zero_mv_sse, int recon_yoffset, int recon_uvoffset, loop_filter_info_n *lfi_n, int mb_row, int mb_col, int block_index, int consec_zero_last) { … }