rtc: Improve gf length decision
In real time mode, intended to use longer gf intervals.
Forced the golden frame refresh for a high motion frame.
This change gave good coding gains, and made the encode
slightly faster.
Borg test results at rt speed 5 and 7.
avg_psnr: ovr_psnr: ssim: encoder speed:
speed 5:
rtc_derf: -0.628 -0.675 -0.942 0.767
rtc: -0.347 -0.377 -0.439 0.693
speed 7:
rtc_derf: -0.762 -0.772 -1.066 0.536
rtc: -0.540 -0.607 -0.700 0.338
STATS_CHANGED
Change-Id: I3230da4ed3ae3e7be102bcb26ccfac884b3ec506
diff --git a/av1/encoder/aq_cyclicrefresh.c b/av1/encoder/aq_cyclicrefresh.c
index 452a66f..0a955b8 100644
--- a/av1/encoder/aq_cyclicrefresh.c
+++ b/av1/encoder/aq_cyclicrefresh.c
@@ -268,7 +268,9 @@
!cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame &&
cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) {
rc->avg_frame_low_motion =
- (3 * rc->avg_frame_low_motion + avg_cnt_zeromv) / 4;
+ (rc->avg_frame_low_motion == 0)
+ ? avg_cnt_zeromv
+ : (3 * rc->avg_frame_low_motion + avg_cnt_zeromv) / 4;
// For SVC: set avg_frame_low_motion (only computed on top spatial layer)
// to all lower spatial layers.
if (cpi->ppi->use_svc &&
@@ -292,10 +294,12 @@
// with some max limit. Depending on past encoding stats, GF flag may be
// reset and update may not occur until next baseline_gf_interval.
if (cr->percent_refresh > 0)
- p_rc->baseline_gf_interval = AOMMIN(2 * (100 / cr->percent_refresh), 40);
+ p_rc->baseline_gf_interval =
+ AOMMIN(8 * (100 / cr->percent_refresh), MAX_GF_INTERVAL_RT);
else
- p_rc->baseline_gf_interval = 20;
- if (rc->avg_frame_low_motion < 40) p_rc->baseline_gf_interval = 8;
+ p_rc->baseline_gf_interval = FIXED_GF_INTERVAL_RT;
+ if (rc->avg_frame_low_motion && rc->avg_frame_low_motion < 40)
+ p_rc->baseline_gf_interval = 16;
}
// Update the segmentation map, and related quantities: cyclic refresh map,
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 292bdeb..c916eb3 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -2346,6 +2346,8 @@
// period) based on QP. Look into add info on segment deltaq.
PRIMARY_RATE_CONTROL *p_rc = &cpi->ppi->p_rc;
const int avg_qp = p_rc->avg_frame_qindex[INTER_FRAME];
+ const int allow_gf_update =
+ rc->frames_till_gf_update_due <= (p_rc->baseline_gf_interval - 10);
int gf_update_changed = 0;
int thresh = 87;
if (rc->frames_till_gf_update_due == 1 &&
@@ -2353,10 +2355,11 @@
// Disable GF refresh since QP is above the runninhg average QP.
svc->refresh[svc->gld_idx_1layer] = 0;
gf_update_changed = 1;
- } else if (rc->frames_till_gf_update_due <
- (p_rc->baseline_gf_interval >> 1) &&
- cm->quant_params.base_qindex < thresh * avg_qp / 100) {
- // Force refresh since QP is well below average QP.
+ } else if (allow_gf_update &&
+ ((cm->quant_params.base_qindex < thresh * avg_qp / 100) ||
+ (rc->avg_frame_low_motion < 20))) {
+ // Force refresh since QP is well below average QP or this is a high
+ // motion frame.
svc->refresh[svc->gld_idx_1layer] = 1;
gf_update_changed = 1;
}
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 07c98a4..651f19b 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -46,6 +46,9 @@
#define FIXED_GF_INTERVAL 16
#define MAX_GF_LENGTH_LAP 16
+#define FIXED_GF_INTERVAL_RT 80
+#define MAX_GF_INTERVAL_RT 160
+
#define MAX_NUM_GF_INTERVALS 15
#define MAX_ARF_LAYERS 6