Commit e0786c28 authored by paulwilkins's avatar paulwilkins
Browse files

Adjust ARF min and max interval.

Previously limit on max interval  set to 0.5 seconds.
Though this helped some low frame rate material it
appears to be a bit too aggressive for some 24 and 25 fps
content. This patch relaxes the limit to 0.75 seconds.

The patch also adds a new minimum interval variable
to replace the current hard wired value. This allows us
to impose a limit on the maximum number of primary
arfs per second for high frame rate (e.g. 50 & 60fps)
content. This is to address concerns regarding playback
performance on some platforms if there is a high base
frame rate and very frequent arfs.

Change-Id: I373e8b6b2a8ef522eced6c6d2cceb234ff763fcf
parent c77b1f5a
......@@ -51,7 +51,6 @@
#define KF_MAX_BOOST 128.0
#define MIN_ARF_GF_BOOST 240
#define MIN_DECAY_FACTOR 0.01
#define MIN_GF_INTERVAL 4
#define MIN_KF_BOOST 300
#define NEW_MV_MODE_PENALTY 32
#define SVC_FACTOR_PT_LOW 0.45
......@@ -1323,14 +1322,17 @@ static double get_prediction_decay_rate(const VP9_COMP *cpi,
// Function to test for a condition where a complex transition is followed
// by a static section. For example in slide shows where there is a fade
// between slides. This is to help with more optimal kf and gf positioning.
static int detect_transition_to_still(const TWO_PASS *twopass,
static int detect_transition_to_still(VP9_COMP *cpi,
int frame_interval, int still_interval,
double loop_decay_rate,
double last_decay_rate) {
TWO_PASS *const twopass = &cpi->twopass;
RATE_CONTROL *const rc = &cpi->rc;
// Break clause to detect very still sections after motion
// For example a static image after a fade or other transition
// instead of a clean scene cut.
if (frame_interval > MIN_GF_INTERVAL &&
if (frame_interval > rc->min_gf_interval &&
loop_decay_rate >= 0.999 &&
last_decay_rate < 0.9) {
int j;
......@@ -1838,7 +1840,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
int int_lbq =
(int)(vp9_convert_qindex_to_q(rc->last_boosted_qindex,
cpi->common.bit_depth));
active_min_gf_interval = MIN_GF_INTERVAL + MIN(2, int_max_q / 200);
active_min_gf_interval = rc->min_gf_interval + MIN(2, int_max_q / 200);
if (active_min_gf_interval > rc->max_gf_interval)
active_min_gf_interval = rc->max_gf_interval;
......@@ -1894,7 +1896,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Break clause to detect very still sections after motion. For example,
// a static image after a fade or other transition.
if (detect_transition_to_still(twopass, i, 5, loop_decay_rate,
if (detect_transition_to_still(cpi, i, 5, loop_decay_rate,
last_loop_decay_rate)) {
allow_alt_ref = 0;
break;
......@@ -1960,7 +1962,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Should we use the alternate reference frame.
if (allow_alt_ref &&
(i < cpi->oxcf.lag_in_frames) &&
(i >= MIN_GF_INTERVAL)) {
(i >= rc->min_gf_interval)) {
// Calculate the boost for alt ref.
rc->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost,
&b_boost);
......@@ -2239,7 +2241,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Special check for transition or high motion followed by a
// static scene.
if (detect_transition_to_still(twopass, i, cpi->oxcf.key_freq - i,
if (detect_transition_to_still(cpi, i, cpi->oxcf.key_freq - i,
loop_decay_rate, decay_accumulator))
break;
......
......@@ -1609,12 +1609,19 @@ int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type,
return target_index - qindex;
}
void vp9_rc_set_gf_max_interval(const VP9_COMP *const cpi,
RATE_CONTROL *const rc) {
#define MIN_GF_INTERVAL 4
#define MAX_GF_INTERVAL 16
void vp9_rc_set_gf_interval_range(const VP9_COMP *const cpi,
RATE_CONTROL *const rc) {
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
// Set a minimum interval.
rc->min_gf_interval =
MIN(MAX_GF_INTERVAL, MAX(MIN_GF_INTERVAL, (int)(cpi->framerate * 0.125)));
// Set Maximum gf/arf interval.
rc->max_gf_interval =
MIN(16, (int)(cpi->framerate / 2.0));
MIN(MAX_GF_INTERVAL, (int)(cpi->framerate * 0.75));
// Round up to next even number if odd.
rc->max_gf_interval += (rc->max_gf_interval & 0x01);
......@@ -1628,6 +1635,9 @@ void vp9_rc_set_gf_max_interval(const VP9_COMP *const cpi,
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 = MIN(rc->min_gf_interval, rc->max_gf_interval);
}
void vp9_rc_update_framerate(VP9_COMP *cpi) {
......@@ -1654,7 +1664,7 @@ void vp9_rc_update_framerate(VP9_COMP *cpi) {
rc->max_frame_bandwidth = MAX(MAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P),
vbr_max_bits);
vp9_rc_set_gf_max_interval(cpi, rc);
vp9_rc_set_gf_interval_range(cpi, rc);
}
#define VBR_PCT_ADJUSTMENT_LIMIT 50
......
......@@ -73,6 +73,7 @@ typedef struct {
int frames_since_golden;
int frames_till_gf_update_due;
int min_gf_interval;
int max_gf_interval;
int static_scene_max_gf_interval;
int baseline_gf_interval;
......@@ -238,8 +239,8 @@ int vp9_frame_type_qdelta(const struct VP9_COMP *cpi, int rf_level, int q);
void vp9_rc_update_framerate(struct VP9_COMP *cpi);
void vp9_rc_set_gf_max_interval(const struct VP9_COMP *const cpi,
RATE_CONTROL *const rc);
void vp9_rc_set_gf_interval_range(const struct VP9_COMP *const cpi,
RATE_CONTROL *const rc);
void vp9_set_target_rate(struct VP9_COMP *cpi);
......
......@@ -195,7 +195,7 @@ void vp9_update_spatial_layer_framerate(VP9_COMP *const cpi, double framerate) {
oxcf->two_pass_vbrmin_section / 100);
lrc->max_frame_bandwidth = (int)(((int64_t)lrc->avg_frame_bandwidth *
oxcf->two_pass_vbrmax_section) / 100);
vp9_rc_set_gf_max_interval(cpi, lrc);
vp9_rc_set_gf_interval_range(cpi, lrc);
}
void vp9_restore_layer_context(VP9_COMP *const cpi) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment