From e30781ff80d931bc113a2dcb6970b1760c1feb1e Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 26 May 2017 11:36:45 -0700 Subject: [PATCH] vp9: SVC: Force subpel search off under certain conditions. For SVC 1 pass non-rd mode: Force subpel seach off for SVC for non-reference frames under motion threshold. Add flag to svc context to indicate if the frame is not used as a reference. Little/no quaity loss, ~2% speedup. Change-Id: Ic433c44b514d19d08b28f80ff05231dc943b28e9 --- vp9/encoder/vp9_pickmode.c | 8 +++++++- vp9/encoder/vp9_speed_features.c | 6 +++++- vp9/encoder/vp9_svc_layercontext.c | 7 +++++++ vp9/encoder/vp9_svc_layercontext.h | 1 + 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index b05f4184b..28d6a493d 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -158,6 +158,7 @@ static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x, const MvLimits tmp_mv_limits = x->mv_limits; int rv = 0; int cost_list[5]; + int search_subpel = 1; const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi, ref); if (scaled_ref_frame) { @@ -210,7 +211,12 @@ static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x, rv = !(RDCOST(x->rdmult, x->rddiv, (*rate_mv + rate_mode), 0) > best_rd_sofar); - if (rv) { + // For SVC on non-reference frame, avoid subpel for (0, 0) motion. + if (cpi->use_svc && cpi->svc.non_reference_frame) { + if (mvp_full.row == 0 && mvp_full.col == 0) search_subpel = 0; + } + + if (rv && search_subpel) { const int subpel_force_stop = cpi->sf.mv.subpel_force_stop; cpi->find_fractional_mv_step( x, &tmp_mv->as_mv, &ref_mv, cpi->common.allow_high_precision_mv, diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 011be9710..cf8f0c1be 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -534,7 +534,11 @@ static void set_rt_speed_feature_framesize_independent( if (cpi->svc.temporal_layer_id > 0) { sf->adaptive_rd_thresh = 4; sf->limit_newmv_early_exit = 0; - sf->mv.subpel_force_stop = (cpi->svc.temporal_layer_id == 1) ? 1 : 2; + // Use 1/2-pel for non-reference frame. + if (cpi->svc.non_reference_frame) + sf->mv.subpel_force_stop = 2; + else + sf->mv.subpel_force_stop = 1; sf->base_mv_aggressive = (cpi->svc.temporal_layer_id == cpi->svc.number_temporal_layers - 1) ? 1 diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index 5867a6c38..71aa82065 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -36,6 +36,7 @@ void vp9_init_layer_context(VP9_COMP *const cpi) { svc->scaled_temp_is_alloc = 0; svc->scaled_one_half = 0; svc->current_superframe = 0; + svc->non_reference_frame = 0; for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1; for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { svc->ext_frame_flags[sl] = 0; @@ -677,6 +678,12 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { } } + cpi->svc.non_reference_frame = 0; + if (cpi->common.frame_type != KEY_FRAME && !cpi->ext_refresh_last_frame && + !cpi->ext_refresh_golden_frame && !cpi->ext_refresh_alt_ref_frame) { + cpi->svc.non_reference_frame = 1; + } + if (vp9_set_size_literal(cpi, width, height) != 0) return VPX_CODEC_INVALID_PARAM; diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index d8e6772b2..4e8aaf73f 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -87,6 +87,7 @@ typedef struct { int ref_frame_index[REF_FRAMES]; int force_zero_mode_spatial_ref; int current_superframe; + int non_reference_frame; int use_base_mv; // Used to control the downscaling filter for source scaling, for 1 pass CBR. // downsample_filter_phase: = 0 will do sub-sampling (no weighted average), -- 2.40.0