From 88fa7efb1c6430f07ea93c736d85489fb8a8f1ae Mon Sep 17 00:00:00 2001 From: Jerome Jiang Date: Mon, 11 Jun 2018 11:05:36 -0700 Subject: [PATCH] vp9 svc: Denoise golden when it's a temporal ref. When golden was the inter-layer reference, a block that selected the golden ref would not be denoised. But when golden is used as a second temporal reference then we should denoise blocks that select the golden reference. This changes allows for that. Change-Id: Ifdea2ac88f6a74f73520fedcd7fec2f32c559ec9 --- vp9/encoder/vp9_denoiser.c | 14 +++++++++----- vp9/encoder/vp9_denoiser.h | 3 ++- vp9/encoder/vp9_pickmode.c | 19 ++++++++++--------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c index 8ec5dd91d..011ab889f 100644 --- a/vp9/encoder/vp9_denoiser.c +++ b/vp9/encoder/vp9_denoiser.c @@ -189,7 +189,7 @@ static VP9_DENOISER_DECISION perform_motion_compensation( int increase_denoising, int mi_row, int mi_col, PICK_MODE_CONTEXT *ctx, int motion_magnitude, int is_skin, int *zeromv_filter, int consec_zeromv, int num_spatial_layers, int width, int lst_fb_idx, int gld_fb_idx, - int use_svc, int spatial_layer) { + int use_svc, int spatial_layer, int use_gf_temporal_ref) { const int sse_diff = (ctx->newmv_sse == UINT_MAX) ? 0 : ((int)ctx->zeromv_sse - (int)ctx->newmv_sse); @@ -220,7 +220,8 @@ static VP9_DENOISER_DECISION perform_motion_compensation( // 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 && frame != ALTREF_FRAME && - (frame != GOLDEN_FRAME || num_spatial_layers == 1) && + (frame != GOLDEN_FRAME || num_spatial_layers == 1 || + use_gf_temporal_ref) && sse_diff > sse_diff_thresh(bs, increase_denoising, motion_magnitude)) { mi->ref_frame[0] = ctx->best_reference_frame; mi->mode = ctx->best_sse_inter_mode; @@ -230,7 +231,8 @@ static VP9_DENOISER_DECISION perform_motion_compensation( frame = ctx->best_zeromv_reference_frame; ctx->newmv_sse = ctx->zeromv_sse; // Bias to last reference. - if (num_spatial_layers > 1 || frame == ALTREF_FRAME || + if ((num_spatial_layers > 1 && !use_gf_temporal_ref) || + frame == ALTREF_FRAME || (frame != LAST_FRAME && ((ctx->zeromv_lastref_sse<(5 * ctx->zeromv_sse)>> 2) || denoiser->denoising_level >= kDenHigh))) { @@ -326,7 +328,8 @@ static VP9_DENOISER_DECISION perform_motion_compensation( void vp9_denoiser_denoise(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx, - VP9_DENOISER_DECISION *denoiser_decision) { + VP9_DENOISER_DECISION *denoiser_decision, + int use_gf_temporal_ref) { int mv_col, mv_row; int motion_magnitude = 0; int zeromv_filter = 0; @@ -397,7 +400,8 @@ void vp9_denoiser_denoise(VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col, &cpi->common, denoiser, mb, bs, increase_denoising, mi_row, mi_col, ctx, motion_magnitude, is_skin, &zeromv_filter, consec_zeromv, cpi->svc.number_spatial_layers, cpi->Source->y_width, cpi->lst_fb_idx, - cpi->gld_fb_idx, cpi->use_svc, cpi->svc.spatial_layer_id); + cpi->gld_fb_idx, cpi->use_svc, cpi->svc.spatial_layer_id, + use_gf_temporal_ref); if (decision == FILTER_BLOCK) { decision = vp9_denoiser_filter(src.buf, src.stride, mc_avg_start, diff --git a/vp9/encoder/vp9_denoiser.h b/vp9/encoder/vp9_denoiser.h index f4da24cbf..8f3724fa8 100644 --- a/vp9/encoder/vp9_denoiser.h +++ b/vp9/encoder/vp9_denoiser.h @@ -77,7 +77,8 @@ void vp9_denoiser_update_frame_info( void vp9_denoiser_denoise(struct VP9_COMP *cpi, MACROBLOCK *mb, int mi_row, int mi_col, BLOCK_SIZE bs, PICK_MODE_CONTEXT *ctx, - VP9_DENOISER_DECISION *denoiser_decision); + VP9_DENOISER_DECISION *denoiser_decision, + int use_gf_temporal_ref); void vp9_denoiser_reset_frame_stats(PICK_MODE_CONTEXT *ctx); diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index f97d18333..8b5ad9ac5 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -1497,7 +1497,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, int skip_ref_find_pred[4] = { 0 }; unsigned int sse_zeromv_normalized = UINT_MAX; unsigned int best_sse_sofar = UINT_MAX; - int gf_is_longterm_ref = 0; + int gf_temporal_ref = 0; #if CONFIG_VP9_TEMPORAL_DENOISING VP9_PICKMODE_CTX_DEN ctx_den; int64_t zero_last_cost_orig = INT64_MAX; @@ -1542,7 +1542,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, if (!cpi->use_svc || (svc->use_gf_temporal_ref_current_layer && !svc->layer_context[svc->temporal_layer_id].is_key_frame)) - gf_is_longterm_ref = 1; + gf_temporal_ref = 1; init_ref_frame_cost(cm, xd, ref_frame_cost); memset(&mode_checked[0][0], 0, MB_MODE_COUNT * MAX_REF_FRAMES); @@ -1616,7 +1616,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, } #endif - if (cpi->rc.frames_since_golden == 0 && gf_is_longterm_ref && + if (cpi->rc.frames_since_golden == 0 && gf_temporal_ref && !cpi->rc.alt_ref_gf_group && !cpi->rc.last_frame_is_src_altref) { usable_ref_frame = LAST_FRAME; } else { @@ -1643,7 +1643,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, // For svc mode, on spatial_layer_id > 0: if the reference has different scale // constrain the inter mode to only test zero motion. if (cpi->use_svc && svc->force_zero_mode_spatial_ref && - svc->spatial_layer_id > 0 && !gf_is_longterm_ref) { + svc->spatial_layer_id > 0 && !gf_temporal_ref) { if (cpi->ref_frame_flags & flag_list[LAST_FRAME]) { struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf; if (vp9_is_scaled(sf)) { @@ -1723,7 +1723,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, if (cpi->use_svc && svc->spatial_layer_id > 0 && svc_force_zero_mode[inter_layer_ref - 1] && svc->downsample_filter_phase[svc->spatial_layer_id - 1] == 8 && - !gf_is_longterm_ref) { + !gf_temporal_ref) { svc_mv_col = -4; svc_mv_row = -4; flag_svc_subpel = 1; @@ -1796,7 +1796,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, // For SVC, skip the golden (spatial) reference search if sse of zeromv_last // is below threshold. - if (cpi->use_svc && ref_frame == GOLDEN_FRAME && !gf_is_longterm_ref && + if (cpi->use_svc && ref_frame == GOLDEN_FRAME && !gf_temporal_ref && sse_zeromv_normalized < thresh_svc_skip_golden) continue; @@ -1916,7 +1916,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, if (frame_mv[this_mode][ref_frame].as_int != 0) continue; if (this_mode == NEWMV && !force_mv_inter_layer) { - if (ref_frame > LAST_FRAME && gf_is_longterm_ref && + if (ref_frame > LAST_FRAME && gf_temporal_ref && cpi->oxcf.rc_mode == VPX_CBR) { int tmp_sad; uint32_t dis; @@ -2284,7 +2284,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, // layer is chosen as the reference. Always perform intra prediction if // LAST is the only reference, or is_key_frame is set, or on base // temporal layer. - if (svc->spatial_layer_id && !gf_is_longterm_ref) { + if (svc->spatial_layer_id && !gf_temporal_ref) { perform_intra_pred = svc->temporal_layer_id == 0 || svc->layer_context[svc->temporal_layer_id].is_key_frame || @@ -2459,7 +2459,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, frame_mv, reuse_inter_pred, best_tx_size, best_mode, best_ref_frame, best_pred_filter, best_mode_skip_txfm); - vp9_denoiser_denoise(cpi, x, mi_row, mi_col, bsize, ctx, &decision); + vp9_denoiser_denoise(cpi, x, mi_row, mi_col, bsize, ctx, &decision, + gf_temporal_ref); recheck_zeromv_after_denoising(cpi, mi, x, xd, decision, &ctx_den, yv12_mb, &best_rdc, bsize, mi_row, mi_col); best_ref_frame = ctx_den.best_ref_frame; -- 2.40.0