ref: 60244ec1f4240f9f83c8861355cd23aa76ce3133
parent: 11b34f1e19528831c2e970c4af5a6670e6608177
author: Paul Wilkins <[email protected]>
date: Mon Jun 23 09:07:24 EDT 2014
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
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -904,8 +904,7 @@
(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];
}
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -1514,7 +1514,7 @@
} 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];
}
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1282,6 +1282,18 @@
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 @@
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 @@
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,10 +1346,12 @@
// 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;
@@ -1341,8 +1358,8 @@
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 @@
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 @@
// 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 @@
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,7 +1412,18 @@
++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;
@@ -1407,16 +1430,9 @@
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;
}
}
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -51,12 +51,12 @@
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 {
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1356,6 +1356,8 @@
// 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)