11b362b15af34006e6a11974088a46d42b903418eJohann/* 21b362b15af34006e6a11974088a46d42b903418eJohann * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 31b362b15af34006e6a11974088a46d42b903418eJohann * 41b362b15af34006e6a11974088a46d42b903418eJohann * Use of this source code is governed by a BSD-style license 51b362b15af34006e6a11974088a46d42b903418eJohann * that can be found in the LICENSE file in the root of the source 61b362b15af34006e6a11974088a46d42b903418eJohann * tree. An additional intellectual property rights grant can be found 71b362b15af34006e6a11974088a46d42b903418eJohann * in the file PATENTS. All contributing project authors may 81b362b15af34006e6a11974088a46d42b903418eJohann * be found in the AUTHORS file in the root of the source tree. 91b362b15af34006e6a11974088a46d42b903418eJohann */ 101b362b15af34006e6a11974088a46d42b903418eJohann 111b362b15af34006e6a11974088a46d42b903418eJohann#include "denoising.h" 121b362b15af34006e6a11974088a46d42b903418eJohann 131b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/reconinter.h" 141b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx/vpx_integer.h" 151b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_mem/vpx_mem.h" 16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp8_rtcd.h" 171b362b15af34006e6a11974088a46d42b903418eJohann 181b362b15af34006e6a11974088a46d42b903418eJohannstatic const unsigned int NOISE_MOTION_THRESHOLD = 25 * 25; 191b362b15af34006e6a11974088a46d42b903418eJohann/* SSE_DIFF_THRESHOLD is selected as ~95% confidence assuming 201b362b15af34006e6a11974088a46d42b903418eJohann * var(noise) ~= 100. 211b362b15af34006e6a11974088a46d42b903418eJohann */ 221b362b15af34006e6a11974088a46d42b903418eJohannstatic const unsigned int SSE_DIFF_THRESHOLD = 16 * 16 * 20; 231b362b15af34006e6a11974088a46d42b903418eJohannstatic const unsigned int SSE_THRESHOLD = 16 * 16 * 40; 241b362b15af34006e6a11974088a46d42b903418eJohann 251b362b15af34006e6a11974088a46d42b903418eJohann/* 261b362b15af34006e6a11974088a46d42b903418eJohann * The filter function was modified to reduce the computational complexity. 271b362b15af34006e6a11974088a46d42b903418eJohann * Step 1: 281b362b15af34006e6a11974088a46d42b903418eJohann * Instead of applying tap coefficients for each pixel, we calculated the 291b362b15af34006e6a11974088a46d42b903418eJohann * pixel adjustments vs. pixel diff value ahead of time. 301b362b15af34006e6a11974088a46d42b903418eJohann * adjustment = filtered_value - current_raw 311b362b15af34006e6a11974088a46d42b903418eJohann * = (filter_coefficient * diff + 128) >> 8 321b362b15af34006e6a11974088a46d42b903418eJohann * where 331b362b15af34006e6a11974088a46d42b903418eJohann * filter_coefficient = (255 << 8) / (256 + ((absdiff * 330) >> 3)); 341b362b15af34006e6a11974088a46d42b903418eJohann * filter_coefficient += filter_coefficient / 351b362b15af34006e6a11974088a46d42b903418eJohann * (3 + motion_magnitude_adjustment); 361b362b15af34006e6a11974088a46d42b903418eJohann * filter_coefficient is clamped to 0 ~ 255. 371b362b15af34006e6a11974088a46d42b903418eJohann * 381b362b15af34006e6a11974088a46d42b903418eJohann * Step 2: 391b362b15af34006e6a11974088a46d42b903418eJohann * The adjustment vs. diff curve becomes flat very quick when diff increases. 401b362b15af34006e6a11974088a46d42b903418eJohann * This allowed us to use only several levels to approximate the curve without 411b362b15af34006e6a11974088a46d42b903418eJohann * changing the filtering algorithm too much. 421b362b15af34006e6a11974088a46d42b903418eJohann * The adjustments were further corrected by checking the motion magnitude. 431b362b15af34006e6a11974088a46d42b903418eJohann * The levels used are: 441b362b15af34006e6a11974088a46d42b903418eJohann * diff adjustment w/o motion correction adjustment w/ motion correction 451b362b15af34006e6a11974088a46d42b903418eJohann * [-255, -16] -6 -7 461b362b15af34006e6a11974088a46d42b903418eJohann * [-15, -8] -4 -5 471b362b15af34006e6a11974088a46d42b903418eJohann * [-7, -4] -3 -4 481b362b15af34006e6a11974088a46d42b903418eJohann * [-3, 3] diff diff 491b362b15af34006e6a11974088a46d42b903418eJohann * [4, 7] 3 4 501b362b15af34006e6a11974088a46d42b903418eJohann * [8, 15] 4 5 511b362b15af34006e6a11974088a46d42b903418eJohann * [16, 255] 6 7 521b362b15af34006e6a11974088a46d42b903418eJohann */ 531b362b15af34006e6a11974088a46d42b903418eJohann 541b362b15af34006e6a11974088a46d42b903418eJohannint vp8_denoiser_filter_c(YV12_BUFFER_CONFIG *mc_running_avg, 551b362b15af34006e6a11974088a46d42b903418eJohann YV12_BUFFER_CONFIG *running_avg, MACROBLOCK *signal, 561b362b15af34006e6a11974088a46d42b903418eJohann unsigned int motion_magnitude, int y_offset, 571b362b15af34006e6a11974088a46d42b903418eJohann int uv_offset) 581b362b15af34006e6a11974088a46d42b903418eJohann{ 591b362b15af34006e6a11974088a46d42b903418eJohann unsigned char *sig = signal->thismb; 601b362b15af34006e6a11974088a46d42b903418eJohann int sig_stride = 16; 611b362b15af34006e6a11974088a46d42b903418eJohann unsigned char *mc_running_avg_y = mc_running_avg->y_buffer + y_offset; 621b362b15af34006e6a11974088a46d42b903418eJohann int mc_avg_y_stride = mc_running_avg->y_stride; 631b362b15af34006e6a11974088a46d42b903418eJohann unsigned char *running_avg_y = running_avg->y_buffer + y_offset; 641b362b15af34006e6a11974088a46d42b903418eJohann int avg_y_stride = running_avg->y_stride; 651b362b15af34006e6a11974088a46d42b903418eJohann int r, c, i; 661b362b15af34006e6a11974088a46d42b903418eJohann int sum_diff = 0; 671b362b15af34006e6a11974088a46d42b903418eJohann int adj_val[3] = {3, 4, 6}; 681b362b15af34006e6a11974088a46d42b903418eJohann 691b362b15af34006e6a11974088a46d42b903418eJohann /* If motion_magnitude is small, making the denoiser more aggressive by 701b362b15af34006e6a11974088a46d42b903418eJohann * increasing the adjustment for each level. */ 711b362b15af34006e6a11974088a46d42b903418eJohann if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) 721b362b15af34006e6a11974088a46d42b903418eJohann { 731b362b15af34006e6a11974088a46d42b903418eJohann for (i = 0; i < 3; i++) 741b362b15af34006e6a11974088a46d42b903418eJohann adj_val[i] += 1; 751b362b15af34006e6a11974088a46d42b903418eJohann } 761b362b15af34006e6a11974088a46d42b903418eJohann 771b362b15af34006e6a11974088a46d42b903418eJohann for (r = 0; r < 16; ++r) 781b362b15af34006e6a11974088a46d42b903418eJohann { 791b362b15af34006e6a11974088a46d42b903418eJohann for (c = 0; c < 16; ++c) 801b362b15af34006e6a11974088a46d42b903418eJohann { 811b362b15af34006e6a11974088a46d42b903418eJohann int diff = 0; 821b362b15af34006e6a11974088a46d42b903418eJohann int adjustment = 0; 831b362b15af34006e6a11974088a46d42b903418eJohann int absdiff = 0; 841b362b15af34006e6a11974088a46d42b903418eJohann 851b362b15af34006e6a11974088a46d42b903418eJohann diff = mc_running_avg_y[c] - sig[c]; 861b362b15af34006e6a11974088a46d42b903418eJohann absdiff = abs(diff); 871b362b15af34006e6a11974088a46d42b903418eJohann 881b362b15af34006e6a11974088a46d42b903418eJohann /* When |diff| < 4, use pixel value from last denoised raw. */ 891b362b15af34006e6a11974088a46d42b903418eJohann if (absdiff <= 3) 901b362b15af34006e6a11974088a46d42b903418eJohann { 911b362b15af34006e6a11974088a46d42b903418eJohann running_avg_y[c] = mc_running_avg_y[c]; 921b362b15af34006e6a11974088a46d42b903418eJohann sum_diff += diff; 931b362b15af34006e6a11974088a46d42b903418eJohann } 941b362b15af34006e6a11974088a46d42b903418eJohann else 951b362b15af34006e6a11974088a46d42b903418eJohann { 961b362b15af34006e6a11974088a46d42b903418eJohann if (absdiff >= 4 && absdiff <= 7) 971b362b15af34006e6a11974088a46d42b903418eJohann adjustment = adj_val[0]; 981b362b15af34006e6a11974088a46d42b903418eJohann else if (absdiff >= 8 && absdiff <= 15) 991b362b15af34006e6a11974088a46d42b903418eJohann adjustment = adj_val[1]; 1001b362b15af34006e6a11974088a46d42b903418eJohann else 1011b362b15af34006e6a11974088a46d42b903418eJohann adjustment = adj_val[2]; 1021b362b15af34006e6a11974088a46d42b903418eJohann 1031b362b15af34006e6a11974088a46d42b903418eJohann if (diff > 0) 1041b362b15af34006e6a11974088a46d42b903418eJohann { 1051b362b15af34006e6a11974088a46d42b903418eJohann if ((sig[c] + adjustment) > 255) 1061b362b15af34006e6a11974088a46d42b903418eJohann running_avg_y[c] = 255; 1071b362b15af34006e6a11974088a46d42b903418eJohann else 1081b362b15af34006e6a11974088a46d42b903418eJohann running_avg_y[c] = sig[c] + adjustment; 1091b362b15af34006e6a11974088a46d42b903418eJohann 1101b362b15af34006e6a11974088a46d42b903418eJohann sum_diff += adjustment; 1111b362b15af34006e6a11974088a46d42b903418eJohann } 1121b362b15af34006e6a11974088a46d42b903418eJohann else 1131b362b15af34006e6a11974088a46d42b903418eJohann { 1141b362b15af34006e6a11974088a46d42b903418eJohann if ((sig[c] - adjustment) < 0) 1151b362b15af34006e6a11974088a46d42b903418eJohann running_avg_y[c] = 0; 1161b362b15af34006e6a11974088a46d42b903418eJohann else 1171b362b15af34006e6a11974088a46d42b903418eJohann running_avg_y[c] = sig[c] - adjustment; 1181b362b15af34006e6a11974088a46d42b903418eJohann 1191b362b15af34006e6a11974088a46d42b903418eJohann sum_diff -= adjustment; 1201b362b15af34006e6a11974088a46d42b903418eJohann } 1211b362b15af34006e6a11974088a46d42b903418eJohann } 1221b362b15af34006e6a11974088a46d42b903418eJohann } 1231b362b15af34006e6a11974088a46d42b903418eJohann 1241b362b15af34006e6a11974088a46d42b903418eJohann /* Update pointers for next iteration. */ 1251b362b15af34006e6a11974088a46d42b903418eJohann sig += sig_stride; 1261b362b15af34006e6a11974088a46d42b903418eJohann mc_running_avg_y += mc_avg_y_stride; 1271b362b15af34006e6a11974088a46d42b903418eJohann running_avg_y += avg_y_stride; 1281b362b15af34006e6a11974088a46d42b903418eJohann } 1291b362b15af34006e6a11974088a46d42b903418eJohann 1301b362b15af34006e6a11974088a46d42b903418eJohann if (abs(sum_diff) > SUM_DIFF_THRESHOLD) 1311b362b15af34006e6a11974088a46d42b903418eJohann return COPY_BLOCK; 1321b362b15af34006e6a11974088a46d42b903418eJohann 1331b362b15af34006e6a11974088a46d42b903418eJohann vp8_copy_mem16x16(running_avg->y_buffer + y_offset, avg_y_stride, 1341b362b15af34006e6a11974088a46d42b903418eJohann signal->thismb, sig_stride); 1351b362b15af34006e6a11974088a46d42b903418eJohann return FILTER_BLOCK; 1361b362b15af34006e6a11974088a46d42b903418eJohann} 1371b362b15af34006e6a11974088a46d42b903418eJohann 1381b362b15af34006e6a11974088a46d42b903418eJohannint vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height) 1391b362b15af34006e6a11974088a46d42b903418eJohann{ 1401b362b15af34006e6a11974088a46d42b903418eJohann int i; 1411b362b15af34006e6a11974088a46d42b903418eJohann assert(denoiser); 1421b362b15af34006e6a11974088a46d42b903418eJohann 143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < MAX_REF_FRAMES; i++) 1441b362b15af34006e6a11974088a46d42b903418eJohann { 1451b362b15af34006e6a11974088a46d42b903418eJohann denoiser->yv12_running_avg[i].flags = 0; 1461b362b15af34006e6a11974088a46d42b903418eJohann 1471b362b15af34006e6a11974088a46d42b903418eJohann if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_running_avg[i]), width, 1481b362b15af34006e6a11974088a46d42b903418eJohann height, VP8BORDERINPIXELS) 1491b362b15af34006e6a11974088a46d42b903418eJohann < 0) 1501b362b15af34006e6a11974088a46d42b903418eJohann { 1511b362b15af34006e6a11974088a46d42b903418eJohann vp8_denoiser_free(denoiser); 1521b362b15af34006e6a11974088a46d42b903418eJohann return 1; 1531b362b15af34006e6a11974088a46d42b903418eJohann } 1541b362b15af34006e6a11974088a46d42b903418eJohann vpx_memset(denoiser->yv12_running_avg[i].buffer_alloc, 0, 1551b362b15af34006e6a11974088a46d42b903418eJohann denoiser->yv12_running_avg[i].frame_size); 1561b362b15af34006e6a11974088a46d42b903418eJohann 1571b362b15af34006e6a11974088a46d42b903418eJohann } 1581b362b15af34006e6a11974088a46d42b903418eJohann denoiser->yv12_mc_running_avg.flags = 0; 1591b362b15af34006e6a11974088a46d42b903418eJohann 1601b362b15af34006e6a11974088a46d42b903418eJohann if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_mc_running_avg), width, 1611b362b15af34006e6a11974088a46d42b903418eJohann height, VP8BORDERINPIXELS) < 0) 1621b362b15af34006e6a11974088a46d42b903418eJohann { 1631b362b15af34006e6a11974088a46d42b903418eJohann vp8_denoiser_free(denoiser); 1641b362b15af34006e6a11974088a46d42b903418eJohann return 1; 1651b362b15af34006e6a11974088a46d42b903418eJohann } 1661b362b15af34006e6a11974088a46d42b903418eJohann 1671b362b15af34006e6a11974088a46d42b903418eJohann vpx_memset(denoiser->yv12_mc_running_avg.buffer_alloc, 0, 1681b362b15af34006e6a11974088a46d42b903418eJohann denoiser->yv12_mc_running_avg.frame_size); 1691b362b15af34006e6a11974088a46d42b903418eJohann return 0; 1701b362b15af34006e6a11974088a46d42b903418eJohann} 1711b362b15af34006e6a11974088a46d42b903418eJohann 1721b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_denoiser_free(VP8_DENOISER *denoiser) 1731b362b15af34006e6a11974088a46d42b903418eJohann{ 1741b362b15af34006e6a11974088a46d42b903418eJohann int i; 1751b362b15af34006e6a11974088a46d42b903418eJohann assert(denoiser); 1761b362b15af34006e6a11974088a46d42b903418eJohann 177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0; i < MAX_REF_FRAMES ; i++) 1781b362b15af34006e6a11974088a46d42b903418eJohann { 1791b362b15af34006e6a11974088a46d42b903418eJohann vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_running_avg[i]); 1801b362b15af34006e6a11974088a46d42b903418eJohann } 1811b362b15af34006e6a11974088a46d42b903418eJohann vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_mc_running_avg); 1821b362b15af34006e6a11974088a46d42b903418eJohann} 1831b362b15af34006e6a11974088a46d42b903418eJohann 1841b362b15af34006e6a11974088a46d42b903418eJohann 1851b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, 1861b362b15af34006e6a11974088a46d42b903418eJohann MACROBLOCK *x, 1871b362b15af34006e6a11974088a46d42b903418eJohann unsigned int best_sse, 1881b362b15af34006e6a11974088a46d42b903418eJohann unsigned int zero_mv_sse, 1891b362b15af34006e6a11974088a46d42b903418eJohann int recon_yoffset, 1901b362b15af34006e6a11974088a46d42b903418eJohann int recon_uvoffset) 1911b362b15af34006e6a11974088a46d42b903418eJohann{ 1921b362b15af34006e6a11974088a46d42b903418eJohann int mv_row; 1931b362b15af34006e6a11974088a46d42b903418eJohann int mv_col; 1941b362b15af34006e6a11974088a46d42b903418eJohann unsigned int motion_magnitude2; 1951b362b15af34006e6a11974088a46d42b903418eJohann 1961b362b15af34006e6a11974088a46d42b903418eJohann MV_REFERENCE_FRAME frame = x->best_reference_frame; 1971b362b15af34006e6a11974088a46d42b903418eJohann MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame; 1981b362b15af34006e6a11974088a46d42b903418eJohann 1991b362b15af34006e6a11974088a46d42b903418eJohann enum vp8_denoiser_decision decision = FILTER_BLOCK; 2001b362b15af34006e6a11974088a46d42b903418eJohann 2011b362b15af34006e6a11974088a46d42b903418eJohann if (zero_frame) 2021b362b15af34006e6a11974088a46d42b903418eJohann { 2031b362b15af34006e6a11974088a46d42b903418eJohann YV12_BUFFER_CONFIG *src = &denoiser->yv12_running_avg[frame]; 2041b362b15af34006e6a11974088a46d42b903418eJohann YV12_BUFFER_CONFIG *dst = &denoiser->yv12_mc_running_avg; 2051b362b15af34006e6a11974088a46d42b903418eJohann YV12_BUFFER_CONFIG saved_pre,saved_dst; 2061b362b15af34006e6a11974088a46d42b903418eJohann MB_MODE_INFO saved_mbmi; 2071b362b15af34006e6a11974088a46d42b903418eJohann MACROBLOCKD *filter_xd = &x->e_mbd; 2081b362b15af34006e6a11974088a46d42b903418eJohann MB_MODE_INFO *mbmi = &filter_xd->mode_info_context->mbmi; 2091b362b15af34006e6a11974088a46d42b903418eJohann int sse_diff = zero_mv_sse - best_sse; 2101b362b15af34006e6a11974088a46d42b903418eJohann 2111b362b15af34006e6a11974088a46d42b903418eJohann saved_mbmi = *mbmi; 2121b362b15af34006e6a11974088a46d42b903418eJohann 2131b362b15af34006e6a11974088a46d42b903418eJohann /* Use the best MV for the compensation. */ 2141b362b15af34006e6a11974088a46d42b903418eJohann mbmi->ref_frame = x->best_reference_frame; 2151b362b15af34006e6a11974088a46d42b903418eJohann mbmi->mode = x->best_sse_inter_mode; 2161b362b15af34006e6a11974088a46d42b903418eJohann mbmi->mv = x->best_sse_mv; 2171b362b15af34006e6a11974088a46d42b903418eJohann mbmi->need_to_clamp_mvs = x->need_to_clamp_best_mvs; 2181b362b15af34006e6a11974088a46d42b903418eJohann mv_col = x->best_sse_mv.as_mv.col; 2191b362b15af34006e6a11974088a46d42b903418eJohann mv_row = x->best_sse_mv.as_mv.row; 2201b362b15af34006e6a11974088a46d42b903418eJohann 2211b362b15af34006e6a11974088a46d42b903418eJohann if (frame == INTRA_FRAME || 2221b362b15af34006e6a11974088a46d42b903418eJohann ((unsigned int)(mv_row *mv_row + mv_col *mv_col) 2231b362b15af34006e6a11974088a46d42b903418eJohann <= NOISE_MOTION_THRESHOLD && 2241b362b15af34006e6a11974088a46d42b903418eJohann sse_diff < (int)SSE_DIFF_THRESHOLD)) 2251b362b15af34006e6a11974088a46d42b903418eJohann { 2261b362b15af34006e6a11974088a46d42b903418eJohann /* 2271b362b15af34006e6a11974088a46d42b903418eJohann * Handle intra blocks as referring to last frame with zero motion 2281b362b15af34006e6a11974088a46d42b903418eJohann * and let the absolute pixel difference affect the filter factor. 2291b362b15af34006e6a11974088a46d42b903418eJohann * Also consider small amount of motion as being random walk due 2301b362b15af34006e6a11974088a46d42b903418eJohann * to noise, if it doesn't mean that we get a much bigger error. 2311b362b15af34006e6a11974088a46d42b903418eJohann * Note that any changes to the mode info only affects the 2321b362b15af34006e6a11974088a46d42b903418eJohann * denoising. 2331b362b15af34006e6a11974088a46d42b903418eJohann */ 2341b362b15af34006e6a11974088a46d42b903418eJohann mbmi->ref_frame = 2351b362b15af34006e6a11974088a46d42b903418eJohann x->best_zeromv_reference_frame; 2361b362b15af34006e6a11974088a46d42b903418eJohann 2371b362b15af34006e6a11974088a46d42b903418eJohann src = &denoiser->yv12_running_avg[zero_frame]; 2381b362b15af34006e6a11974088a46d42b903418eJohann 2391b362b15af34006e6a11974088a46d42b903418eJohann mbmi->mode = ZEROMV; 2401b362b15af34006e6a11974088a46d42b903418eJohann mbmi->mv.as_int = 0; 2411b362b15af34006e6a11974088a46d42b903418eJohann x->best_sse_inter_mode = ZEROMV; 2421b362b15af34006e6a11974088a46d42b903418eJohann x->best_sse_mv.as_int = 0; 2431b362b15af34006e6a11974088a46d42b903418eJohann best_sse = zero_mv_sse; 2441b362b15af34006e6a11974088a46d42b903418eJohann } 2451b362b15af34006e6a11974088a46d42b903418eJohann 2461b362b15af34006e6a11974088a46d42b903418eJohann saved_pre = filter_xd->pre; 2471b362b15af34006e6a11974088a46d42b903418eJohann saved_dst = filter_xd->dst; 2481b362b15af34006e6a11974088a46d42b903418eJohann 2491b362b15af34006e6a11974088a46d42b903418eJohann /* Compensate the running average. */ 2501b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->pre.y_buffer = src->y_buffer + recon_yoffset; 2511b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->pre.u_buffer = src->u_buffer + recon_uvoffset; 2521b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->pre.v_buffer = src->v_buffer + recon_uvoffset; 2531b362b15af34006e6a11974088a46d42b903418eJohann /* Write the compensated running average to the destination buffer. */ 2541b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->dst.y_buffer = dst->y_buffer + recon_yoffset; 2551b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->dst.u_buffer = dst->u_buffer + recon_uvoffset; 2561b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->dst.v_buffer = dst->v_buffer + recon_uvoffset; 2571b362b15af34006e6a11974088a46d42b903418eJohann 2581b362b15af34006e6a11974088a46d42b903418eJohann if (!x->skip) 2591b362b15af34006e6a11974088a46d42b903418eJohann { 2601b362b15af34006e6a11974088a46d42b903418eJohann vp8_build_inter_predictors_mb(filter_xd); 2611b362b15af34006e6a11974088a46d42b903418eJohann } 2621b362b15af34006e6a11974088a46d42b903418eJohann else 2631b362b15af34006e6a11974088a46d42b903418eJohann { 2641b362b15af34006e6a11974088a46d42b903418eJohann vp8_build_inter16x16_predictors_mb(filter_xd, 2651b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->dst.y_buffer, 2661b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->dst.u_buffer, 2671b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->dst.v_buffer, 2681b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->dst.y_stride, 2691b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->dst.uv_stride); 2701b362b15af34006e6a11974088a46d42b903418eJohann } 2711b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->pre = saved_pre; 2721b362b15af34006e6a11974088a46d42b903418eJohann filter_xd->dst = saved_dst; 2731b362b15af34006e6a11974088a46d42b903418eJohann *mbmi = saved_mbmi; 2741b362b15af34006e6a11974088a46d42b903418eJohann 2751b362b15af34006e6a11974088a46d42b903418eJohann } 2761b362b15af34006e6a11974088a46d42b903418eJohann 2771b362b15af34006e6a11974088a46d42b903418eJohann mv_row = x->best_sse_mv.as_mv.row; 2781b362b15af34006e6a11974088a46d42b903418eJohann mv_col = x->best_sse_mv.as_mv.col; 2791b362b15af34006e6a11974088a46d42b903418eJohann motion_magnitude2 = mv_row * mv_row + mv_col * mv_col; 2801b362b15af34006e6a11974088a46d42b903418eJohann if (best_sse > SSE_THRESHOLD || motion_magnitude2 2811b362b15af34006e6a11974088a46d42b903418eJohann > 8 * NOISE_MOTION_THRESHOLD) 2821b362b15af34006e6a11974088a46d42b903418eJohann { 2831b362b15af34006e6a11974088a46d42b903418eJohann decision = COPY_BLOCK; 2841b362b15af34006e6a11974088a46d42b903418eJohann } 2851b362b15af34006e6a11974088a46d42b903418eJohann 2861b362b15af34006e6a11974088a46d42b903418eJohann if (decision == FILTER_BLOCK) 2871b362b15af34006e6a11974088a46d42b903418eJohann { 2881b362b15af34006e6a11974088a46d42b903418eJohann /* Filter. */ 2891b362b15af34006e6a11974088a46d42b903418eJohann decision = vp8_denoiser_filter(&denoiser->yv12_mc_running_avg, 290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang &denoiser->yv12_running_avg[INTRA_FRAME], 2911b362b15af34006e6a11974088a46d42b903418eJohann x, 2921b362b15af34006e6a11974088a46d42b903418eJohann motion_magnitude2, 2931b362b15af34006e6a11974088a46d42b903418eJohann recon_yoffset, recon_uvoffset); 2941b362b15af34006e6a11974088a46d42b903418eJohann } 2951b362b15af34006e6a11974088a46d42b903418eJohann if (decision == COPY_BLOCK) 2961b362b15af34006e6a11974088a46d42b903418eJohann { 2971b362b15af34006e6a11974088a46d42b903418eJohann /* No filtering of this block; it differs too much from the predictor, 2981b362b15af34006e6a11974088a46d42b903418eJohann * or the motion vector magnitude is considered too big. 2991b362b15af34006e6a11974088a46d42b903418eJohann */ 3001b362b15af34006e6a11974088a46d42b903418eJohann vp8_copy_mem16x16( 3011b362b15af34006e6a11974088a46d42b903418eJohann x->thismb, 16, 302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset, 303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang denoiser->yv12_running_avg[INTRA_FRAME].y_stride); 3041b362b15af34006e6a11974088a46d42b903418eJohann } 3051b362b15af34006e6a11974088a46d42b903418eJohann} 306