summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJingning Han <jingning@google.com>2018-07-13 14:08:45 -0700
committerJingning Han <jingning@google.com>2018-07-13 15:17:54 -0700
commitb073af5925aabb36a3f4ef6a6760899e041f6ca5 (patch)
tree98c2e1f742da1dad2e491adb23a1ff26254d74c7
parent2718de54ca7863777c45a74f3e7285bdd6000573 (diff)
downloadlibvpx-b073af5925aabb36a3f4ef6a6760899e041f6ca5.tar.gz
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
-rw-r--r--vp9/encoder/vp9_encoder.c6
-rw-r--r--vp9/encoder/vp9_firstpass.c40
-rw-r--r--vp9/encoder/vp9_ratectrl.c54
-rw-r--r--vp9/encoder/vp9_ratectrl.h4
4 files changed, 65 insertions, 39 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index a317c306e..40ccc5bc9 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -6138,7 +6138,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
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
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 7cc4659a9..b234fe287 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -3541,42 +3541,6 @@ static void configure_multi_arf_buffer_updates(VP9_COMP *cpi) {
}
}
-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 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
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 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
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
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index b417aa7d0..eb398e251 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1402,6 +1402,60 @@ int vp9_rc_pick_q_and_bounds(const VP9_COMP *cpi, int *bottom_index,
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) {
diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h
index 488dae12d..6266ae940 100644
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -304,6 +304,10 @@ void vp9_scene_detection_onepass(struct VP9_COMP *cpi);
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