diff options
Diffstat (limited to 'vp9/encoder/vp9_ratectrl.c')
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 177 |
1 files changed, 129 insertions, 48 deletions
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 342081644..76ec84b5f 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -27,6 +27,11 @@ #include "vp9/encoder/vp9_encodemv.h" #include "vp9/encoder/vp9_ratectrl.h" +// Max rate target for 1080P and below encodes under normal circumstances +// (1920 * 1080 / (16 * 16)) * MAX_MB_RATE bits per MB +#define MAX_MB_RATE 250 +#define MAXRATE_1080P 2025000 + #define DEFAULT_KF_BOOST 2000 #define DEFAULT_GF_BOOST 2000 @@ -74,14 +79,13 @@ void vp9_rc_init_minq_luts() { for (i = 0; i < QINDEX_RANGE; i++) { const double maxq = vp9_convert_qindex_to_q(i); - kf_low_motion_minq[i] = get_minq_index(maxq, 0.000001, -0.0004, 0.15); kf_high_motion_minq[i] = get_minq_index(maxq, 0.000002, -0.0012, 0.50); gf_low_motion_minq[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.32); gf_high_motion_minq[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.50); afq_low_motion_minq[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.33); afq_high_motion_minq[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55); - inter_minq[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.75); + inter_minq[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.55); } } @@ -367,8 +371,8 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame, // Calculate required scaling factor based on target frame size and size of // frame produced using previous Q. - target_bits_per_mb = - ((uint64_t)target_bits_per_frame << BPER_MB_NORMBITS) / cm->MBs; + target_bits_per_mb = + ((uint64_t)target_bits_per_frame << BPER_MB_NORMBITS) / cm->MBs; i = active_best_quality; @@ -565,11 +569,18 @@ static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi, #if LIMIT_QRANGE_FOR_ALTREF_AND_KEY // Limit Q range for the adaptive loop. - if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) { - if (!(cm->current_video_frame == 0)) - *top_index = (active_worst_quality + active_best_quality * 3) / 4; + if (cm->frame_type == KEY_FRAME && + !rc->this_key_frame_forced && + !(cm->current_video_frame == 0)) { + int qdelta = 0; + vp9_clear_system_state(); + qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, + active_worst_quality, 2.0); + *top_index = active_worst_quality + qdelta; + *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index; } #endif + // Special case code to try and match quality with forced key frames if (cm->frame_type == KEY_FRAME && rc->this_key_frame_forced) { q = rc->last_boosted_qindex; @@ -725,15 +736,26 @@ static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi, *bottom_index = active_best_quality; #if LIMIT_QRANGE_FOR_ALTREF_AND_KEY - // Limit Q range for the adaptive loop. - if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) { - if (!(cm->current_video_frame == 0)) - *top_index = (active_worst_quality + active_best_quality * 3) / 4; - } else if (!rc->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - *top_index = (active_worst_quality + active_best_quality) / 2; + { + int qdelta = 0; + vp9_clear_system_state(); + + // Limit Q range for the adaptive loop. + if (cm->frame_type == KEY_FRAME && + !rc->this_key_frame_forced && + !(cm->current_video_frame == 0)) { + qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, + active_worst_quality, 2.0); + } else if (!rc->is_src_frame_alt_ref && + (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { + qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, + active_worst_quality, 1.75); + } + *top_index = active_worst_quality + qdelta; + *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index; } #endif + if (oxcf->end_usage == USAGE_CONSTANT_QUALITY) { q = active_best_quality; // Special case code to try and match quality with forced key frames @@ -907,13 +929,22 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, *bottom_index = active_best_quality; #if LIMIT_QRANGE_FOR_ALTREF_AND_KEY - // Limit Q range for the adaptive loop. - if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) { - *top_index = (active_worst_quality + active_best_quality * 3) / 4; - } else if (!rc->is_src_frame_alt_ref && - (oxcf->end_usage != USAGE_STREAM_FROM_SERVER) && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - *top_index = (active_worst_quality + active_best_quality) / 2; + { + int qdelta = 0; + vp9_clear_system_state(); + + // Limit Q range for the adaptive loop. + if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) { + qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, + active_worst_quality, 2.0); + } else if (!rc->is_src_frame_alt_ref && + (oxcf->end_usage != USAGE_STREAM_FROM_SERVER) && + (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { + qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type, + active_worst_quality, 1.75); + } + *top_index = active_worst_quality + qdelta; + *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index; } #endif @@ -1065,11 +1096,11 @@ static void update_golden_frame_stats(VP9_COMP *cpi) { } void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { - VP9_COMMON *const cm = &cpi->common; + const VP9_COMMON *const cm = &cpi->common; const VP9_CONFIG *const oxcf = &cpi->oxcf; RATE_CONTROL *const rc = &cpi->rc; + const int qindex = cm->base_qindex; - cm->last_frame_type = cm->frame_type; // Update rate control heuristics rc->projected_frame_size = (int)(bytes_used << 3); @@ -1080,25 +1111,24 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { // Keep a record of last Q and ambient average Q. if (cm->frame_type == KEY_FRAME) { - rc->last_q[KEY_FRAME] = cm->base_qindex; - rc->avg_frame_qindex[KEY_FRAME] = ROUND_POWER_OF_TWO( - 3 * rc->avg_frame_qindex[KEY_FRAME] + cm->base_qindex, 2); + rc->last_q[KEY_FRAME] = qindex; + rc->avg_frame_qindex[KEY_FRAME] = + ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2); } else if (!rc->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) && - !(cpi->use_svc && oxcf->end_usage == USAGE_STREAM_FROM_SERVER)) { - rc->last_q[2] = cm->base_qindex; - rc->avg_frame_qindex[2] = ROUND_POWER_OF_TWO( - 3 * rc->avg_frame_qindex[2] + cm->base_qindex, 2); + (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) && + !(cpi->use_svc && oxcf->end_usage == USAGE_STREAM_FROM_SERVER)) { + rc->last_q[2] = qindex; + rc->avg_frame_qindex[2] = + ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[2] + qindex, 2); } else { - rc->last_q[INTER_FRAME] = cm->base_qindex; - rc->avg_frame_qindex[INTER_FRAME] = ROUND_POWER_OF_TWO( - 3 * rc->avg_frame_qindex[INTER_FRAME] + cm->base_qindex, 2); + rc->last_q[INTER_FRAME] = qindex; + rc->avg_frame_qindex[INTER_FRAME] = + ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[INTER_FRAME] + qindex, 2); rc->ni_frames++; - rc->tot_q += vp9_convert_qindex_to_q(cm->base_qindex); - rc->avg_q = rc->tot_q / (double)rc->ni_frames; - + rc->tot_q += vp9_convert_qindex_to_q(qindex); + rc->avg_q = rc->tot_q / rc->ni_frames; // Calculate the average Q for normal inter frames (not key or GFU frames). - rc->ni_tot_qi += cm->base_qindex; + rc->ni_tot_qi += qindex; rc->ni_av_qi = rc->ni_tot_qi / rc->ni_frames; } @@ -1107,11 +1137,11 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { // If all mbs in this group are skipped only update if the Q value is // better than that already stored. // This is used to help set quality in forced key frames to reduce popping - if ((cm->base_qindex < rc->last_boosted_qindex) || + if ((qindex < rc->last_boosted_qindex) || ((cpi->static_mb_pct < 100) && ((cm->frame_type == KEY_FRAME) || cpi->refresh_alt_ref_frame || (cpi->refresh_golden_frame && !rc->is_src_frame_alt_ref)))) { - rc->last_boosted_qindex = cm->base_qindex; + rc->last_boosted_qindex = qindex; } update_buffer_level(cpi, rc->projected_frame_size); @@ -1196,7 +1226,7 @@ void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) { int target; if (!cpi->refresh_alt_ref_frame && (cm->current_video_frame == 0 || - (cm->frame_flags & FRAMEFLAGS_KEY) || + (cpi->frame_flags & FRAMEFLAGS_KEY) || rc->frames_to_key == 0 || (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) { cm->frame_type = KEY_FRAME; @@ -1258,17 +1288,25 @@ static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { static int calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { const RATE_CONTROL *rc = &cpi->rc; + const VP9_CONFIG *oxcf = &cpi->oxcf; + const SVC *const svc = &cpi->svc; int target; - if (cpi->common.current_video_frame == 0) { target = ((cpi->oxcf.starting_buffer_level / 2) > INT_MAX) ? INT_MAX : (int)(cpi->oxcf.starting_buffer_level / 2); } else { - const int initial_boost = 32; - int kf_boost = MAX(initial_boost, (int)(2 * cpi->output_framerate - 16)); - if (rc->frames_since_key < cpi->output_framerate / 2) { + int kf_boost = 32; + double framerate = oxcf->framerate; + if (svc->number_temporal_layers > 1 && + oxcf->end_usage == USAGE_STREAM_FROM_SERVER) { + // Use the layer framerate for temporal layers CBR mode. + const LAYER_CONTEXT *lc = &svc->layer_context[svc->temporal_layer_id]; + framerate = lc->framerate; + } + kf_boost = MAX(kf_boost, (int)(2 * framerate - 16)); + if (rc->frames_since_key < framerate / 2) { kf_boost = (int)(kf_boost * rc->frames_since_key / - (cpi->output_framerate / 2)); + (framerate / 2)); } target = ((16 + kf_boost) * rc->av_per_frame_bandwidth) >> 4; } @@ -1280,7 +1318,7 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { RATE_CONTROL *const rc = &cpi->rc; int target = rc->av_per_frame_bandwidth; if ((cm->current_video_frame == 0) || - (cm->frame_flags & FRAMEFLAGS_KEY) || + (cpi->frame_flags & FRAMEFLAGS_KEY) || (cpi->oxcf.auto_key && (rc->frames_since_key % cpi->key_frame_frequency == 0))) { cm->frame_type = KEY_FRAME; @@ -1304,7 +1342,7 @@ void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) { RATE_CONTROL *const rc = &cpi->rc; int target; if ((cm->current_video_frame == 0 || - (cm->frame_flags & FRAMEFLAGS_KEY) || + (cpi->frame_flags & FRAMEFLAGS_KEY) || rc->frames_to_key == 0 || (cpi->oxcf.auto_key && test_for_kf_one_pass(cpi)))) { cm->frame_type = KEY_FRAME; @@ -1366,3 +1404,46 @@ int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type, return target_index - qindex; } + +void vp9_rc_update_framerate(VP9_COMP *cpi) { + const VP9_COMMON *const cm = &cpi->common; + const VP9_CONFIG *const oxcf = &cpi->oxcf; + RATE_CONTROL *const rc = &cpi->rc; + int vbr_max_bits; + + rc->av_per_frame_bandwidth = (int)(oxcf->target_bandwidth / oxcf->framerate); + rc->min_frame_bandwidth = (int)(rc->av_per_frame_bandwidth * + oxcf->two_pass_vbrmin_section / 100); + + rc->min_frame_bandwidth = MAX(rc->min_frame_bandwidth, FRAME_OVERHEAD_BITS); + + // A maximum bitrate for a frame is defined. + // The baseline for this aligns with HW implementations that + // can support decode of 1080P content up to a bitrate of MAX_MB_RATE bits + // per 16x16 MB (averaged over a frame). However this limit is extended if + // a very high rate is given on the command line or the the rate cannnot + // be acheived because of a user specificed max q (e.g. when the user + // specifies lossless encode. + vbr_max_bits = (int)(((int64_t)rc->av_per_frame_bandwidth * + oxcf->two_pass_vbrmax_section) / 100); + rc->max_frame_bandwidth = MAX(MAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P), + vbr_max_bits); + + // Set Maximum gf/arf interval + rc->max_gf_interval = 16; + + // Extended interval for genuinely static scenes + rc->static_scene_max_gf_interval = cpi->key_frame_frequency >> 1; + + // Special conditions when alt ref frame enabled in lagged compress mode + if (oxcf->play_alternate && oxcf->lag_in_frames) { + if (rc->max_gf_interval > oxcf->lag_in_frames - 1) + rc->max_gf_interval = oxcf->lag_in_frames - 1; + + if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1) + rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1; + } + + if (rc->max_gf_interval > rc->static_scene_max_gf_interval) + rc->max_gf_interval = rc->static_scene_max_gf_interval; +} |