Bugfix for gf-max-pyr-height option.
oxcf->gf_max_pyr_height was being set to the appropriate value *after*
av1_rc_init() was already called. So, rc->max_gf_length was always 16
earlier, irrespective of gf_max_pyr_height value passed in by the user.
This inconsistency was causing the creation of an invalid bitstream.
Now, we set rc->max_gf_length independently of oxcf->gf_max_pyr_height.
And, in define_gf_group() call, when both are set to their final values,
we pick a max_gf_length that adheres to both the constraints.
Also, for max height = 1 in particular, we make sure that extra arfs are
not allowed.
With this, max height of 1, 2 and 3 work correctly. (4 was working fine
already).
No change in stats for default option (gf_max_pyr_height = 4)
BUG=aomedia:2345
Change-Id: I5abfc8f98e93f4f4c4af6b9d969763b4f48b7196
diff --git a/av1/encoder/gop_structure.h b/av1/encoder/gop_structure.h
index df7798a..497e61a 100644
--- a/av1/encoder/gop_structure.h
+++ b/av1/encoder/gop_structure.h
@@ -40,13 +40,6 @@
}
}
-// Given the maximum allowed height of the pyramid structure, return the fixed
-// GF length to be used.
-static INLINE int get_fixed_gf_length(int max_pyr_height) {
- const int max_gf_length_allowed = get_max_gf_length(max_pyr_height);
- return AOMMIN(max_gf_length_allowed, MAX_GF_INTERVAL);
-}
-
struct AV1_COMP;
struct EncodeFrameParams;
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index 36debcb..b6e14ec 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -736,6 +736,13 @@
}
}
+// Given the maximum allowed height of the pyramid structure, return the fixed
+// GF length to be used.
+static INLINE int get_fixed_gf_length(int max_pyr_height) {
+ const int max_gf_length_allowed = get_max_gf_length(max_pyr_height);
+ return AOMMIN(max_gf_length_allowed, MAX_GF_INTERVAL);
+}
+
// Returns true if KF group and GF group both are almost completely static.
static INLINE int is_almost_static(double gf_zero_motion, int kf_zero_motion) {
return (gf_zero_motion >= 0.995) &&
@@ -762,8 +769,6 @@
int i;
double boost_score = 0.0;
- int active_min_gf_interval;
- int active_max_gf_interval;
double gf_group_err = 0.0;
#if GROUP_ADAPTIVE_MAXQ
double gf_group_raw_error = 0.0;
@@ -796,7 +801,7 @@
frame_params->frame_type == INTRA_ONLY_FRAME;
const int arf_active_or_kf = is_intra_only || rc->source_alt_ref_active;
- cpi->extra_arf_allowed = 1;
+ cpi->extra_arf_allowed = (oxcf->gf_max_pyr_height > 1);
// Reset the GF group data structures unless this is a key
// frame in which case it will already have been done.
@@ -829,8 +834,9 @@
(cpi->initial_height + cpi->initial_width) / 4.0;
// TODO(urvang): Try logic to vary min and max interval based on q.
- active_min_gf_interval = rc->min_gf_interval;
- active_max_gf_interval = rc->max_gf_interval;
+ const int active_min_gf_interval = rc->min_gf_interval;
+ const int active_max_gf_interval =
+ AOMMIN(rc->max_gf_interval, get_fixed_gf_length(oxcf->gf_max_pyr_height));
double avg_sr_coded_error = 0;
double avg_raw_err_stdev = 0;
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index cb412b7..84022ea 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -249,10 +249,10 @@
// 4K60: 12
}
-int av1_rc_get_default_max_gf_interval(double framerate, int min_gf_interval,
- int max_pyr_height) {
+int av1_rc_get_default_max_gf_interval(double framerate, int min_gf_interval) {
int interval = AOMMIN(MAX_GF_INTERVAL, (int)(framerate * 0.75));
- interval = AOMMAX(get_fixed_gf_length(max_pyr_height), interval);
+ interval += (interval & 0x01); // Round to even value
+ interval = AOMMAX(MAX_GF_INTERVAL, interval);
return AOMMAX(interval, min_gf_interval);
}
@@ -309,7 +309,7 @@
oxcf->width, oxcf->height, oxcf->init_framerate);
if (rc->max_gf_interval == 0)
rc->max_gf_interval = av1_rc_get_default_max_gf_interval(
- oxcf->init_framerate, rc->min_gf_interval, oxcf->gf_max_pyr_height);
+ oxcf->init_framerate, rc->min_gf_interval);
rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2;
}
@@ -1803,7 +1803,7 @@
oxcf->width, oxcf->height, cpi->framerate);
if (rc->max_gf_interval == 0)
rc->max_gf_interval = av1_rc_get_default_max_gf_interval(
- cpi->framerate, rc->min_gf_interval, oxcf->gf_max_pyr_height);
+ cpi->framerate, rc->min_gf_interval);
// Extended max interval for genuinely static scenes like slide shows.
rc->static_scene_max_gf_interval = MAX_STATIC_GF_GROUP_LENGTH;
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 5121c72..2d8a762 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -173,8 +173,7 @@
// Note av1_rc_get_default_max_gf_interval() requires the min_gf_interval to
// be passed in to ensure that the max_gf_interval returned is at least as bis
// as that.
-int av1_rc_get_default_max_gf_interval(double framerate, int min_frame_rate,
- int max_pyr_height);
+int av1_rc_get_default_max_gf_interval(double framerate, int min_gf_interval);
// Generally at the high level, the following flow is expected
// to be enforced for rate control: