Merge "Dual ARF changes: Buffer index selection."

This commit is contained in:
Paul Wilkins
2014-06-25 02:35:56 -07:00
committed by Gerrit Code Review
5 changed files with 58 additions and 41 deletions

View File

@@ -904,8 +904,7 @@ static int get_refresh_mask(VP9_COMP *cpi) {
(cpi->refresh_golden_frame << cpi->alt_fb_idx); (cpi->refresh_golden_frame << cpi->alt_fb_idx);
} else { } else {
int arf_idx = cpi->alt_fb_idx; int arf_idx = cpi->alt_fb_idx;
if (cpi->pass == 2) {
if ((cpi->pass == 2) && cpi->multi_arf_enabled) {
const GF_GROUP *const gf_group = &cpi->twopass.gf_group; const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
arf_idx = gf_group->arf_update_idx[gf_group->index]; arf_idx = gf_group->arf_update_idx[gf_group->index];
} }

View File

@@ -1514,7 +1514,7 @@ void vp9_update_reference_frames(VP9_COMP *cpi) {
} else { /* For non key/golden frames */ } else { /* For non key/golden frames */
if (cpi->refresh_alt_ref_frame) { if (cpi->refresh_alt_ref_frame) {
int arf_idx = cpi->alt_fb_idx; 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; const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
arf_idx = gf_group->arf_update_idx[gf_group->index]; arf_idx = gf_group->arf_update_idx[gf_group->index];
} }

View File

@@ -1282,6 +1282,18 @@ static int calculate_boost_bits(int frame_count,
return MAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0); 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, static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
double group_error, int gf_arf_bits) { double group_error, int gf_arf_bits) {
RATE_CONTROL *const rc = &cpi->rc; 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; double err_fraction;
int mid_boost_bits = 0; int mid_boost_bits = 0;
int middle_frame_idx; int middle_frame_idx;
unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS];
key_frame = cpi->common.frame_type == KEY_FRAME || key_frame = cpi->common.frame_type == KEY_FRAME ||
vp9_is_upper_layer_key_frame(cpi); 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 // For key frames the frame target rate is already set and it
// is also the golden frame. // is also the golden frame.
if (!key_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.update_type[0] = OVERLAY_UPDATE;
twopass->gf_group.rf_level[0] = INTER_NORMAL; twopass->gf_group.rf_level[0] = INTER_NORMAL;
twopass->gf_group.bit_allocation[0] = 0; twopass->gf_group.bit_allocation[0] = 0;
twopass->gf_group.arf_update_idx[0] = 2; twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0];
twopass->gf_group.arf_ref_idx[0] = 2; twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0];
} else { } else {
twopass->gf_group.update_type[0] = GF_UPDATE; twopass->gf_group.update_type[0] = GF_UPDATE;
twopass->gf_group.rf_level[0] = GF_ARF_STD; twopass->gf_group.rf_level[0] = GF_ARF_STD;
twopass->gf_group.bit_allocation[0] = gf_arf_bits; twopass->gf_group.bit_allocation[0] = gf_arf_bits;
twopass->gf_group.arf_update_idx[0] = 2; twopass->gf_group.arf_update_idx[0] = arf_buffer_indices[0];
twopass->gf_group.arf_ref_idx[0] = 2; twopass->gf_group.arf_ref_idx[0] = arf_buffer_indices[0];
} }
// Step over the golden frame / overlay frame // 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. // Store the bits to spend on the ARF if there is one.
if (rc->source_alt_ref_pending) { 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 // A portion of the gf / arf extra bits are set asside for lower level
// boosted frames in the middle of the group. // boosted frames in the middle of the group.
mid_boost_bits = gf_arf_bits >> 5; mid_boost_bits += gf_arf_bits >> 5;
gf_arf_bits -= (gf_arf_bits >> 5); gf_arf_bits -= (gf_arf_bits >> 5);
}
twopass->gf_group.update_type[frame_index] = ARF_UPDATE; twopass->gf_group.update_type[frame_index] = ARF_UPDATE;
twopass->gf_group.rf_level[frame_index] = GF_ARF_STD; twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
twopass->gf_group.bit_allocation[frame_index] = gf_arf_bits; twopass->gf_group.bit_allocation[frame_index] = gf_arf_bits;
twopass->gf_group.arf_src_offset[frame_index] = twopass->gf_group.arf_src_offset[frame_index] =
(unsigned char)(rc->baseline_gf_interval - 1); (unsigned char)(rc->baseline_gf_interval - 1);
twopass->gf_group.arf_update_idx[frame_index] = 2; twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[0];
twopass->gf_group.arf_ref_idx[frame_index] = 2; twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0];
++frame_index; ++frame_index;
if (cpi->multi_arf_enabled) { 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.rf_level[frame_index] = GF_ARF_LOW;
twopass->gf_group.arf_src_offset[frame_index] = twopass->gf_group.arf_src_offset[frame_index] =
(unsigned char)((rc->baseline_gf_interval >> 1) - 1); (unsigned char)((rc->baseline_gf_interval >> 1) - 1);
twopass->gf_group.arf_update_idx[frame_index] = 3; twopass->gf_group.arf_update_idx[frame_index] = arf_buffer_indices[1];
twopass->gf_group.arf_ref_idx[frame_index] = 2; twopass->gf_group.arf_ref_idx[frame_index] = arf_buffer_indices[0];
++frame_index; ++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. // Allocate bits to the other frames in the group.
for (i = 0; i < rc->baseline_gf_interval - 1; ++i) { for (i = 0; i < rc->baseline_gf_interval - 1; ++i) {
int arf_idx = 0;
if (EOF == input_stats(twopass, &frame_stats)) if (EOF == input_stats(twopass, &frame_stats))
break; 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); mid_boost_bits += (target_frame_size >> 4);
target_frame_size -= (target_frame_size >> 4); target_frame_size -= (target_frame_size >> 4);
if (frame_index <= middle_frame_idx) { if (frame_index <= middle_frame_idx)
twopass->gf_group.arf_update_idx[frame_index] = 3; arf_idx = 1;
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;
} }
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, target_frame_size = clamp(target_frame_size, 0,
MIN(max_bits, (int)total_group_bits)); 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; ++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) { 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) { if (cpi->multi_arf_enabled) {
twopass->gf_group.bit_allocation[2] = twopass->gf_group.bit_allocation[2] =
twopass->gf_group.bit_allocation[middle_frame_idx] + mid_boost_bits; twopass->gf_group.bit_allocation[middle_frame_idx] + mid_boost_bits;
twopass->gf_group.update_type[middle_frame_idx] = OVERLAY_UPDATE; twopass->gf_group.update_type[middle_frame_idx] = OVERLAY_UPDATE;
twopass->gf_group.bit_allocation[middle_frame_idx] = 0; twopass->gf_group.bit_allocation[middle_frame_idx] = 0;
} }
} else {
// Configure the overlay frame at the end of the sequence that will also twopass->gf_group.update_type[frame_index] = GF_UPDATE;
// be the start frame of the next group. The reason for doing this here twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
// 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;
} }
} }

