From: Jingning Han Date: Sat, 11 Aug 2018 00:01:08 +0000 (-0700) Subject: Use YUV components to build the temporal filter X-Git-Tag: v1.8.0~417 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=daa8482fa71fc744e2153cec3c6ef337064ef882;p=libvpx Use YUV components to build the temporal filter Use both luma and chroma components simultaneously to estimate the non-local mean kernel and build the temporal filter. It improves the compression performance primarily for chroma components. Tested in speed 0 and vbr mode, the coding gains are: Overall PSNR SSIM PSNR_U PSNR_V low -0.10% -0.12% -0.48% -0.49% mid -0.13% -0.16% -0.58% -0.88% 720p -0.31% -0.24% -0.75% -0.72% hd -0.09% -0.10% -0.59% -0.79% nefl2k -0.30% -0.13% -0.53% -0.50% Change-Id: I24d39997818322b0d69bd9dbeda02c60cd2b2e1b --- diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c index c0ecbb7b1..4b28af15c 100644 --- a/vp9/encoder/vp9_temporal_filter.c +++ b/vp9/encoder/vp9_temporal_filter.c @@ -136,6 +136,11 @@ static void apply_temporal_filter( int diff_sse[9] = { 0 }; int idx, idy, index = 0; + const int uv_r = i >> ss_y; + const int uv_c = j >> ss_x; + + int diff; + for (idy = -1; idy <= 1; ++idy) { for (idx = -1; idx <= 1; ++idx) { const int row = (int)i + idy; @@ -156,6 +161,16 @@ static void apply_temporal_filter( modifier = 0; for (idx = 0; idx < 9; ++idx) modifier += diff_sse[idx]; + diff = u_frame1[uv_r * uv_stride + uv_c] - + u_pred[uv_r * uv_buf_stride + uv_c]; + modifier += diff * diff; + + diff = v_frame1[uv_r * uv_stride + uv_c] - + v_pred[uv_r * uv_buf_stride + uv_c]; + modifier += diff * diff; + + index += 2; + modifier = mod_index(modifier, index, rounding, strength, filter_weight); y_count[k] += modifier; @@ -165,9 +180,6 @@ static void apply_temporal_filter( // Process chroma component if (!(i & ss_y) && !(j & ss_x)) { - const int uv_r = i >> ss_y; - const int uv_c = j >> ss_x; - const int u_pixel_value = u_pred[uv_r * uv_buf_stride + uv_c]; const int v_pixel_value = v_pred[uv_r * uv_buf_stride + uv_c]; @@ -176,6 +188,7 @@ static void apply_temporal_filter( int v_diff_sse[9] = { 0 }; int idx, idy, index = 0; int u_mod = 0, v_mod = 0; + int y_diff = 0; for (idy = -1; idy <= 1; ++idy) { for (idx = -1; idx <= 1; ++idx) { @@ -204,6 +217,20 @@ static void apply_temporal_filter( v_mod += v_diff_sse[idx]; } + for (idy = 0; idy < 1 + ss_y; ++idy) { + for (idx = 0; idx < 1 + ss_x; ++idx) { + const int row = (uv_r << ss_y) + idy; + const int col = (uv_c << ss_x) + idx; + const int diff = y_frame1[row * (int)y_stride + col] - + y_pred[row * (int)block_width + col]; + y_diff += diff * diff; + ++index; + } + } + + u_mod += y_diff; + v_mod += y_diff; + u_mod = mod_index(u_mod, index, rounding, strength, filter_weight); v_mod = mod_index(v_mod, index, rounding, strength, filter_weight); @@ -517,6 +544,13 @@ void vp9_temporal_filter_iterate_row_c(VP9_COMP *cpi, ThreadData *td, // score is lower. If not applying MC default behavior // is to weight all MBs equal. filter_weight = err < thresh_low ? 2 : err < thresh_high ? 1 : 0; + + switch (abs(frame - alt_ref_index)) { + case 1: filter_weight = VPXMIN(filter_weight, 2); break; + case 2: + case 3: filter_weight = VPXMIN(filter_weight, 1); break; + default: break; + } } if (filter_weight != 0) {