From 8830772370cec94963d8cd63cdc39f0492ebfbd8 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Mon, 30 Jun 2014 10:35:00 +0100 Subject: Multi-arf: Add code to turn it on and off. Add test code to turn multi-arf on and off depending on group length and zero motion. Changes to active max group length for mult-arf. Fund second arf only from normal frame bits. Change-Id: I920287fac1c886428c15a39f731a25d07c2b796c --- vp9/encoder/vp9_encoder.c | 1 + vp9/encoder/vp9_encoder.h | 1 + vp9/encoder/vp9_firstpass.c | 46 +++++++++++++++++++++++++-------------------- 3 files changed, 28 insertions(+), 20 deletions(-) (limited to 'vp9/encoder') diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 4f17a15a9..897edbb9f 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -790,6 +790,7 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) { // For the current check in all the execution paths are defaulted to 0 // pending further tuning and testing. The code is left in place here // as a place holder in regard to the required paths. + cpi->multi_arf_last_grp_enabled = 0; if (cpi->pass == 2) { if (cpi->use_svc) { cpi->multi_arf_allowed = 0; diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index b38f9c246..6f6c3bb30 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -428,6 +428,7 @@ typedef struct VP9_COMP { int multi_arf_allowed; int multi_arf_enabled; + int multi_arf_last_grp_enabled; #if CONFIG_DENOISING VP9_DENOISER denoiser; diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index f90c9df5e..b02555931 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -1407,13 +1407,6 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, // Store the bits to spend on the ARF if there is one. if (rc->source_alt_ref_pending) { - if (cpi->multi_arf_enabled) { - // A portion of the gf / arf extra bits are set asside for lower level - // boosted frames in the middle of the group. - mid_boost_bits += gf_arf_bits >> 5; - gf_arf_bits -= (gf_arf_bits >> 5); - } - twopass->gf_group.update_type[frame_index] = ARF_UPDATE; twopass->gf_group.rf_level[frame_index] = GF_ARF_STD; twopass->gf_group.bit_allocation[frame_index] = gf_arf_bits; @@ -1421,7 +1414,8 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, (unsigned char)(rc->baseline_gf_interval - 1); twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0]; twopass->gf_group.arf_ref_idx[frame_index] = - arf_buffer_indices[cpi->multi_arf_enabled && rc->source_alt_ref_active]; + arf_buffer_indices[cpi->multi_arf_last_grp_enabled && + rc->source_alt_ref_active]; ++frame_index; if (cpi->multi_arf_enabled) { @@ -1496,6 +1490,9 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, twopass->gf_group.update_type[frame_index] = GF_UPDATE; twopass->gf_group.rf_level[frame_index] = GF_ARF_STD; } + + // Note whether multi-arf was enabled this group for next time. + cpi->multi_arf_last_grp_enabled = cpi->multi_arf_enabled; } // Analyse and define a gf/arf group. @@ -1560,18 +1557,21 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Motion breakout threshold for loop below depends on image size. mv_ratio_accumulator_thresh = (cpi->common.width + cpi->common.height) / 10.0; - // Work out a maximum interval for the GF. - // If the image appears completely static we can extend beyond this. - // 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 = - 12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME]) >> 5); - - if (active_max_gf_interval > rc->max_gf_interval) + // Work out a maximum interval for the GF group. + // If the image appears almost completely static we can extend beyond this. + if (cpi->multi_arf_allowed) { active_max_gf_interval = rc->max_gf_interval; + } else { + // 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 = + 12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME]) >> 5); + + if (active_max_gf_interval > rc->max_gf_interval) + active_max_gf_interval = rc->max_gf_interval; + } i = 0; while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) { @@ -1679,6 +1679,10 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { &b_boost); rc->source_alt_ref_pending = 1; + // Test to see if multi arf is appropriate. + cpi->multi_arf_enabled = + (cpi->multi_arf_allowed && (rc->baseline_gf_interval >= 6) && + (zero_motion_accumulator < 0.995)) ? 1 : 0; } else { rc->gfu_boost = (int)boost_score; rc->source_alt_ref_pending = 0; @@ -1838,8 +1842,10 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Is this a forced key frame by interval. rc->this_key_frame_forced = rc->next_key_frame_forced; - // Clear the alt ref active flag as this can never be active on a key frame. + // Clear the alt ref active flag and last group multi arf flags as they + // can never be set for a key frame. rc->source_alt_ref_active = 0; + cpi->multi_arf_last_grp_enabled = 0; // KF is always a GF so clear frames till next gf counter. rc->frames_till_gf_update_due = 0; -- cgit v1.2.3