OLD | NEW |
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 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 int increase_denoising) | 61 int increase_denoising) |
62 { | 62 { |
63 unsigned char *running_avg_y_start = running_avg_y; | 63 unsigned char *running_avg_y_start = running_avg_y; |
64 unsigned char *sig_start = sig; | 64 unsigned char *sig_start = sig; |
65 int sum_diff_thresh; | 65 int sum_diff_thresh; |
66 int r, c; | 66 int r, c; |
67 int sum_diff = 0; | 67 int sum_diff = 0; |
68 int adj_val[3] = {3, 4, 6}; | 68 int adj_val[3] = {3, 4, 6}; |
69 int shift_inc1 = 0; | 69 int shift_inc1 = 0; |
70 int shift_inc2 = 1; | 70 int shift_inc2 = 1; |
| 71 int col_sum[16] = {0, 0, 0, 0, |
| 72 0, 0, 0, 0, |
| 73 0, 0, 0, 0, |
| 74 0, 0, 0, 0}; |
71 /* If motion_magnitude is small, making the denoiser more aggressive by | 75 /* If motion_magnitude is small, making the denoiser more aggressive by |
72 * increasing the adjustment for each level. Add another increment for | 76 * increasing the adjustment for each level. Add another increment for |
73 * blocks that are labeled for increase denoising. */ | 77 * blocks that are labeled for increase denoising. */ |
74 if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) | 78 if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD) |
75 { | 79 { |
76 if (increase_denoising) { | 80 if (increase_denoising) { |
77 shift_inc1 = 1; | 81 shift_inc1 = 1; |
78 shift_inc2 = 2; | 82 shift_inc2 = 2; |
79 } | 83 } |
80 adj_val[0] += shift_inc2; | 84 adj_val[0] += shift_inc2; |
(...skipping 10 matching lines...) Expand all Loading... |
91 int absdiff = 0; | 95 int absdiff = 0; |
92 | 96 |
93 diff = mc_running_avg_y[c] - sig[c]; | 97 diff = mc_running_avg_y[c] - sig[c]; |
94 absdiff = abs(diff); | 98 absdiff = abs(diff); |
95 | 99 |
96 // When |diff| <= |3 + shift_inc1|, use pixel value from | 100 // When |diff| <= |3 + shift_inc1|, use pixel value from |
97 // last denoised raw. | 101 // last denoised raw. |
98 if (absdiff <= 3 + shift_inc1) | 102 if (absdiff <= 3 + shift_inc1) |
99 { | 103 { |
100 running_avg_y[c] = mc_running_avg_y[c]; | 104 running_avg_y[c] = mc_running_avg_y[c]; |
101 sum_diff += diff; | 105 col_sum[c] += diff; |
102 } | 106 } |
103 else | 107 else |
104 { | 108 { |
105 if (absdiff >= 4 && absdiff <= 7) | 109 if (absdiff >= 4 + shift_inc1 && absdiff <= 7) |
106 adjustment = adj_val[0]; | 110 adjustment = adj_val[0]; |
107 else if (absdiff >= 8 && absdiff <= 15) | 111 else if (absdiff >= 8 && absdiff <= 15) |
108 adjustment = adj_val[1]; | 112 adjustment = adj_val[1]; |
109 else | 113 else |
110 adjustment = adj_val[2]; | 114 adjustment = adj_val[2]; |
111 | 115 |
112 if (diff > 0) | 116 if (diff > 0) |
113 { | 117 { |
114 if ((sig[c] + adjustment) > 255) | 118 if ((sig[c] + adjustment) > 255) |
115 running_avg_y[c] = 255; | 119 running_avg_y[c] = 255; |
116 else | 120 else |
117 running_avg_y[c] = sig[c] + adjustment; | 121 running_avg_y[c] = sig[c] + adjustment; |
118 | 122 |
119 sum_diff += adjustment; | 123 col_sum[c] += adjustment; |
120 } | 124 } |
121 else | 125 else |
122 { | 126 { |
123 if ((sig[c] - adjustment) < 0) | 127 if ((sig[c] - adjustment) < 0) |
124 running_avg_y[c] = 0; | 128 running_avg_y[c] = 0; |
125 else | 129 else |
126 running_avg_y[c] = sig[c] - adjustment; | 130 running_avg_y[c] = sig[c] - adjustment; |
127 | 131 |
128 sum_diff -= adjustment; | 132 col_sum[c] -= adjustment; |
129 } | 133 } |
130 } | 134 } |
131 } | 135 } |
132 | 136 |
133 /* Update pointers for next iteration. */ | 137 /* Update pointers for next iteration. */ |
134 sig += sig_stride; | 138 sig += sig_stride; |
135 mc_running_avg_y += mc_avg_y_stride; | 139 mc_running_avg_y += mc_avg_y_stride; |
136 running_avg_y += avg_y_stride; | 140 running_avg_y += avg_y_stride; |
137 } | 141 } |
138 | 142 |
| 143 for (c = 0; c < 16; ++c) { |
| 144 // Below we clip the value in the same way which SSE code use. |
| 145 // When adopting aggressive denoiser, the adj_val for each pixel |
| 146 // could be at most 8 (this is current max adjustment of the map). |
| 147 // In SSE code, we calculate the sum of adj_val for |
| 148 // the columns, so the sum could be upto 128(16 rows). However, |
| 149 // the range of the value is -128 ~ 127 in SSE code, that's why |
| 150 // we do this change in C code. |
| 151 // We don't do this for UV denoiser, since there are only 8 rows, |
| 152 // and max adjustments <= 8, so the sum of the columns will not |
| 153 // exceed 64. |
| 154 if (col_sum[c] >= 128) { |
| 155 col_sum[c] = 127; |
| 156 } |
| 157 sum_diff += col_sum[c]; |
| 158 } |
| 159 |
139 sum_diff_thresh= SUM_DIFF_THRESHOLD; | 160 sum_diff_thresh= SUM_DIFF_THRESHOLD; |
140 if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; | 161 if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH; |
141 if (abs(sum_diff) > sum_diff_thresh) { | 162 if (abs(sum_diff) > sum_diff_thresh) { |
142 // Before returning to copy the block (i.e., apply no denoising), check | 163 // Before returning to copy the block (i.e., apply no denoising), check |
143 // if we can still apply some (weaker) temporal filtering to this block, | 164 // if we can still apply some (weaker) temporal filtering to this block, |
144 // that would otherwise not be denoised at all. Simplest is to apply | 165 // that would otherwise not be denoised at all. Simplest is to apply |
145 // an additional adjustment to running_avg_y to bring it closer to sig. | 166 // an additional adjustment to running_avg_y to bring it closer to sig. |
146 // The adjustment is capped by a maximum delta, and chosen such that | 167 // The adjustment is capped by a maximum delta, and chosen such that |
147 // in most cases the resulting sum_diff will be within the | 168 // in most cases the resulting sum_diff will be within the |
148 // accceptable range given by sum_diff_thresh. | 169 // accceptable range given by sum_diff_thresh. |
(...skipping 10 matching lines...) Expand all Loading... |
159 int diff = mc_running_avg_y[c] - sig[c]; | 180 int diff = mc_running_avg_y[c] - sig[c]; |
160 int adjustment = abs(diff); | 181 int adjustment = abs(diff); |
161 if (adjustment > delta) | 182 if (adjustment > delta) |
162 adjustment = delta; | 183 adjustment = delta; |
163 if (diff > 0) { | 184 if (diff > 0) { |
164 // Bring denoised signal down. | 185 // Bring denoised signal down. |
165 if (running_avg_y[c] - adjustment < 0) | 186 if (running_avg_y[c] - adjustment < 0) |
166 running_avg_y[c] = 0; | 187 running_avg_y[c] = 0; |
167 else | 188 else |
168 running_avg_y[c] = running_avg_y[c] - adjustment; | 189 running_avg_y[c] = running_avg_y[c] - adjustment; |
169 sum_diff -= adjustment; | 190 col_sum[c] -= adjustment; |
170 } else if (diff < 0) { | 191 } else if (diff < 0) { |
171 // Bring denoised signal up. | 192 // Bring denoised signal up. |
172 if (running_avg_y[c] + adjustment > 255) | 193 if (running_avg_y[c] + adjustment > 255) |
173 running_avg_y[c] = 255; | 194 running_avg_y[c] = 255; |
174 else | 195 else |
175 running_avg_y[c] = running_avg_y[c] + adjustment; | 196 running_avg_y[c] = running_avg_y[c] + adjustment; |
176 sum_diff += adjustment; | 197 col_sum[c] += adjustment; |
177 } | 198 } |
178 } | 199 } |
179 // TODO(marpan): Check here if abs(sum_diff) has gone below the | 200 // TODO(marpan): Check here if abs(sum_diff) has gone below the |
180 // threshold sum_diff_thresh, and if so, we can exit the row loop. | 201 // threshold sum_diff_thresh, and if so, we can exit the row loop. |
181 sig += sig_stride; | 202 sig += sig_stride; |
182 mc_running_avg_y += mc_avg_y_stride; | 203 mc_running_avg_y += mc_avg_y_stride; |
183 running_avg_y += avg_y_stride; | 204 running_avg_y += avg_y_stride; |
184 } | 205 } |
| 206 |
| 207 sum_diff = 0; |
| 208 for (c = 0; c < 16; ++c) { |
| 209 if (col_sum[c] >= 128) { |
| 210 col_sum[c] = 127; |
| 211 } |
| 212 sum_diff += col_sum[c]; |
| 213 } |
| 214 |
185 if (abs(sum_diff) > sum_diff_thresh) | 215 if (abs(sum_diff) > sum_diff_thresh) |
186 return COPY_BLOCK; | 216 return COPY_BLOCK; |
187 } else { | 217 } else { |
188 return COPY_BLOCK; | 218 return COPY_BLOCK; |
189 } | 219 } |
190 } | 220 } |
191 | 221 |
192 vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride); | 222 vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride); |
193 return FILTER_BLOCK; | 223 return FILTER_BLOCK; |
194 } | 224 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 denoiser->denoiser_mode = kDenoiserOnAdaptive; | 377 denoiser->denoiser_mode = kDenoiserOnAdaptive; |
348 } | 378 } |
349 if (denoiser->denoiser_mode != kDenoiserOnYUVAggressive) { | 379 if (denoiser->denoiser_mode != kDenoiserOnYUVAggressive) { |
350 denoiser->denoise_pars.scale_sse_thresh = 1; | 380 denoiser->denoise_pars.scale_sse_thresh = 1; |
351 denoiser->denoise_pars.scale_motion_thresh = 8; | 381 denoiser->denoise_pars.scale_motion_thresh = 8; |
352 denoiser->denoise_pars.scale_increase_filter = 0; | 382 denoiser->denoise_pars.scale_increase_filter = 0; |
353 denoiser->denoise_pars.denoise_mv_bias = 95; | 383 denoiser->denoise_pars.denoise_mv_bias = 95; |
354 denoiser->denoise_pars.pickmode_mv_bias = 100; | 384 denoiser->denoise_pars.pickmode_mv_bias = 100; |
355 denoiser->denoise_pars.qp_thresh = 0; | 385 denoiser->denoise_pars.qp_thresh = 0; |
356 denoiser->denoise_pars.consec_zerolast = UINT_MAX; | 386 denoiser->denoise_pars.consec_zerolast = UINT_MAX; |
| 387 denoiser->denoise_pars.spatial_blur = 0; |
357 } else { | 388 } else { |
358 denoiser->denoise_pars.scale_sse_thresh = 2; | 389 denoiser->denoise_pars.scale_sse_thresh = 2; |
359 denoiser->denoise_pars.scale_motion_thresh = 16; | 390 denoiser->denoise_pars.scale_motion_thresh = 16; |
360 denoiser->denoise_pars.scale_increase_filter = 1; | 391 denoiser->denoise_pars.scale_increase_filter = 1; |
361 denoiser->denoise_pars.denoise_mv_bias = 60; | 392 denoiser->denoise_pars.denoise_mv_bias = 60; |
362 denoiser->denoise_pars.pickmode_mv_bias = 60; | 393 denoiser->denoise_pars.pickmode_mv_bias = 60; |
363 denoiser->denoise_pars.qp_thresh = 100; | 394 denoiser->denoise_pars.qp_thresh = 100; |
364 denoiser->denoise_pars.consec_zerolast = 10; | 395 denoiser->denoise_pars.consec_zerolast = 10; |
| 396 denoiser->denoise_pars.spatial_blur = 20; |
365 } | 397 } |
366 } | 398 } |
367 | 399 |
368 int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height, | 400 int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height, |
369 int num_mb_rows, int num_mb_cols, int mode) | 401 int num_mb_rows, int num_mb_cols, int mode) |
370 { | 402 { |
371 int i; | 403 int i; |
372 assert(denoiser); | 404 assert(denoiser); |
373 denoiser->num_mb_cols = num_mb_cols; | 405 denoiser->num_mb_cols = num_mb_cols; |
374 | 406 |
(...skipping 30 matching lines...) Expand all Loading... |
405 return 1; | 437 return 1; |
406 } | 438 } |
407 vpx_memset(denoiser->yv12_last_source.buffer_alloc, 0, | 439 vpx_memset(denoiser->yv12_last_source.buffer_alloc, 0, |
408 denoiser->yv12_last_source.frame_size); | 440 denoiser->yv12_last_source.frame_size); |
409 | 441 |
410 denoiser->denoise_state = vpx_calloc((num_mb_rows * num_mb_cols), 1); | 442 denoiser->denoise_state = vpx_calloc((num_mb_rows * num_mb_cols), 1); |
411 vpx_memset(denoiser->denoise_state, 0, (num_mb_rows * num_mb_cols)); | 443 vpx_memset(denoiser->denoise_state, 0, (num_mb_rows * num_mb_cols)); |
412 vp8_denoiser_set_parameters(denoiser, mode); | 444 vp8_denoiser_set_parameters(denoiser, mode); |
413 denoiser->nmse_source_diff = 0; | 445 denoiser->nmse_source_diff = 0; |
414 denoiser->nmse_source_diff_count = 0; | 446 denoiser->nmse_source_diff_count = 0; |
| 447 denoiser->qp_avg = 0; |
| 448 // QP threshold below which we can go up to aggressive mode. |
| 449 denoiser->qp_threshold_up = 80; |
| 450 // QP threshold above which we can go back down to normal mode. |
| 451 // For now keep this second threshold high, so not used currently. |
| 452 denoiser->qp_threshold_down = 128; |
| 453 // Bitrate thresholds and noise metric (nmse) thresholds for switching to |
| 454 // aggressive mode. |
415 // TODO(marpan): Adjust thresholds, including effect on resolution. | 455 // TODO(marpan): Adjust thresholds, including effect on resolution. |
| 456 denoiser->bitrate_threshold = 200000; // (bits/sec). |
416 denoiser->threshold_aggressive_mode = 35; | 457 denoiser->threshold_aggressive_mode = 35; |
417 if (width * height > 640 * 480) | 458 if (width * height > 640 * 480) { |
| 459 denoiser->bitrate_threshold = 500000; |
| 460 denoiser->threshold_aggressive_mode = 100; |
| 461 } else if (width * height > 960 * 540) { |
| 462 denoiser->bitrate_threshold = 800000; |
418 denoiser->threshold_aggressive_mode = 150; | 463 denoiser->threshold_aggressive_mode = 150; |
419 else if (width * height > 1280 * 720) | 464 } else if (width * height > 1280 * 720) { |
| 465 denoiser->bitrate_threshold = 2000000; |
420 denoiser->threshold_aggressive_mode = 1400; | 466 denoiser->threshold_aggressive_mode = 1400; |
| 467 } |
421 return 0; | 468 return 0; |
422 } | 469 } |
423 | 470 |
424 | 471 |
425 void vp8_denoiser_free(VP8_DENOISER *denoiser) | 472 void vp8_denoiser_free(VP8_DENOISER *denoiser) |
426 { | 473 { |
427 int i; | 474 int i; |
428 assert(denoiser); | 475 assert(denoiser); |
429 | 476 |
430 for (i = 0; i < MAX_REF_FRAMES ; i++) | 477 for (i = 0; i < MAX_REF_FRAMES ; i++) |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 } | 729 } |
683 if (apply_filter) { | 730 if (apply_filter) { |
684 // Update the signal block |x|. Pixel changes are only to top and/or | 731 // Update the signal block |x|. Pixel changes are only to top and/or |
685 // left boundary pixels: can we avoid full block copy here. | 732 // left boundary pixels: can we avoid full block copy here. |
686 vp8_copy_mem16x16( | 733 vp8_copy_mem16x16( |
687 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset, | 734 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset, |
688 y_stride, x->thismb, 16); | 735 y_stride, x->thismb, 16); |
689 } | 736 } |
690 } | 737 } |
691 } | 738 } |
OLD | NEW |