summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorDeb Mukherjee <debargha@google.com>2014-01-22 18:00:08 -0800
committerDeb Mukherjee <debargha@google.com>2014-01-29 11:04:52 -0800
commit50bf8fd4f5f0991f8788cf5ac9e6e89f49fd6937 (patch)
treee95f0a9e72076cf8a2e7b4ee8a6b7cdc9e9cc84b /vp9/encoder
parent00bfacb769d95c89b361aa57a9f0da10bc2810a3 (diff)
downloadlibvpx-50bf8fd4f5f0991f8788cf5ac9e6e89f49fd6937.tar
libvpx-50bf8fd4f5f0991f8788cf5ac9e6e89f49fd6937.tar.gz
libvpx-50bf8fd4f5f0991f8788cf5ac9e6e89f49fd6937.tar.bz2
libvpx-50bf8fd4f5f0991f8788cf5ac9e6e89f49fd6937.zip
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
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_firstpass.c21
-rw-r--r--vp9/encoder/vp9_lookahead.c1
-rw-r--r--vp9/encoder/vp9_onyx_if.c17
-rw-r--r--vp9/encoder/vp9_ratectrl.c44
-rw-r--r--vp9/encoder/vp9_temporal_filter.c22
-rw-r--r--vp9/encoder/vp9_temporal_filter.h5
6 files changed, 56 insertions, 54 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 28b343ce7..ee20b8eb6 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -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->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;
}
- if (!cpi->twopass.stats_in)
- return;
vp9_clear_system_state();
diff --git a/vp9/encoder/vp9_lookahead.c b/vp9/encoder/vp9_lookahead.c
index ee73ff15a..e6e59c05a 100644
--- a/vp9/encoder/vp9_lookahead.c
+++ b/vp9/encoder/vp9_lookahead.c
@@ -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)
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 1852d1ea0..379e0ac47 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -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;
}
}
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 3c816a3d0..74eb98fb0 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -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;
diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c
index c9a424648..e822e4c64 100644
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -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
diff --git a/vp9/encoder/vp9_temporal_filter.h b/vp9/encoder/vp9_temporal_filter.h
index eea2f1018..3028d7884 100644
--- a/vp9/encoder/vp9_temporal_filter.h
+++ b/vp9/encoder/vp9_temporal_filter.h
@@ -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"