Misc. adjustment of boost and gf length
This patch mostly improve the coding performance for small
keyframe interval by reducing boost on the last ARF and also
trying to balance the lengths of last two gf groups.
The boost reduction on the last GF group is now set as constant.
Experiments on finding the optimal boost reduction factor for
different GF lengths are working in progress.
BDRATE Results (overall psnr):
lowres midres
keyframe interval
30 -0.447 -0.722
40 -0.530 -0.669
60 -0.081 -0.253
------------------------------
19 -1.294 -1.141
21 -0.725 -0.730
23 -0.784 -1.067
25 -1.650 -1.472
27 -0.501 -0.765
29 -0.397 -0.629
AWCY: -0.20 gain on PSNR
STATS_CHANGED
Change-Id: I9fc4fadab547b98164d765b556ebea01fbf4fea8
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 8ee72e3..225204a 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -2455,21 +2455,36 @@
assert(num_mbs > 0);
if (i) avg_sr_coded_error /= i;
-#define REDUCE_GF_LENGTH_THRESH 10
+#define REDUCE_GF_LENGTH_THRESH 4
#define REDUCE_GF_LENGTH_TO_KEY_THRESH 9
#define REDUCE_GF_LENGTH_BY 1
int alt_offset = 0;
#if REDUCE_LAST_GF_LENGTH
- // We are going to have an alt ref.
+ // We are going to have an alt ref, but we don't have do adjustment for
+ // lossless mode
if (allow_alt_ref && (i < cpi->oxcf.lag_in_frames) &&
- (i >= rc->min_gf_interval)) {
- // If the last gf is too long, then we have to reduce
- // the current gf length
- if (rc->frames_to_key - i < REDUCE_GF_LENGTH_TO_KEY_THRESH &&
- i > REDUCE_GF_LENGTH_THRESH) {
- // too long, reduce the length by one
- alt_offset = -REDUCE_GF_LENGTH_BY;
- i -= REDUCE_GF_LENGTH_BY;
+ (i >= rc->min_gf_interval) && !is_lossless_requested(&cpi->oxcf)) {
+ // adjust length of this gf group if one of the following condition met
+ // 1: only one overlay frame left and this gf is too long
+ // 2: next gf group is too short to have arf compared to the current gf
+
+ // maximum length of next gf group
+ const int next_gf_len = rc->frames_to_key - i;
+ const int single_overlay_left =
+ next_gf_len == 0 && i > REDUCE_GF_LENGTH_THRESH;
+ // the next gf is probably going to have a ARF but it will be shorter than
+ // this gf
+ const int unbalanced_gf =
+ i > REDUCE_GF_LENGTH_TO_KEY_THRESH &&
+ next_gf_len + 1 < REDUCE_GF_LENGTH_TO_KEY_THRESH &&
+ next_gf_len + 1 >= rc->min_gf_interval;
+
+ if (single_overlay_left || unbalanced_gf) {
+ // Note: Tried roll_back = DIVIDE_AND_ROUND(i, 8), but is does not work
+ // better in the current setting
+ const int roll_back = REDUCE_GF_LENGTH_BY;
+ alt_offset = -roll_back;
+ i -= roll_back;
}
}
#endif
@@ -2501,13 +2516,13 @@
}
#if REDUCE_LAST_ALT_BOOST
+#define LAST_ALR_BOOST_FACTOR 0.2f
rc->arf_boost_factor = 1.0;
- if (rc->source_alt_ref_pending) {
- // If the last gf is too long, then we have to reduce
- // the boost factor on current alt ref
- if (rc->frames_to_key - i == REDUCE_GF_LENGTH_BY &&
- i > REDUCE_GF_LENGTH_THRESH) {
- rc->arf_boost_factor = 0;
+ if (rc->source_alt_ref_pending && !is_lossless_requested(&cpi->oxcf)) {
+ // Reduce the boost of altref in the last gf group
+ if (rc->frames_to_key - i == REDUCE_GF_LENGTH_BY ||
+ rc->frames_to_key - i == 0) {
+ rc->arf_boost_factor = LAST_ALR_BOOST_FACTOR;
}
}
#endif
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 6eb6741..8237459 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -1025,10 +1025,8 @@
active_best_quality = get_gf_active_quality(rc, q, bit_depth);
*arf_q = active_best_quality;
#if REDUCE_LAST_ALT_BOOST
- int min_boost = (get_gf_high_motion_quality(q, bit_depth) +
- 3 * active_best_quality) /
- 4;
- int boost = min_boost - active_best_quality;
+ const int min_boost = get_gf_high_motion_quality(q, bit_depth);
+ const int boost = min_boost - active_best_quality;
active_best_quality = min_boost - (int)(boost * rc->arf_boost_factor);
#endif