| Index: source/libvpx/vp9/encoder/vp9_denoiser.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_denoiser.c (revision 293588)
|
| +++ source/libvpx/vp9/encoder/vp9_denoiser.c (working copy)
|
| @@ -49,9 +49,7 @@
|
| }
|
|
|
| static unsigned int sse_thresh(BLOCK_SIZE bs, int increase_denoising) {
|
| - return (4 << b_width_log2_lookup[bs]) *
|
| - (4 << b_height_log2_lookup[bs]) *
|
| - (increase_denoising ? 60 : 40);
|
| + return (1 << num_pels_log2_lookup[bs]) * (increase_denoising ? 60 : 40);
|
| }
|
|
|
| static int sse_diff_thresh(BLOCK_SIZE bs, int increase_denoising,
|
| @@ -60,19 +58,16 @@
|
| noise_motion_thresh(bs, increase_denoising)) {
|
| return 0;
|
| } else {
|
| - return (4 << b_width_log2_lookup[bs]) *
|
| - (4 << b_height_log2_lookup[bs]) * 20;
|
| + return (1 << num_pels_log2_lookup[bs]) * 20;
|
| }
|
| }
|
|
|
| int total_adj_strong_thresh(BLOCK_SIZE bs, int increase_denoising) {
|
| - return (4 << b_width_log2_lookup[bs]) *
|
| - (4 << b_height_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
|
| + return (1 << num_pels_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
|
| }
|
|
|
| static int total_adj_weak_thresh(BLOCK_SIZE bs, int increase_denoising) {
|
| - return (4 << b_width_log2_lookup[bs]) *
|
| - (4 << b_height_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
|
| + return (1 << num_pels_log2_lookup[bs]) * (increase_denoising ? 3 : 2);
|
| }
|
|
|
| // TODO(jackychen): If increase_denoising is enabled in the future,
|
| @@ -195,16 +190,6 @@
|
| return framebuf + (stride * mi_row * 8) + (mi_col * 8);
|
| }
|
|
|
| -static void copy_block(uint8_t *dest, int dest_stride,
|
| - const uint8_t *src, int src_stride, BLOCK_SIZE bs) {
|
| - int r;
|
| - for (r = 0; r < (4 << b_height_log2_lookup[bs]); ++r) {
|
| - vpx_memcpy(dest, src, (4 << b_width_log2_lookup[bs]));
|
| - dest += dest_stride;
|
| - src += src_stride;
|
| - }
|
| -}
|
| -
|
| static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
|
| MACROBLOCK *mb,
|
| BLOCK_SIZE bs,
|
| @@ -219,28 +204,18 @@
|
| MV_REFERENCE_FRAME frame;
|
| MACROBLOCKD *filter_mbd = &mb->e_mbd;
|
| MB_MODE_INFO *mbmi = &filter_mbd->mi[0].src_mi->mbmi;
|
| -
|
| MB_MODE_INFO saved_mbmi;
|
| int i, j;
|
| struct buf_2d saved_dst[MAX_MB_PLANE];
|
| struct buf_2d saved_pre[MAX_MB_PLANE][2]; // 2 pre buffers
|
|
|
| - // We will restore these after motion compensation.
|
| - saved_mbmi = *mbmi;
|
| - for (i = 0; i < MAX_MB_PLANE; ++i) {
|
| - for (j = 0; j < 2; ++j) {
|
| - saved_pre[i][j] = filter_mbd->plane[i].pre[j];
|
| - }
|
| - saved_dst[i] = filter_mbd->plane[i].dst;
|
| - }
|
| -
|
| mv_col = ctx->best_sse_mv.as_mv.col;
|
| mv_row = ctx->best_sse_mv.as_mv.row;
|
| -
|
| *motion_magnitude = mv_row * mv_row + mv_col * mv_col;
|
| -
|
| frame = ctx->best_reference_frame;
|
|
|
| + saved_mbmi = *mbmi;
|
| +
|
| // If the best reference frame uses inter-prediction and there is enough of a
|
| // difference in sum-squared-error, use it.
|
| if (frame != INTRA_FRAME &&
|
| @@ -261,6 +236,26 @@
|
| ctx->newmv_sse = ctx->zeromv_sse;
|
| }
|
|
|
| + if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) {
|
| + // Restore everything to its original state
|
| + *mbmi = saved_mbmi;
|
| + return COPY_BLOCK;
|
| + }
|
| + if (mv_row * mv_row + mv_col * mv_col >
|
| + 8 * noise_motion_thresh(bs, increase_denoising)) {
|
| + // Restore everything to its original state
|
| + *mbmi = saved_mbmi;
|
| + return COPY_BLOCK;
|
| + }
|
| +
|
| + // We will restore these after motion compensation.
|
| + for (i = 0; i < MAX_MB_PLANE; ++i) {
|
| + for (j = 0; j < 2; ++j) {
|
| + saved_pre[i][j] = filter_mbd->plane[i].pre[j];
|
| + }
|
| + saved_dst[i] = filter_mbd->plane[i].dst;
|
| + }
|
| +
|
| // Set the pointers in the MACROBLOCKD to point to the buffers in the denoiser
|
| // struct.
|
| for (j = 0; j < 2; ++j) {
|
| @@ -313,13 +308,6 @@
|
| mv_row = ctx->best_sse_mv.as_mv.row;
|
| mv_col = ctx->best_sse_mv.as_mv.col;
|
|
|
| - if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) {
|
| - return COPY_BLOCK;
|
| - }
|
| - if (mv_row * mv_row + mv_col * mv_col >
|
| - 8 * noise_motion_thresh(bs, increase_denoising)) {
|
| - return COPY_BLOCK;
|
| - }
|
| return FILTER_BLOCK;
|
| }
|
|
|
| @@ -348,9 +336,15 @@
|
| }
|
|
|
| if (decision == FILTER_BLOCK) {
|
| - copy_block(src.buf, src.stride, avg_start, avg.y_stride, bs);
|
| + vp9_convolve_copy(avg_start, avg.y_stride, src.buf, src.stride,
|
| + NULL, 0, NULL, 0,
|
| + num_4x4_blocks_wide_lookup[bs] << 2,
|
| + num_4x4_blocks_high_lookup[bs] << 2);
|
| } else { // COPY_BLOCK
|
| - copy_block(avg_start, avg.y_stride, src.buf, src.stride, bs);
|
| + vp9_convolve_copy(src.buf, src.stride, avg_start, avg.y_stride,
|
| + NULL, 0, NULL, 0,
|
| + num_4x4_blocks_wide_lookup[bs] << 2,
|
| + num_4x4_blocks_high_lookup[bs] << 2);
|
| }
|
| }
|
|
|
| @@ -368,6 +362,15 @@
|
| }
|
| }
|
|
|
| +static void swap_frame_buffer(YV12_BUFFER_CONFIG dest,
|
| + YV12_BUFFER_CONFIG src) {
|
| + uint8_t *tmp_buf = dest.y_buffer;
|
| + assert(dest.y_width == src.y_width);
|
| + assert(dest.y_height == src.y_height);
|
| + dest.y_buffer = src.y_buffer;
|
| + src.y_buffer = tmp_buf;
|
| +}
|
| +
|
| void vp9_denoiser_update_frame_info(VP9_DENOISER *denoiser,
|
| YV12_BUFFER_CONFIG src,
|
| FRAME_TYPE frame_type,
|
| @@ -377,28 +380,32 @@
|
| if (frame_type == KEY_FRAME) {
|
| int i;
|
| // Start at 1 so as not to overwrite the INTRA_FRAME
|
| - for (i = 1; i < MAX_REF_FRAMES; ++i) {
|
| + for (i = 1; i < MAX_REF_FRAMES; ++i)
|
| copy_frame(denoiser->running_avg_y[i], src);
|
| - }
|
| - } else { /* For non key frames */
|
| - if (refresh_alt_ref_frame) {
|
| - copy_frame(denoiser->running_avg_y[ALTREF_FRAME],
|
| - denoiser->running_avg_y[INTRA_FRAME]);
|
| - }
|
| - if (refresh_golden_frame) {
|
| - copy_frame(denoiser->running_avg_y[GOLDEN_FRAME],
|
| - denoiser->running_avg_y[INTRA_FRAME]);
|
| - }
|
| - if (refresh_last_frame) {
|
| - copy_frame(denoiser->running_avg_y[LAST_FRAME],
|
| - denoiser->running_avg_y[INTRA_FRAME]);
|
| - }
|
| + return;
|
| }
|
| +
|
| + /* For non key frames */
|
| + if (refresh_alt_ref_frame) {
|
| + swap_frame_buffer(denoiser->running_avg_y[ALTREF_FRAME],
|
| + denoiser->running_avg_y[INTRA_FRAME]);
|
| + }
|
| + if (refresh_golden_frame) {
|
| + swap_frame_buffer(denoiser->running_avg_y[GOLDEN_FRAME],
|
| + denoiser->running_avg_y[INTRA_FRAME]);
|
| + }
|
| + if (refresh_last_frame) {
|
| + swap_frame_buffer(denoiser->running_avg_y[LAST_FRAME],
|
| + denoiser->running_avg_y[INTRA_FRAME]);
|
| + }
|
| }
|
|
|
| void vp9_denoiser_reset_frame_stats(PICK_MODE_CONTEXT *ctx) {
|
| ctx->zeromv_sse = UINT_MAX;
|
| - ctx->newmv_sse = UINT_MAX;
|
| + // This should be initialized as zero since mode search stage might skip
|
| + // NEWMV mode if inferred motion vector modes provide sufficiently good
|
| + // prediction quality.
|
| + ctx->newmv_sse = 0;
|
| }
|
|
|
| void vp9_denoiser_update_frame_stats(MB_MODE_INFO *mbmi, unsigned int sse,
|
| @@ -425,6 +432,7 @@
|
| #endif
|
| int border) {
|
| int i, fail;
|
| + const int legacy_byte_alignment = 0;
|
| assert(denoiser != NULL);
|
|
|
| for (i = 0; i < MAX_REF_FRAMES; ++i) {
|
| @@ -433,7 +441,7 @@
|
| #if CONFIG_VP9_HIGHBITDEPTH
|
| use_highbitdepth,
|
| #endif
|
| - border);
|
| + border, legacy_byte_alignment);
|
| if (fail) {
|
| vp9_denoiser_free(denoiser);
|
| return 1;
|
| @@ -448,7 +456,7 @@
|
| #if CONFIG_VP9_HIGHBITDEPTH
|
| use_highbitdepth,
|
| #endif
|
| - border);
|
| + border, legacy_byte_alignment);
|
| if (fail) {
|
| vp9_denoiser_free(denoiser);
|
| return 1;
|
| @@ -457,6 +465,7 @@
|
| make_grayscale(&denoiser->running_avg_y[i]);
|
| #endif
|
| denoiser->increase_denoising = 0;
|
| + denoiser->frame_buffer_initialized = 1;
|
|
|
| return 0;
|
| }
|
| @@ -463,6 +472,7 @@
|
|
|
| void vp9_denoiser_free(VP9_DENOISER *denoiser) {
|
| int i;
|
| + denoiser->frame_buffer_initialized = 0;
|
| if (denoiser == NULL) {
|
| return;
|
| }
|
| @@ -482,15 +492,13 @@
|
| uint8_t *u = yuv->u_buffer;
|
| uint8_t *v = yuv->v_buffer;
|
|
|
| - // The '/2's are there because we have a 440 buffer, but we want to output
|
| - // 420.
|
| - for (r = 0; r < yuv->uv_height / 2; ++r) {
|
| - for (c = 0; c < yuv->uv_width / 2; ++c) {
|
| + for (r = 0; r < yuv->uv_height; ++r) {
|
| + for (c = 0; c < yuv->uv_width; ++c) {
|
| u[c] = UINT8_MAX / 2;
|
| v[c] = UINT8_MAX / 2;
|
| }
|
| - u += yuv->uv_stride + yuv->uv_width / 2;
|
| - v += yuv->uv_stride + yuv->uv_width / 2;
|
| + u += yuv->uv_stride;
|
| + v += yuv->uv_stride;
|
| }
|
| }
|
| #endif
|
|
|