| 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 |