From: Jingning Han Date: Fri, 13 Jul 2018 21:08:45 +0000 (-0700) Subject: Estimate the frame qp in a gop X-Git-Tag: v1.8.0~530 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b073af5925aabb36a3f4ef6a6760899e041f6ca5;p=libvpx 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 --- 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