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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 return COPY_BLOCK; | 184 return COPY_BLOCK; |
185 } else { | 185 } else { |
186 return COPY_BLOCK; | 186 return COPY_BLOCK; |
187 } | 187 } |
188 } | 188 } |
189 | 189 |
190 vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride); | 190 vp8_copy_mem16x16(running_avg_y_start, avg_y_stride, sig_start, sig_stride); |
191 return FILTER_BLOCK; | 191 return FILTER_BLOCK; |
192 } | 192 } |
193 | 193 |
| 194 int vp8_denoiser_filter_uv_c(unsigned char *mc_running_avg_uv, |
| 195 int mc_avg_uv_stride, |
| 196 unsigned char *running_avg_uv, |
| 197 int avg_uv_stride, |
| 198 unsigned char *sig, |
| 199 int sig_stride, |
| 200 unsigned int motion_magnitude, |
| 201 int increase_denoising) { |
| 202 unsigned char *running_avg_uv_start = running_avg_uv; |
| 203 unsigned char *sig_start = sig; |
| 204 int sum_diff_thresh; |
| 205 int r, c; |
| 206 int sum_diff = 0; |
| 207 int sum_block = 0; |
| 208 int adj_val[3] = {3, 4, 6}; |
| 209 int shift_inc1 = 0; |
| 210 int shift_inc2 = 1; |
| 211 /* If motion_magnitude is small, making the denoiser more aggressive by |
| 212 * increasing the adjustment for each level. Add another increment for |
| 213 * blocks that are labeled for increase denoising. */ |
| 214 if (motion_magnitude <= MOTION_MAGNITUDE_THRESHOLD_UV) { |
| 215 if (increase_denoising) { |
| 216 shift_inc1 = 1; |
| 217 shift_inc2 = 2; |
| 218 } |
| 219 adj_val[0] += shift_inc2; |
| 220 adj_val[1] += shift_inc2; |
| 221 adj_val[2] += shift_inc2; |
| 222 } |
| 223 |
| 224 // Avoid denoising color signal if its close to average level. |
| 225 for (r = 0; r < 8; ++r) { |
| 226 for (c = 0; c < 8; ++c) { |
| 227 sum_block += sig[c]; |
| 228 } |
| 229 sig += sig_stride; |
| 230 } |
| 231 if (abs(sum_block - (128 * 8 * 8)) < SUM_DIFF_FROM_AVG_THRESH_UV) { |
| 232 return COPY_BLOCK; |
| 233 } |
| 234 |
| 235 sig -= sig_stride * 8; |
| 236 for (r = 0; r < 8; ++r) { |
| 237 for (c = 0; c < 8; ++c) { |
| 238 int diff = 0; |
| 239 int adjustment = 0; |
| 240 int absdiff = 0; |
| 241 |
| 242 diff = mc_running_avg_uv[c] - sig[c]; |
| 243 absdiff = abs(diff); |
| 244 |
| 245 // When |diff| <= |3 + shift_inc1|, use pixel value from |
| 246 // last denoised raw. |
| 247 if (absdiff <= 3 + shift_inc1) { |
| 248 running_avg_uv[c] = mc_running_avg_uv[c]; |
| 249 sum_diff += diff; |
| 250 } else { |
| 251 if (absdiff >= 4 && absdiff <= 7) |
| 252 adjustment = adj_val[0]; |
| 253 else if (absdiff >= 8 && absdiff <= 15) |
| 254 adjustment = adj_val[1]; |
| 255 else |
| 256 adjustment = adj_val[2]; |
| 257 if (diff > 0) { |
| 258 if ((sig[c] + adjustment) > 255) |
| 259 running_avg_uv[c] = 255; |
| 260 else |
| 261 running_avg_uv[c] = sig[c] + adjustment; |
| 262 sum_diff += adjustment; |
| 263 } else { |
| 264 if ((sig[c] - adjustment) < 0) |
| 265 running_avg_uv[c] = 0; |
| 266 else |
| 267 running_avg_uv[c] = sig[c] - adjustment; |
| 268 sum_diff -= adjustment; |
| 269 } |
| 270 } |
| 271 } |
| 272 /* Update pointers for next iteration. */ |
| 273 sig += sig_stride; |
| 274 mc_running_avg_uv += mc_avg_uv_stride; |
| 275 running_avg_uv += avg_uv_stride; |
| 276 } |
| 277 |
| 278 sum_diff_thresh= SUM_DIFF_THRESHOLD_UV; |
| 279 if (increase_denoising) sum_diff_thresh = SUM_DIFF_THRESHOLD_HIGH_UV; |
| 280 if (abs(sum_diff) > sum_diff_thresh) { |
| 281 // Before returning to copy the block (i.e., apply no denoising), check |
| 282 // if we can still apply some (weaker) temporal filtering to this block, |
| 283 // that would otherwise not be denoised at all. Simplest is to apply |
| 284 // an additional adjustment to running_avg_y to bring it closer to sig. |
| 285 // The adjustment is capped by a maximum delta, and chosen such that |
| 286 // in most cases the resulting sum_diff will be within the |
| 287 // accceptable range given by sum_diff_thresh. |
| 288 |
| 289 // The delta is set by the excess of absolute pixel diff over threshold. |
| 290 int delta = ((abs(sum_diff) - sum_diff_thresh) >> 8) + 1; |
| 291 // Only apply the adjustment for max delta up to 3. |
| 292 if (delta < 4) { |
| 293 sig -= sig_stride * 8; |
| 294 mc_running_avg_uv -= mc_avg_uv_stride * 8; |
| 295 running_avg_uv -= avg_uv_stride * 8; |
| 296 for (r = 0; r < 8; ++r) { |
| 297 for (c = 0; c < 8; ++c) { |
| 298 int diff = mc_running_avg_uv[c] - sig[c]; |
| 299 int adjustment = abs(diff); |
| 300 if (adjustment > delta) |
| 301 adjustment = delta; |
| 302 if (diff > 0) { |
| 303 // Bring denoised signal down. |
| 304 if (running_avg_uv[c] - adjustment < 0) |
| 305 running_avg_uv[c] = 0; |
| 306 else |
| 307 running_avg_uv[c] = running_avg_uv[c] - adjustment; |
| 308 sum_diff -= adjustment; |
| 309 } else if (diff < 0) { |
| 310 // Bring denoised signal up. |
| 311 if (running_avg_uv[c] + adjustment > 255) |
| 312 running_avg_uv[c] = 255; |
| 313 else |
| 314 running_avg_uv[c] = running_avg_uv[c] + adjustment; |
| 315 sum_diff += adjustment; |
| 316 } |
| 317 } |
| 318 // TODO(marpan): Check here if abs(sum_diff) has gone below the |
| 319 // threshold sum_diff_thresh, and if so, we can exit the row loop. |
| 320 sig += sig_stride; |
| 321 mc_running_avg_uv += mc_avg_uv_stride; |
| 322 running_avg_uv += avg_uv_stride; |
| 323 } |
| 324 if (abs(sum_diff) > sum_diff_thresh) |
| 325 return COPY_BLOCK; |
| 326 } else { |
| 327 return COPY_BLOCK; |
| 328 } |
| 329 } |
| 330 |
| 331 vp8_copy_mem8x8(running_avg_uv_start, avg_uv_stride, sig_start, |
| 332 sig_stride); |
| 333 return FILTER_BLOCK; |
| 334 } |
| 335 |
194 int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height, | 336 int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height, |
195 int num_mb_rows, int num_mb_cols) | 337 int num_mb_rows, int num_mb_cols) |
196 { | 338 { |
197 int i; | 339 int i; |
198 assert(denoiser); | 340 assert(denoiser); |
199 denoiser->num_mb_cols = num_mb_cols; | 341 denoiser->num_mb_cols = num_mb_cols; |
200 | 342 |
201 for (i = 0; i < MAX_REF_FRAMES; i++) | 343 for (i = 0; i < MAX_REF_FRAMES; i++) |
202 { | 344 { |
203 denoiser->yv12_running_avg[i].flags = 0; | 345 denoiser->yv12_running_avg[i].flags = 0; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 loop_filter_info_n *lfi_n, | 396 loop_filter_info_n *lfi_n, |
255 int mb_row, | 397 int mb_row, |
256 int mb_col, | 398 int mb_col, |
257 int block_index) | 399 int block_index) |
258 { | 400 { |
259 int mv_row; | 401 int mv_row; |
260 int mv_col; | 402 int mv_col; |
261 unsigned int motion_magnitude2; | 403 unsigned int motion_magnitude2; |
262 unsigned int sse_thresh; | 404 unsigned int sse_thresh; |
263 int sse_diff_thresh = 0; | 405 int sse_diff_thresh = 0; |
| 406 // Denoise the UV channel. |
| 407 int apply_color_denoise = 0; |
264 // Spatial loop filter: only applied selectively based on | 408 // Spatial loop filter: only applied selectively based on |
265 // temporal filter state of block relative to top/left neighbors. | 409 // temporal filter state of block relative to top/left neighbors. |
266 int apply_spatial_loop_filter = 1; | 410 int apply_spatial_loop_filter = 1; |
267 MV_REFERENCE_FRAME frame = x->best_reference_frame; | 411 MV_REFERENCE_FRAME frame = x->best_reference_frame; |
268 MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame; | 412 MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame; |
269 | 413 |
270 enum vp8_denoiser_decision decision = FILTER_BLOCK; | 414 enum vp8_denoiser_decision decision = FILTER_BLOCK; |
| 415 enum vp8_denoiser_decision decision_u = FILTER_BLOCK; |
| 416 enum vp8_denoiser_decision decision_v = FILTER_BLOCK; |
271 | 417 |
272 if (zero_frame) | 418 if (zero_frame) |
273 { | 419 { |
274 YV12_BUFFER_CONFIG *src = &denoiser->yv12_running_avg[frame]; | 420 YV12_BUFFER_CONFIG *src = &denoiser->yv12_running_avg[frame]; |
275 YV12_BUFFER_CONFIG *dst = &denoiser->yv12_mc_running_avg; | 421 YV12_BUFFER_CONFIG *dst = &denoiser->yv12_mc_running_avg; |
276 YV12_BUFFER_CONFIG saved_pre,saved_dst; | 422 YV12_BUFFER_CONFIG saved_pre,saved_dst; |
277 MB_MODE_INFO saved_mbmi; | 423 MB_MODE_INFO saved_mbmi; |
278 MACROBLOCKD *filter_xd = &x->e_mbd; | 424 MACROBLOCKD *filter_xd = &x->e_mbd; |
279 MB_MODE_INFO *mbmi = &filter_xd->mode_info_context->mbmi; | 425 MB_MODE_INFO *mbmi = &filter_xd->mode_info_context->mbmi; |
280 int sse_diff = 0; | 426 int sse_diff = 0; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 { | 516 { |
371 unsigned char *mc_running_avg_y = | 517 unsigned char *mc_running_avg_y = |
372 denoiser->yv12_mc_running_avg.y_buffer + recon_yoffset; | 518 denoiser->yv12_mc_running_avg.y_buffer + recon_yoffset; |
373 int mc_avg_y_stride = denoiser->yv12_mc_running_avg.y_stride; | 519 int mc_avg_y_stride = denoiser->yv12_mc_running_avg.y_stride; |
374 unsigned char *running_avg_y = | 520 unsigned char *running_avg_y = |
375 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset; | 521 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset; |
376 int avg_y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride; | 522 int avg_y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride; |
377 | 523 |
378 /* Filter. */ | 524 /* Filter. */ |
379 decision = vp8_denoiser_filter(mc_running_avg_y, mc_avg_y_stride, | 525 decision = vp8_denoiser_filter(mc_running_avg_y, mc_avg_y_stride, |
380 running_avg_y, avg_y_stride, | 526 running_avg_y, avg_y_stride, |
381 x->thismb, 16, motion_magnitude2, | 527 x->thismb, 16, motion_magnitude2, |
382 x->increase_denoising); | 528 x->increase_denoising); |
383 denoiser->denoise_state[block_index] = motion_magnitude2 > 0 ? | 529 denoiser->denoise_state[block_index] = motion_magnitude2 > 0 ? |
384 kFilterNonZeroMV : kFilterZeroMV; | 530 kFilterNonZeroMV : kFilterZeroMV; |
| 531 // Only denoise UV for zero motion, and if y channel was denoised. |
| 532 if (apply_color_denoise && |
| 533 motion_magnitude2 == 0 && |
| 534 decision == FILTER_BLOCK) { |
| 535 unsigned char *mc_running_avg_u = |
| 536 denoiser->yv12_mc_running_avg.u_buffer + recon_uvoffset; |
| 537 unsigned char *running_avg_u = |
| 538 denoiser->yv12_running_avg[INTRA_FRAME].u_buffer + recon_uvoffset; |
| 539 unsigned char *mc_running_avg_v = |
| 540 denoiser->yv12_mc_running_avg.v_buffer + recon_uvoffset; |
| 541 unsigned char *running_avg_v = |
| 542 denoiser->yv12_running_avg[INTRA_FRAME].v_buffer + recon_uvoffset; |
| 543 int mc_avg_uv_stride = denoiser->yv12_mc_running_avg.uv_stride; |
| 544 int avg_uv_stride = denoiser->yv12_running_avg[INTRA_FRAME].uv_stride; |
| 545 int signal_stride = x->block[16].src_stride; |
| 546 decision_u = |
| 547 vp8_denoiser_filter_uv(mc_running_avg_u, mc_avg_uv_stride, |
| 548 running_avg_u, avg_uv_stride, |
| 549 x->block[16].src + *x->block[16].base_src, |
| 550 signal_stride, motion_magnitude2, 0); |
| 551 decision_v = |
| 552 vp8_denoiser_filter_uv(mc_running_avg_v, mc_avg_uv_stride, |
| 553 running_avg_v, avg_uv_stride, |
| 554 x->block[20].src + *x->block[20].base_src, |
| 555 signal_stride, motion_magnitude2, 0); |
| 556 } |
385 } | 557 } |
386 if (decision == COPY_BLOCK) | 558 if (decision == COPY_BLOCK) |
387 { | 559 { |
388 /* No filtering of this block; it differs too much from the predictor, | 560 /* No filtering of this block; it differs too much from the predictor, |
389 * or the motion vector magnitude is considered too big. | 561 * or the motion vector magnitude is considered too big. |
390 */ | 562 */ |
391 vp8_copy_mem16x16( | 563 vp8_copy_mem16x16( |
392 x->thismb, 16, | 564 x->thismb, 16, |
393 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset
, | 565 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset
, |
394 denoiser->yv12_running_avg[INTRA_FRAME].y_stride); | 566 denoiser->yv12_running_avg[INTRA_FRAME].y_stride); |
395 denoiser->denoise_state[block_index] = kNoFilter; | 567 denoiser->denoise_state[block_index] = kNoFilter; |
396 } | 568 } |
397 // Option to selectively deblock the denoised signal. | 569 if (apply_color_denoise) { |
| 570 if (decision_u == COPY_BLOCK) { |
| 571 vp8_copy_mem8x8( |
| 572 x->block[16].src + *x->block[16].base_src, x->block[16].src_stride, |
| 573 denoiser->yv12_running_avg[INTRA_FRAME].u_buffer + recon_uvoffset, |
| 574 denoiser->yv12_running_avg[INTRA_FRAME].uv_stride); |
| 575 } |
| 576 if (decision_v == COPY_BLOCK) { |
| 577 vp8_copy_mem8x8( |
| 578 x->block[20].src + *x->block[20].base_src, x->block[16].src_stride, |
| 579 denoiser->yv12_running_avg[INTRA_FRAME].v_buffer + recon_uvoffset, |
| 580 denoiser->yv12_running_avg[INTRA_FRAME].uv_stride); |
| 581 } |
| 582 } |
| 583 // Option to selectively deblock the denoised signal, for y channel only. |
398 if (apply_spatial_loop_filter) { | 584 if (apply_spatial_loop_filter) { |
399 loop_filter_info lfi; | 585 loop_filter_info lfi; |
400 int apply_filter_col = 0; | 586 int apply_filter_col = 0; |
401 int apply_filter_row = 0; | 587 int apply_filter_row = 0; |
402 int apply_filter = 0; | 588 int apply_filter = 0; |
403 int y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride; | 589 int y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride; |
404 int uv_stride =denoiser->yv12_running_avg[INTRA_FRAME].uv_stride; | 590 int uv_stride =denoiser->yv12_running_avg[INTRA_FRAME].uv_stride; |
405 | 591 |
406 // Fix filter level to some nominal value for now. | 592 // Fix filter level to some nominal value for now. |
407 int filter_level = 32; | 593 int filter_level = 32; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 } | 627 } |
442 if (apply_filter) { | 628 if (apply_filter) { |
443 // Update the signal block |x|. Pixel changes are only to top and/or | 629 // Update the signal block |x|. Pixel changes are only to top and/or |
444 // left boundary pixels: can we avoid full block copy here. | 630 // left boundary pixels: can we avoid full block copy here. |
445 vp8_copy_mem16x16( | 631 vp8_copy_mem16x16( |
446 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset, | 632 denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset, |
447 y_stride, x->thismb, 16); | 633 y_stride, x->thismb, 16); |
448 } | 634 } |
449 } | 635 } |
450 } | 636 } |
OLD | NEW |