Dual ARF changes: Buffer index selection.
Add indirection to the section of buffer indices. This is to help simplify things in the future if we have other codec features that switch indices. Limit the max GF interval for static sections to fit the gf_group structures. Change-Id: I38310daaf23fd906004c0e8ee3e99e15570f84cb
This commit is contained in:
parent
11b34f1e19
commit
60244ec1f4
@ -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];
|
||||||
}
|
}
|
||||||
|
@ -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];
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
// A portion of the gf / arf extra bits are set asside for lower level
|
if (cpi->multi_arf_enabled) {
|
||||||
// boosted frames in the middle of the group.
|
// A portion of the gf / arf extra bits are set asside for lower level
|
||||||
mid_boost_bits = gf_arf_bits >> 5;
|
// boosted frames in the middle of the group.
|
||||||
gf_arf_bits -= (gf_arf_bits >> 5);
|
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.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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user