Commit 2e430cba authored by Paul Wilkins's avatar Paul Wilkins
Browse files

Experiment for mid group second arf.

This patch implements a mechanism for inserting a second
arf at the mid position of arf groups.

It is currently disabled by default using the flag multi_arf_enabled.

Results are currently down somewhat in initial testing if
multi-arf is enabled. Most of the loss is attributable to the
fact that code to preserve the previous golden frame
(in the arf buffer) in cases where we are coding an overlay
frame, is currently disabled in the multi-arf case.

Change-Id: I1d777318ca09f147db2e8c86d7315fe86168c865
parent 2518e33b
...@@ -895,8 +895,8 @@ static int get_refresh_mask(VP9_COMP *cpi) { ...@@ -895,8 +895,8 @@ static int get_refresh_mask(VP9_COMP *cpi) {
if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame && if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
!cpi->refresh_alt_ref_frame) { !cpi->refresh_alt_ref_frame) {
#else #else
if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame && if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
!cpi->use_svc) { cpi->rc.is_src_frame_alt_ref && !cpi->use_svc) {
#endif #endif
// Preserve the previously existing golden frame and update the frame in // Preserve the previously existing golden frame and update the frame in
// the alt ref slot instead. This is highly specific to the use of // the alt ref slot instead. This is highly specific to the use of
...@@ -919,6 +919,11 @@ static int get_refresh_mask(VP9_COMP *cpi) { ...@@ -919,6 +919,11 @@ static int get_refresh_mask(VP9_COMP *cpi) {
cpi->arf_buffer_idx[sn]; cpi->arf_buffer_idx[sn];
} }
#endif #endif
if ((cpi->pass == 2) && cpi->multi_arf_enabled) {
GF_GROUP *gf_group = &cpi->twopass.gf_group;
arf_idx = gf_group->arf_update_idx[gf_group->index];
}
return (cpi->refresh_last_frame << cpi->lst_fb_idx) | return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
(cpi->refresh_golden_frame << cpi->gld_fb_idx) | (cpi->refresh_golden_frame << cpi->gld_fb_idx) |
(cpi->refresh_alt_ref_frame << arf_idx); (cpi->refresh_alt_ref_frame << arf_idx);
......
...@@ -766,6 +766,10 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) { ...@@ -766,6 +766,10 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
cpi->refresh_alt_ref_frame = 0; cpi->refresh_alt_ref_frame = 0;
if (cpi->pass == 2)
cpi->multi_arf_enabled = 0;
else
cpi->multi_arf_enabled = 0;
#if CONFIG_MULTIPLE_ARF #if CONFIG_MULTIPLE_ARF
// Turn multiple ARF usage on/off. This is a quick hack for the initial test // Turn multiple ARF usage on/off. This is a quick hack for the initial test
// version. It should eventually be set via the codec API. // version. It should eventually be set via the codec API.
...@@ -1492,8 +1496,8 @@ void vp9_update_reference_frames(VP9_COMP *cpi) { ...@@ -1492,8 +1496,8 @@ void vp9_update_reference_frames(VP9_COMP *cpi) {
else if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame && else if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
!cpi->refresh_alt_ref_frame) { !cpi->refresh_alt_ref_frame) {
#else #else
else if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame && else if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
!cpi->use_svc) { cpi->rc.is_src_frame_alt_ref && !cpi->use_svc) {
#endif #endif
/* Preserve the previously existing golden frame and update the frame in /* Preserve the previously existing golden frame and update the frame in
* the alt ref slot instead. This is highly specific to the current use of * the alt ref slot instead. This is highly specific to the current use of
...@@ -1520,6 +1524,11 @@ void vp9_update_reference_frames(VP9_COMP *cpi) { ...@@ -1520,6 +1524,11 @@ void vp9_update_reference_frames(VP9_COMP *cpi) {
arf_idx = cpi->arf_buffer_idx[cpi->sequence_number + 1]; arf_idx = cpi->arf_buffer_idx[cpi->sequence_number + 1];
} }
#endif #endif
if ((cpi->pass == 2) && cpi->multi_arf_enabled) {
GF_GROUP *gf_group = &cpi->twopass.gf_group;
arf_idx = gf_group->arf_update_idx[gf_group->index];
}
ref_cnt_fb(cm->frame_bufs, ref_cnt_fb(cm->frame_bufs,
&cm->ref_frame_map[arf_idx], cm->new_fb_idx); &cm->ref_frame_map[arf_idx], cm->new_fb_idx);
} }
...@@ -2397,6 +2406,66 @@ void adjust_frame_rate(VP9_COMP *cpi) { ...@@ -2397,6 +2406,66 @@ void adjust_frame_rate(VP9_COMP *cpi) {
cpi->last_end_time_stamp_seen = cpi->source->ts_end; cpi->last_end_time_stamp_seen = cpi->source->ts_end;
} }
// Returns 0 if this is not an alt ref else the offset of the source frame
// used as the arf midpoint.
static int get_arf_src_index(VP9_COMP *cpi) {
RATE_CONTROL *const rc = &cpi->rc;
int arf_src_index = 0;
if (is_altref_enabled(&cpi->oxcf)) {
if (cpi->pass == 2) {
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
if (gf_group->update_type[gf_group->index] == ARF_UPDATE) {
arf_src_index = gf_group->arf_src_offset[gf_group->index];
}
} else if (rc->source_alt_ref_pending) {
arf_src_index = rc->frames_till_gf_update_due;
}
}
return arf_src_index;
}
static void is_src_altref(VP9_COMP *cpi) {
RATE_CONTROL *const rc = &cpi->rc;
#if CONFIG_MULTIPLE_ARF
int i;
// Is this frame the ARF overlay.
rc->is_src_frame_alt_ref = 0;
for (i = 0; i < cpi->arf_buffered; ++i) {
if (cpi->source == cpi->alt_ref_source[i]) {
rc->is_src_frame_alt_ref = 1;
cpi->refresh_golden_frame = 1;
break;
}
}
#else
if (cpi->pass == 2) {
GF_GROUP *gf_group = &cpi->twopass.gf_group;
rc->is_src_frame_alt_ref =
(gf_group->update_type[gf_group->index] == OVERLAY_UPDATE);
} else {
rc->is_src_frame_alt_ref = cpi->alt_ref_source &&
(cpi->source == cpi->alt_ref_source);
}
#endif
if (rc->is_src_frame_alt_ref) {
// Current frame is an ARF overlay frame.
#if CONFIG_MULTIPLE_ARF
cpi->alt_ref_source[i] = NULL;
#else
cpi->alt_ref_source = NULL;
#endif
// Don't refresh the last buffer for an ARF overlay frame. It will
// become the GF so preserve last as an alternative prediction option.
cpi->refresh_last_frame = 0;
}
#if CONFIG_MULTIPLE_ARF
++cpi->next_frame_in_order;
#endif
}
int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
size_t *size, uint8_t *dest, size_t *size, uint8_t *dest,
int64_t *time_stamp, int64_t *time_end, int flush) { int64_t *time_stamp, int64_t *time_end, int flush) {
...@@ -2406,6 +2475,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2406,6 +2475,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
struct vpx_usec_timer cmptimer; struct vpx_usec_timer cmptimer;
YV12_BUFFER_CONFIG *force_src_buffer = NULL; YV12_BUFFER_CONFIG *force_src_buffer = NULL;
MV_REFERENCE_FRAME ref_frame; MV_REFERENCE_FRAME ref_frame;
int arf_src_index;
if (!cpi) if (!cpi)
return -1; return -1;
...@@ -2428,24 +2498,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2428,24 +2498,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
cpi->refresh_golden_frame = 0; cpi->refresh_golden_frame = 0;
cpi->refresh_alt_ref_frame = 0; cpi->refresh_alt_ref_frame = 0;
// Should we code an alternate reference frame. // Should we encode an arf frame.
if (is_altref_enabled(&cpi->oxcf) && rc->source_alt_ref_pending) { arf_src_index = get_arf_src_index(cpi);
int frames_to_arf; if (arf_src_index) {
assert(arf_src_index <= rc->frames_to_key);
#if CONFIG_MULTIPLE_ARF
assert(!cpi->multi_arf_enabled ||
cpi->frame_coding_order[cpi->sequence_number] < 0);
if (cpi->multi_arf_enabled && (cpi->pass == 2))
frames_to_arf = (-cpi->frame_coding_order[cpi->sequence_number])
- cpi->next_frame_in_order;
else
#endif
frames_to_arf = rc->frames_till_gf_update_due;
assert(frames_to_arf <= rc->frames_to_key);
if ((cpi->source = vp9_lookahead_peek(cpi->lookahead, frames_to_arf))) { if ((cpi->source = vp9_lookahead_peek(cpi->lookahead, arf_src_index))) {
#if CONFIG_MULTIPLE_ARF #if CONFIG_MULTIPLE_ARF
cpi->alt_ref_source[cpi->arf_buffered] = cpi->source; cpi->alt_ref_source[cpi->arf_buffered] = cpi->source;
#else #else
...@@ -2455,8 +2513,8 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2455,8 +2513,8 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if (cpi->oxcf.arnr_max_frames > 0) { if (cpi->oxcf.arnr_max_frames > 0) {
// Produce the filtered ARF frame. // Produce the filtered ARF frame.
// TODO(agrange) merge these two functions. // TODO(agrange) merge these two functions.
vp9_configure_arnr_filter(cpi, frames_to_arf, rc->gfu_boost); vp9_configure_arnr_filter(cpi, arf_src_index, rc->gfu_boost);
vp9_temporal_filter_prepare(cpi, frames_to_arf); vp9_temporal_filter_prepare(cpi, arf_src_index);
vp9_extend_frame_borders(&cpi->alt_ref_buffer); vp9_extend_frame_borders(&cpi->alt_ref_buffer);
force_src_buffer = &cpi->alt_ref_buffer; force_src_buffer = &cpi->alt_ref_buffer;
} }
...@@ -2466,59 +2524,28 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2466,59 +2524,28 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
cpi->refresh_golden_frame = 0; cpi->refresh_golden_frame = 0;
cpi->refresh_last_frame = 0; cpi->refresh_last_frame = 0;
rc->is_src_frame_alt_ref = 0; rc->is_src_frame_alt_ref = 0;
rc->source_alt_ref_pending = 0;
#if CONFIG_MULTIPLE_ARF
if (!cpi->multi_arf_enabled)
#endif
rc->source_alt_ref_pending = 0;
} else { } else {
rc->source_alt_ref_pending = 0; rc->source_alt_ref_pending = 0;
} }
} }
if (!cpi->source) { if (!cpi->source) {
#if CONFIG_MULTIPLE_ARF
int i;
#endif
// Get last frame source. // Get last frame source.
if (cm->current_video_frame > 0) { if (cm->current_video_frame > 0) {
if ((cpi->last_source = vp9_lookahead_peek(cpi->lookahead, -1)) == NULL) if ((cpi->last_source = vp9_lookahead_peek(cpi->lookahead, -1)) == NULL)
return -1; return -1;
} }
// Read in the source frame.
if ((cpi->source = vp9_lookahead_pop(cpi->lookahead, flush))) { if ((cpi->source = vp9_lookahead_pop(cpi->lookahead, flush))) {
cm->show_frame = 1; cm->show_frame = 1;
cm->intra_only = 0; cm->intra_only = 0;
#if CONFIG_MULTIPLE_ARF // Check to see if the frame to be encoded is an overlay
// Is this frame the ARF overlay. // for a previous arf frame and if so configure it as such.
rc->is_src_frame_alt_ref = 0; if (cpi->pass == 0)
for (i = 0; i < cpi->arf_buffered; ++i) { is_src_altref(cpi);
if (cpi->source == cpi->alt_ref_source[i]) {
rc->is_src_frame_alt_ref = 1;
cpi->refresh_golden_frame = 1;
break;
}
}
#else
rc->is_src_frame_alt_ref = cpi->alt_ref_source &&
(cpi->source == cpi->alt_ref_source);
#endif
if (rc->is_src_frame_alt_ref) {
// Current frame is an ARF overlay frame.
#if CONFIG_MULTIPLE_ARF
cpi->alt_ref_source[i] = NULL;
#else
cpi->alt_ref_source = NULL;
#endif
// Don't refresh the last buffer for an ARF overlay frame. It will
// become the GF so preserve last as an alternative prediction option.
cpi->refresh_last_frame = 0;
}
#if CONFIG_MULTIPLE_ARF
++cpi->next_frame_in_order;
#endif
} }
} }
...@@ -2587,6 +2614,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, ...@@ -2587,6 +2614,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
cpi->alt_fb_idx = cpi->arf_buffer_idx[cpi->sequence_number]; cpi->alt_fb_idx = cpi->arf_buffer_idx[cpi->sequence_number];
} }
#endif #endif
if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) &&
(cpi->pass == 2)) {
const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
cpi->alt_fb_idx = gf_group->arf_ref_idx[gf_group->index];
}
cpi->frame_flags = *frame_flags; cpi->frame_flags = *frame_flags;
......
...@@ -430,9 +430,9 @@ typedef struct VP9_COMP { ...@@ -430,9 +430,9 @@ typedef struct VP9_COMP {
PC_TREE *pc_root; PC_TREE *pc_root;
int partition_cost[PARTITION_CONTEXTS][PARTITION_TYPES]; int partition_cost[PARTITION_CONTEXTS][PARTITION_TYPES];
int multi_arf_enabled;
#if CONFIG_MULTIPLE_ARF #if CONFIG_MULTIPLE_ARF
// ARF tracking variables. // ARF tracking variables.
int multi_arf_enabled;
unsigned int frame_coding_order_period; unsigned int frame_coding_order_period;
unsigned int new_frame_coding_order_period; unsigned int new_frame_coding_order_period;
int frame_coding_order[MAX_LAG_BUFFERS * 2]; int frame_coding_order[MAX_LAG_BUFFERS * 2];
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "vp9/encoder/vp9_firstpass.h" #include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_mcomp.h" #include "vp9/encoder/vp9_mcomp.h"
#include "vp9/encoder/vp9_quantize.h" #include "vp9/encoder/vp9_quantize.h"
#include "vp9/encoder/vp9_ratectrl.h"
#include "vp9/encoder/vp9_rdopt.h" #include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_variance.h" #include "vp9/encoder/vp9_variance.h"
...@@ -1435,39 +1434,76 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, ...@@ -1435,39 +1434,76 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
TWO_PASS *twopass = &cpi->twopass; TWO_PASS *twopass = &cpi->twopass;
FIRSTPASS_STATS frame_stats; FIRSTPASS_STATS frame_stats;
int i; int i;
int group_frame_index = 1; int frame_index = 1;
int target_frame_size; int target_frame_size;
int key_frame; int key_frame;
const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf); const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
int64_t total_group_bits = gf_group_bits; int64_t total_group_bits = gf_group_bits;
double modified_err = 0.0; double modified_err = 0.0;
double err_fraction; double err_fraction;
int mid_boost_bits = 0;
int middle_frame_idx;
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);
// 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.
// NOTE: We dont bother to check for the special case of ARF overlay
// frames here, as there is clamping code for this in the function
// vp9_rc_clamp_pframe_target_size(), which applies to one and two pass
// encodes.
if (!key_frame) { if (!key_frame) {
twopass->gf_group_bit_allocation[0] = gf_arf_bits; if (rc->source_alt_ref_active) {
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;
} 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;
}
// Step over the golden frame / overlay frame // Step over the golden frame / overlay frame
if (EOF == input_stats(twopass, &frame_stats)) if (EOF == input_stats(twopass, &frame_stats))
return; return;
} }
// Deduct the boost bits for arf (or gf if it is not a key frame)
// from the group total.
if (rc->source_alt_ref_pending || !key_frame)
total_group_bits -= gf_arf_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) {
twopass->gf_group_bit_allocation[group_frame_index++] = gf_arf_bits; // 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] =
rc->baseline_gf_interval - 1;
twopass->gf_group.arf_update_idx[frame_index] = 2;
twopass->gf_group.arf_ref_idx[frame_index] = 2;
++frame_index;
if (cpi->multi_arf_enabled) {
// Set aside a slot for a level 1 arf.
twopass->gf_group.update_type[frame_index] = ARF_UPDATE;
twopass->gf_group.rf_level[frame_index] = GF_ARF_LOW;
twopass->gf_group.arf_src_offset[frame_index] =
((rc->baseline_gf_interval - 1) >> 1);
twopass->gf_group.arf_update_idx[frame_index] = 3;
twopass->gf_group.arf_ref_idx[frame_index] = 2;
++frame_index;
}
} }
// Deduct the boost bits for arf or gf if it is not a key frame. // Define middle frame
if (rc->source_alt_ref_pending || !key_frame) middle_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
total_group_bits -= gf_arf_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) {
...@@ -1482,10 +1518,35 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits, ...@@ -1482,10 +1518,35 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
err_fraction = 0.0; err_fraction = 0.0;
target_frame_size = (int)((double)total_group_bits * err_fraction); target_frame_size = (int)((double)total_group_bits * err_fraction);
if (rc->source_alt_ref_pending && cpi->multi_arf_enabled) {
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;
}
}
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));
twopass->gf_group_bit_allocation[group_frame_index++] = target_frame_size; twopass->gf_group.update_type[frame_index] = LF_UPDATE;
twopass->gf_group.rf_level[frame_index] = INTER_NORMAL;
twopass->gf_group.bit_allocation[frame_index] = target_frame_size;
++frame_index;
}
if (rc->source_alt_ref_pending && 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;
} }
} }
...@@ -1528,8 +1589,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { ...@@ -1528,8 +1589,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Reset the GF group data structures unless this is a key // Reset the GF group data structures unless this is a key
// frame in which case it will already have been done. // frame in which case it will already have been done.
if (cpi->common.frame_type != KEY_FRAME) { if (cpi->common.frame_type != KEY_FRAME) {
twopass->gf_group_index = 0; vp9_zero(twopass->gf_group);
vp9_zero(twopass->gf_group_bit_allocation);
} }
vp9_clear_system_state(); vp9_clear_system_state();
...@@ -1669,6 +1729,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { ...@@ -1669,6 +1729,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
else else
rc->baseline_gf_interval = i; rc->baseline_gf_interval = i;
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
// Should we use the alternate reference frame. // Should we use the alternate reference frame.
if (allow_alt_ref && if (allow_alt_ref &&
(i < cpi->oxcf.lag_in_frames) && (i < cpi->oxcf.lag_in_frames) &&
...@@ -1886,8 +1948,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { ...@@ -1886,8 +1948,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
cpi->common.frame_type = KEY_FRAME; cpi->common.frame_type = KEY_FRAME;
// Reset the GF group data structures. // Reset the GF group data structures.
twopass->gf_group_index = 0; vp9_zero(twopass->gf_group);
vp9_zero(twopass->gf_group_bit_allocation);
// Is this a forced key frame by interval. // Is this a forced key frame by interval.
rc->this_key_frame_forced = rc->next_key_frame_forced; rc->this_key_frame_forced = rc->next_key_frame_forced;
...@@ -2078,7 +2139,9 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { ...@@ -2078,7 +2139,9 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
twopass->kf_group_bits -= kf_bits; twopass->kf_group_bits -= kf_bits;
// Save the bits to spend on the key frame. // Save the bits to spend on the key frame.
twopass->gf_group_bit_allocation[0] = kf_bits; twopass->gf_group.bit_allocation[0] = kf_bits;
twopass->gf_group.update_type[0] = KF_UPDATE;
twopass->gf_group.rf_level[0] = KF_STD;
// Note the total error score of the kf group minus the key frame itself. // Note the total error score of the kf group minus the key frame itself.
twopass->kf_group_error_left = (int)(kf_group_err - kf_mod_err); twopass->kf_group_error_left = (int)(kf_group_err - kf_mod_err);
...@@ -2106,6 +2169,44 @@ void vbr_rate_correction(int * this_frame_target, ...@@ -2106,6 +2169,44 @@ void vbr_rate_correction(int * this_frame_target,
} }
} }
// Define the reference buffers that will be updated post encode.
void configure_buffer_updates(VP9_COMP *cpi) {
TWO_PASS *const twopass = &cpi->twopass;
cpi->rc.is_src_frame_alt_ref = 0;
switch (twopass->gf_group.update_type[twopass->gf_group.index]) {
case KF_UPDATE:
cpi->refresh_last_frame = 1;
cpi->refresh_golden_frame = 1;
cpi->refresh_alt_ref_frame = 1;
break;
case LF_UPDATE:
cpi->refresh_last_frame = 1;
cpi->refresh_golden_frame = 0;
cpi->refresh_alt_ref_frame = 0;
break;
case GF_UPDATE:
cpi->refresh_last_frame = 1;
cpi->refresh_golden_frame = 1;
cpi->refresh_alt_ref_frame = 0;
break;
case OVERLAY_UPDATE:
cpi->refresh_last_frame = 0;
cpi->refresh_golden_frame = 1;
cpi->refresh_alt_ref_frame = 0;
cpi->rc.is_src_frame_alt_ref = 1;
break;
case ARF_UPDATE:
cpi->refresh_last_frame = 0;
cpi->refresh_golden_frame = 0;
cpi->refresh_alt_ref_frame = 1;
break;
default:
assert(0);
}
}
void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common; VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc; RATE_CONTROL *const rc = &cpi->rc;
...@@ -2130,14 +2231,12 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { ...@@ -2130,14 +2231,12 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
if (!twopass->stats_in) if (!twopass->stats_in)
return; return;