summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_bitstream.c20
-rw-r--r--vp9/encoder/vp9_firstpass.c321
-rw-r--r--vp9/encoder/vp9_onyx_if.c312
-rw-r--r--vp9/encoder/vp9_onyx_int.h41
-rw-r--r--vp9/encoder/vp9_ratectrl.c11
5 files changed, 579 insertions, 126 deletions
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 9cb448a99..c2ae957c8 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -2617,7 +2617,12 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
int refresh_mask;
// Should the GF or ARF be updated using the transmitted frame or buffer
- if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) {
+#if CONFIG_MULTIPLE_ARF
+ if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
+ !cpi->refresh_alt_ref_frame) {
+#else
+ if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) {
+#endif
/* Preserve the previously existing golden frame and update the frame in
* the alt ref slot instead. This is highly specific to the use of
* alt-ref as a forward reference, and this needs to be generalized as
@@ -2630,10 +2635,21 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) |
(cpi->refresh_golden_frame << cpi->alt_fb_idx);
} else {
+ int arf_idx = cpi->alt_fb_idx;
+#if CONFIG_MULTIPLE_ARF
+ // Determine which ARF buffer to use to encode this ARF frame.
+ if (cpi->multi_arf_enabled) {
+ int sn = cpi->sequence_number;
+ arf_idx = (cpi->frame_coding_order[sn] < 0) ?
+ cpi->arf_buffer_idx[sn + 1] :
+ cpi->arf_buffer_idx[sn];
+ }
+#endif
refresh_mask = (cpi->refresh_last_frame << cpi->lst_fb_idx) |
(cpi->refresh_golden_frame << cpi->gld_fb_idx) |
- (cpi->refresh_alt_ref_frame << cpi->alt_fb_idx);
+ (cpi->refresh_alt_ref_frame << arf_idx);
}
+
vp9_write_literal(&header_bc, refresh_mask, NUM_REF_FRAMES);
vp9_write_literal(&header_bc, cpi->lst_fb_idx, NUM_REF_FRAMES_LG2);
vp9_write_literal(&header_bc, cpi->gld_fb_idx, NUM_REF_FRAMES_LG2);
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);
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 05977b3f5..890195204 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -82,6 +82,10 @@ extern double vp9_calc_ssimg(YV12_BUFFER_CONFIG *source,
#endif
+// TODO(agrange) Move this function.
+extern void configure_arnr_filter(VP9_COMP *cpi, const unsigned int this_frame,
+ int group_boost);
+
// #define OUTPUT_YUV_REC
#ifdef OUTPUT_YUV_SRC
@@ -738,7 +742,12 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->optimize_coefficients = !cpi->oxcf.lossless;
sf->first_step = 0;
sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
+#if CONFIG_MULTIPLE_ARF
+ // Switch segmentation off.
+ sf->static_segmentation = 0;
+#else
sf->static_segmentation = 1;
+#endif
sf->splitmode_breakout = 0;
sf->mb16_breakout = 0;
@@ -748,7 +757,12 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
break;
case 1:
+#if CONFIG_MULTIPLE_ARF
+ // Switch segmentation off.
+ sf->static_segmentation = 0;
+#else
sf->static_segmentation = 1;
+#endif
sf->splitmode_breakout = 1;
sf->mb16_breakout = 0;
@@ -1265,7 +1279,11 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
}
// YX Temp
+#if CONFIG_MULTIPLE_ARF
+ vp9_zero(cpi->alt_ref_source);
+#else
cpi->alt_ref_source = NULL;
+#endif
cpi->is_src_frame_alt_ref = 0;
#if 0
@@ -1356,9 +1374,9 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
cpi->common.current_video_frame = 0;
cpi->kf_overspend_bits = 0;
cpi->kf_bitrate_adjustment = 0;
- cpi->frames_till_gf_update_due = 0;
+ cpi->frames_till_gf_update_due = 0;
cpi->gf_overspend_bits = 0;
- cpi->non_gf_bitrate_adjustment = 0;
+ cpi->non_gf_bitrate_adjustment = 0;
cm->prob_last_coded = 128;
cm->prob_gf_coded = 128;
cm->prob_intra_coded = 63;
@@ -1369,7 +1387,7 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
for (i = 0; i < TX_SIZE_MAX_SB - 1; i++)
cm->prob_tx[i] = 128;
- // Prime the recent reference frame useage counters.
+ // Prime the recent reference frame usage counters.
// Hereafter they will be maintained as a sort of moving average
cpi->recent_ref_frame_usage[INTRA_FRAME] = 1;
cpi->recent_ref_frame_usage[LAST_FRAME] = 1;
@@ -1449,6 +1467,19 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
cpi->source_alt_ref_active = FALSE;
cpi->refresh_alt_ref_frame = 0;
+#if CONFIG_MULTIPLE_ARF
+ // 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.
+ cpi->multi_arf_enabled = 1;
+
+ if (cpi->multi_arf_enabled) {
+ cpi->sequence_number = 0;
+ cpi->frame_coding_order_period = 0;
+ vp9_zero(cpi->frame_coding_order);
+ vp9_zero(cpi->arf_buffer_idx);
+ }
+#endif
+
cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
#if CONFIG_INTERNAL_STATS
cpi->b_calculate_ssimg = 0;
@@ -2193,10 +2224,13 @@ static void update_alt_ref_frame_stats(VP9_COMP *cpi) {
// this frame refreshes means next frames don't unless specified by user
cpi->common.frames_since_golden = 0;
- // Clear the alternate reference update pending flag.
- cpi->source_alt_ref_pending = FALSE;
+#if CONFIG_MULTIPLE_ARF
+ if (!cpi->multi_arf_enabled)
+#endif
+ // Clear the alternate reference update pending flag.
+ cpi->source_alt_ref_pending = FALSE;
- // Set the alternate refernce frame active flag
+ // Set the alternate reference frame active flag
cpi->source_alt_ref_active = TRUE;
@@ -2223,7 +2257,7 @@ static void update_golden_frame_stats(VP9_COMP *cpi) {
// }
// else
// {
- // // Carry a potrtion of count over to begining of next gf sequence
+ // // Carry a portion of count over to beginning of next gf sequence
// cpi->recent_ref_frame_usage[INTRA_FRAME] >>= 5;
// cpi->recent_ref_frame_usage[LAST_FRAME] >>= 5;
// cpi->recent_ref_frame_usage[GOLDEN_FRAME] >>= 5;
@@ -2362,7 +2396,7 @@ static int recode_loop_test(VP9_COMP *cpi,
VP9_COMMON *cm = &cpi->common;
// Is frame recode allowed at all
- // Yes if either recode mode 1 is selected or mode two is selcted
+ // Yes if either recode mode 1 is selected or mode two is selected
// and the frame is a key frame. golden frame or alt_ref_frame
if ((cpi->sf.recode_loop == 1) ||
((cpi->sf.recode_loop == 2) &&
@@ -2403,13 +2437,19 @@ static void update_reference_frames(VP9_COMP * const cpi) {
&cm->ref_frame_map[cpi->gld_fb_idx], cm->new_fb_idx);
ref_cnt_fb(cm->fb_idx_ref_cnt,
&cm->ref_frame_map[cpi->alt_fb_idx], cm->new_fb_idx);
- } else if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) {
+ }
+#if CONFIG_MULTIPLE_ARF
+ else if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
+ !cpi->refresh_alt_ref_frame) {
+#else
+ else if (cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) {
+#endif
/* 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
* alt-ref as a forward reference, and this needs to be generalized as
* other uses are implemented (like RTC/temporal scaling)
*
- * The update to the buffer in the alt ref slot was signalled in
+ * The update to the buffer in the alt ref slot was signaled in
* vp9_pack_bitstream(), now swap the buffer pointers so that it's treated
* as the golden frame next time.
*/
@@ -2421,10 +2461,16 @@ static void update_reference_frames(VP9_COMP * const cpi) {
tmp = cpi->alt_fb_idx;
cpi->alt_fb_idx = cpi->gld_fb_idx;
cpi->gld_fb_idx = tmp;
- } else { /* For non key/golden frames */
+ } else { /* For non key/golden frames */
if (cpi->refresh_alt_ref_frame) {
+ int arf_idx = cpi->alt_fb_idx;
+#if CONFIG_MULTIPLE_ARF
+ if (cpi->multi_arf_enabled) {
+ arf_idx = cpi->arf_buffer_idx[cpi->sequence_number + 1];
+ }
+#endif
ref_cnt_fb(cm->fb_idx_ref_cnt,
- &cm->ref_frame_map[cpi->alt_fb_idx], cm->new_fb_idx);
+ &cm->ref_frame_map[arf_idx], cm->new_fb_idx);
}
if (cpi->refresh_golden_frame) {
@@ -2615,7 +2661,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// For an alt ref frame in 2 pass we skip the call to the second
// pass function that sets the target bandwidth so must set it here
if (cpi->refresh_alt_ref_frame) {
- cpi->per_frame_bandwidth = cpi->twopass.gf_bits; // Per frame bit target for the alt ref frame
+ // Per frame bit target for the alt ref frame
+ cpi->per_frame_bandwidth = cpi->twopass.gf_bits;
// per second target bitrate
cpi->target_bandwidth = (int)(cpi->twopass.gf_bits *
cpi->output_frame_rate);
@@ -2637,7 +2684,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// Current default encoder behaviour for the altref sign bias
cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = cpi->source_alt_ref_active;
- // Check to see if a key frame is signalled
+ // Check to see if a key frame is signaled
// For two pass with auto key frame enabled cm->frame_type may already be set, but not for one pass.
if ((cm->current_video_frame == 0) ||
(cm->frame_flags & FRAMEFLAGS_KEY) ||
@@ -2681,7 +2728,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// Configure use of segmentation for enhanced coding of static regions.
// Only allowed for now in second pass of two pass (as requires lagged coding)
- // and if the relevent speed feature flag is set.
+ // and if the relevant speed feature flag is set.
if ((cpi->pass == 2) && (cpi->sf.static_segmentation)) {
configure_static_seg_features(cpi);
}
@@ -2695,6 +2742,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
q = cpi->active_worst_quality;
if (cm->frame_type == KEY_FRAME) {
+#if CONFIG_MULTIPLE_ARF
+ double current_q;
+#endif
int high = 2000;
int low = 400;
@@ -2711,7 +2761,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cpi->active_best_quality = kf_low_motion_minq[q] + adjustment;
}
- // Make an adjustment based on the %s static
+ // Make an adjustment based on the % static
// The main impact of this is at lower Q to prevent overly large key
// frames unless a lot of the image is static.
if (cpi->kf_zeromotion_pct < 64)
@@ -2728,9 +2778,14 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
delta_qindex = compute_qdelta(cpi, last_boosted_q,
(last_boosted_q * 0.75));
-
cpi->active_best_quality = MAX(qindex + delta_qindex, cpi->best_quality);
}
+#if CONFIG_MULTIPLE_ARF
+ // Force the KF quantizer to be 30% of the active_worst_quality.
+ current_q = vp9_convert_qindex_to_q(cpi->active_worst_quality);
+ cpi->active_best_quality = cpi->active_worst_quality
+ + compute_qdelta(cpi, current_q, current_q * 0.3);
+#endif
} else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) {
int high = 2000;
int low = 400;
@@ -2776,7 +2831,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cpi->active_best_quality = inter_minq[q];
#endif
- // For the constant/constrained quality mode we dont want
+ // For the constant/constrained quality mode we don't want
// q to fall below the cq level.
if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
(cpi->active_best_quality < cpi->cq_target_quality)) {
@@ -2814,12 +2869,34 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_compute_frame_size_bounds(cpi, &frame_under_shoot_limit,
&frame_over_shoot_limit);
- // Limit Q range for the adaptive loop.
- bottom_index = cpi->active_best_quality;
- top_index = cpi->active_worst_quality;
- q_low = cpi->active_best_quality;
- q_high = cpi->active_worst_quality;
+#if CONFIG_MULTIPLE_ARF
+ // Force the quantizer determined by the coding order pattern.
+ if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME)) {
+ double new_q;
+ double current_q = vp9_convert_qindex_to_q(cpi->active_worst_quality);
+ int level = cpi->this_frame_weight;
+ assert(level >= 0);
+ // Set quantizer steps at 10% increments.
+ new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level)));
+ q = cpi->active_worst_quality + compute_qdelta(cpi, current_q, new_q);
+
+ bottom_index = q;
+ top_index = q;
+ q_low = q;
+ q_high = q;
+
+ printf("frame:%d q:%d\n", cm->current_video_frame, q);
+ } else {
+#endif
+ // Limit Q range for the adaptive loop.
+ bottom_index = cpi->active_best_quality;
+ top_index = cpi->active_worst_quality;
+ q_low = cpi->active_best_quality;
+ q_high = cpi->active_worst_quality;
+#if CONFIG_MULTIPLE_ARF
+ }
+#endif
loop_count = 0;
if (cm->frame_type != KEY_FRAME) {
@@ -2936,8 +3013,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
if (cm->frame_type == KEY_FRAME) {
/* Choose which entropy context to use. When using a forward reference
* frame, it immediately follows the keyframe, and thus benefits from
- * using the same entropy context established by the keyframe. Otherwise,
- * use the default context 0.
+ * using the same entropy context established by the keyframe.
+ * Otherwise, use the default context 0.
*/
cm->frame_context_idx = cpi->oxcf.play_alternate;
vp9_setup_key_frame(cpi);
@@ -3191,7 +3268,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
}
- // Update the GF useage maps.
+ // Update the GF usage maps.
// This is done after completing the compression of a frame when all modes
// etc. are finalized but before loop filter
vp9_update_gf_useage_maps(cpi, cm, &cpi->mb);
@@ -3366,7 +3443,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// in this frame.
update_base_skip_probs(cpi);
-#if 0 // 1 && CONFIG_INTERNAL_STATS
+#if 0 && CONFIG_INTERNAL_STATS
{
FILE *f = fopen("tmp.stt", "a");
int recon_err;
@@ -3513,10 +3590,33 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// Tell the caller that the frame was coded as a key frame
*frame_flags = cm->frame_flags | FRAMEFLAGS_KEY;
- // As this frame is a key frame the next defaults to an inter frame.
+#if CONFIG_MULTIPLE_ARF
+ // Reset the sequence number.
+ if (cpi->multi_arf_enabled) {
+ cpi->sequence_number = 0;
+ cpi->frame_coding_order_period = cpi->new_frame_coding_order_period;
+ cpi->new_frame_coding_order_period = -1;
+ }
+#endif
+
+ // As this frame is a key frame the next defaults to an inter frame.
cm->frame_type = INTER_FRAME;
} else {
*frame_flags = cm->frame_flags&~FRAMEFLAGS_KEY;
+
+#if CONFIG_MULTIPLE_ARF
+ /* Increment position in the coded frame sequence. */
+ if (cpi->multi_arf_enabled) {
+ ++cpi->sequence_number;
+ if (cpi->sequence_number >= cpi->frame_coding_order_period) {
+ cpi->sequence_number = 0;
+ cpi->frame_coding_order_period = cpi->new_frame_coding_order_period;
+ cpi->new_frame_coding_order_period = -1;
+ }
+ cpi->this_frame_weight = cpi->arf_weight[cpi->sequence_number];
+ assert(cpi->this_frame_weight >= 0);
+ }
+#endif
}
// Clear the one shot update flags for segmentation map and mode/ref loop filter deltas.
@@ -3528,16 +3628,15 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cm->last_width = cm->width;
cm->last_height = cm->height;
- // Dont increment frame counters if this was an altref buffer update not a real frame
+ // Don't increment frame counters if this was an altref buffer
+ // update not a real frame
if (cm->show_frame) {
- cm->current_video_frame++;
- cpi->frames_since_key++;
+ ++cm->current_video_frame;
+ ++cpi->frames_since_key;
}
// reset to normal state now that we are done.
-
-
#if 0
{
char filename[512];
@@ -3624,6 +3723,12 @@ static int frame_is_reference(const VP9_COMP *cpi) {
mb->update_mb_segmentation_data;
}
+#if CONFIG_MULTIPLE_ARF
+int is_next_frame_arf(VP9_COMP *cpi) {
+ // Negative entry in frame_coding_order indicates an ARF at this position.
+ return cpi->frame_coding_order[cpi->sequence_number + 1] < 0 ? 1 : 0;
+}
+#endif
int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
unsigned long *size, unsigned char *dest,
@@ -3633,6 +3738,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
struct vpx_usec_timer cmptimer;
YV12_BUFFER_CONFIG *force_src_buffer = NULL;
int i;
+ // FILE *fp_out = fopen("enc_frame_type.txt", "a");
if (!cpi)
return -1;
@@ -3644,37 +3750,90 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
cpi->mb.e_mbd.allow_high_precision_mv = ALTREF_HIGH_PRECISION_MV;
set_mvcost(&cpi->mb);
- // Should we code an alternate reference frame
- if (cpi->oxcf.play_alternate &&
- cpi->source_alt_ref_pending) {
- if ((cpi->source = vp9_lookahead_peek(cpi->lookahead,
- cpi->frames_till_gf_update_due))) {
+ // Should we code an alternate reference frame.
+ if (cpi->oxcf.play_alternate && cpi->source_alt_ref_pending) {
+ int frames_to_arf;
+
+#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 = cpi->frames_till_gf_update_due;
+
+ assert(frames_to_arf < cpi->twopass.frames_to_key);
+
+ if ((cpi->source = vp9_lookahead_peek(cpi->lookahead, frames_to_arf))) {
+#if CONFIG_MULTIPLE_ARF
+ cpi->alt_ref_source[cpi->arf_buffered] = cpi->source;
+#else
cpi->alt_ref_source = cpi->source;
+#endif
+
if (cpi->oxcf.arnr_max_frames > 0) {
- vp9_temporal_filter_prepare(cpi, cpi->frames_till_gf_update_due);
+ // Produce the filtered ARF frame.
+ // TODO(agrange) merge these two functions.
+ configure_arnr_filter(cpi, cm->current_video_frame + frames_to_arf,
+ cpi->gfu_boost);
+ vp9_temporal_filter_prepare(cpi, frames_to_arf);
force_src_buffer = &cpi->alt_ref_buffer;
}
- cm->frames_till_alt_ref_frame = cpi->frames_till_gf_update_due;
+
+ cm->show_frame = 0;
cpi->refresh_alt_ref_frame = 1;
cpi->refresh_golden_frame = 0;
cpi->refresh_last_frame = 0;
- cm->show_frame = 0;
- cpi->source_alt_ref_pending = FALSE; // Clear Pending altf Ref flag.
cpi->is_src_frame_alt_ref = 0;
+
+ // TODO(agrange) This needs to vary depending on where the next ARF is.
+ cm->frames_till_alt_ref_frame = frames_to_arf;
+
+#if CONFIG_MULTIPLE_ARF
+ if (!cpi->multi_arf_enabled)
+#endif
+ cpi->source_alt_ref_pending = FALSE; // Clear Pending altf Ref flag.
}
}
if (!cpi->source) {
+#if CONFIG_MULTIPLE_ARF
+ int i;
+#endif
if ((cpi->source = vp9_lookahead_pop(cpi->lookahead, flush))) {
cm->show_frame = 1;
+#if CONFIG_MULTIPLE_ARF
+ // Is this frame the ARF overlay.
+ cpi->is_src_frame_alt_ref = FALSE;
+ for (i = 0; i < cpi->arf_buffered; ++i) {
+ if (cpi->source == cpi->alt_ref_source[i]) {
+ cpi->is_src_frame_alt_ref = TRUE;
+ cpi->refresh_golden_frame = TRUE;
+ break;
+ }
+ }
+#else
cpi->is_src_frame_alt_ref = cpi->alt_ref_source
&& (cpi->source == cpi->alt_ref_source);
-
+#endif
if (cpi->is_src_frame_alt_ref) {
- cpi->refresh_last_frame = 0;
+ // 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
}
}
@@ -3684,6 +3843,23 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
*time_stamp = cpi->source->ts_start;
*time_end = cpi->source->ts_end;
*frame_flags = cpi->source->flags;
+
+ // fprintf(fp_out, " Frame:%d", cm->current_video_frame);
+#if CONFIG_MULTIPLE_ARF
+ if (cpi->multi_arf_enabled) {
+ // fprintf(fp_out, " seq_no:%d this_frame_weight:%d",
+ // cpi->sequence_number, cpi->this_frame_weight);
+ } else {
+ // fprintf(fp_out, "\n");
+ }
+#else
+ // fprintf(fp_out, "\n");
+#endif
+
+#if CONFIG_MULTIPLE_ARF
+ if ((cm->frame_type != KEY_FRAME) && (cpi->pass == 2))
+ cpi->source_alt_ref_pending = is_next_frame_arf(cpi);
+#endif
} else {
*size = 0;
if (flush && cpi->pass == 1 && !cpi->twopass.first_pass_done) {
@@ -3691,6 +3867,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
cpi->twopass.first_pass_done = 1;
}
+ // fclose(fp_out);
return -1;
}
@@ -3745,33 +3922,44 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
// Clear down mmx registers
vp9_clear_system_state(); // __asm emms;
- cm->frame_type = INTER_FRAME;
- cm->frame_flags = *frame_flags;
-
-#if 0
-
- if (cpi->refresh_alt_ref_frame) {
- // cpi->refresh_golden_frame = 1;
- cpi->refresh_golden_frame = 0;
- cpi->refresh_last_frame = 0;
- } else {
- cpi->refresh_golden_frame = 0;
- cpi->refresh_last_frame = 1;
- }
-
-#endif
-
/* find a free buffer for the new frame, releasing the reference previously
* held.
*/
cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
cm->new_fb_idx = get_free_fb(cm);
+#if CONFIG_MULTIPLE_ARF
+ /* Set up the correct ARF frame. */
+ if (cpi->refresh_alt_ref_frame) {
+ ++cpi->arf_buffered;
+ }
+ if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) &&
+ (cpi->pass == 2)) {
+ cpi->alt_fb_idx = cpi->arf_buffer_idx[cpi->sequence_number];
+ }
+#endif
+
/* Get the mapping of L/G/A to the reference buffer pool */
cm->active_ref_idx[0] = cm->ref_frame_map[cpi->lst_fb_idx];
cm->active_ref_idx[1] = cm->ref_frame_map[cpi->gld_fb_idx];
cm->active_ref_idx[2] = cm->ref_frame_map[cpi->alt_fb_idx];
+#if 0 // CONFIG_MULTIPLE_ARF
+ if (cpi->multi_arf_enabled) {
+ fprintf(fp_out, " idx(%d, %d, %d, %d) active(%d, %d, %d)",
+ cpi->lst_fb_idx, cpi->gld_fb_idx, cpi->alt_fb_idx, cm->new_fb_idx,
+ cm->active_ref_idx[0], cm->active_ref_idx[1], cm->active_ref_idx[2]);
+ if (cpi->refresh_alt_ref_frame)
+ fprintf(fp_out, " type:ARF");
+ if (cpi->is_src_frame_alt_ref)
+ fprintf(fp_out, " type:OVERLAY[%d]", cpi->alt_fb_idx);
+ fprintf(fp_out, "\n");
+ }
+#endif
+
+ cm->frame_type = INTER_FRAME;
+ cm->frame_flags = *frame_flags;
+
/* Reset the frame pointers to the current frame size */
vp8_yv12_realloc_frame_buffer(&cm->yv12_fb[cm->new_fb_idx],
cm->width, cm->height,
@@ -3814,7 +4002,6 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
cpi->refresh_golden_frame = 0;
cpi->refresh_last_frame = 1;
cm->frame_type = INTER_FRAME;
-
}
vpx_usec_timer_mark(&cmptimer);
@@ -3927,12 +4114,11 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
cpi->total_ssimg_v += v;
cpi->total_ssimg_all += frame_all;
}
-
}
}
#endif
-
+ // fclose(fp_out);
return 0;
}
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 15daa7e83..f3209a3f7 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -31,18 +31,22 @@
// Experimental rate control switches
#if CONFIG_ONESHOTQ
-#define ONE_SHOT_Q_ESTIMATE 1
-#define STRICT_ONE_SHOT_Q 1
-#define DISABLE_RC_LONG_TERM_MEM 1
+#define ONE_SHOT_Q_ESTIMATE 0
+#define STRICT_ONE_SHOT_Q 0
+#define DISABLE_RC_LONG_TERM_MEM 0
#endif
+
// #define SPEEDSTATS 1
+#if CONFIG_MULTIPLE_ARF
+// Set MIN_GF_INTERVAL to 1 for the full decomposition.
+#define MIN_GF_INTERVAL 2
+#else
#define MIN_GF_INTERVAL 4
+#endif
#define DEFAULT_GF_INTERVAL 7
#define KEY_FRAME_CONTEXT 5
-#define MAX_LAG_BUFFERS 25
-
#if CONFIG_COMP_INTERINTRA_PRED
#define MAX_MODES 54
#else
@@ -326,7 +330,11 @@ typedef struct VP9_COMP {
struct lookahead_ctx *lookahead;
struct lookahead_entry *source;
+#if CONFIG_MULTIPLE_ARF
+ struct lookahead_entry *alt_ref_source[NUM_REF_FRAMES];
+#else
struct lookahead_entry *alt_ref_source;
+#endif
YV12_BUFFER_CONFIG *Source;
YV12_BUFFER_CONFIG *un_scaled_source;
@@ -345,6 +353,9 @@ typedef struct VP9_COMP {
int lst_fb_idx;
int gld_fb_idx;
int alt_fb_idx;
+#if CONFIG_MULTIPLE_ARF
+ int alt_ref_fb_idx[NUM_REF_FRAMES - 3];
+#endif
int refresh_last_frame;
int refresh_golden_frame;
int refresh_alt_ref_frame;
@@ -358,6 +369,12 @@ typedef struct VP9_COMP {
unsigned int key_frame_frequency;
unsigned int this_key_frame_forced;
unsigned int next_key_frame_forced;
+#if CONFIG_MULTIPLE_ARF
+ // Position within a frame coding order (including any additional ARF frames).
+ unsigned int sequence_number;
+ // Next frame in naturally occurring order that has not yet been coded.
+ int next_frame_in_order;
+#endif
// Ambient reconstruction err target for force key frames
int ambient_err;
@@ -396,7 +413,6 @@ typedef struct VP9_COMP {
double gf_rate_correction_factor;
int frames_till_gf_update_due; // Count down till next GF
- int current_gf_interval; // GF interval chosen when we coded the last GF
int gf_overspend_bits; // Total bits overspent becasue of GF boost (cumulative)
@@ -686,6 +702,19 @@ typedef struct VP9_COMP {
int initial_width;
int initial_height;
+
+#if CONFIG_MULTIPLE_ARF
+ // ARF tracking variables.
+ int multi_arf_enabled;
+ unsigned int frame_coding_order_period;
+ unsigned int new_frame_coding_order_period;
+ int frame_coding_order[MAX_LAG_BUFFERS * 2];
+ int arf_buffer_idx[MAX_LAG_BUFFERS * 3 / 2];
+ int arf_weight[MAX_LAG_BUFFERS];
+ int arf_buffered;
+ int this_frame_weight;
+ int max_arf_level;
+#endif
} VP9_COMP;
void vp9_encode_frame(VP9_COMP *cpi);
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index d26f5ec46..fc22146c3 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -112,7 +112,7 @@ int vp9_bits_per_mb(FRAME_TYPE frame_type, int qindex,
const double q = vp9_convert_qindex_to_q(qindex);
int enumerator = frame_type == KEY_FRAME ? 4000000 : 2500000;
- // q based adjustment to baseline enumberator
+ // q based adjustment to baseline enumerator
enumerator += (int)(enumerator * q) >> 12;
return (int)(0.5 + (enumerator * correction_factor / q));
}
@@ -300,7 +300,7 @@ static void calc_iframe_target_size(VP9_COMP *cpi) {
}
-// Do the best we can to define the parameteres for the next GF based
+// Do the best we can to define the parameters for the next GF based
// on what information we have available.
//
// In this experimental code only two pass is supported
@@ -358,16 +358,13 @@ static void calc_pframe_target_size(VP9_COMP *cpi) {
(estimate_bits_at_q(1, q, cpi->common.MBs, 1.0)
* cpi->last_boost) / 100;
}
-
} else {
// If there is an active ARF at this location use the minimum
- // bits on this frame even if it is a contructed arf.
+ // bits on this frame even if it is a constructed arf.
// The active maximum quantizer insures that an appropriate
- // number of bits will be spent if needed for contstructed ARFs.
+ // number of bits will be spent if needed for constructed ARFs.
cpi->this_frame_target = 0;
}
-
- cpi->current_gf_interval = cpi->frames_till_gf_update_due;
}
}