From 99309004bf349f4d66beb2a90e934fb25855b1e9 Mon Sep 17 00:00:00 2001 From: paulwilkins Date: Tue, 15 Dec 2015 15:23:47 +0000 Subject: [PATCH] Fixed interval, fixed Q 1 pass test patch. For testing implemented a fixed pattern and delta, 1 pass, fixed Q, low delay mode. This has not in any way been tuned or optimized. Change-Id: Icf9b57c3bb16cc5c0726d5229009212af36eb6d9 --- vp10/encoder/encoder.c | 6 ++- vp10/encoder/ratectrl.c | 90 +++++++++++++++++++++++++---------------- vp10/encoder/ratectrl.h | 1 + 3 files changed, 61 insertions(+), 36 deletions(-) diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c index 6bba84845..175c6d855 100644 --- a/vp10/encoder/encoder.c +++ b/vp10/encoder/encoder.c @@ -1422,7 +1422,11 @@ void vp10_change_config(struct VP10_COMP *cpi, const VP10EncoderConfig *oxcf) { cpi->td.mb.e_mbd.bd = (int)cm->bit_depth; #endif // CONFIG_VP9_HIGHBITDEPTH - rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2; + if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) { + rc->baseline_gf_interval = FIXED_GF_INTERVAL; + } else { + rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2; + } cpi->refresh_golden_frame = 0; cpi->refresh_last_frame = 1; diff --git a/vp10/encoder/ratectrl.c b/vp10/encoder/ratectrl.c index 64244166c..606877594 100644 --- a/vp10/encoder/ratectrl.c +++ b/vp10/encoder/ratectrl.c @@ -794,16 +794,18 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP10_COMP *cpi, ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq); if (frame_is_intra_only(cm)) { - - // Handle the special case for key frames forced when we have reached - // the maximum key frame interval. Here force the Q to a range - // based on the ambient Q to reduce the risk of popping. - if (rc->this_key_frame_forced) { + if (oxcf->rc_mode == VPX_Q) { + int qindex = cq_level; + double q = vp10_convert_qindex_to_q(qindex, cm->bit_depth); + int delta_qindex = vp10_compute_qdelta(rc, q, q * 0.25, + cm->bit_depth); + active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); + } else if (rc->this_key_frame_forced) { int qindex = rc->last_boosted_qindex; double last_boosted_q = vp10_convert_qindex_to_q(qindex, cm->bit_depth); int delta_qindex = vp10_compute_qdelta(rc, last_boosted_q, - last_boosted_q * 0.75, - cm->bit_depth); + last_boosted_q * 0.75, + cm->bit_depth); active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); } else { // not first frame of one pass and kf_boost is set @@ -823,8 +825,8 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP10_COMP *cpi, // on active_best_quality. q_val = vp10_convert_qindex_to_q(active_best_quality, cm->bit_depth); active_best_quality += vp10_compute_qdelta(rc, q_val, - q_val * q_adj_factor, - cm->bit_depth); + q_val * q_adj_factor, + cm->bit_depth); } } else if (!rc->is_src_frame_alt_ref && (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { @@ -848,17 +850,28 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP10_COMP *cpi, active_best_quality = active_best_quality * 15 / 16; } else if (oxcf->rc_mode == VPX_Q) { - if (!cpi->refresh_alt_ref_frame) { - active_best_quality = cq_level; - } else { - active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); - } + int qindex = cq_level; + double q = vp10_convert_qindex_to_q(qindex, cm->bit_depth); + int delta_qindex; + if (cpi->refresh_alt_ref_frame) + delta_qindex = vp10_compute_qdelta(rc, q, q * 0.40, cm->bit_depth); + else + delta_qindex = vp10_compute_qdelta(rc, q, q * 0.50, cm->bit_depth); + active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); } else { active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); } } else { if (oxcf->rc_mode == VPX_Q) { - active_best_quality = cq_level; + int qindex = cq_level; + double q = vp10_convert_qindex_to_q(qindex, cm->bit_depth); + double delta_rate[FIXED_GF_INTERVAL] = + {0.50, 1.0, 0.85, 1.0, 0.70, 1.0, 0.85, 1.0}; + int delta_qindex = + vp10_compute_qdelta(rc, q, + q * delta_rate[cm->current_video_frame % + FIXED_GF_INTERVAL], cm->bit_depth); + active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality); } else { // Use the lower of active_worst_quality and recent/average Q. if (cm->current_video_frame > 1) @@ -1562,29 +1575,36 @@ void vp10_rc_set_gf_interval_range(const VP10_COMP *const cpi, RATE_CONTROL *const rc) { const VP10EncoderConfig *const oxcf = &cpi->oxcf; - // Set Maximum gf/arf interval - rc->max_gf_interval = oxcf->max_gf_interval; - rc->min_gf_interval = oxcf->min_gf_interval; - if (rc->min_gf_interval == 0) - rc->min_gf_interval = vp10_rc_get_default_min_gf_interval( - oxcf->width, oxcf->height, cpi->framerate); - if (rc->max_gf_interval == 0) - rc->max_gf_interval = vp10_rc_get_default_max_gf_interval( - cpi->framerate, rc->min_gf_interval); + // Special case code for 1 pass fixed Q mode tests + if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) { + rc->max_gf_interval = FIXED_GF_INTERVAL; + rc->min_gf_interval = FIXED_GF_INTERVAL; + rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL; + } else { + // Set Maximum gf/arf interval + rc->max_gf_interval = oxcf->max_gf_interval; + rc->min_gf_interval = oxcf->min_gf_interval; + if (rc->min_gf_interval == 0) + rc->min_gf_interval = vp10_rc_get_default_min_gf_interval( + oxcf->width, oxcf->height, cpi->framerate); + if (rc->max_gf_interval == 0) + rc->max_gf_interval = vp10_rc_get_default_max_gf_interval( + cpi->framerate, rc->min_gf_interval); + + // Extended interval for genuinely static scenes + rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2; + + if (is_altref_enabled(cpi)) { + if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1) + rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1; + } - // Extended interval for genuinely static scenes - rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2; + if (rc->max_gf_interval > rc->static_scene_max_gf_interval) + rc->max_gf_interval = rc->static_scene_max_gf_interval; - if (is_altref_enabled(cpi)) { - if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1) - rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1; + // Clamp min to max + rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval); } - - if (rc->max_gf_interval > rc->static_scene_max_gf_interval) - rc->max_gf_interval = rc->static_scene_max_gf_interval; - - // Clamp min to max - rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval); } void vp10_rc_update_framerate(VP10_COMP *cpi) { diff --git a/vp10/encoder/ratectrl.h b/vp10/encoder/ratectrl.h index 8008c1610..0b9fd456d 100644 --- a/vp10/encoder/ratectrl.h +++ b/vp10/encoder/ratectrl.h @@ -26,6 +26,7 @@ extern "C" { #define MIN_GF_INTERVAL 4 #define MAX_GF_INTERVAL 16 +#define FIXED_GF_INTERVAL 8 // Used in some testing modes only typedef enum { INTER_NORMAL = 0, -- 2.40.0