View File

@@ -51,12 +51,12 @@ typedef enum {
typedef struct { typedef struct {
unsigned char index; unsigned char index;
RATE_FACTOR_LEVEL rf_level[MAX_LAG_BUFFERS * 2]; RATE_FACTOR_LEVEL rf_level[(MAX_LAG_BUFFERS * 2) + 1];
FRAME_UPDATE_TYPE update_type[MAX_LAG_BUFFERS * 2]; FRAME_UPDATE_TYPE update_type[(MAX_LAG_BUFFERS * 2) + 1];
unsigned char arf_src_offset[MAX_LAG_BUFFERS * 2]; unsigned char arf_src_offset[(MAX_LAG_BUFFERS * 2) + 1];
unsigned char arf_update_idx[MAX_LAG_BUFFERS * 2]; unsigned char arf_update_idx[(MAX_LAG_BUFFERS * 2) + 1];
unsigned char arf_ref_idx[MAX_LAG_BUFFERS * 2]; unsigned char arf_ref_idx[(MAX_LAG_BUFFERS * 2) + 1];
int bit_allocation[MAX_LAG_BUFFERS * 2]; int bit_allocation[(MAX_LAG_BUFFERS * 2) + 1];
} GF_GROUP; } GF_GROUP;
typedef struct { typedef struct {

View File

@@ -1356,6 +1356,8 @@ void vp9_rc_set_gf_max_interval(const VP9EncoderConfig *const oxcf,
// Extended interval for genuinely static scenes // Extended interval for genuinely static scenes
rc->static_scene_max_gf_interval = oxcf->key_freq >> 1; 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 (is_altref_enabled(oxcf)) {
if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1) if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1)