ref: b073af5925aabb36a3f4ef6a6760899e041f6ca5
parent: 2718de54ca7863777c45a74f3e7285bdd6000573
author: Jingning Han <[email protected]>
date: Fri Jul 13 10:08:45 EDT 2018
Estimate the frame qp in a gop Gather the availabel statistics to estimate the frame level quantization parameter set in a group of pictures. This will be called in the tpl model construction. No visible coding stats change would occur. Change-Id: Ic412e4afd9a60f1317a5f8eab6a4f6d5e48c4c07
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -6138,7 +6138,11 @@
for (i = 0; i < MAX_REF_FRAMES; ++i) cpi->scaled_ref_idx[i] = INVALID_IDX;
}
- if (arf_src_index && cpi->sf.enable_tpl_model) setup_tpl_stats(cpi);
+ if (arf_src_index && cpi->sf.enable_tpl_model) {
+ setup_tpl_stats(cpi);
+ vp9_estimate_qp_gop(cpi);
+ vp9_configure_buffer_updates(cpi, cpi->twopass.gf_group.index);
+ }
cpi->td.mb.fp_src_pred = 0;
#if CONFIG_REALTIME_ONLY
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -3541,42 +3541,6 @@
}
}
-static void configure_buffer_updates(VP9_COMP *cpi) {
- TWO_PASS *const twopass = &cpi->twopass;
-
- cpi->rc.is_src_frame_alt_ref = 0;
- switch (twopass->gf_group.update_type[twopass->gf_group.index]) {
- case KF_UPDATE:
- cpi->refresh_last_frame = 1;
- cpi->refresh_golden_frame = 1;
- cpi->refresh_alt_ref_frame = 1;
- break;
- case LF_UPDATE:
- cpi->refresh_last_frame = 1;
- cpi->refresh_golden_frame = 0;
- cpi->refresh_alt_ref_frame = 0;
- break;
- case GF_UPDATE:
- cpi->refresh_last_frame = 1;
- cpi->refresh_golden_frame = 1;
- cpi->refresh_alt_ref_frame = 0;
- break;
- case OVERLAY_UPDATE:
- cpi->refresh_last_frame = 0;
- cpi->refresh_golden_frame = 1;
- cpi->refresh_alt_ref_frame = 0;
- cpi->rc.is_src_frame_alt_ref = 1;
- break;
- default:
- assert(twopass->gf_group.update_type[twopass->gf_group.index] ==
- ARF_UPDATE);
- cpi->refresh_last_frame = 0;
- cpi->refresh_golden_frame = 0;
- cpi->refresh_alt_ref_frame = 1;
- break;
- }
-}
-
static int is_skippable_frame(const VP9_COMP *cpi) {
// If the current frame does not have non-zero motion vector detected in the
// first pass, and so do its previous and forward frames, then this frame
@@ -3613,7 +3577,7 @@
if (cpi->extra_arf_allowed) {
configure_multi_arf_buffer_updates(cpi);
} else {
- configure_buffer_updates(cpi);
+ vp9_configure_buffer_updates(cpi, gf_group->index);
}
target_rate = gf_group->bit_allocation[gf_group->index];
@@ -3710,7 +3674,7 @@
if (cpi->extra_arf_allowed) {
configure_multi_arf_buffer_updates(cpi);
} else {
- configure_buffer_updates(cpi);
+ vp9_configure_buffer_updates(cpi, gf_group->index);
}
// Do the firstpass stats indicate that this frame is skippable for the
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1402,6 +1402,60 @@
return q;
}
+void vp9_configure_buffer_updates(VP9_COMP *cpi, int gf_group_index) {
+ TWO_PASS *const twopass = &cpi->twopass;
+
+ cpi->rc.is_src_frame_alt_ref = 0;
+ switch (twopass->gf_group.update_type[gf_group_index]) {
+ case KF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_alt_ref_frame = 1;
+ break;
+ case LF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+ case GF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+ case OVERLAY_UPDATE:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_alt_ref_frame = 0;
+ cpi->rc.is_src_frame_alt_ref = 1;
+ break;
+ default:
+ assert(twopass->gf_group.update_type[gf_group_index] == ARF_UPDATE);
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_alt_ref_frame = 1;
+ break;
+ }
+}
+
+void vp9_estimate_qp_gop(VP9_COMP *cpi) {
+ int gop_length = cpi->rc.baseline_gf_interval;
+ int bottom_index, top_index;
+ int idx;
+ int q;
+ const int gf_index = cpi->twopass.gf_group.index;
+
+ for (idx = 1; idx <= gop_length; ++idx) {
+ int target_rate = cpi->twopass.gf_group.bit_allocation[idx];
+ cpi->twopass.gf_group.index = idx;
+ vp9_rc_set_frame_target(cpi, target_rate);
+ vp9_configure_buffer_updates(cpi, idx);
+ q = rc_pick_q_and_bounds_two_pass(cpi, &bottom_index, &top_index, idx);
+ (void)q;
+ }
+ // Reset the actual index
+ cpi->twopass.gf_group.index = gf_index;
+}
+
void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, int frame_target,
int *frame_under_shoot_limit,
int *frame_over_shoot_limit) {
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -304,6 +304,10 @@
int vp9_encodedframe_overshoot(struct VP9_COMP *cpi, int frame_size, int *q);
+void vp9_configure_buffer_updates(struct VP9_COMP *cpi, int gf_group_index);
+
+void vp9_estimate_qp_gop(struct VP9_COMP *cpi);
+
#ifdef __cplusplus
} // extern "C"
#endif