Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(878)

Side by Side Diff: source/libvpx/vp8/encoder/denoising.c

Issue 290613006: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "denoising.h" 11 #include "denoising.h"
12 12
13 #include "vp8/common/reconinter.h" 13 #include "vp8/common/reconinter.h"
14 #include "vpx/vpx_integer.h" 14 #include "vpx/vpx_integer.h"
15 #include "vpx_mem/vpx_mem.h" 15 #include "vpx_mem/vpx_mem.h"
16 #include "vp8_rtcd.h" 16 #include "vp8_rtcd.h"
17 17
18 static const unsigned int NOISE_MOTION_THRESHOLD = 25 * 25; 18 static const unsigned int NOISE_MOTION_THRESHOLD = 25 * 25;
19 /* SSE_DIFF_THRESHOLD is selected as ~95% confidence assuming 19 /* SSE_DIFF_THRESHOLD is selected as ~95% confidence assuming
20 * var(noise) ~= 100. 20 * var(noise) ~= 100.
21 */ 21 */
22 static const unsigned int SSE_DIFF_THRESHOLD = 16 * 16 * 20; 22 static const unsigned int SSE_DIFF_THRESHOLD = 16 * 16 * 20;
23 static const unsigned int SSE_THRESHOLD = 16 * 16 * 40; 23 static const unsigned int SSE_THRESHOLD = 16 * 16 * 40;
24 static const unsigned int SSE_THRESHOLD_HIGH = 16 * 16 * 60;
24 25
25 /* 26 /*
26 * The filter function was modified to reduce the computational complexity. 27 * The filter function was modified to reduce the computational complexity.
27 * Step 1: 28 * Step 1:
28 * Instead of applying tap coefficients for each pixel, we calculated the 29 * Instead of applying tap coefficients for each pixel, we calculated the
29 * pixel adjustments vs. pixel diff value ahead of time. 30 * pixel adjustments vs. pixel diff value ahead of time.
30 * adjustment = filtered_value - current_raw 31 * adjustment = filtered_value - current_raw
31 * = (filter_coefficient * diff + 128) >> 8 32 * = (filter_coefficient * diff + 128) >> 8
32 * where 33 * where
33 * filter_coefficient = (255 << 8) / (256 + ((absdiff * 330) >> 3)); 34 * filter_coefficient = (255 << 8) / (256 + ((absdiff * 330) >> 3));
(...skipping 13 matching lines...) Expand all
47 * [-7, -4] -3 -4 48 * [-7, -4] -3 -4
48 * [-3, 3] diff diff 49 * [-3, 3] diff diff
49 * [4, 7] 3 4 50 * [4, 7] 3 4
50 * [8, 15] 4 5 51 * [8, 15] 4 5
51 * [16, 255] 6 7 52 * [16, 255] 6 7
52 */ 53 */
53 54
54 int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, 55 int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride,
55 unsigned char *running_avg_y, int avg_y_stride, 56 unsigned char *running_avg_y, int avg_y_stride,
56 unsigned char *sig, int sig_stride, 57 unsigned char *sig, int sig_stride,
57 unsigned int motion_magnitude) 58 unsigned int motion_magnitude,
59 int increase_denoising)
58 { 60 {
59 unsigned char *running_avg_y_start = running_avg_y; 61 unsigned char *running_avg_y_start = running_avg_y;
60 unsigned char *sig_start = sig; 62 unsigned char *sig_start = sig;
61 int r, c, i; 63 int sum_diff_thresh;
64 int r, c;
62 int sum_diff = 0; 65 int sum_diff = 0;
63 int adj_val[3] = {3, 4, 6}; 66 int adj_val[3] = {3, 4, 6};
64 67 int shift_inc1 = 0;
68 int shift_inc2 = 1;
65 /* If motion_magnitude is small, making the denoiser more aggressive by 69 /* If motion_magnitude is small, making the denoiser more aggressive by
66 * increasing the adjustment for each level. */ 70 * increasing the adjustment for each level. Add another increment for
71 * blocks that are labeled for increase denoising. */
67 if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) 72 if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD)
68 { 73 {
69 for (i = 0; i < 3; i++) 74 if (increase_denoising) {
70 adj_val[i] += 1; 75 shift_inc1 = 1;
76 shift_inc2 = 2;
77 }
78 adj_val[0] += shift_inc2;
79 adj_val[1] += shift_inc2;
80 adj_val[2] += shift_inc2;
71 } 81 }
72 82
73 for (r = 0; r < 16; ++r) 83 for (r = 0; r < 16; ++r)
74 { 84 {
75 for (c = 0; c < 16; ++c) 85 for (c = 0; c < 16; ++c)
76 { 86 {
77 int diff = 0; 87 int diff = 0;
78 int adjustment = 0; 88 int adjustment = 0;
79 int absdiff = 0; 89 int absdiff = 0;
80 90
81 diff = mc_running_avg_y[c] - sig[c]; 91 diff = mc_running_avg_y[c] - sig[c];
82 absdiff = abs(diff); 92 absdiff = abs(diff);
83 93
84 /* When |diff| < 4, use pixel value from last denoised raw. */ 94 // When |diff| <= |3 + shift_inc1|, use pixel value from
85 if (absdiff <= 3) 95 // last denoised raw.
96 if (absdiff <= 3 + shift_inc1)
86 { 97 {
87 running_avg_y[c] = mc_running_avg_y[c]; 98 running_avg_y[c] = mc_running_avg_y[c];
88 sum_diff += diff; 99 sum_diff += diff;
89 } 100 }
90 else 101 else
91 { 102 {
92 if (absdiff >= 4 && absdiff <= 7) 103 if (absdiff >= 4 && absdiff <= 7)
93 adjustment = adj_val[0]; 104 adjustment = adj_val[0];
94 else if (absdiff >= 8 && absdiff <= 15) 105 else if (absdiff >= 8 && absdiff <= 15)
95 adjustment = adj_val[1]; 106 adjustment = adj_val[1];
(...skipping 20 matching lines...) Expand all
116 } 127 }
117 } 128 }
118 } 129 }
119 130
120 /* Update pointers for next iteration. */ 131 /* Update pointers for next iteration. */
121 sig += sig_stride; 132 sig += sig_stride;
122 mc_running_avg_y += mc_avg_y_stride; 133 mc_running_avg_y += mc_avg_y_stride;
123 running_avg_y += avg_y_stride; 134 running_avg_y += avg_y_stride;
124 } 135 }
125 136
126 if (abs(sum_diff) > SUM_DIFF_THRESHOLD) 137 sum_diff_thresh= SUM_DIFF_THRESHOLD;
138 if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH;
139 if (abs(sum_diff) > sum_diff_thresh)
127 return COPY_BLOCK; 140 return COPY_BLOCK;
128 141
129 vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride); 142 vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride);
130 return FILTER_BLOCK; 143 return FILTER_BLOCK;
131 } 144 }
132 145
133 int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height) 146 int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height)
134 { 147 {
135 int i; 148 int i;
136 assert(denoiser); 149 assert(denoiser);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser, 193 void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
181 MACROBLOCK *x, 194 MACROBLOCK *x,
182 unsigned int best_sse, 195 unsigned int best_sse,
183 unsigned int zero_mv_sse, 196 unsigned int zero_mv_sse,
184 int recon_yoffset, 197 int recon_yoffset,
185 int recon_uvoffset) 198 int recon_uvoffset)
186 { 199 {
187 int mv_row; 200 int mv_row;
188 int mv_col; 201 int mv_col;
189 unsigned int motion_magnitude2; 202 unsigned int motion_magnitude2;
190 203 unsigned int sse_thresh;
191 MV_REFERENCE_FRAME frame = x->best_reference_frame; 204 MV_REFERENCE_FRAME frame = x->best_reference_frame;
192 MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame; 205 MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame;
193 206
194 enum vp8_denoiser_decision decision = FILTER_BLOCK; 207 enum vp8_denoiser_decision decision = FILTER_BLOCK;
195 208
196 if (zero_frame) 209 if (zero_frame)
197 { 210 {
198 YV12_BUFFER_CONFIG *src = &denoiser->yv12_running_avg[frame]; 211 YV12_BUFFER_CONFIG *src = &denoiser->yv12_running_avg[frame];
199 YV12_BUFFER_CONFIG *dst = &denoiser->yv12_mc_running_avg; 212 YV12_BUFFER_CONFIG *dst = &denoiser->yv12_mc_running_avg;
200 YV12_BUFFER_CONFIG saved_pre,saved_dst; 213 YV12_BUFFER_CONFIG saved_pre,saved_dst;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 278 }
266 filter_xd->pre = saved_pre; 279 filter_xd->pre = saved_pre;
267 filter_xd->dst = saved_dst; 280 filter_xd->dst = saved_dst;
268 *mbmi = saved_mbmi; 281 *mbmi = saved_mbmi;
269 282
270 } 283 }
271 284
272 mv_row = x->best_sse_mv.as_mv.row; 285 mv_row = x->best_sse_mv.as_mv.row;
273 mv_col = x->best_sse_mv.as_mv.col; 286 mv_col = x->best_sse_mv.as_mv.col;
274 motion_magnitude2 = mv_row * mv_row + mv_col * mv_col; 287 motion_magnitude2 = mv_row * mv_row + mv_col * mv_col;
275 if (best_sse > SSE_THRESHOLD || motion_magnitude2 288 sse_thresh = SSE_THRESHOLD;
289 if (x->increase_denoising) sse_thresh = SSE_THRESHOLD_HIGH;
290
291 if (best_sse > sse_thresh || motion_magnitude2
276 > 8 * NOISE_MOTION_THRESHOLD) 292 > 8 * NOISE_MOTION_THRESHOLD)
277 { 293 {
278 decision = COPY_BLOCK; 294 decision = COPY_BLOCK;
279 } 295 }
280 296
281 if (decision == FILTER_BLOCK) 297 if (decision == FILTER_BLOCK)
282 { 298 {
283 unsigned char *mc_running_avg_y = 299 unsigned char *mc_running_avg_y =
284 denoiser->yv12_mc_running_avg.y_buffer + recon_yoffset; 300 denoiser->yv12_mc_running_avg.y_buffer + recon_yoffset;
285 int mc_avg_y_stride = denoiser->yv12_mc_running_avg.y_stride; 301 int mc_avg_y_stride = denoiser->yv12_mc_running_avg.y_stride;
286 unsigned char *running_avg_y = 302 unsigned char *running_avg_y =
287 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset; 303 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset;
288 int avg_y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride; 304 int avg_y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride;
289 305
290 /* Filter. */ 306 /* Filter. */
291 decision = vp8_denoiser_filter(mc_running_avg_y, mc_avg_y_stride, 307 decision = vp8_denoiser_filter(mc_running_avg_y, mc_avg_y_stride,
292 running_avg_y, avg_y_stride, 308 running_avg_y, avg_y_stride,
293 x->thismb, 16, motion_magnitude2); 309 x->thismb, 16, motion_magnitude2,
310 x->increase_denoising);
294 } 311 }
295 if (decision == COPY_BLOCK) 312 if (decision == COPY_BLOCK)
296 { 313 {
297 /* No filtering of this block; it differs too much from the predictor, 314 /* No filtering of this block; it differs too much from the predictor,
298 * or the motion vector magnitude is considered too big. 315 * or the motion vector magnitude is considered too big.
299 */ 316 */
300 vp8_copy_mem16x16( 317 vp8_copy_mem16x16(
301 x->thismb, 16, 318 x->thismb, 16,
302 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset , 319 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset ,
303 denoiser->yv12_running_avg[INTRA_FRAME].y_stride); 320 denoiser->yv12_running_avg[INTRA_FRAME].y_stride);
304 } 321 }
305 } 322 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698