diff --git a/vp9/encoder/vp9_context_tree.h b/vp9/encoder/vp9_context_tree.h index 8e365ce33..86ba03d69 100644 --- a/vp9/encoder/vp9_context_tree.h +++ b/vp9/encoder/vp9_context_tree.h @@ -60,6 +60,7 @@ typedef struct { #if CONFIG_VP9_TEMPORAL_DENOISING unsigned int newmv_sse; unsigned int zeromv_sse; + unsigned int zeromv_lastref_sse; PREDICTION_MODE best_sse_inter_mode; int_mv best_sse_mv; MV_REFERENCE_FRAME best_reference_frame; diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c index c382b77f3..e87a12e44 100644 --- a/vp9/encoder/vp9_denoiser.c +++ b/vp9/encoder/vp9_denoiser.c @@ -224,14 +224,19 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser, } else { // Otherwise, use the zero reference frame. frame = ctx->best_zeromv_reference_frame; - - mbmi->ref_frame[0] = ctx->best_zeromv_reference_frame; + ctx->newmv_sse = ctx->zeromv_sse; + // Bias to last reference. + if (frame != LAST_FRAME && + ((ctx->zeromv_lastref_sse < (5 * ctx->zeromv_sse) >> 2) || + denoiser->denoising_level >= kDenHigh)) { + frame = LAST_FRAME; + ctx->newmv_sse = ctx->zeromv_lastref_sse; + } + mbmi->ref_frame[0] = frame; mbmi->mode = ZEROMV; mbmi->mv[0].as_int = 0; - ctx->best_sse_inter_mode = ZEROMV; ctx->best_sse_mv.as_int = 0; - ctx->newmv_sse = ctx->zeromv_sse; } if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) { @@ -462,6 +467,8 @@ void vp9_denoiser_update_frame_stats(MB_MODE_INFO *mbmi, unsigned int sse, if (mbmi->mv[0].as_int == 0 && sse < ctx->zeromv_sse) { ctx->zeromv_sse = sse; ctx->best_zeromv_reference_frame = mbmi->ref_frame[0]; + if (mbmi->ref_frame[0] == LAST_FRAME) + ctx->zeromv_lastref_sse = sse; } if (mbmi->mv[0].as_int != 0 && sse < ctx->newmv_sse) {