Commit d677ea1f authored by Paul Wilkins's avatar Paul Wilkins
Browse files

Further two pass clean up.

The variation in boost calculation for gf and arf groups
is not significant enough to justify the extra complexity.
Also removed some other spurious code that no longer
has much material impact.

The handling of the rare case, where the boost bits
number is less than the number of bits a that would
be allocated if a frame was not boosted, will be dealt
with in a subsequent patch.

This change actually helps on all sets a little by
~0.1% - 0.2% with slightly bigger gains on SSIM.

Change-Id: Id42c1ac22a80a8c4993cfa0e51bc733eb9ed4f75
parent eecc750b
......@@ -1469,6 +1469,28 @@ static int64_t calculate_total_gf_group_bits(VP9_COMP *cpi,
return total_group_bits;
}
// Calculate the number bits extra to assign to boosted frames in a group.
static int calculate_boost_bits(int frame_count,
int boost, int64_t total_group_bits) {
int allocation_chunks;
if (!boost)
return 0;
allocation_chunks = (frame_count * 100) + boost;
// Prevent overflow.
if (boost > 1023) {
int divisor = boost >> 10;
boost /= divisor;
allocation_chunks /= divisor;
}
// Calculate the number of extra bits for use in the boosted frame or frames.
return MAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0);
}
// Analyse and define a gf/arf group.
static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
RATE_CONTROL *const rc = &cpi->rc;
......@@ -1707,84 +1729,36 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
}
#endif
#endif
// Reset the file position.
reset_fpf_position(twopass, start_pos);
// Calculate the bits to be allocated to the gf/arf group as a whole
twopass->gf_group_bits = calculate_total_gf_group_bits(cpi, gf_group_err);
// Reset the file position.
reset_fpf_position(twopass, start_pos);
// Assign bits to the arf or gf.
for (i = 0; i <= (rc->source_alt_ref_pending &&
cpi->common.frame_type != KEY_FRAME); ++i) {
int allocation_chunks;
// Calculate the extra bits to be used for boosted frame(s)
{
int q = rc->last_q[INTER_FRAME];
int gf_bits;
int boost = (rc->gfu_boost * gfboost_qadjust(q)) / 100;
// Set max and minimum boost and hence minimum allocation.
boost = clamp(boost, 125, (rc->baseline_gf_interval + 1) * 200);
if (rc->source_alt_ref_pending && i == 0)
allocation_chunks = ((rc->baseline_gf_interval + 1) * 100) + boost;
else
allocation_chunks = (rc->baseline_gf_interval * 100) + (boost - 100);
// Prevent overflow.
if (boost > 1023) {
int divisor = boost >> 10;
boost /= divisor;
allocation_chunks /= divisor;
}
// Calculate the number of bits to be spent on the gf or arf based on
// the boost number.
gf_bits = (int)((double)boost * (twopass->gf_group_bits /
(double)allocation_chunks));
// If the frame that is to be boosted is simpler than the average for
// the gf/arf group then use an alternative calculation
// based on the error score of the frame itself.
if (rc->baseline_gf_interval < 1 ||
mod_frame_err < gf_group_err / (double)rc->baseline_gf_interval) {
double alt_gf_grp_bits = (double)twopass->kf_group_bits *
(mod_frame_err * (double)rc->baseline_gf_interval) /
DOUBLE_DIVIDE_CHECK(twopass->kf_group_error_left);
// Calculate the extra bits to be used for boosted frame(s)
twopass->gf_bits = calculate_boost_bits(rc->baseline_gf_interval,
boost, twopass->gf_group_bits);
int alt_gf_bits = (int)((double)boost * (alt_gf_grp_bits /
(double)allocation_chunks));
if (gf_bits > alt_gf_bits)
gf_bits = alt_gf_bits;
} else {
// If it is harder than other frames in the group make sure it at
// least receives an allocation in keeping with its relative error
// score, otherwise it may be worse off than an "un-boosted" frame.
int alt_gf_bits = (int)((double)twopass->kf_group_bits *
mod_frame_err /
DOUBLE_DIVIDE_CHECK(twopass->kf_group_error_left));
if (alt_gf_bits > gf_bits)
gf_bits = alt_gf_bits;
}
// Don't allow a negative value for gf_bits.
if (gf_bits < 0)
gf_bits = 0;
if (i == 0) {
twopass->gf_bits = gf_bits;
}
if (i == 1 ||
(!rc->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME &&
!vp9_is_upper_layer_key_frame(cpi))) {
// Calculate the per frame bit target for this frame.
vp9_rc_set_frame_target(cpi, gf_bits);
// For key frames the frame target rate is set already.
// 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 (cpi->common.frame_type != KEY_FRAME &&
!vp9_is_upper_layer_key_frame(cpi)) {
vp9_rc_set_frame_target(cpi, twopass->gf_bits);
}
}
{
// Adjust KF group bits and error remaining.
twopass->kf_group_error_left -= (int64_t)gf_group_err;
......@@ -1803,22 +1777,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
twopass->gf_group_error_left = (int64_t)gf_group_err;
}
// This condition could fail if there are two kfs very close together
// despite MIN_GF_INTERVAL and would cause a divide by 0 in the
// calculation of alt_extra_bits.
if (rc->baseline_gf_interval >= 3) {
const int boost = rc->source_alt_ref_pending ? b_boost : rc->gfu_boost;
if (boost >= 150) {
const int pct_extra = MIN(20, (boost - 100) / 50);
const int alt_extra_bits = (int)((
MAX(twopass->gf_group_bits - twopass->gf_bits, 0) *
pct_extra) / 100);
twopass->gf_group_bits -= alt_extra_bits;
}
}
}
// Calculate a section intra ratio used in setting max loop filter.
if (cpi->common.frame_type != KEY_FRAME) {
calculate_section_intra_ratio(twopass, start_pos, rc->baseline_gf_interval);
......
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