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 &&
- !cpi->use_svc) {
+ if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
+ cpi->rc.is_src_frame_alt_ref && !cpi->use_svc) {
#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
cpi->arf_buffer_idx[sn];
}
#endif
+ if ((cpi->pass == 2) && cpi->multi_arf_enabled) {
+ GF_GROUP *gf_group = &cpi->twopass.gf_group;
+ arf_idx = gf_group->arf_update_idx[gf_group->index];
+ }
+
return (cpi->refresh_last_frame << cpi->lst_fb_idx) |
(cpi->refresh_golden_frame << cpi->gld_fb_idx) |
(cpi->refresh_alt_ref_frame << arf_idx);
cpi->refresh_alt_ref_frame = 0;
+ if (cpi->pass == 2)
+ cpi->multi_arf_enabled = 0;
+ else
+ cpi->multi_arf_enabled = 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.
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 &&
- !cpi->use_svc) {
+ else if (!cpi->multi_arf_enabled && cpi->refresh_golden_frame &&
+ cpi->rc.is_src_frame_alt_ref && !cpi->use_svc) {
#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
arf_idx = cpi->arf_buffer_idx[cpi->sequence_number + 1];
}
#endif
+ if ((cpi->pass == 2) && cpi->multi_arf_enabled) {
+ GF_GROUP *gf_group = &cpi->twopass.gf_group;
+ arf_idx = gf_group->arf_update_idx[gf_group->index];
+ }
+
ref_cnt_fb(cm->frame_bufs,
&cm->ref_frame_map[arf_idx], cm->new_fb_idx);
}
cpi->last_end_time_stamp_seen = cpi->source->ts_end;
}
+// Returns 0 if this is not an alt ref else the offset of the source frame
+// used as the arf midpoint.
+static int get_arf_src_index(VP9_COMP *cpi) {
+ RATE_CONTROL *const rc = &cpi->rc;
+ int arf_src_index = 0;
+ if (is_altref_enabled(&cpi->oxcf)) {
+ if (cpi->pass == 2) {
+ const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
+ if (gf_group->update_type[gf_group->index] == ARF_UPDATE) {
+ arf_src_index = gf_group->arf_src_offset[gf_group->index];
+ }
+ } else if (rc->source_alt_ref_pending) {
+ arf_src_index = rc->frames_till_gf_update_due;
+ }
+ }
+ return arf_src_index;
+}
+
+static void is_src_altref(VP9_COMP *cpi) {
+ RATE_CONTROL *const rc = &cpi->rc;
+
+#if CONFIG_MULTIPLE_ARF
+ int i;
+ // Is this frame the ARF overlay.
+ rc->is_src_frame_alt_ref = 0;
+ for (i = 0; i < cpi->arf_buffered; ++i) {
+ if (cpi->source == cpi->alt_ref_source[i]) {
+ rc->is_src_frame_alt_ref = 1;
+ cpi->refresh_golden_frame = 1;
+ break;
+ }
+ }
+#else
+ if (cpi->pass == 2) {
+ GF_GROUP *gf_group = &cpi->twopass.gf_group;
+ rc->is_src_frame_alt_ref =
+ (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE);
+ } else {
+ rc->is_src_frame_alt_ref = cpi->alt_ref_source &&
+ (cpi->source == cpi->alt_ref_source);
+ }
+#endif
+
+ if (rc->is_src_frame_alt_ref) {
+ // 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
+}
+
int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
size_t *size, uint8_t *dest,
int64_t *time_stamp, int64_t *time_end, int flush) {
struct vpx_usec_timer cmptimer;
YV12_BUFFER_CONFIG *force_src_buffer = NULL;
MV_REFERENCE_FRAME ref_frame;
+ int arf_src_index;
if (!cpi)
return -1;
cpi->refresh_golden_frame = 0;
cpi->refresh_alt_ref_frame = 0;
- // Should we code an alternate reference frame.
- if (is_altref_enabled(&cpi->oxcf) && rc->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 = rc->frames_till_gf_update_due;
-
- assert(frames_to_arf <= rc->frames_to_key);
+ // Should we encode an arf frame.
+ arf_src_index = get_arf_src_index(cpi);
+ if (arf_src_index) {
+ assert(arf_src_index <= rc->frames_to_key);
- if ((cpi->source = vp9_lookahead_peek(cpi->lookahead, frames_to_arf))) {
+ if ((cpi->source = vp9_lookahead_peek(cpi->lookahead, arf_src_index))) {
#if CONFIG_MULTIPLE_ARF
cpi->alt_ref_source[cpi->arf_buffered] = cpi->source;
#else
if (cpi->oxcf.arnr_max_frames > 0) {
// Produce the filtered ARF frame.
// TODO(agrange) merge these two functions.
- vp9_configure_arnr_filter(cpi, frames_to_arf, rc->gfu_boost);
- vp9_temporal_filter_prepare(cpi, frames_to_arf);
+ vp9_configure_arnr_filter(cpi, arf_src_index, rc->gfu_boost);
+ vp9_temporal_filter_prepare(cpi, arf_src_index);
vp9_extend_frame_borders(&cpi->alt_ref_buffer);
force_src_buffer = &cpi->alt_ref_buffer;
}
cpi->refresh_golden_frame = 0;
cpi->refresh_last_frame = 0;
rc->is_src_frame_alt_ref = 0;
-
-#if CONFIG_MULTIPLE_ARF
- if (!cpi->multi_arf_enabled)
-#endif
- rc->source_alt_ref_pending = 0;
+ rc->source_alt_ref_pending = 0;
} else {
rc->source_alt_ref_pending = 0;
}
}
if (!cpi->source) {
-#if CONFIG_MULTIPLE_ARF
- int i;
-#endif
-
// Get last frame source.
if (cm->current_video_frame > 0) {
if ((cpi->last_source = vp9_lookahead_peek(cpi->lookahead, -1)) == NULL)
return -1;
}
+ // Read in the source frame.
if ((cpi->source = vp9_lookahead_pop(cpi->lookahead, flush))) {
cm->show_frame = 1;
cm->intra_only = 0;
-#if CONFIG_MULTIPLE_ARF
- // Is this frame the ARF overlay.
- rc->is_src_frame_alt_ref = 0;
- for (i = 0; i < cpi->arf_buffered; ++i) {
- if (cpi->source == cpi->alt_ref_source[i]) {
- rc->is_src_frame_alt_ref = 1;
- cpi->refresh_golden_frame = 1;
- break;
- }
- }
-#else
- rc->is_src_frame_alt_ref = cpi->alt_ref_source &&
- (cpi->source == cpi->alt_ref_source);
-#endif
- if (rc->is_src_frame_alt_ref) {
- // 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
+ // Check to see if the frame to be encoded is an overlay
+ // for a previous arf frame and if so configure it as such.
+ if (cpi->pass == 0)
+ is_src_altref(cpi);
}
}
cpi->alt_fb_idx = cpi->arf_buffer_idx[cpi->sequence_number];
}
#endif
+ if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) &&
+ (cpi->pass == 2)) {
+ const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
+ cpi->alt_fb_idx = gf_group->arf_ref_idx[gf_group->index];
+ }
cpi->frame_flags = *frame_flags;
PC_TREE *pc_root;
int partition_cost[PARTITION_CONTEXTS][PARTITION_TYPES];
+ int multi_arf_enabled;
#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];
#include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_mcomp.h"
#include "vp9/encoder/vp9_quantize.h"
-#include "vp9/encoder/vp9_ratectrl.h"
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_variance.h"
TWO_PASS *twopass = &cpi->twopass;
FIRSTPASS_STATS frame_stats;
int i;
- int group_frame_index = 1;
+ int frame_index = 1;
int target_frame_size;
int key_frame;
const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
int64_t total_group_bits = gf_group_bits;
double modified_err = 0.0;
double err_fraction;
+ int mid_boost_bits = 0;
+ int middle_frame_idx;
key_frame = cpi->common.frame_type == KEY_FRAME ||
vp9_is_upper_layer_key_frame(cpi);
// For key frames the frame target rate is already set and it
// is also the golden frame.
- // 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 (!key_frame) {
- twopass->gf_group_bit_allocation[0] = gf_arf_bits;
+ if (rc->source_alt_ref_active) {
+ twopass->gf_group.update_type[0] = OVERLAY_UPDATE;
+ twopass->gf_group.rf_level[0] = INTER_NORMAL;
+ twopass->gf_group.bit_allocation[0] = 0;
+ twopass->gf_group.arf_update_idx[0] = 2;
+ twopass->gf_group.arf_ref_idx[0] = 2;
+ } else {
+ twopass->gf_group.update_type[0] = GF_UPDATE;
+ twopass->gf_group.rf_level[0] = GF_ARF_STD;
+ twopass->gf_group.bit_allocation[0] = gf_arf_bits;
+ twopass->gf_group.arf_update_idx[0] = 2;
+ twopass->gf_group.arf_ref_idx[0] = 2;
+ }
// Step over the golden frame / overlay frame
if (EOF == input_stats(twopass, &frame_stats))
return;
}
+ // Deduct the boost bits for arf (or gf if it is not a key frame)
+ // from the group total.
+ if (rc->source_alt_ref_pending || !key_frame)
+ total_group_bits -= gf_arf_bits;
+
// Store the bits to spend on the ARF if there is one.
if (rc->source_alt_ref_pending) {
- twopass->gf_group_bit_allocation[group_frame_index++] = gf_arf_bits;
+ // A portion of the gf / arf extra bits are set asside for lower level
+ // boosted frames in the middle of the group.
+ mid_boost_bits = gf_arf_bits >> 5;
+ gf_arf_bits -= (gf_arf_bits >> 5);
+
+ twopass->gf_group.update_type[frame_index] = ARF_UPDATE;
+ twopass->gf_group.rf_level[frame_index] = GF_ARF_STD;
+ twopass->gf_group.bit_allocation[frame_index] = gf_arf_bits;
+ twopass->gf_group.arf_src_offset[frame_index] =
+ rc->baseline_gf_interval - 1;
+ twopass->gf_group.arf_update_idx[frame_index] = 2;
+ twopass->gf_group.arf_ref_idx[frame_index] = 2;
+ ++frame_index;
+
+ if (cpi->multi_arf_enabled) {
+ // Set aside a slot for a level 1 arf.
+ twopass->gf_group.update_type[frame_index] = ARF_UPDATE;
+ twopass->gf_group.rf_level[frame_index] = GF_ARF_LOW;
+ twopass->gf_group.arf_src_offset[frame_index] =
+ ((rc->baseline_gf_interval - 1) >> 1);
+ twopass->gf_group.arf_update_idx[frame_index] = 3;
+ twopass->gf_group.arf_ref_idx[frame_index] = 2;
+ ++frame_index;
+ }
}
- // Deduct the boost bits for arf or gf if it is not a key frame.
- if (rc->source_alt_ref_pending || !key_frame)
- total_group_bits -= gf_arf_bits;
+ // Define middle frame
+ middle_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
// Allocate bits to the other frames in the group.
for (i = 0; i < rc->baseline_gf_interval - 1; ++i) {
err_fraction = 0.0;
target_frame_size = (int)((double)total_group_bits * err_fraction);
+
+ if (rc->source_alt_ref_pending && cpi->multi_arf_enabled) {
+ mid_boost_bits += (target_frame_size >> 4);
+ target_frame_size -= (target_frame_size >> 4);
+
+ if (frame_index <= middle_frame_idx) {
+ twopass->gf_group.arf_update_idx[frame_index] = 3;
+ twopass->gf_group.arf_ref_idx[frame_index] = 3;
+ } else {
+ twopass->gf_group.arf_update_idx[frame_index] = 2;
+ twopass->gf_group.arf_ref_idx[frame_index] = 2;
+ }
+ }
+
target_frame_size = clamp(target_frame_size, 0,
MIN(max_bits, (int)total_group_bits));
- twopass->gf_group_bit_allocation[group_frame_index++] = target_frame_size;
+ twopass->gf_group.update_type[frame_index] = LF_UPDATE;
+ twopass->gf_group.rf_level[frame_index] = INTER_NORMAL;
+
+ twopass->gf_group.bit_allocation[frame_index] = target_frame_size;
+ ++frame_index;
+ }
+
+ if (rc->source_alt_ref_pending && cpi->multi_arf_enabled) {
+ twopass->gf_group.bit_allocation[2] =
+ twopass->gf_group.bit_allocation[middle_frame_idx] + mid_boost_bits;
+ twopass->gf_group.update_type[middle_frame_idx] = OVERLAY_UPDATE;
+ twopass->gf_group.bit_allocation[middle_frame_idx] = 0;
}
}
// Reset the GF group data structures unless this is a key
// frame in which case it will already have been done.
if (cpi->common.frame_type != KEY_FRAME) {
- twopass->gf_group_index = 0;
- vp9_zero(twopass->gf_group_bit_allocation);
+ vp9_zero(twopass->gf_group);
}
vp9_clear_system_state();
else
rc->baseline_gf_interval = i;
+ rc->frames_till_gf_update_due = rc->baseline_gf_interval;
+
// Should we use the alternate reference frame.
if (allow_alt_ref &&
(i < cpi->oxcf.lag_in_frames) &&
cpi->common.frame_type = KEY_FRAME;
// Reset the GF group data structures.
- twopass->gf_group_index = 0;
- vp9_zero(twopass->gf_group_bit_allocation);
+ vp9_zero(twopass->gf_group);
// Is this a forced key frame by interval.
rc->this_key_frame_forced = rc->next_key_frame_forced;
twopass->kf_group_bits -= kf_bits;
// Save the bits to spend on the key frame.
- twopass->gf_group_bit_allocation[0] = kf_bits;
+ twopass->gf_group.bit_allocation[0] = kf_bits;
+ twopass->gf_group.update_type[0] = KF_UPDATE;
+ twopass->gf_group.rf_level[0] = KF_STD;
// Note the total error score of the kf group minus the key frame itself.
twopass->kf_group_error_left = (int)(kf_group_err - kf_mod_err);
}
}
+// Define the reference buffers that will be updated post encode.
+void configure_buffer_updates(VP9_COMP *cpi) {
+ TWO_PASS *const twopass = &cpi->twopass;
+
+ cpi->rc.is_src_frame_alt_ref = 0;
+ switch (twopass->gf_group.update_type[twopass->gf_group.index]) {
+ case KF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_alt_ref_frame = 1;
+ break;
+ case LF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+ case GF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+ case OVERLAY_UPDATE:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_alt_ref_frame = 0;
+ cpi->rc.is_src_frame_alt_ref = 1;
+ break;
+ case ARF_UPDATE:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_alt_ref_frame = 1;
+ break;
+ default:
+ assert(0);
+ }
+}
+
+
void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
if (!twopass->stats_in)
return;
- // Increment the gf group index.
- ++twopass->gf_group_index;
-
// If this is an arf frame then we dont want to read the stats file or
// advance the input pointer as we already have what we need.
- if (cpi->refresh_alt_ref_frame) {
+ if (twopass->gf_group.update_type[twopass->gf_group.index] == ARF_UPDATE) {
int target_rate;
- target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
+ configure_buffer_updates(cpi);
+ target_rate = twopass->gf_group.bit_allocation[twopass->gf_group.index];
target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate);
rc->base_frame_target = target_rate;
#ifdef LONG_TERM_VBR_CORRECTION
}
}
- target_rate = twopass->gf_group_bit_allocation[twopass->gf_group_index];
+ configure_buffer_updates(cpi);
+
+ target_rate = twopass->gf_group.bit_allocation[twopass->gf_group.index];
if (cpi->common.frame_type == KEY_FRAME)
target_rate = vp9_rc_clamp_iframe_target_size(cpi, target_rate);
else
twopass->kf_group_bits -= bits_used;
}
twopass->kf_group_bits = MAX(twopass->kf_group_bits, 0);
+
+ // Increment the gf group index ready for the next frame.
+ ++twopass->gf_group.index;
}
#define VP9_ENCODER_VP9_FIRSTPASS_H_
#include "vp9/encoder/vp9_lookahead.h"
+#include "vp9/encoder/vp9_ratectrl.h"
#ifdef __cplusplus
extern "C" {
int64_t spatial_layer_id;
} FIRSTPASS_STATS;
+typedef enum {
+ KF_UPDATE = 0,
+ LF_UPDATE = 1,
+ GF_UPDATE = 2,
+ ARF_UPDATE = 3,
+ OVERLAY_UPDATE = 4,
+ FRAME_UPDATE_TYPES = 5
+} FRAME_UPDATE_TYPE;
+
+typedef struct {
+ unsigned char index;
+ RATE_FACTOR_LEVEL rf_level[MAX_LAG_BUFFERS * 2];
+ FRAME_UPDATE_TYPE update_type[MAX_LAG_BUFFERS * 2];
+ unsigned char arf_src_offset[MAX_LAG_BUFFERS * 2];
+ unsigned char arf_update_idx[MAX_LAG_BUFFERS * 2];
+ unsigned char arf_ref_idx[MAX_LAG_BUFFERS * 2];
+ int bit_allocation[MAX_LAG_BUFFERS * 2];
+} GF_GROUP;
+
typedef struct {
unsigned int section_intra_rating;
unsigned int next_iiratio;
int active_worst_quality;
- int gf_group_index;
- int gf_group_bit_allocation[MAX_LAG_BUFFERS * 2];
+ GF_GROUP gf_group;
} TWO_PASS;
struct VP9_COMP;
}
void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) {
+ int i;
+
if (pass == 0 && oxcf->rc_mode == VPX_CBR) {
rc->avg_frame_qindex[KEY_FRAME] = oxcf->worst_allowed_q;
rc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q;
rc->tot_q = 0.0;
rc->avg_q = vp9_convert_qindex_to_q(oxcf->worst_allowed_q);
- rc->rate_correction_factor = 1.0;
- rc->key_frame_rate_correction_factor = 1.0;
- rc->gf_rate_correction_factor = 1.0;
+ for (i = 0; i < RATE_FACTOR_LEVELS; ++i) {
+ rc->rate_correction_factors[i] = 1.0;
+ }
}
int vp9_rc_drop_frame(VP9_COMP *cpi) {
}
static double get_rate_correction_factor(const VP9_COMP *cpi) {
+ const RATE_CONTROL *const rc = &cpi->rc;
+
if (cpi->common.frame_type == KEY_FRAME) {
- return cpi->rc.key_frame_rate_correction_factor;
+ return rc->rate_correction_factors[KF_STD];
+ } else if (cpi->pass == 2) {
+ RATE_FACTOR_LEVEL rf_lvl =
+ cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index];
+ return rc->rate_correction_factors[rf_lvl];
} else {
if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) &&
- !cpi->rc.is_src_frame_alt_ref &&
+ !rc->is_src_frame_alt_ref &&
!(cpi->use_svc && cpi->oxcf.rc_mode == VPX_CBR))
- return cpi->rc.gf_rate_correction_factor;
+ return rc->rate_correction_factors[GF_ARF_STD];
else
- return cpi->rc.rate_correction_factor;
+ return rc->rate_correction_factors[INTER_NORMAL];
}
}
static void set_rate_correction_factor(VP9_COMP *cpi, double factor) {
+ RATE_CONTROL *const rc = &cpi->rc;
+
if (cpi->common.frame_type == KEY_FRAME) {
- cpi->rc.key_frame_rate_correction_factor = factor;
+ rc->rate_correction_factors[KF_STD] = factor;
+ } else if (cpi->pass == 2) {
+ RATE_FACTOR_LEVEL rf_lvl =
+ cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index];
+ rc->rate_correction_factors[rf_lvl] = factor;
} else {
if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) &&
- !cpi->rc.is_src_frame_alt_ref &&
+ !rc->is_src_frame_alt_ref &&
!(cpi->use_svc && cpi->oxcf.rc_mode == VPX_CBR))
- cpi->rc.gf_rate_correction_factor = factor;
+ rc->rate_correction_factors[GF_ARF_STD] = factor;
else
- cpi->rc.rate_correction_factor = factor;
+ rc->rate_correction_factors[INTER_NORMAL] = factor;
}
}
active_worst_quality, 2.0);
} else if (!rc->is_src_frame_alt_ref &&
(oxcf->rc_mode != VPX_CBR) &&
- (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
+ (cpi->refresh_alt_ref_frame)) {
qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type,
active_worst_quality, 1.75);
}
RATE_CONTROL *const rc = &cpi->rc;
rc->frames_since_golden = 0;
-#if CONFIG_MULTIPLE_ARF
- if (!cpi->multi_arf_enabled)
-#endif
- // Clear the alternate reference update pending flag.
- rc->source_alt_ref_pending = 0;
+ // Mark the alt ref as done (setting to 0 means no further alt refs pending).
+ rc->source_alt_ref_pending = 0;
// Set the alternate reference frame active flag
rc->source_alt_ref_active = 1;
// this frame refreshes means next frames don't unless specified by user
rc->frames_since_golden = 0;
- if (!rc->source_alt_ref_pending)
+ if (cpi->pass == 2) {
+ if (!rc->source_alt_ref_pending &&
+ cpi->twopass.gf_group.rf_level[0] == GF_ARF_STD)
+ rc->source_alt_ref_active = 0;
+ } else if (!rc->source_alt_ref_pending) {
rc->source_alt_ref_active = 0;
+ }
// Decrement count down till next gf
if (rc->frames_till_gf_update_due > 0)
// Bits Per MB at different Q (Multiplied by 512)
#define BPER_MB_NORMBITS 9
+typedef enum {
+ INTER_NORMAL = 0,
+ INTER_HIGH = 1,
+ GF_ARF_LOW = 2,
+ GF_ARF_STD = 3,
+ KF_STD = 4,
+ RATE_FACTOR_LEVELS = 5
+} RATE_FACTOR_LEVEL;
+
typedef struct {
// Rate targetting variables
int base_frame_target; // A baseline frame target before adjustment
int last_boost;
int kf_boost;
- double rate_correction_factor;
- double key_frame_rate_correction_factor;
- double gf_rate_correction_factor;
+ double rate_correction_factors[RATE_FACTOR_LEVELS];
int frames_since_golden;
int frames_till_gf_update_due;
for (layer = 0; layer < layer_end; ++layer) {
LAYER_CONTEXT *const lc = &svc->layer_context[layer];
RATE_CONTROL *const lrc = &lc->rc;
+ int i;
lc->current_video_frame_in_layer = 0;
lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q;
lrc->ni_av_qi = oxcf->worst_allowed_q;
lrc->ni_frames = 0;
lrc->decimation_count = 0;
lrc->decimation_factor = 0;
- lrc->rate_correction_factor = 1.0;
- lrc->key_frame_rate_correction_factor = 1.0;
+
+ for (i = 0; i < RATE_FACTOR_LEVELS; ++i) {
+ lrc->rate_correction_factors[i] = 1.0;
+ }
if (svc->number_temporal_layers > 1) {
lc->target_bandwidth = oxcf->ts_target_bitrate[layer];