From: angiebird Date: Wed, 23 Oct 2019 23:36:08 +0000 (-0700) Subject: Add get_gf_interval_active_range() X-Git-Tag: v1.8.2~69^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a82f32d59b614cb692b3a2280f56b6327075aca1;p=libvpx Add get_gf_interval_active_range() Change-Id: I94f3b93a932f351b6c9743932238d7ede2938462 --- diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 5f1c8b2f0..659ec6f58 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -2458,6 +2458,11 @@ static void adjust_group_arnr_filter(VP9_COMP *cpi, double section_noise, #define MAX_GF_BOOST 5400 +typedef struct RANGE { + int min; + int max; +} RANGE; + static int get_gop_coding_frame_num( int *use_alt_ref, const FRAME_INFO *frame_info, const FIRST_PASS_INFO *first_pass_info, const RATE_CONTROL *rc, @@ -2571,6 +2576,50 @@ static int get_gop_coding_frame_num( return gop_coding_frames; } +static RANGE get_active_gf_inverval_range( + const FRAME_INFO *frame_info, const RATE_CONTROL *rc, int arf_active_or_kf, + int gf_start_show_idx, int active_worst_quality, int last_boosted_qindex) { + RANGE active_gf_interval; + int int_max_q = (int)(vp9_convert_qindex_to_q(active_worst_quality, + frame_info->bit_depth)); + int q_term = (gf_start_show_idx == 0) + ? int_max_q / 32 + : (int)(vp9_convert_qindex_to_q(last_boosted_qindex, + frame_info->bit_depth) / + 6); + active_gf_interval.min = + rc->min_gf_interval + arf_active_or_kf + VPXMIN(2, int_max_q / 200); + active_gf_interval.min = + VPXMIN(active_gf_interval.min, rc->max_gf_interval + arf_active_or_kf); + + // The value chosen depends on the active Q range. At low Q we have + // bits to spare and are better with a smaller interval and smaller boost. + // At high Q when there are few bits to spare we are better with a longer + // interval to spread the cost of the GF. + active_gf_interval.max = 11 + arf_active_or_kf + VPXMIN(5, q_term); + + // Force max GF interval to be odd. + active_gf_interval.max = active_gf_interval.max | 0x01; + + // We have: active_gf_interval.min <= + // rc->max_gf_interval + arf_active_or_kf. + if (active_gf_interval.max < active_gf_interval.min) { + active_gf_interval.max = active_gf_interval.min; + } else { + active_gf_interval.max = + VPXMIN(active_gf_interval.max, rc->max_gf_interval + arf_active_or_kf); + } + + // Would the active max drop us out just before the near the next kf? + if ((active_gf_interval.max <= rc->frames_to_key) && + (active_gf_interval.max >= (rc->frames_to_key - rc->min_gf_interval))) { + active_gf_interval.max = rc->frames_to_key / 2; + } + active_gf_interval.max = + VPXMAX(active_gf_interval.max, active_gf_interval.min); + return active_gf_interval; +} + static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { VP9_COMMON *const cm = &cpi->common; RATE_CONTROL *const rc = &cpi->rc; @@ -2592,8 +2641,6 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { int allow_alt_ref = is_altref_enabled(cpi); int use_alt_ref; - int active_max_gf_interval; - int active_min_gf_interval; int64_t gf_group_bits; int gf_arf_bits; const int is_key_frame = frame_is_intra_only(cm); @@ -2604,6 +2651,7 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { double gop_intra_factor = 1.0; int gop_frames; + RANGE active_gf_interval; // Reset the GF group data structures unless this is a key // frame in which case it will already have been done. @@ -2613,54 +2661,16 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { vpx_clear_system_state(); - // Set a maximum and minimum interval for the GF group. - // If the image appears almost completely static we can extend beyond this. - { - int int_max_q = (int)(vp9_convert_qindex_to_q(twopass->active_worst_quality, - cpi->common.bit_depth)); - int q_term = (cm->current_video_frame == 0) - ? int_max_q / 32 - : (int)(vp9_convert_qindex_to_q(rc->last_boosted_qindex, - cpi->common.bit_depth) / - 6); - active_min_gf_interval = - rc->min_gf_interval + arf_active_or_kf + VPXMIN(2, int_max_q / 200); - active_min_gf_interval = - VPXMIN(active_min_gf_interval, rc->max_gf_interval + arf_active_or_kf); - - // The value chosen depends on the active Q range. At low Q we have - // bits to spare and are better with a smaller interval and smaller boost. - // At high Q when there are few bits to spare we are better with a longer - // interval to spread the cost of the GF. - active_max_gf_interval = 11 + arf_active_or_kf + VPXMIN(5, q_term); - - // Force max GF interval to be odd. - active_max_gf_interval = active_max_gf_interval | 0x01; - - // We have: active_min_gf_interval <= - // rc->max_gf_interval + arf_active_or_kf. - if (active_max_gf_interval < active_min_gf_interval) { - active_max_gf_interval = active_min_gf_interval; - } else { - active_max_gf_interval = VPXMIN(active_max_gf_interval, - rc->max_gf_interval + arf_active_or_kf); - } - - // Would the active max drop us out just before the near the next kf? - if ((active_max_gf_interval <= rc->frames_to_key) && - (active_max_gf_interval >= (rc->frames_to_key - rc->min_gf_interval))) - active_max_gf_interval = rc->frames_to_key / 2; - } - active_max_gf_interval = - VPXMAX(active_max_gf_interval, active_min_gf_interval); - + active_gf_interval = get_active_gf_inverval_range( + frame_info, rc, arf_active_or_kf, gf_start_show_idx, + twopass->active_worst_quality, rc->last_boosted_qindex); if (cpi->multi_layer_arf) { int layers = 0; int max_layers = VPXMIN(MAX_ARF_LAYERS, cpi->oxcf.enable_auto_arf); int i; // Adapt the intra_error factor to active_max_gf_interval limit. - for (i = active_max_gf_interval; i > 0; i >>= 1) ++layers; + for (i = active_gf_interval.max; i > 0; i >>= 1) ++layers; layers = VPXMIN(max_layers, layers); gop_intra_factor += (layers * 0.25); @@ -2669,7 +2679,7 @@ static void define_gf_group(VP9_COMP *cpi, int gf_start_show_idx) { { gop_coding_frames = get_gop_coding_frame_num( &use_alt_ref, frame_info, first_pass_info, rc, gf_start_show_idx, - active_min_gf_interval, active_max_gf_interval, gop_intra_factor, + active_gf_interval.min, active_gf_interval.max, gop_intra_factor, cpi->oxcf.lag_in_frames); use_alt_ref &= allow_alt_ref; }