From 3134a52d26cc8deff4bd197537aca6cfdc597e44 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 20 Apr 2017 09:50:16 -0700 Subject: [PATCH] vp9: SVC: Redefine the source downsample filter choice. Rename the source downsampling filter, and define it per spatial layers. Used 1 pass CBR SVC. Change-Id: I8135f2ab89c535c53429b9c58b586f746bb668c7 --- vp9/encoder/vp9_encoder.c | 27 +++++++++++++++------------ vp9/encoder/vp9_encoder.h | 2 +- vp9/encoder/vp9_svc_layercontext.c | 6 ++++-- vp9/encoder/vp9_svc_layercontext.h | 11 ++++++----- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 24e8bbd5b..d9027e001 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -3124,7 +3124,11 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest) { VP9_COMMON *const cm = &cpi->common; int q = 0, bottom_index = 0, top_index = 0; // Dummy variables. - const int phase_scaler = is_one_pass_cbr_svc(cpi) ? cpi->svc.phase_scaler : 0; + const int phase_scaler = + (is_one_pass_cbr_svc(cpi) && + cpi->svc.filtertype_downsample_source[cpi->svc.spatial_layer_id]) + ? 8 + : 0; // Flag to check if its valid to compute the source sad (used for // scene detection and for superblock content state in CBR mode). @@ -3144,9 +3148,10 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size, // For svc, if it is a 1/4x1/4 downscaling, do a two-stage scaling to take // advantage of the 1:2 optimized scaler. In the process, the 1/2x1/2 // result will be saved in scaled_temp and might be used later. - cpi->Source = - vp9_svc_twostage_scale(cm, cpi->un_scaled_source, &cpi->scaled_source, - &cpi->svc.scaled_temp, phase_scaler); + int phase_scaler2 = (cpi->svc.filtertype_downsample_source[1]) ? 8 : 0; + cpi->Source = vp9_svc_twostage_scale( + cm, cpi->un_scaled_source, &cpi->scaled_source, &cpi->svc.scaled_temp, + phase_scaler, phase_scaler2); cpi->svc.scaled_one_half = 1; } else if (is_one_pass_cbr_svc(cpi) && cpi->un_scaled_source->y_width == cm->width << 1 && @@ -3685,25 +3690,23 @@ static void set_ext_overrides(VP9_COMP *cpi) { } } -YV12_BUFFER_CONFIG *vp9_svc_twostage_scale(VP9_COMMON *cm, - YV12_BUFFER_CONFIG *unscaled, - YV12_BUFFER_CONFIG *scaled, - YV12_BUFFER_CONFIG *scaled_temp, - int phase_scaler) { +YV12_BUFFER_CONFIG *vp9_svc_twostage_scale( + VP9_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *scaled, + YV12_BUFFER_CONFIG *scaled_temp, int phase_scaler, int phase_scaler2) { if (cm->mi_cols * MI_SIZE != unscaled->y_width || cm->mi_rows * MI_SIZE != unscaled->y_height) { #if CONFIG_VP9_HIGHBITDEPTH if (cm->bit_depth == VPX_BITS_8) { - vp9_scale_and_extend_frame(unscaled, scaled_temp, phase_scaler); + vp9_scale_and_extend_frame(unscaled, scaled_temp, phase_scaler2); vp9_scale_and_extend_frame(scaled_temp, scaled, phase_scaler); } else { scale_and_extend_frame(unscaled, scaled_temp, (int)cm->bit_depth, - phase_scaler); + phase_scaler2); scale_and_extend_frame(scaled_temp, scaled, (int)cm->bit_depth, phase_scaler); } #else - vp9_scale_and_extend_frame(unscaled, scaled_temp, phase_scaler); + vp9_scale_and_extend_frame(unscaled, scaled_temp, phase_scaler2); vp9_scale_and_extend_frame(scaled_temp, scaled, phase_scaler); #endif // CONFIG_VP9_HIGHBITDEPTH return scaled; diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index f81ae4e62..7040ed9a9 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -844,7 +844,7 @@ YV12_BUFFER_CONFIG *vp9_svc_twostage_scale(VP9_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *scaled, YV12_BUFFER_CONFIG *scaled_temp, - int phase_scaler); + int phase_scaler, int phase_scaler2); YV12_BUFFER_CONFIG *vp9_scale_if_required(VP9_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c index 4368d7193..ed628758b 100644 --- a/vp9/encoder/vp9_svc_layercontext.c +++ b/vp9/encoder/vp9_svc_layercontext.c @@ -36,13 +36,13 @@ 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->phase_scaler = 0; for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1; for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { cpi->svc.ext_frame_flags[sl] = 0; cpi->svc.ext_lst_fb_idx[sl] = 0; cpi->svc.ext_gld_fb_idx[sl] = 1; cpi->svc.ext_alt_fb_idx[sl] = 2; + cpi->svc.filtertype_downsample_source[sl] = 0; } if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) { @@ -664,8 +664,10 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) { if ((lc->scaling_factor_num != lc->scaling_factor_den >> 1) && !(lc->scaling_factor_num == lc->scaling_factor_den >> 2 && sl == 0 && cpi->svc.number_spatial_layers == 3)) { + int sl2; cpi->svc.use_base_mv = 0; - cpi->svc.phase_scaler = 0; + for (sl2 = 0; sl2 < cpi->svc.number_spatial_layers - 1; ++sl2) + cpi->svc.filtertype_downsample_source[sl2] = 0; break; } } diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h index e43055594..7442e6ff7 100644 --- a/vp9/encoder/vp9_svc_layercontext.h +++ b/vp9/encoder/vp9_svc_layercontext.h @@ -88,11 +88,12 @@ typedef struct { int force_zero_mode_spatial_ref; int current_superframe; int use_base_mv; - // phase_scaler used to control the downscaling filter for source scaling. - // phase_scaler = 0 will do sub-sampling (no weighted average), - // phase_scaler = 8 will center the target pixel and use the averaging filter, - // for eightap regular: {-1, 6, -19, 78, 78, -19, 6, -1 }. - int phase_scaler; + // Used to control the downscaling filter for source scaling, for 1 pass CBR. + // 0 will do sub-sampling (no weighted average), 1 will center the target + // pixel and use the averaging filter, for the default eightap_regular: + // {-1, 6, -19, 78, 78, -19, 6, -1 }. + // TODO(marpan): Add option for bilinear. + int filtertype_downsample_source[VPX_SS_MAX_LAYERS]; } SVC; struct VP9_COMP;