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.c321
1 files changed, 273 insertions, 48 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 70f9e3153..1dd2a7dd8 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -317,15 +317,20 @@ static double simple_weight(YV12_BUFFER_CONFIG *source) {
}
-// This function returns the current per frame maximum bitrate target
+// This function returns the current per frame maximum bitrate target.
static int frame_max_bits(VP9_COMP *cpi) {
- // Max allocation for a single frame based on the max section guidelines passed in and how many bits are left
+ // Max allocation for a single frame based on the max section guidelines
+ // passed in and how many bits are left.
int max_bits;
- // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
- max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
+ // For VBR base this on the bits and frames left plus the
+ // two_pass_vbrmax_section rate passed in by the user.
+ max_bits = (int) (((double) cpi->twopass.bits_left
+ / (cpi->twopass.total_stats->count - (double) cpi->common
+ .current_video_frame))
+ * ((double) cpi->oxcf.two_pass_vbrmax_section / 100.0));
- // Trap case where we are out of bits
+ // Trap case where we are out of bits.
if (max_bits < 0)
max_bits = 0;
@@ -746,7 +751,7 @@ void vp9_first_pass(VP9_COMP *cpi) {
}
// TODO: handle the case when duration is set to 0, or something less
- // than the full time between subsequent cpi->source_time_stamp s .
+ // than the full time between subsequent values of cpi->source_time_stamp.
fps.duration = (double)(cpi->source->ts_end
- cpi->source->ts_start);
@@ -873,7 +878,7 @@ static double calc_correction_factor(double err_per_mb,
// Given a current maxQ value sets a range for future values.
// PGW TODO..
-// This code removes direct dependency on QIndex to determin the range
+// This code removes direct dependency on QIndex to determine the range
// (now uses the actual quantizer) but has not been tuned.
static void adjust_maxq_qrange(VP9_COMP *cpi) {
int i;
@@ -991,7 +996,7 @@ static int estimate_max_q(VP9_COMP *cpi,
}
// Adjust maxq_min_limit and maxq_max_limit limits based on
- // averaga q observed in clip for non kf/gf/arf frames
+ // average q observed in clip for non kf/gf/arf frames
// Give average a chance to settle though.
// PGW TODO.. This code is broken for the extended Q range
if ((cpi->ni_frames >
@@ -1379,7 +1384,7 @@ static int calc_arf_boost(
&this_frame_mv_in_out, &mv_in_out_accumulator,
&abs_mv_in_out_accumulator, &mv_ratio_accumulator);
- // We want to discount the the flash frame itself and the recovery
+ // We want to discount the flash frame itself and the recovery
// frame that follows as both will have poor scores.
flash_detected = detect_flash(cpi, (i + offset)) ||
detect_flash(cpi, (i + offset + 1));
@@ -1442,9 +1447,8 @@ static int calc_arf_boost(
return arf_boost;
}
-static void configure_arnr_filter(VP9_COMP *cpi,
- FIRSTPASS_STATS *this_frame,
- int group_boost) {
+void configure_arnr_filter(VP9_COMP *cpi, const unsigned int this_frame,
+ int group_boost) {
int half_gf_int;
int frames_after_arf;
int frames_bwd = cpi->oxcf.arnr_max_frames - 1;
@@ -1458,8 +1462,7 @@ static void configure_arnr_filter(VP9_COMP *cpi,
// Note: this_frame->frame has been updated in the loop
// so it now points at the ARF frame.
half_gf_int = cpi->baseline_gf_interval >> 1;
- frames_after_arf = (int)(cpi->twopass.total_stats->count -
- this_frame->frame - 1);
+ frames_after_arf = (int)(cpi->twopass.total_stats->count - this_frame - 1);
switch (cpi->oxcf.arnr_type) {
case 1: // Backward filter
@@ -1515,7 +1518,144 @@ static void configure_arnr_filter(VP9_COMP *cpi,
}
}
-// Analyse and define a gf/arf group .
+#if CONFIG_MULTIPLE_ARF
+// Work out the frame coding order for a GF or an ARF group.
+// The current implementation codes frames in their natural order for a
+// GF group, and inserts additional ARFs into an ARF group using a
+// binary split approach.
+// NOTE: this function is currently implemented recursively.
+static void schedule_frames(VP9_COMP *cpi, const int start, const int end,
+ const int arf_idx, const int gf_or_arf_group,
+ const int level) {
+ int i, abs_end, half_range;
+ int *cfo = cpi->frame_coding_order;
+ int idx = cpi->new_frame_coding_order_period;
+
+ // If (end < 0) an ARF should be coded at position (-end).
+ assert(start >= 0);
+
+ // printf("start:%d end:%d\n", start, end);
+
+ // GF Group: code frames in logical order.
+ if (gf_or_arf_group == 0) {
+ assert(end >= start);
+ for (i = start; i <= end; ++i) {
+ cfo[idx] = i;
+ cpi->arf_buffer_idx[idx] = arf_idx;
+ cpi->arf_weight[idx] = -1;
+ ++idx;
+ }
+ cpi->new_frame_coding_order_period = idx;
+ return;
+ }
+
+ // ARF Group: work out the ARF schedule.
+ // Mark ARF frames as negative.
+ if (end < 0) {
+ // printf("start:%d end:%d\n", -end, -end);
+ // ARF frame is at the end of the range.
+ cfo[idx] = end;
+ // What ARF buffer does this ARF use as predictor.
+ cpi->arf_buffer_idx[idx] = (arf_idx > 2) ? (arf_idx - 1) : 2;
+ cpi->arf_weight[idx] = level;
+ ++idx;
+ abs_end = -end;
+ } else {
+ abs_end = end;
+ }
+
+ half_range = (abs_end - start) >> 1;
+
+ // ARFs may not be adjacent, they must be separated by at least
+ // MIN_GF_INTERVAL non-ARF frames.
+ if ((start + MIN_GF_INTERVAL) >= (abs_end - MIN_GF_INTERVAL)) {
+ // printf("start:%d end:%d\n", start, abs_end);
+ // Update the coding order and active ARF.
+ for (i = start; i <= abs_end; ++i) {
+ cfo[idx] = i;
+ cpi->arf_buffer_idx[idx] = arf_idx;
+ cpi->arf_weight[idx] = -1;
+ ++idx;
+ }
+ cpi->new_frame_coding_order_period = idx;
+ } else {
+ // Place a new ARF at the mid-point of the range.
+ cpi->new_frame_coding_order_period = idx;
+ schedule_frames(cpi, start, -(start + half_range), arf_idx + 1,
+ gf_or_arf_group, level + 1);
+ schedule_frames(cpi, start + half_range + 1, abs_end, arf_idx,
+ gf_or_arf_group, level + 1);
+ }
+}
+
+#define FIXED_ARF_GROUP_SIZE 16
+
+void define_fixed_arf_period(VP9_COMP *cpi) {
+ int i;
+ int max_level = INT_MIN;
+
+ assert(cpi->multi_arf_enabled);
+ assert(cpi->oxcf.lag_in_frames >= FIXED_ARF_GROUP_SIZE);
+
+ // Save the weight of the last frame in the sequence before next
+ // sequence pattern overwrites it.
+ cpi->this_frame_weight = cpi->arf_weight[cpi->sequence_number];
+ assert(cpi->this_frame_weight >= 0);
+
+ // Initialize frame coding order variables.
+ cpi->new_frame_coding_order_period = 0;
+ cpi->next_frame_in_order = 0;
+ cpi->arf_buffered = 0;
+ vp9_zero(cpi->frame_coding_order);
+ vp9_zero(cpi->arf_buffer_idx);
+ vpx_memset(cpi->arf_weight, -1, sizeof(cpi->arf_weight));
+
+ if (cpi->twopass.frames_to_key <= (FIXED_ARF_GROUP_SIZE + 8)) {
+ // Setup a GF group close to the keyframe.
+ cpi->source_alt_ref_pending = FALSE;
+ cpi->baseline_gf_interval = cpi->twopass.frames_to_key;
+ schedule_frames(cpi, 0, (cpi->baseline_gf_interval - 1), 2, 0, 0);
+ } else {
+ // Setup a fixed period ARF group.
+ cpi->source_alt_ref_pending = TRUE;
+ cpi->baseline_gf_interval = FIXED_ARF_GROUP_SIZE;
+ schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0);
+ }
+
+ // Replace level indicator of -1 with correct level.
+ for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
+ if (cpi->arf_weight[i] > max_level) {
+ max_level = cpi->arf_weight[i];
+ }
+ }
+ ++max_level;
+ for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
+ if (cpi->arf_weight[i] == -1) {
+ cpi->arf_weight[i] = max_level;
+ }
+ }
+ cpi->max_arf_level = max_level;
+#if 0
+ printf("\nSchedule: ");
+ for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
+ printf("%4d ", cpi->frame_coding_order[i]);
+ }
+ printf("\n");
+ printf("ARFref: ");
+ for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
+ printf("%4d ", cpi->arf_buffer_idx[i]);
+ }
+ printf("\n");
+ printf("Weight: ");
+ for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
+ printf("%4d ", cpi->arf_weight[i]);
+ }
+ printf("\n");
+#endif
+}
+#endif
+
+// Analyse and define a gf/arf group.
static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
FIRSTPASS_STATS next_frame;
FIRSTPASS_STATS *start_pos;
@@ -1619,7 +1759,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
}
// Break clause to detect very still sections after motion
- // (for example a staic image after a fade or other transition).
+ // (for example a static image after a fade or other transition).
if (detect_transition_to_still(cpi, i, 5, loop_decay_rate,
last_loop_decay_rate)) {
allow_alt_ref = FALSE;
@@ -1637,9 +1777,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Break at cpi->max_gf_interval unless almost totally static
(i >= active_max_gf_interval && (zero_motion_accumulator < 0.995)) ||
(
- // Dont break out with a very short interval
+ // Don't break out with a very short interval
(i > MIN_GF_INTERVAL) &&
- // Dont break out very close to a key frame
+ // Don't break out very close to a key frame
((cpi->twopass.frames_to_key - i) >= MIN_GF_INTERVAL) &&
((boost_score > 125.0) || (next_frame.pcnt_inter < 0.75)) &&
(!flash_detected) &&
@@ -1657,7 +1797,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
old_boost_score = boost_score;
}
- // Dont allow a gf too near the next kf
+ // Don't allow a gf too near the next kf
if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL) {
while (i < cpi->twopass.frames_to_key) {
i++;
@@ -1672,10 +1812,22 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
}
}
- // Set the interval till the next gf or arf.
+ // Set the interval until the next gf or arf.
cpi->baseline_gf_interval = i;
- // Should we use the alternate refernce frame
+#if CONFIG_MULTIPLE_ARF
+ if (cpi->multi_arf_enabled) {
+ // Initialize frame coding order variables.
+ cpi->new_frame_coding_order_period = 0;
+ cpi->next_frame_in_order = 0;
+ cpi->arf_buffered = 0;
+ vp9_zero(cpi->frame_coding_order);
+ vp9_zero(cpi->arf_buffer_idx);
+ vpx_memset(cpi->arf_weight, -1, sizeof(cpi->arf_weight));
+ }
+#endif
+
+ // Should we use the alternate reference frame
if (allow_alt_ref &&
(i < cpi->oxcf.lag_in_frames) &&
(i >= MIN_GF_INTERVAL) &&
@@ -1686,16 +1838,66 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
((mv_in_out_accumulator / (double)i > -0.2) ||
(mv_in_out_accumulator > -2.0)) &&
(boost_score > 100)) {
- // Alterrnative boost calculation for alt ref
+ // Alternative boost calculation for alt ref
cpi->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost, &b_boost);
cpi->source_alt_ref_pending = TRUE;
- configure_arnr_filter(cpi, this_frame, cpi->gfu_boost);
+#if CONFIG_MULTIPLE_ARF
+ // Set the ARF schedule.
+ if (cpi->multi_arf_enabled) {
+ schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0);
+ }
+#endif
} else {
cpi->gfu_boost = (int)boost_score;
cpi->source_alt_ref_pending = FALSE;
+#if CONFIG_MULTIPLE_ARF
+ // Set the GF schedule.
+ if (cpi->multi_arf_enabled) {
+ schedule_frames(cpi, 0, cpi->baseline_gf_interval - 1, 2, 0, 0);
+ assert(cpi->new_frame_coding_order_period == cpi->baseline_gf_interval);
+ }
+#endif
}
+#if CONFIG_MULTIPLE_ARF
+ if (cpi->multi_arf_enabled && (cpi->common.frame_type != KEY_FRAME)) {
+ int max_level = INT_MIN;
+ // Replace level indicator of -1 with correct level.
+ for (i = 0; i < cpi->frame_coding_order_period; ++i) {
+ if (cpi->arf_weight[i] > max_level) {
+ max_level = cpi->arf_weight[i];
+ }
+ }
+ ++max_level;
+ for (i = 0; i < cpi->frame_coding_order_period; ++i) {
+ if (cpi->arf_weight[i] == -1) {
+ cpi->arf_weight[i] = max_level;
+ }
+ }
+ cpi->max_arf_level = max_level;
+ }
+#if 0
+ if (cpi->multi_arf_enabled) {
+ printf("\nSchedule: ");
+ for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
+ printf("%4d ", cpi->frame_coding_order[i]);
+ }
+ printf("\n");
+ printf("ARFref: ");
+ for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
+ printf("%4d ", cpi->arf_buffer_idx[i]);
+ }
+ printf("\n");
+ printf("Weight: ");
+ for (i = 0; i < cpi->new_frame_coding_order_period; ++i) {
+ printf("%4d ", cpi->arf_weight[i]);
+ }
+ printf("\n");
+ }
+#endif
+#endif
+
// Now decide how many bits should be allocated to the GF group as a
// proportion of those remaining in the kf group.
// The final key frame group in the clip is treated as a special case
@@ -1736,10 +1938,13 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
cpi->twopass.modified_error_used += gf_group_err;
// Assign bits to the arf or gf.
- for (i = 0; i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME); i++) {
+ for (i = 0;
+ i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME);
+ ++i) {
int boost;
int allocation_chunks;
- int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
+ int Q =
+ (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
int gf_bits;
boost = (cpi->gfu_boost * vp9_gfboost_qadjust(Q)) / 100;
@@ -1758,7 +1963,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
(cpi->baseline_gf_interval * 100) + (boost - 100);
// Prevent overflow
- if (boost > 1028) {
+ if (boost > 1028) { // TODO(agrange) Should this be 1024?
int divisor = boost >> 10;
boost /= divisor;
allocation_chunks /= divisor;
@@ -1807,18 +2012,21 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
if (gf_bits < 0)
gf_bits = 0;
- gf_bits += cpi->min_frame_bandwidth; // Add in minimum for a frame
+ // Add in minimum for a frame
+ gf_bits += cpi->min_frame_bandwidth;
if (i == 0) {
cpi->twopass.gf_bits = gf_bits;
}
- if (i == 1 || (!cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME))) {
- cpi->per_frame_bandwidth = gf_bits; // Per frame bit target for this frame
+ if (i == 1 || (!cpi->source_alt_ref_pending
+ && (cpi->common.frame_type != KEY_FRAME))) {
+ // Per frame bit target for this frame
+ cpi->per_frame_bandwidth = gf_bits;
}
}
{
- // Adjust KF group bits and error remainin
+ // Adjust KF group bits and error remaining
cpi->twopass.kf_group_error_left -= (int64_t)gf_group_err;
cpi->twopass.kf_group_bits -= cpi->twopass.gf_group_bits;
@@ -1835,13 +2043,14 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
else
cpi->twopass.gf_group_error_left = (int64_t)gf_group_err;
- cpi->twopass.gf_group_bits -= cpi->twopass.gf_bits - cpi->min_frame_bandwidth;
+ cpi->twopass.gf_group_bits -= cpi->twopass.gf_bits
+ - cpi->min_frame_bandwidth;
if (cpi->twopass.gf_group_bits < 0)
cpi->twopass.gf_group_bits = 0;
// This condition could fail if there are two kfs very close together
- // despite (MIN_GF_INTERVAL) and would cause a devide by 0 in the
+ // despite (MIN_GF_INTERVAL) and would cause a divide by 0 in the
// calculation of cpi->twopass.alt_extra_bits.
if (cpi->baseline_gf_interval >= 3) {
int boost = (cpi->source_alt_ref_pending)
@@ -1853,6 +2062,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
pct_extra = (boost - 100) / 50;
pct_extra = (pct_extra > 20) ? 20 : pct_extra;
+ // TODO(agrange) Remove cpi->twopass.alt_extra_bits.
cpi->twopass.alt_extra_bits = (int)
((cpi->twopass.gf_group_bits * pct_extra) / 100);
cpi->twopass.gf_group_bits -= cpi->twopass.alt_extra_bits;
@@ -1887,24 +2097,28 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Allocate bits to a normal frame that is neither a gf an arf or a key frame.
static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
- int target_frame_size; // gf_group_error_left
+ int target_frame_size;
double modified_err;
- double err_fraction; // What portion of the remaining GF group error is used by this frame
+ double err_fraction;
- int max_bits = frame_max_bits(cpi); // Max for a single frame
+ // Max for a single frame.
+ int max_bits = frame_max_bits(cpi);
- // Calculate modified prediction error used in bit allocation
+ // Calculate modified prediction error used in bit allocation.
modified_err = calculate_modified_err(cpi, this_frame);
if (cpi->twopass.gf_group_error_left > 0)
- err_fraction = modified_err / cpi->twopass.gf_group_error_left; // What portion of the remaining GF group error is used by this frame
+ // What portion of the remaining GF group error is used by this frame.
+ err_fraction = modified_err / cpi->twopass.gf_group_error_left;
else
err_fraction = 0.0;
- target_frame_size = (int)((double)cpi->twopass.gf_group_bits * err_fraction); // How many of those bits available for allocation should we give it?
+ // How many of those bits available for allocation should we give it?
+ target_frame_size = (int)((double)cpi->twopass.gf_group_bits * err_fraction);
- // Clip to target size to 0 - max_bits (or cpi->twopass.gf_group_bits) at the top end.
+ // Clip target size to 0 - max_bits (or cpi->twopass.gf_group_bits) at
+ // the top end.
if (target_frame_size < 0)
target_frame_size = 0;
else {
@@ -1915,17 +2129,18 @@ static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
target_frame_size = (int)cpi->twopass.gf_group_bits;
}
- // Adjust error remaining
+ // Adjust error and bits remaining.
cpi->twopass.gf_group_error_left -= (int64_t)modified_err;
- cpi->twopass.gf_group_bits -= target_frame_size; // Adjust bits remaining
+ cpi->twopass.gf_group_bits -= target_frame_size;
if (cpi->twopass.gf_group_bits < 0)
cpi->twopass.gf_group_bits = 0;
- target_frame_size += cpi->min_frame_bandwidth; // Add in the minimum number of bits that is set aside for every frame.
-
+ // Add in the minimum number of bits that is set aside for every frame.
+ target_frame_size += cpi->min_frame_bandwidth;
- cpi->per_frame_bandwidth = target_frame_size; // Per frame bit target for this frame
+ // Per frame bit target for this frame.
+ cpi->per_frame_bandwidth = target_frame_size;
}
// Make a damped adjustment to the active max q.
@@ -2059,7 +2274,16 @@ void vp9_second_pass(VP9_COMP *cpi) {
if (cpi->frames_till_gf_update_due == 0) {
// Define next gf group and assign bits to it
vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
- define_gf_group(cpi, &this_frame_copy);
+
+#if CONFIG_MULTIPLE_ARF
+ if (cpi->multi_arf_enabled) {
+ define_fixed_arf_period(cpi);
+ } else {
+#endif
+ define_gf_group(cpi, &this_frame_copy);
+#if CONFIG_MULTIPLE_ARF
+ }
+#endif
// If we are going to code an altref frame at the end of the group
// and the current frame is not a key frame....
@@ -2101,7 +2325,7 @@ void vp9_second_pass(VP9_COMP *cpi) {
cpi->twopass.frames_to_key--;
- // Update the total stats remaining sturcture
+ // Update the total stats remaining structure
subtract_stats(cpi->twopass.total_left_stats, &this_frame);
}
@@ -2178,7 +2402,8 @@ static int test_candidate_kf(VP9_COMP *cpi,
break;
}
- // If there is tolerable prediction for at least the next 3 frames then break out else discard this pottential key frame and move on
+ // If there is tolerable prediction for at least the next 3 frames then
+ // break out else discard this potential key frame and move on
if (boost_score > 30.0 && (i > 3))
is_viable_kf = TRUE;
else {
@@ -2231,7 +2456,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Take a copy of the initial frame details
vpx_memcpy(&first_frame, this_frame, sizeof(*this_frame));
- cpi->twopass.kf_group_bits = 0; // Total bits avaialable to kf group
+ cpi->twopass.kf_group_bits = 0; // Total bits available to kf group
cpi->twopass.kf_group_error_left = 0; // Group modified error score.
kf_mod_err = calculate_modified_err(cpi, this_frame);