Enables alt-ref frames in one pass mode
Includes a few fixes and clean-ups that adds the ability to use alt-ref frames in one-pass mode. Whether alt-refs are actually used or not is controlled by a macro USE_ALTREF_FOR_ONE_PASS in vp9_firstpass.c. This first cut seems to improve derf by 15+% in 1-pass mode. But further experiments with parameters are underway. Change-Id: I78254421435478003367c788c7930d2dc4ee2816
This commit is contained in:
parent
00bfacb769
commit
50bf8fd4f5
@ -2328,6 +2328,7 @@ void vp9_get_svc_params(VP9_COMP *cpi) {
|
||||
(cpi->oxcf.auto_key && (cpi->rc.frames_since_key %
|
||||
cpi->key_frame_frequency == 0))) {
|
||||
cm->frame_type = KEY_FRAME;
|
||||
cpi->rc.source_alt_ref_active = 0;
|
||||
} else {
|
||||
cm->frame_type = INTER_FRAME;
|
||||
}
|
||||
@ -2335,6 +2336,9 @@ void vp9_get_svc_params(VP9_COMP *cpi) {
|
||||
cpi->rc.baseline_gf_interval = INT_MAX;
|
||||
}
|
||||
|
||||
// Use this macro to turn on/off use of alt-refs in one-pass mode.
|
||||
#define USE_ALTREF_FOR_ONE_PASS 1
|
||||
|
||||
void vp9_get_one_pass_params(VP9_COMP *cpi) {
|
||||
VP9_COMMON *const cm = &cpi->common;
|
||||
if (!cpi->refresh_alt_ref_frame &&
|
||||
@ -2346,13 +2350,20 @@ void vp9_get_one_pass_params(VP9_COMP *cpi) {
|
||||
cpi->rc.this_key_frame_forced = cm->current_video_frame != 0 &&
|
||||
cpi->rc.frames_to_key == 0;
|
||||
cpi->rc.frames_to_key = cpi->key_frame_frequency;
|
||||
cpi->rc.kf_boost = 300;
|
||||
cpi->rc.kf_boost = 2000;
|
||||
cpi->rc.source_alt_ref_active = 0;
|
||||
} else {
|
||||
cm->frame_type = INTER_FRAME;
|
||||
}
|
||||
if (cpi->rc.frames_till_gf_update_due == 0) {
|
||||
cpi->rc.baseline_gf_interval = DEFAULT_GF_INTERVAL;
|
||||
cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval;
|
||||
// NOTE: frames_till_gf_update_due must be <= frames_to_key.
|
||||
if (cpi->rc.frames_till_gf_update_due > cpi->rc.frames_to_key)
|
||||
cpi->rc.frames_till_gf_update_due = cpi->rc.frames_to_key;
|
||||
cpi->refresh_golden_frame = 1;
|
||||
cpi->rc.source_alt_ref_pending = USE_ALTREF_FOR_ONE_PASS;
|
||||
cpi->rc.gfu_boost = 1000;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2366,7 +2377,8 @@ void vp9_get_one_pass_cbr_params(VP9_COMP *cpi) {
|
||||
cpi->rc.this_key_frame_forced = cm->current_video_frame != 0 &&
|
||||
cpi->rc.frames_to_key == 0;
|
||||
cpi->rc.frames_to_key = cpi->key_frame_frequency;
|
||||
cpi->rc.kf_boost = 300;
|
||||
cpi->rc.kf_boost = 2000;
|
||||
cpi->rc.source_alt_ref_active = 0;
|
||||
} else {
|
||||
cm->frame_type = INTER_FRAME;
|
||||
}
|
||||
@ -2400,12 +2412,13 @@ void vp9_get_second_pass_params(VP9_COMP *cpi) {
|
||||
double this_frame_intra_error;
|
||||
double this_frame_coded_error;
|
||||
|
||||
if (cpi->refresh_alt_ref_frame) {
|
||||
cpi->common.frame_type = INTER_FRAME;
|
||||
return;
|
||||
}
|
||||
if (!cpi->twopass.stats_in)
|
||||
return;
|
||||
if (cpi->refresh_alt_ref_frame) {
|
||||
cpi->common.frame_type = INTER_FRAME;
|
||||
rc->per_frame_bandwidth = cpi->twopass.gf_bits;
|
||||
return;
|
||||
}
|
||||
|
||||
vp9_clear_system_state();
|
||||
|
||||
|
@ -173,7 +173,6 @@ struct lookahead_entry * vp9_lookahead_peek(struct lookahead_ctx *ctx,
|
||||
int index) {
|
||||
struct lookahead_entry *buf = NULL;
|
||||
|
||||
assert(index < (int)ctx->max_sz);
|
||||
if (index < (int)ctx->sz) {
|
||||
index += ctx->read_idx;
|
||||
if (index >= (int)ctx->max_sz)
|
||||
|
@ -2953,15 +2953,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
||||
// Clear down mmx registers to allow floating point in what follows.
|
||||
vp9_clear_system_state();
|
||||
|
||||
// For an alt ref frame in 2 pass we skip the call to the second
|
||||
// pass function that sets the target bandwidth so we must set it here.
|
||||
if (cpi->refresh_alt_ref_frame) {
|
||||
// Set a per frame bit target for the alt ref frame.
|
||||
cpi->rc.per_frame_bandwidth = cpi->twopass.gf_bits;
|
||||
// Set a per second target bitrate.
|
||||
cpi->target_bandwidth = (int)(cpi->twopass.gf_bits * cpi->output_framerate);
|
||||
}
|
||||
|
||||
// Clear zbin over-quant value and mode boost values.
|
||||
cpi->zbin_mode_boost = 0;
|
||||
|
||||
@ -3293,7 +3284,6 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size,
|
||||
|
||||
vp9_get_second_pass_params(cpi);
|
||||
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
|
||||
// vp9_print_modes_and_motion_vectors(&cpi->common, "encode.stt");
|
||||
|
||||
vp9_twopass_postencode_update(cpi, *size);
|
||||
}
|
||||
@ -3442,8 +3432,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
|
||||
if (cpi->oxcf.arnr_max_frames > 0) {
|
||||
// Produce the filtered ARF frame.
|
||||
// TODO(agrange) merge these two functions.
|
||||
configure_arnr_filter(cpi, cm->current_video_frame + frames_to_arf,
|
||||
cpi->rc.gfu_boost);
|
||||
vp9_configure_arnr_filter(cpi, frames_to_arf, cpi->rc.gfu_boost);
|
||||
vp9_temporal_filter_prepare(cpi, frames_to_arf);
|
||||
vp9_extend_frame_borders(&cpi->alt_ref_buffer,
|
||||
cm->subsampling_x, cm->subsampling_y);
|
||||
@ -3459,7 +3448,9 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
|
||||
#if CONFIG_MULTIPLE_ARF
|
||||
if (!cpi->multi_arf_enabled)
|
||||
#endif
|
||||
cpi->rc.source_alt_ref_pending = 0; // Clear Pending altf Ref flag.
|
||||
cpi->rc.source_alt_ref_pending = 0;
|
||||
} else {
|
||||
cpi->rc.source_alt_ref_pending = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ static void calc_iframe_target_size(VP9_COMP *cpi) {
|
||||
vp9_clear_system_state(); // __asm emms;
|
||||
|
||||
// For 1-pass.
|
||||
if (cpi->pass == 0) {
|
||||
if (cpi->pass == 0 && oxcf->end_usage == USAGE_STREAM_FROM_SERVER) {
|
||||
if (cpi->common.current_video_frame == 0) {
|
||||
target = oxcf->starting_buffer_level / 2;
|
||||
} else {
|
||||
@ -246,7 +246,7 @@ static void calc_iframe_target_size(VP9_COMP *cpi) {
|
||||
|
||||
if (oxcf->rc_max_intra_bitrate_pct) {
|
||||
const int max_rate = rc->per_frame_bandwidth *
|
||||
oxcf->rc_max_intra_bitrate_pct / 100;
|
||||
oxcf->rc_max_intra_bitrate_pct / 100;
|
||||
target = MIN(target, max_rate);
|
||||
}
|
||||
rc->this_frame_target = target;
|
||||
@ -375,27 +375,22 @@ static int target_size_from_buffer_level(const VP9_CONFIG *oxcf,
|
||||
static void calc_pframe_target_size(VP9_COMP *const cpi) {
|
||||
RATE_CONTROL *const rc = &cpi->rc;
|
||||
const VP9_CONFIG *const oxcf = &cpi->oxcf;
|
||||
int min_frame_target = MAX(rc->min_frame_bandwidth,
|
||||
rc->av_per_frame_bandwidth >> 5);
|
||||
if (cpi->refresh_alt_ref_frame) {
|
||||
// Special alt reference frame case
|
||||
// Per frame bit target for the alt ref frame
|
||||
rc->per_frame_bandwidth = cpi->twopass.gf_bits;
|
||||
rc->this_frame_target = rc->per_frame_bandwidth;
|
||||
} else {
|
||||
// Normal frames (gf and inter).
|
||||
rc->this_frame_target = rc->per_frame_bandwidth;
|
||||
// Set target frame size based on buffer level, for 1 pass CBR.
|
||||
if (cpi->pass == 0 && oxcf->end_usage == USAGE_STREAM_FROM_SERVER) {
|
||||
// Need to decide how low min_frame_target should be for 1-pass CBR.
|
||||
// For now, use: cpi->rc.av_per_frame_bandwidth / 16:
|
||||
min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4,
|
||||
FRAME_OVERHEAD_BITS);
|
||||
rc->this_frame_target = target_size_from_buffer_level(oxcf, rc);
|
||||
// Adjust qp-max based on buffer level.
|
||||
rc->active_worst_quality =
|
||||
adjust_active_worst_quality_from_buffer_level(oxcf, rc);
|
||||
}
|
||||
int min_frame_target;
|
||||
rc->this_frame_target = rc->per_frame_bandwidth;
|
||||
|
||||
if (cpi->pass == 0 && oxcf->end_usage == USAGE_STREAM_FROM_SERVER) {
|
||||
// Need to decide how low min_frame_target should be for 1-pass CBR.
|
||||
// For now, use: cpi->rc.av_per_frame_bandwidth / 16:
|
||||
min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4,
|
||||
FRAME_OVERHEAD_BITS);
|
||||
rc->this_frame_target = target_size_from_buffer_level(oxcf, rc);
|
||||
// Adjust qp-max based on buffer level.
|
||||
rc->active_worst_quality =
|
||||
adjust_active_worst_quality_from_buffer_level(oxcf, rc);
|
||||
|
||||
if (rc->this_frame_target < min_frame_target)
|
||||
rc->this_frame_target = min_frame_target;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that the total sum of adjustments is not above the maximum allowed.
|
||||
@ -404,6 +399,9 @@ static void calc_pframe_target_size(VP9_COMP *const cpi) {
|
||||
// not capable of recovering all the extra bits we have spent in the KF or GF,
|
||||
// then the remainder will have to be recovered over a longer time span via
|
||||
// other buffer / rate control mechanisms.
|
||||
min_frame_target = MAX(rc->min_frame_bandwidth,
|
||||
rc->av_per_frame_bandwidth >> 5);
|
||||
|
||||
if (rc->this_frame_target < min_frame_target)
|
||||
rc->this_frame_target = min_frame_target;
|
||||
|
||||
|
@ -392,7 +392,6 @@ void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance) {
|
||||
const int num_frames_backward = distance;
|
||||
const int num_frames_forward = vp9_lookahead_depth(cpi->lookahead)
|
||||
- (num_frames_backward + 1);
|
||||
|
||||
struct scale_factors sf;
|
||||
|
||||
switch (blur_type) {
|
||||
@ -408,7 +407,6 @@ void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance) {
|
||||
|
||||
case 2:
|
||||
// Forward Blur
|
||||
|
||||
frames_to_blur_forward = num_frames_forward;
|
||||
|
||||
if (frames_to_blur_forward >= max_frames)
|
||||
@ -471,22 +469,24 @@ void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance) {
|
||||
strength, &sf);
|
||||
}
|
||||
|
||||
void configure_arnr_filter(VP9_COMP *cpi, const unsigned int this_frame,
|
||||
const int group_boost) {
|
||||
void vp9_configure_arnr_filter(VP9_COMP *cpi,
|
||||
const unsigned int frames_to_arnr,
|
||||
const int group_boost) {
|
||||
int half_gf_int;
|
||||
int frames_after_arf;
|
||||
int frames_bwd = cpi->oxcf.arnr_max_frames - 1;
|
||||
int frames_fwd = cpi->oxcf.arnr_max_frames - 1;
|
||||
int q;
|
||||
|
||||
// Define the arnr filter width for this group of frames:
|
||||
// We only filter frames that lie within a distance of half
|
||||
// the GF interval from the ARF frame. We also have to trap
|
||||
// cases where the filter extends beyond the end of clip.
|
||||
// Note: this_frame->frame has been updated in the loop
|
||||
// so it now points at the ARF frame.
|
||||
// Define the arnr filter width for this group of frames. We only
|
||||
// filter frames that lie within a distance of half the GF interval
|
||||
// from the ARF frame. We also have to trap cases where the filter
|
||||
// extends beyond the end of the lookahead buffer.
|
||||
// Note: frames_to_arnr parameter is the offset of the arnr
|
||||
// frame from the current frame.
|
||||
half_gf_int = cpi->rc.baseline_gf_interval >> 1;
|
||||
frames_after_arf = (int)(cpi->twopass.total_stats.count - this_frame - 1);
|
||||
frames_after_arf = vp9_lookahead_depth(cpi->lookahead)
|
||||
- frames_to_arnr - 1;
|
||||
|
||||
switch (cpi->oxcf.arnr_type) {
|
||||
case 1: // Backward filter
|
||||
|
@ -16,8 +16,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance);
|
||||
void configure_arnr_filter(VP9_COMP *cpi, const unsigned int this_frame,
|
||||
const int group_boost);
|
||||
void vp9_configure_arnr_filter(VP9_COMP *cpi,
|
||||
const unsigned int frames_to_arnr,
|
||||
const int group_boost);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
Loading…
x
Reference in New Issue
Block a user