summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_firstpass.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder/vp9_firstpass.c')
-rw-r--r--vp9/encoder/vp9_firstpass.c148
1 files changed, 53 insertions, 95 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 43ae7c1f4..905885f1f 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -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,116 +1729,52 @@ 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);
-
- 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;
- }
+ // 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);
- // 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;
-
- // If this is an arf update we want to remove the score for the overlay
- // frame at the end which will usually be very cheap to code.
- // The overlay frame has already, in effect, been coded so we want to spread
- // the remaining bits among the other frames.
- // For normal GFs remove the score for the GF itself unless this is
- // also a key frame in which case it has already been accounted for.
- if (rc->source_alt_ref_pending) {
- twopass->gf_group_error_left = (int64_t)(gf_group_err - mod_frame_err);
- } else if (cpi->common.frame_type != KEY_FRAME) {
- twopass->gf_group_error_left = (int64_t)(gf_group_err
- - gf_first_frame_err);
- } else {
- 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;
- }
- }
+ // Adjust KF group bits and error remaining.
+ twopass->kf_group_error_left -= (int64_t)gf_group_err;
+
+ // If this is an arf update we want to remove the score for the overlay
+ // frame at the end which will usually be very cheap to code.
+ // The overlay frame has already, in effect, been coded so we want to spread
+ // the remaining bits among the other frames.
+ // For normal GFs remove the score for the GF itself unless this is
+ // also a key frame in which case it has already been accounted for.
+ if (rc->source_alt_ref_pending) {
+ twopass->gf_group_error_left = (int64_t)(gf_group_err - mod_frame_err);
+ } else if (cpi->common.frame_type != KEY_FRAME) {
+ twopass->gf_group_error_left = (int64_t)(gf_group_err
+ - gf_first_frame_err);
+ } else {
+ twopass->gf_group_error_left = (int64_t)gf_group_err;
}
// Calculate a section intra ratio used in setting max loop filter.