diff options
author | Deb Mukherjee <debargha@google.com> | 2014-01-22 18:00:08 -0800 |
---|---|---|
committer | Deb Mukherjee <debargha@google.com> | 2014-01-29 11:04:52 -0800 |
commit | 50bf8fd4f5f0991f8788cf5ac9e6e89f49fd6937 (patch) | |
tree | e95f0a9e72076cf8a2e7b4ee8a6b7cdc9e9cc84b /vp9/encoder | |
parent | 00bfacb769d95c89b361aa57a9f0da10bc2810a3 (diff) | |
download | libvpx-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.c | 21 | ||||
-rw-r--r-- | vp9/encoder/vp9_lookahead.c | 1 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_if.c | 17 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 44 | ||||
-rw-r--r-- | vp9/encoder/vp9_temporal_filter.c | 22 | ||||
-rw-r--r-- | vp9/encoder/vp9_temporal_filter.h | 5 |
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" |