diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index ed52999dd..c69ed16a7 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -904,8 +904,7 @@ static int get_refresh_mask(VP9_COMP *cpi) { (cpi->refresh_golden_frame << cpi->alt_fb_idx); } else { int arf_idx = cpi->alt_fb_idx; - - if ((cpi->pass == 2) && cpi->multi_arf_enabled) { + if (cpi->pass == 2) { const GF_GROUP *const gf_group = &cpi->twopass.gf_group; arf_idx = gf_group->arf_update_idx[gf_group->index]; } diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index be29201e0..7a689767c 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -1514,7 +1514,7 @@ void vp9_update_reference_frames(VP9_COMP *cpi) { } else { /* For non key/golden frames */ if (cpi->refresh_alt_ref_frame) { int arf_idx = cpi->alt_fb_idx; - if ((cpi->pass == 2) && cpi->multi_arf_enabled) { + if (cpi->pass == 2) { const GF_GROUP *const gf_group = &cpi->twopass.gf_group; arf_idx = gf_group->arf_update_idx[gf_group->index]; } diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index f2e89b819..6fb263fd6 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -1282,6 +1282,18 @@ static int calculate_boost_bits(int frame_count, return MAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0); } +// Current limit on maximum number of active arfs in a GF/ARF group. +#define MAX_ACTIVE_ARFS 2 +#define ARF_SLOT1 2 +#define ARF_SLOT2 3 +// This function indirects the choice of buffers for arfs. +// At the moment the values are fixed but this may change as part of +// the integration process with other codec features that swap buffers around. +static void get_arf_buffer_indices(unsigned char *arf_buffer_indices) { + arf_buffer_indices[0] = ARF_SLOT1; + arf_buffer_indices[1] = ARF_SLOT2; +} + static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, double group_error, int gf_arf_bits) { RATE_CONTROL *const rc = &cpi->rc; @@ -1298,10 +1310,13 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, double err_fraction; int mid_boost_bits = 0; int middle_frame_idx; + unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS]; key_frame = cpi->common.frame_type == KEY_FRAME || vp9_is_upper_layer_key_frame(cpi); + get_arf_buffer_indices(arf_buffer_indices); + // For key frames the frame target rate is already set and it // is also the golden frame. if (!key_frame) { @@ -1309,14 +1324,14 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, twopass->gf_group.update_type[0] = OVERLAY_UPDATE; twopass->gf_group.rf_level[0] = INTER_NORMAL; twopass->gf_group.bit_allocation[0] = 0; - twopass->gf_group.arf_update_idx[0] = 2; - twopass->gf_group.arf_ref_idx[0] = 2; + twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0]; + twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0]; } else { twopass->gf_group.update_type[0] = GF_UPDATE; twopass->gf_group.rf_level[0] = GF_ARF_STD; twopass->gf_group.bit_allocation[0] = gf_arf_bits; - twopass->gf_group.arf_update_idx[0] = 2; - twopass->gf_group.arf_ref_idx[0] = 2; + twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0]; + twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0]; } // Step over the golden frame / overlay frame @@ -1331,18 +1346,20 @@ 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) { - // 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); + 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; twopass->gf_group.arf_src_offset[frame_index] = (unsigned char)(rc->baseline_gf_interval - 1); - twopass->gf_group.arf_update_idx[frame_index] = 2; - twopass->gf_group.arf_ref_idx[frame_index] = 2; + twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0]; + twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0]; ++frame_index; if (cpi->multi_arf_enabled) { @@ -1351,8 +1368,8 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, twopass->gf_group.rf_level[frame_index] = GF_ARF_LOW; twopass->gf_group.arf_src_offset[frame_index] = (unsigned char)((rc->baseline_gf_interval >> 1) - 1); - twopass->gf_group.arf_update_idx[frame_index] = 3; - twopass->gf_group.arf_ref_idx[frame_index] = 2; + twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[1]; + twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0]; ++frame_index; } } @@ -1362,6 +1379,7 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, // Allocate bits to the other frames in the group. for (i = 0; i < rc->baseline_gf_interval - 1; ++i) { + int arf_idx = 0; if (EOF == input_stats(twopass, &frame_stats)) break; @@ -1378,17 +1396,11 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, mid_boost_bits += (target_frame_size >> 4); target_frame_size -= (target_frame_size >> 4); - if (frame_index <= middle_frame_idx) { - twopass->gf_group.arf_update_idx[frame_index] = 3; - twopass->gf_group.arf_ref_idx[frame_index] = 3; - } else { - twopass->gf_group.arf_update_idx[frame_index] = 2; - twopass->gf_group.arf_ref_idx[frame_index] = 2; - } - } else { - twopass->gf_group.arf_update_idx[frame_index] = 2; - twopass->gf_group.arf_ref_idx[frame_index] = 2; + if (frame_index <= middle_frame_idx) + arf_idx = 1; } + twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[arf_idx]; + twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[arf_idx]; target_frame_size = clamp(target_frame_size, 0, MIN(max_bits, (int)total_group_bits)); @@ -1400,23 +1412,27 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, ++frame_index; } + // Note: + // We need to configure the frame at the end of the sequence + 1 that will be + // the start frame for the next group. Otherwise prior to the call to + // vp9_rc_get_second_pass_params() the data will be undefined. + twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0]; + twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0]; + if (rc->source_alt_ref_pending) { + twopass->gf_group.update_type[frame_index] = OVERLAY_UPDATE; + twopass->gf_group.rf_level[frame_index] = INTER_NORMAL; + + // Final setup for second arf and its overlay. if (cpi->multi_arf_enabled) { twopass->gf_group.bit_allocation[2] = twopass->gf_group.bit_allocation[middle_frame_idx] + mid_boost_bits; twopass->gf_group.update_type[middle_frame_idx] = OVERLAY_UPDATE; twopass->gf_group.bit_allocation[middle_frame_idx] = 0; } - - // Configure the overlay frame at the end of the sequence that will also - // be the start frame of the next group. The reason for doing this here - // is that on entry to vp9_get_compressed_data() for the overlay - // frame, but before the call to vp9_rc_get_second_pass_params() the - // data will otherwise be undefined. - twopass->gf_group.update_type[frame_index] = OVERLAY_UPDATE; - twopass->gf_group.rf_level[frame_index] = INTER_NORMAL; - twopass->gf_group.arf_update_idx[frame_index] = 2; - twopass->gf_group.arf_ref_idx[frame_index] = 2; + } else { + twopass->gf_group.update_type[frame_index] = GF_UPDATE; + twopass->gf_group.rf_level[frame_index] = GF_ARF_STD; } } diff --git a/vp9/encoder/vp9_firstpass.h b/vp9/encoder/vp9_firstpass.h index 61268ff57..1ee56a3a7 100644 --- a/vp9/encoder/vp9_firstpass.h +++ b/vp9/encoder/vp9_firstpass.h @@ -51,12 +51,12 @@ typedef enum { typedef struct { unsigned char index; - RATE_FACTOR_LEVEL rf_level[MAX_LAG_BUFFERS * 2]; - FRAME_UPDATE_TYPE update_type[MAX_LAG_BUFFERS * 2]; - unsigned char arf_src_offset[MAX_LAG_BUFFERS * 2]; - unsigned char arf_update_idx[MAX_LAG_BUFFERS * 2]; - unsigned char arf_ref_idx[MAX_LAG_BUFFERS * 2]; - int bit_allocation[MAX_LAG_BUFFERS * 2]; + RATE_FACTOR_LEVEL rf_level[(MAX_LAG_BUFFERS * 2) + 1]; + FRAME_UPDATE_TYPE update_type[(MAX_LAG_BUFFERS * 2) + 1]; + unsigned char arf_src_offset[(MAX_LAG_BUFFERS * 2) + 1]; + unsigned char arf_update_idx[(MAX_LAG_BUFFERS * 2) + 1]; + unsigned char arf_ref_idx[(MAX_LAG_BUFFERS * 2) + 1]; + int bit_allocation[(MAX_LAG_BUFFERS * 2) + 1]; } GF_GROUP; typedef struct { diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index c39d90b22..e1109838c 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -1356,6 +1356,8 @@ void vp9_rc_set_gf_max_interval(const VP9EncoderConfig *const oxcf, // Extended interval for genuinely static scenes rc->static_scene_max_gf_interval = oxcf->key_freq >> 1; + if (rc->static_scene_max_gf_interval > (MAX_LAG_BUFFERS * 2)) + rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2; if (is_altref_enabled(oxcf)) { if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1)