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

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

Issue 375983002: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 5 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
« no previous file with comments | « source/libvpx/vp8/encoder/denoising.h ('k') | source/libvpx/vp8/encoder/x86/denoising_sse2.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 }
OLDNEW
« no previous file with comments | « source/libvpx/vp8/encoder/denoising.h ('k') | source/libvpx/vp8/encoder/x86/denoising_sse2.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698