Commit c2876cf0 authored by Adrian Grange's avatar Adrian Grange
Browse files

Initial addition of multiple ARF frames

This is work-in-progress, it implements multiple ARF
encoding behind an experimental flag.

It adds the ability to insert multiple ARF frames into a
single ARF group. This patch implements the reordering
of the coded frames, and implements a fixed-length coding
pattern. It applies a fixed quantizer strategy based on
where the frame is in the coding sequence.

Further work to modify the rate control strategy is
ongoing and will be submitted via a set of future patches.

In this first step, each ARF group is recursively
bisected and an ARF frame added at that position in the
sequence. The recursion continues until ARF frames are
within MIN_GF_INTERVAL frames.

The code sits behind the "multiple-arf" experimental
flag ("CONFIG_MULTIPLE_ARF"). The experimental flag
"oneshotq" ("CONFIG_ONESHOTQ") also needs to be enabled
for this patch to work correctly.

Change-Id: Ie473b05ebb43ac473c0cfb659b2b8042823085e2
parent 626d0650
......@@ -253,6 +253,7 @@ EXPERIMENT_LIST="
scatterscan
oneshotq
sbsegment
multiple_arf
"
CONFIG_LIST="
external_build
......
......@@ -2685,7 +2685,7 @@ static void update_alt_ref_frame_stats(VP8_COMP *cpi)
/* Clear the alternate reference update pending flag. */
cpi->source_alt_ref_pending = 0;
/* Set the alternate refernce frame active flag */
/* Set the alternate reference frame active flag */
cpi->source_alt_ref_active = 1;
......@@ -3332,7 +3332,7 @@ static void encode_frame_to_data_rate
else
cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 0;
/* 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.
*/
......
......@@ -18,6 +18,7 @@
#include "vp9/common/vp9_entropymv.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_entropymode.h"
#if CONFIG_POSTPROC
#include "vp9/common/vp9_postproc.h"
#endif
......@@ -37,8 +38,13 @@ void vp9_initialize_common(void);
#define QINDEX_RANGE (MAXQ + 1)
#if CONFIG_MULTIPLE_ARF
#define NUM_REF_FRAMES 8
#define NUM_REF_FRAMES_LG2 3
#else
#define NUM_REF_FRAMES 3
#define NUM_REF_FRAMES_LG2 2
#endif
#define ALLOWED_REFS_PER_FRAME 3
......@@ -52,6 +58,8 @@ void vp9_initialize_common(void);
#define COMP_PRED_CONTEXTS 2
#define MAX_LAG_BUFFERS 25
typedef struct frame_contexts {
vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1];
vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */
......
......@@ -249,7 +249,7 @@ int vp9_get_reference_dec(VP9D_PTR ptr, int index, YV12_BUFFER_CONFIG **fb) {
return 0;
}
/* If any buffer updating is signalled it should be done here. */
/* If any buffer updating is signaled it should be done here. */
static void swap_frame_buffers(VP9D_COMP *pbi) {
int ref_index = 0, mask;
......
......@@ -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);
......
......@@ -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;