From 4dbad63a71135c11e11206656b750ff78361dff2 Mon Sep 17 00:00:00 2001 From: Deb Mukherjee <debargha@google.com> Date: Wed, 18 Dec 2013 10:26:27 -0800 Subject: [PATCH] Begin refactor of frame schedule in rate control Various cleanups and streamlining of interfaces as precursor to further advancements in rate control. Pre-encode parameter setting for different use cases: One-pass, first of 2-pass, second of 2-pass, and Svc are separated out. There is no change in output with this change. Change-Id: Ied8ca7d84d610993776aa30ef263fe20452e0e3e --- vp9/encoder/vp9_firstpass.c | 50 +++++++++++++++++++++- vp9/encoder/vp9_firstpass.h | 6 ++- vp9/encoder/vp9_onyx_if.c | 82 +++++++++++++++++++------------------ vp9/encoder/vp9_ratectrl.c | 5 +-- 4 files changed, 98 insertions(+), 45 deletions(-) diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 2d7ac7ce5..2e07c5d76 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -2035,7 +2035,49 @@ static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { cpi->rc.per_frame_bandwidth = target_frame_size; } -void vp9_second_pass(VP9_COMP *cpi) { +void vp9_get_svc_params(VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + if ((cm->current_video_frame == 0) || + (cm->frame_flags & FRAMEFLAGS_KEY) || + (cpi->oxcf.auto_key && (cpi->rc.frames_since_key % + cpi->key_frame_frequency == 0))) { + cm->frame_type = KEY_FRAME; + } else { + cm->frame_type = INTER_FRAME; + } + cpi->rc.frames_till_gf_update_due = INT_MAX; + cpi->rc.baseline_gf_interval = INT_MAX; +} + +void vp9_get_one_pass_params(VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + if (!cpi->refresh_alt_ref_frame && + (cm->current_video_frame == 0 || + cm->frame_flags & FRAMEFLAGS_KEY || + (cpi->oxcf.auto_key && (cpi->rc.frames_since_key % + cpi->key_frame_frequency == 0)))) { + cm->frame_type = KEY_FRAME; + } else { + cm->frame_type = INTER_FRAME; + } + if (cpi->rc.frames_till_gf_update_due == 0) { + cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval; + cpi->refresh_golden_frame = 1; + } +} + +void vp9_get_first_pass_params(VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + if (!cpi->refresh_alt_ref_frame && + (cm->current_video_frame == 0 || + cm->frame_flags & FRAMEFLAGS_KEY)) { + cm->frame_type = KEY_FRAME; + } else { + cm->frame_type = INTER_FRAME; + } +} + +void vp9_get_second_pass_params(VP9_COMP *cpi) { int tmp_q; int frames_left = (int)(cpi->twopass.total_stats.count - cpi->common.current_video_frame); @@ -2046,6 +2088,10 @@ void vp9_second_pass(VP9_COMP *cpi) { double this_frame_intra_error; double this_frame_coded_error; + if (cpi->refresh_alt_ref_frame) { + cpi->common.frame_type = INTER_FRAME; + return; + } if (!cpi->twopass.stats_in) return; @@ -2129,6 +2175,8 @@ void vp9_second_pass(VP9_COMP *cpi) { assign_std_frame_bits(cpi, &this_frame_copy); cpi->rc.per_frame_bandwidth = bak; } + cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval; + cpi->refresh_golden_frame = 1; } else { // Otherwise this is an ordinary frame // Assign bits from those allocated to the GF group diff --git a/vp9/encoder/vp9_firstpass.h b/vp9/encoder/vp9_firstpass.h index c18d11e04..43703c2c5 100644 --- a/vp9/encoder/vp9_firstpass.h +++ b/vp9/encoder/vp9_firstpass.h @@ -17,7 +17,11 @@ void vp9_first_pass(VP9_COMP *cpi); void vp9_end_first_pass(VP9_COMP *cpi); void vp9_init_second_pass(VP9_COMP *cpi); -void vp9_second_pass(VP9_COMP *cpi); +void vp9_get_second_pass_params(VP9_COMP *cpi); void vp9_end_second_pass(VP9_COMP *cpi); +void vp9_get_first_pass_params(VP9_COMP *cpi); +void vp9_get_one_pass_params(VP9_COMP *cpi); +void vp9_get_svc_params(VP9_COMP *cpi); + #endif // VP9_ENCODER_VP9_FIRSTPASS_H_ diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 7fbce13db..3f813a1f6 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -2085,6 +2085,7 @@ int vp9_use_as_reference(VP9_PTR ptr, int ref_frame_flags) { cpi->ref_frame_flags = ref_frame_flags; return 0; } + int vp9_update_reference(VP9_PTR ptr, int ref_frame_flags) { VP9_COMP *cpi = (VP9_COMP *)(ptr); @@ -2158,6 +2159,7 @@ int vp9_set_reference_enc(VP9_PTR ptr, VP9_REFFRAME ref_frame_flag, return 0; } + int vp9_update_entropy(VP9_PTR comp, int update) { ((VP9_COMP *)comp)->common.refresh_frame_context = update; return 0; @@ -2304,12 +2306,6 @@ static void update_golden_frame_stats(VP9_COMP *cpi) { cpi->oxcf.play_alternate && !cpi->refresh_alt_ref_frame) { cpi->rc.source_alt_ref_pending = 1; cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval; - - // TODO(ivan): For SVC encoder, GF automatic update is disabled by using - // a large GF_interval. - if (cpi->use_svc) { - cpi->rc.frames_till_gf_update_due = INT_MAX; - } } if (!cpi->rc.source_alt_ref_pending) @@ -2836,6 +2832,34 @@ static void encode_with_recode_loop(VP9_COMP *cpi, } while (loop); } +static void get_ref_frame_flags(VP9_COMP *cpi) { + if (cpi->refresh_last_frame & cpi->refresh_golden_frame) + cpi->gold_is_last = 1; + else if (cpi->refresh_last_frame ^ cpi->refresh_golden_frame) + cpi->gold_is_last = 0; + + if (cpi->refresh_last_frame & cpi->refresh_alt_ref_frame) + cpi->alt_is_last = 1; + else if (cpi->refresh_last_frame ^ cpi->refresh_alt_ref_frame) + cpi->alt_is_last = 0; + + if (cpi->refresh_alt_ref_frame & cpi->refresh_golden_frame) + cpi->gold_is_alt = 1; + else if (cpi->refresh_alt_ref_frame ^ cpi->refresh_golden_frame) + cpi->gold_is_alt = 0; + + cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; + + if (cpi->gold_is_last) + cpi->ref_frame_flags &= ~VP9_GOLD_FLAG; + + if (cpi->alt_is_last) + cpi->ref_frame_flags &= ~VP9_ALT_FLAG; + + if (cpi->gold_is_alt) + cpi->ref_frame_flags &= ~VP9_ALT_FLAG; +} + static void encode_frame_to_data_rate(VP9_COMP *cpi, size_t *size, uint8_t *dest, @@ -3119,32 +3143,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, else cm->frame_flags = cm->frame_flags&~FRAMEFLAGS_ALTREF; - - if (cpi->refresh_last_frame & cpi->refresh_golden_frame) - cpi->gold_is_last = 1; - else if (cpi->refresh_last_frame ^ cpi->refresh_golden_frame) - cpi->gold_is_last = 0; - - if (cpi->refresh_last_frame & cpi->refresh_alt_ref_frame) - cpi->alt_is_last = 1; - else if (cpi->refresh_last_frame ^ cpi->refresh_alt_ref_frame) - cpi->alt_is_last = 0; - - if (cpi->refresh_alt_ref_frame & cpi->refresh_golden_frame) - cpi->gold_is_alt = 1; - else if (cpi->refresh_alt_ref_frame ^ cpi->refresh_golden_frame) - cpi->gold_is_alt = 0; - - cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; - - if (cpi->gold_is_last) - cpi->ref_frame_flags &= ~VP9_GOLD_FLAG; - - if (cpi->alt_is_last) - cpi->ref_frame_flags &= ~VP9_ALT_FLAG; - - if (cpi->gold_is_alt) - cpi->ref_frame_flags &= ~VP9_ALT_FLAG; + get_ref_frame_flags(cpi); if (cpi->oxcf.play_alternate && cpi->refresh_alt_ref_frame && (cm->frame_type != KEY_FRAME)) @@ -3168,7 +3167,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, #endif // As this frame is a key frame the next defaults to an inter frame. - cm->frame_type = INTER_FRAME; vp9_clear_system_state(); cpi->rc.frames_since_key = 0; } else { @@ -3227,8 +3225,15 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; } +static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest, + unsigned int *frame_flags) { + vp9_get_svc_params(cpi); + encode_frame_to_data_rate(cpi, size, dest, frame_flags); +} + static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, unsigned int *frame_flags) { + vp9_get_one_pass_params(cpi); encode_frame_to_data_rate(cpi, size, dest, frame_flags); } @@ -3238,6 +3243,7 @@ static void Pass1Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, (void) dest; (void) frame_flags; + vp9_get_first_pass_params(cpi); vp9_set_quantizer(cpi, find_fp_qindex()); vp9_first_pass(cpi); } @@ -3246,9 +3252,7 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest, unsigned int *frame_flags) { cpi->enable_encode_breakout = 1; - if (!cpi->refresh_alt_ref_frame) - vp9_second_pass(cpi); - + vp9_get_second_pass_params(cpi); encode_frame_to_data_rate(cpi, size, dest, frame_flags); // vp9_print_modes_and_motion_vectors(&cpi->common, "encode.stt"); @@ -3533,7 +3537,6 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, } #endif - cm->frame_type = INTER_FRAME; cm->frame_flags = *frame_flags; // Reset the frame pointers to the current frame size @@ -3556,7 +3559,9 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, vp9_vaq_init(); } - if (cpi->pass == 1) { + if (cpi->use_svc) { + SvcEncode(cpi, size, dest, frame_flags); + } else if (cpi->pass == 1) { Pass1Encode(cpi, size, dest, frame_flags); } else if (cpi->pass == 2) { Pass2Encode(cpi, size, dest, frame_flags); @@ -3583,7 +3588,6 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, cpi->refresh_alt_ref_frame = 0; cpi->refresh_golden_frame = 0; cpi->refresh_last_frame = 1; - cm->frame_type = INTER_FRAME; } vpx_usec_timer_mark(&cmptimer); diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index ca7d6c64c..8a0dd4cee 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -428,10 +428,7 @@ static void calc_pframe_target_size(VP9_COMP *const cpi) { } // Adjust target frame size for Golden Frames: - if (cpi->rc.frames_till_gf_update_due == 0 && - !(cpi->pass == 0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) { - cpi->refresh_golden_frame = 1; - calc_gf_params(cpi); + if (cpi->refresh_golden_frame) { // If we are using alternate ref instead of gf then do not apply the boost // It will instead be applied to the altref update // Jims modified boost -- 2.40.0