Commit ade9693a authored by paulwilkins's avatar paulwilkins
Browse files

Fix issues with mixed ARF and GF groups.

This patch addresses two issues that can occur when the
encoder chooses to use a mixture of ARF and GF groups.

The first issue relates to a failure to reset the "ARF active" flag
correctly when transitioning from coding ARF groups to coding
GF groups. This caused some golden frames to be  encoded
with an incorrect bit rate target as if they were ARF overlay frames.

The second issue relates to the encoding of a single short GF group
just before a key frame.  Where the last group before a key frame
is an ARF group we expect the final frame before the key frame  to
be an low data rate overlay frame. However, when the last  group
is a GF group, the final frame before the key frame should be a normal
frame with a normal bit allocation. This issue had the potential to cause
a single poorly coded frame just before a key frame. If that key frame
were a forced key frame rather than a real scene cut, this might cause
pulsing.

Change-Id: Idf1eb5eaf63a231495a74de7899236e1ead9fb00
parent 976f7f42
......@@ -2795,7 +2795,7 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
recon_err = vp9_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
if (cpi->twopass.total_left_stats.coded_error != 0.0)
fprintf(f, "%10u %dx%d %10d %10d %10d %10d"
fprintf(f, "%10u %dx%d %d %d %10d %10d %10d %10d"
"%10"PRId64" %10"PRId64" %10"PRId64" %10"PRId64" %10d "
"%7.2lf %7.2lf %7.2lf %7.2lf %7.2lf"
"%6d %6d %5d %5d %5d "
......@@ -2803,6 +2803,8 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
"%10lf %8u %10"PRId64" %10d %10d\n",
cpi->common.current_video_frame,
cm->width, cm->height,
cpi->rc.source_alt_ref_pending,
cpi->rc.source_alt_ref_active,
cpi->rc.this_frame_target,
cpi->rc.projected_frame_size,
cpi->rc.projected_frame_size / cpi->common.MBs,
......
......@@ -1696,7 +1696,7 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
mid_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
// 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 - rc->source_alt_ref_pending; ++i) {
int arf_idx = 0;
if (EOF == input_stats(twopass, &frame_stats))
break;
......@@ -1934,8 +1934,26 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Was the group length constrained by the requirement for a new KF?
rc->constrained_gf_group = (i >= rc->frames_to_key) ? 1 : 0;
// Should we use the alternate reference frame.
if (allow_alt_ref &&
(i < cpi->oxcf.lag_in_frames) &&
(i >= rc->min_gf_interval)) {
// Calculate the boost for alt ref.
rc->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost,
&b_boost);
rc->source_alt_ref_pending = 1;
// Test to see if multi arf is appropriate.
cpi->multi_arf_enabled =
(cpi->multi_arf_allowed && (rc->baseline_gf_interval >= 6) &&
(zero_motion_accumulator < 0.995)) ? 1 : 0;
} else {
rc->gfu_boost = MAX((int)boost_score, MIN_ARF_GF_BOOST);
rc->source_alt_ref_pending = 0;
}
// Set the interval until the next gf.
if (is_key_frame || rc->source_alt_ref_active)
if (is_key_frame || rc->source_alt_ref_pending)
rc->baseline_gf_interval = i - 1;
else
rc->baseline_gf_interval = i;
......@@ -1960,24 +1978,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
// Should we use the alternate reference frame.
if (allow_alt_ref &&
(i < cpi->oxcf.lag_in_frames) &&
(i >= rc->min_gf_interval)) {
// Calculate the boost for alt ref.
rc->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost,
&b_boost);
rc->source_alt_ref_pending = 1;
// Test to see if multi arf is appropriate.
cpi->multi_arf_enabled =
(cpi->multi_arf_allowed && (rc->baseline_gf_interval >= 6) &&
(zero_motion_accumulator < 0.995)) ? 1 : 0;
} else {
rc->gfu_boost = MAX((int)boost_score, MIN_ARF_GF_BOOST);
rc->source_alt_ref_pending = 0;
}
// Reset the file position.
reset_fpf_position(twopass, start_pos);
......
......@@ -1207,11 +1207,9 @@ static void update_golden_frame_stats(VP9_COMP *cpi) {
// this frame refreshes means next frames don't unless specified by user
rc->frames_since_golden = 0;
if (cpi->oxcf.pass == 2) {
if (!rc->source_alt_ref_pending &&
cpi->twopass.gf_group.rf_level[0] == GF_ARF_STD)
rc->source_alt_ref_active = 0;
} else if (!rc->source_alt_ref_pending) {
// If we are not using alt ref in the up and coming group clear the arf
// active flag.
if (!rc->source_alt_ref_pending) {
rc->source_alt_ref_active = 0;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment