From f1781e86b76d5fd9e2605655d78679f3153c292d Mon Sep 17 00:00:00 2001 From: Deb Mukherjee Date: Wed, 6 Nov 2013 13:13:59 -0800 Subject: [PATCH] Refactoring of rate control - part 1 Moves all rate control variables to a separate structure, removes some currently unused variables, moves some rate control functions to vp9_ratectrl.c, and splits the encode_frame_to_data_rate function. Change-Id: I4ed54c24764b3b6de2dd676484f01473724ab52b --- vp9/encoder/vp9_firstpass.c | 136 ++--- vp9/encoder/vp9_mbgraph.c | 6 +- vp9/encoder/vp9_onyx_if.c | 924 +++++++++++------------------- vp9/encoder/vp9_onyx_int.h | 117 ++-- vp9/encoder/vp9_ratectrl.c | 395 +++++++++++-- vp9/encoder/vp9_ratectrl.h | 4 + vp9/encoder/vp9_temporal_filter.c | 4 +- 7 files changed, 789 insertions(+), 797 deletions(-) diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 377cffbee..df2841020 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -966,19 +966,19 @@ static double calc_correction_factor(double err_per_mb, // (now uses the actual quantizer) but has not been tuned. static void adjust_maxq_qrange(VP9_COMP *cpi) { int i; - // Set the max corresponding to cpi->avg_q * 2.0 - double q = cpi->avg_q * 2.0; - cpi->twopass.maxq_max_limit = cpi->worst_quality; - for (i = cpi->best_quality; i <= cpi->worst_quality; i++) { + // Set the max corresponding to cpi->rc.avg_q * 2.0 + double q = cpi->rc.avg_q * 2.0; + cpi->twopass.maxq_max_limit = cpi->rc.worst_quality; + for (i = cpi->rc.best_quality; i <= cpi->rc.worst_quality; i++) { cpi->twopass.maxq_max_limit = i; if (vp9_convert_qindex_to_q(i) >= q) break; } - // Set the min corresponding to cpi->avg_q * 0.5 - q = cpi->avg_q * 0.5; - cpi->twopass.maxq_min_limit = cpi->best_quality; - for (i = cpi->worst_quality; i >= cpi->best_quality; i--) { + // Set the min corresponding to cpi->rc.avg_q * 0.5 + q = cpi->rc.avg_q * 0.5; + cpi->twopass.maxq_min_limit = cpi->rc.best_quality; + for (i = cpi->rc.worst_quality; i >= cpi->rc.best_quality; i--) { cpi->twopass.maxq_min_limit = i; if (vp9_convert_qindex_to_q(i) <= q) break; @@ -1017,10 +1017,10 @@ static int estimate_max_q(VP9_COMP *cpi, // Calculate a corrective factor based on a rolling ratio of bits spent // vs target bits - if (cpi->rolling_target_bits > 0 && - cpi->active_worst_quality < cpi->worst_quality) { - double rolling_ratio = (double)cpi->rolling_actual_bits / - (double)cpi->rolling_target_bits; + if (cpi->rc.rolling_target_bits > 0 && + cpi->rc.active_worst_quality < cpi->rc.worst_quality) { + double rolling_ratio = (double)cpi->rc.rolling_actual_bits / + (double)cpi->rc.rolling_target_bits; if (rolling_ratio < 0.95) cpi->twopass.est_max_qcorrection_factor -= 0.005; @@ -1066,8 +1066,8 @@ static int estimate_max_q(VP9_COMP *cpi, // average q observed in clip for non kf/gf/arf frames // Give average a chance to settle though. // PGW TODO.. This code is broken for the extended Q range - if (cpi->ni_frames > ((int)cpi->twopass.total_stats.count >> 8) && - cpi->ni_frames > 25) + if (cpi->rc.ni_frames > ((int)cpi->twopass.total_stats.count >> 8) && + cpi->rc.ni_frames > 25) adjust_maxq_qrange(cpi); return q; @@ -1146,10 +1146,10 @@ static int estimate_cq(VP9_COMP *cpi, // Clip value to range "best allowed to (worst allowed - 1)" q = select_cq_level(q); - if (q >= cpi->worst_quality) - q = cpi->worst_quality - 1; - if (q < cpi->best_quality) - q = cpi->best_quality; + if (q >= cpi->rc.worst_quality) + q = cpi->rc.worst_quality - 1; + if (q < cpi->rc.best_quality) + q = cpi->rc.best_quality; return q; } @@ -1599,13 +1599,13 @@ void define_fixed_arf_period(VP9_COMP *cpi) { if (cpi->twopass.frames_to_key <= (FIXED_ARF_GROUP_SIZE + 8)) { // Setup a GF group close to the keyframe. cpi->source_alt_ref_pending = 0; - cpi->baseline_gf_interval = cpi->twopass.frames_to_key; - schedule_frames(cpi, 0, (cpi->baseline_gf_interval - 1), 2, 0, 0); + cpi->rc.baseline_gf_interval = cpi->twopass.frames_to_key; + schedule_frames(cpi, 0, (cpi->rc.baseline_gf_interval - 1), 2, 0, 0); } else { // Setup a fixed period ARF group. cpi->source_alt_ref_pending = 1; - cpi->baseline_gf_interval = FIXED_ARF_GROUP_SIZE; - schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0); + cpi->rc.baseline_gf_interval = FIXED_ARF_GROUP_SIZE; + schedule_frames(cpi, 0, -(cpi->rc.baseline_gf_interval - 1), 2, 1, 0); } // Replace level indicator of -1 with correct level. @@ -1702,10 +1702,10 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // At high Q when there are few bits to spare we are better with a longer // interval to spread the cost of the GF. active_max_gf_interval = - 12 + ((int)vp9_convert_qindex_to_q(cpi->active_worst_quality) >> 5); + 12 + ((int)vp9_convert_qindex_to_q(cpi->rc.active_worst_quality) >> 5); - if (active_max_gf_interval > cpi->max_gf_interval) - active_max_gf_interval = cpi->max_gf_interval; + if (active_max_gf_interval > cpi->rc.max_gf_interval) + active_max_gf_interval = cpi->rc.max_gf_interval; i = 0; while (((i < cpi->twopass.static_scene_max_gf_interval) || @@ -1799,7 +1799,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { } // Set the interval until the next gf or arf. - cpi->baseline_gf_interval = i; + cpi->rc.baseline_gf_interval = i; #if CONFIG_MULTIPLE_ARF if (cpi->multi_arf_enabled) { @@ -1825,24 +1825,25 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { (mv_in_out_accumulator > -2.0)) && (boost_score > 100)) { // Alternative boost calculation for alt ref - cpi->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost, + cpi->rc.gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost, &b_boost); cpi->source_alt_ref_pending = 1; #if CONFIG_MULTIPLE_ARF // Set the ARF schedule. if (cpi->multi_arf_enabled) { - schedule_frames(cpi, 0, -(cpi->baseline_gf_interval - 1), 2, 1, 0); + schedule_frames(cpi, 0, -(cpi->rc.baseline_gf_interval - 1), 2, 1, 0); } #endif } else { - cpi->gfu_boost = (int)boost_score; + cpi->rc.gfu_boost = (int)boost_score; cpi->source_alt_ref_pending = 0; #if CONFIG_MULTIPLE_ARF // Set the GF schedule. if (cpi->multi_arf_enabled) { - schedule_frames(cpi, 0, cpi->baseline_gf_interval - 1, 2, 0, 0); - assert(cpi->new_frame_coding_order_period == cpi->baseline_gf_interval); + schedule_frames(cpi, 0, cpi->rc.baseline_gf_interval - 1, 2, 0, 0); + assert(cpi->new_frame_coding_order_period == + cpi->rc.baseline_gf_interval); } #endif } @@ -1915,8 +1916,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Clip cpi->twopass.gf_group_bits based on user supplied data rate // variability limit (cpi->oxcf.two_pass_vbrmax_section) if (cpi->twopass.gf_group_bits > - (int64_t)max_bits * cpi->baseline_gf_interval) - cpi->twopass.gf_group_bits = (int64_t)max_bits * cpi->baseline_gf_interval; + (int64_t)max_bits * cpi->rc.baseline_gf_interval) + cpi->twopass.gf_group_bits = + (int64_t)max_bits * cpi->rc.baseline_gf_interval; // Reset the file position reset_fpf_position(cpi, start_pos); @@ -1929,19 +1931,18 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME); ++i) { int allocation_chunks; - int q = cpi->oxcf.fixed_q < 0 ? cpi->last_q[INTER_FRAME] - : cpi->oxcf.fixed_q; + int q = cpi->rc.last_q[INTER_FRAME]; int gf_bits; - int boost = (cpi->gfu_boost * vp9_gfboost_qadjust(q)) / 100; + int boost = (cpi->rc.gfu_boost * vp9_gfboost_qadjust(q)) / 100; // Set max and minimum boost and hence minimum allocation - boost = clamp(boost, 125, (cpi->baseline_gf_interval + 1) * 200); + boost = clamp(boost, 125, (cpi->rc.baseline_gf_interval + 1) * 200); if (cpi->source_alt_ref_pending && i == 0) - allocation_chunks = ((cpi->baseline_gf_interval + 1) * 100) + boost; + allocation_chunks = ((cpi->rc.baseline_gf_interval + 1) * 100) + boost; else - allocation_chunks = (cpi->baseline_gf_interval * 100) + (boost - 100); + allocation_chunks = (cpi->rc.baseline_gf_interval * 100) + (boost - 100); // Prevent overflow if (boost > 1023) { @@ -1958,10 +1959,10 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // If the frame that is to be boosted is simpler than the average for // the gf/arf group then use an alternative calculation // based on the error score of the frame itself - if (mod_frame_err < gf_group_err / (double)cpi->baseline_gf_interval) { + if (mod_frame_err < gf_group_err / (double)cpi->rc.baseline_gf_interval) { double alt_gf_grp_bits = (double)cpi->twopass.kf_group_bits * - (mod_frame_err * (double)cpi->baseline_gf_interval) / + (mod_frame_err * (double)cpi->rc.baseline_gf_interval) / DOUBLE_DIVIDE_CHECK(cpi->twopass.kf_group_error_left); int alt_gf_bits = (int)((double)boost * (alt_gf_grp_bits / @@ -1986,7 +1987,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { gf_bits = 0; // Add in minimum for a frame - gf_bits += cpi->min_frame_bandwidth; + gf_bits += cpi->rc.min_frame_bandwidth; if (i == 0) { cpi->twopass.gf_bits = gf_bits; @@ -1994,7 +1995,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { if (i == 1 || (!cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME))) { // Per frame bit target for this frame - cpi->per_frame_bandwidth = gf_bits; + cpi->rc.per_frame_bandwidth = gf_bits; } } @@ -2017,7 +2018,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { cpi->twopass.gf_group_error_left = (int64_t)gf_group_err; cpi->twopass.gf_group_bits -= cpi->twopass.gf_bits - - cpi->min_frame_bandwidth; + - cpi->rc.min_frame_bandwidth; if (cpi->twopass.gf_group_bits < 0) cpi->twopass.gf_group_bits = 0; @@ -2025,8 +2026,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // This condition could fail if there are two kfs very close together // despite (MIN_GF_INTERVAL) and would cause a divide by 0 in the // calculation of alt_extra_bits. - if (cpi->baseline_gf_interval >= 3) { - const int boost = cpi->source_alt_ref_pending ? b_boost : cpi->gfu_boost; + if (cpi->rc.baseline_gf_interval >= 3) { + const int boost = cpi->source_alt_ref_pending ? + b_boost : cpi->rc.gfu_boost; if (boost >= 150) { int alt_extra_bits; @@ -2045,7 +2047,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { zero_stats(§ionstats); reset_fpf_position(cpi, start_pos); - for (i = 0; i < cpi->baseline_gf_interval; i++) { + for (i = 0; i < cpi->rc.baseline_gf_interval; i++) { input_stats(cpi, &next_frame); accumulate_stats(§ionstats, &next_frame); } @@ -2102,10 +2104,10 @@ static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { cpi->twopass.gf_group_bits = 0; // Add in the minimum number of bits that is set aside for every frame. - target_frame_size += cpi->min_frame_bandwidth; + target_frame_size += cpi->rc.min_frame_bandwidth; // Per frame bit target for this frame. - cpi->per_frame_bandwidth = target_frame_size; + cpi->rc.per_frame_bandwidth = target_frame_size; } // Make a damped adjustment to the active max q. @@ -2145,7 +2147,7 @@ void vp9_second_pass(VP9_COMP *cpi) { vp9_clear_system_state(); if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { - cpi->active_worst_quality = cpi->oxcf.cq_level; + cpi->rc.active_worst_quality = cpi->oxcf.cq_level; } else { // Special case code for first frame. if (cpi->common.current_video_frame == 0) { @@ -2169,15 +2171,15 @@ void vp9_second_pass(VP9_COMP *cpi) { */ // guess at maxq needed in 2nd pass - cpi->twopass.maxq_max_limit = cpi->worst_quality; - cpi->twopass.maxq_min_limit = cpi->best_quality; + cpi->twopass.maxq_max_limit = cpi->rc.worst_quality; + cpi->twopass.maxq_min_limit = cpi->rc.best_quality; tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats, section_target_bandwidth); - cpi->active_worst_quality = tmp_q; - cpi->ni_av_qi = tmp_q; - cpi->avg_q = vp9_convert_qindex_to_q(tmp_q); + cpi->rc.active_worst_quality = tmp_q; + cpi->rc.ni_av_qi = tmp_q; + cpi->rc.avg_q = vp9_convert_qindex_to_q(tmp_q); // Limit the maxq value returned subsequently. // This increases the risk of overspend or underspend if the initial @@ -2193,7 +2195,7 @@ void vp9_second_pass(VP9_COMP *cpi) { // few surplus bits or get beneath the target rate. else if ((cpi->common.current_video_frame < (((unsigned int)cpi->twopass.total_stats.count * 255) >> 8)) && - ((cpi->common.current_video_frame + cpi->baseline_gf_interval) < + ((cpi->common.current_video_frame + cpi->rc.baseline_gf_interval) < (unsigned int)cpi->twopass.total_stats.count)) { int section_target_bandwidth = (int)(cpi->twopass.bits_left / frames_left); @@ -2206,8 +2208,8 @@ void vp9_second_pass(VP9_COMP *cpi) { section_target_bandwidth); // Make a damped adjustment to active max Q - cpi->active_worst_quality = - adjust_active_maxq(cpi->active_worst_quality, tmp_q); + cpi->rc.active_worst_quality = + adjust_active_maxq(cpi->rc.active_worst_quality, tmp_q); } } vp9_zero(this_frame); @@ -2225,7 +2227,7 @@ void vp9_second_pass(VP9_COMP *cpi) { } // Is this a GF / ARF (Note that a KF is always also a GF) - if (cpi->frames_till_gf_update_due == 0) { + if (cpi->rc.frames_till_gf_update_due == 0) { // Define next gf group and assign bits to it this_frame_copy = this_frame; @@ -2259,10 +2261,10 @@ void vp9_second_pass(VP9_COMP *cpi) { if (cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME)) { // Assign a standard frames worth of bits from those allocated // to the GF group - int bak = cpi->per_frame_bandwidth; + int bak = cpi->rc.per_frame_bandwidth; this_frame_copy = this_frame; assign_std_frame_bits(cpi, &this_frame_copy); - cpi->per_frame_bandwidth = bak; + cpi->rc.per_frame_bandwidth = bak; } } else { // Otherwise this is an ordinary frame @@ -2283,7 +2285,7 @@ void vp9_second_pass(VP9_COMP *cpi) { } // Set nominal per second bandwidth for this frame - cpi->target_bandwidth = (int)(cpi->per_frame_bandwidth + cpi->target_bandwidth = (int)(cpi->rc.per_frame_bandwidth * cpi->output_framerate); if (cpi->target_bandwidth < 0) cpi->target_bandwidth = 0; @@ -2416,7 +2418,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { cpi->source_alt_ref_active = 0; // Kf is always a gf so clear frames till next gf counter - cpi->frames_till_gf_update_due = 0; + cpi->rc.frames_till_gf_update_due = 0; cpi->twopass.frames_to_key = 1; @@ -2579,7 +2581,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { } // For the first few frames collect data to decide kf boost. - if (i <= (cpi->max_gf_interval * 2)) { + if (i <= (cpi->rc.max_gf_interval * 2)) { if (next_frame.intra_error > cpi->twopass.kf_intra_err_min) r = (IIKFACTOR2 * next_frame.intra_error / DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); @@ -2637,7 +2639,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Make a note of baseline boost and the zero motion // accumulator value for use elsewhere. - cpi->kf_boost = kf_boost; + cpi->rc.kf_boost = kf_boost; cpi->kf_zeromotion_pct = (int)(zero_motion_accumulator * 100.0); // We do three calculations for kf size. @@ -2707,10 +2709,10 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { cpi->twopass.kf_group_bits -= cpi->twopass.kf_bits; // Add in the minimum frame allowance - cpi->twopass.kf_bits += cpi->min_frame_bandwidth; + cpi->twopass.kf_bits += cpi->rc.min_frame_bandwidth; // Peer frame bit target for this frame - cpi->per_frame_bandwidth = cpi->twopass.kf_bits; + cpi->rc.per_frame_bandwidth = cpi->twopass.kf_bits; // Convert to a per second bitrate cpi->target_bandwidth = (int)(cpi->twopass.kf_bits * cpi->output_framerate); diff --git a/vp9/encoder/vp9_mbgraph.c b/vp9/encoder/vp9_mbgraph.c index 98707383f..544f1304d 100644 --- a/vp9/encoder/vp9_mbgraph.c +++ b/vp9/encoder/vp9_mbgraph.c @@ -323,8 +323,8 @@ static void separate_arf_mbs(VP9_COMP *cpi) { 1)); // We are not interested in results beyond the alt ref itself. - if (n_frames > cpi->frames_till_gf_update_due) - n_frames = cpi->frames_till_gf_update_due; + if (n_frames > cpi->rc.frames_till_gf_update_due) + n_frames = cpi->rc.frames_till_gf_update_due; // defer cost to reference frames for (i = n_frames - 1; i >= 0; i--) { @@ -396,7 +396,7 @@ void vp9_update_mbgraph_stats(VP9_COMP *cpi) { // we need to look ahead beyond where the ARF transitions into // being a GF - so exit if we don't look ahead beyond that - if (n_frames <= cpi->frames_till_gf_update_due) + if (n_frames <= cpi->rc.frames_till_gf_update_due) return; if (n_frames > (int)cpi->frames_till_alt_ref_frame) n_frames = cpi->frames_till_alt_ref_frame; diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index b7874d515..0b137fea0 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -112,15 +112,6 @@ extern unsigned __int64 Sectionbits[500]; extern void vp9_init_quantizer(VP9_COMP *cpi); -// Tables relating active max Q to active min Q -static int kf_low_motion_minq[QINDEX_RANGE]; -static int kf_high_motion_minq[QINDEX_RANGE]; -static int gf_low_motion_minq[QINDEX_RANGE]; -static int gf_high_motion_minq[QINDEX_RANGE]; -static int inter_minq[QINDEX_RANGE]; -static int afq_low_motion_minq[QINDEX_RANGE]; -static int afq_high_motion_minq[QINDEX_RANGE]; - static INLINE void Scale2Ratio(int mode, int *hr, int *hs) { switch (mode) { case NORMAL: @@ -147,96 +138,6 @@ static INLINE void Scale2Ratio(int mode, int *hr, int *hs) { } } -// Functions to compute the active minq lookup table entries based on a -// formulaic approach to facilitate easier adjustment of the Q tables. -// The formulae were derived from computing a 3rd order polynomial best -// fit to the original data (after plotting real maxq vs minq (not q index)) -static int calculate_minq_index(double maxq, - double x3, double x2, double x1, double c) { - int i; - const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq + c, - maxq); - - // Special case handling to deal with the step from q2.0 - // down to lossless mode represented by q 1.0. - if (minqtarget <= 2.0) - return 0; - - for (i = 0; i < QINDEX_RANGE; i++) { - if (minqtarget <= vp9_convert_qindex_to_q(i)) - return i; - } - - return QINDEX_RANGE - 1; -} - -static void init_minq_luts(void) { - int i; - - for (i = 0; i < QINDEX_RANGE; i++) { - const double maxq = vp9_convert_qindex_to_q(i); - - - kf_low_motion_minq[i] = calculate_minq_index(maxq, - 0.000001, - -0.0004, - 0.15, - 0.0); - kf_high_motion_minq[i] = calculate_minq_index(maxq, - 0.000002, - -0.0012, - 0.5, - 0.0); - - gf_low_motion_minq[i] = calculate_minq_index(maxq, - 0.0000015, - -0.0009, - 0.32, - 0.0); - gf_high_motion_minq[i] = calculate_minq_index(maxq, - 0.0000021, - -0.00125, - 0.50, - 0.0); - inter_minq[i] = calculate_minq_index(maxq, - 0.00000271, - -0.00113, - 0.75, - 0.0); - afq_low_motion_minq[i] = calculate_minq_index(maxq, - 0.0000015, - -0.0009, - 0.33, - 0.0); - afq_high_motion_minq[i] = calculate_minq_index(maxq, - 0.0000021, - -0.00125, - 0.55, - 0.0); - } -} - -static int get_active_quality(int q, - int gfu_boost, - int low, - int high, - int *low_motion_minq, - int *high_motion_minq) { - int active_best_quality; - if (gfu_boost > high) { - active_best_quality = low_motion_minq[q]; - } else if (gfu_boost < low) { - active_best_quality = high_motion_minq[q]; - } else { - const int gap = high - low; - const int offset = high - gfu_boost; - const int qdiff = high_motion_minq[q] - low_motion_minq[q]; - const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap; - active_best_quality = low_motion_minq[q] + adjustment; - } - return active_best_quality; -} - static void set_mvcost(VP9_COMP *cpi) { MACROBLOCK *const mb = &cpi->mb; if (cpi->common.allow_high_precision_mv) { @@ -256,7 +157,7 @@ void vp9_initialize_enc() { vp9_tokenize_initialize(); vp9_init_quant_tables(); vp9_init_me_luts(); - init_minq_luts(); + vp9_init_minq_luts(); // init_base_skip_probs(); init_done = 1; } @@ -325,18 +226,18 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { // target q value int vp9_compute_qdelta(VP9_COMP *cpi, double qstart, double qtarget) { int i; - int start_index = cpi->worst_quality; - int target_index = cpi->worst_quality; + int start_index = cpi->rc.worst_quality; + int target_index = cpi->rc.worst_quality; // Convert the average q value to an index. - for (i = cpi->best_quality; i < cpi->worst_quality; i++) { + for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; i++) { start_index = i; if (vp9_convert_qindex_to_q(i) >= qstart) break; } // Convert the q target to an index - for (i = cpi->best_quality; i < cpi->worst_quality; i++) { + for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; i++) { target_index = i; if (vp9_convert_qindex_to_q(i) >= qtarget) break; @@ -349,7 +250,7 @@ static void configure_static_seg_features(VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; struct segmentation *seg = &cm->seg; - int high_q = (int)(cpi->avg_q > 48.0); + int high_q = (int)(cpi->rc.avg_q > 48.0); int qi_delta; // Disable and clear down for KF @@ -387,7 +288,8 @@ static void configure_static_seg_features(VP9_COMP *cpi) { seg->update_map = 1; seg->update_data = 1; - qi_delta = vp9_compute_qdelta(cpi, cpi->avg_q, (cpi->avg_q * 0.875)); + qi_delta = vp9_compute_qdelta( + cpi, cpi->rc.avg_q, (cpi->rc.avg_q * 0.875)); vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, (qi_delta - 2)); vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2); @@ -401,15 +303,15 @@ static void configure_static_seg_features(VP9_COMP *cpi) { // All other frames if segmentation has been enabled // First normal frame in a valid gf or alt ref group - if (cpi->frames_since_golden == 0) { + if (cpi->rc.frames_since_golden == 0) { // Set up segment features for normal frames in an arf group if (cpi->source_alt_ref_active) { seg->update_map = 0; seg->update_data = 1; seg->abs_delta = SEGMENT_DELTADATA; - qi_delta = vp9_compute_qdelta(cpi, cpi->avg_q, - (cpi->avg_q * 1.125)); + qi_delta = vp9_compute_qdelta(cpi, cpi->rc.avg_q, + (cpi->rc.avg_q * 1.125)); vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, (qi_delta + 2)); vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q); @@ -1125,33 +1027,34 @@ void vp9_new_framerate(VP9_COMP *cpi, double framerate) { cpi->oxcf.framerate = framerate; cpi->output_framerate = cpi->oxcf.framerate; - cpi->per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth - / cpi->output_framerate); - cpi->av_per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth - / cpi->output_framerate); - cpi->min_frame_bandwidth = (int)(cpi->av_per_frame_bandwidth * - cpi->oxcf.two_pass_vbrmin_section / 100); + cpi->rc.per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth + / cpi->output_framerate); + cpi->rc.av_per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth + / cpi->output_framerate); + cpi->rc.min_frame_bandwidth = (int)(cpi->rc.av_per_frame_bandwidth * + cpi->oxcf.two_pass_vbrmin_section / 100); - cpi->min_frame_bandwidth = MAX(cpi->min_frame_bandwidth, FRAME_OVERHEAD_BITS); + cpi->rc.min_frame_bandwidth = MAX(cpi->rc.min_frame_bandwidth, + FRAME_OVERHEAD_BITS); // Set Maximum gf/arf interval - cpi->max_gf_interval = 16; + cpi->rc.max_gf_interval = 16; // Extended interval for genuinely static scenes cpi->twopass.static_scene_max_gf_interval = cpi->key_frame_frequency >> 1; // Special conditions when alt ref frame enabled in lagged compress mode if (cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames) { - if (cpi->max_gf_interval > cpi->oxcf.lag_in_frames - 1) - cpi->max_gf_interval = cpi->oxcf.lag_in_frames - 1; + if (cpi->rc.max_gf_interval > cpi->oxcf.lag_in_frames - 1) + cpi->rc.max_gf_interval = cpi->oxcf.lag_in_frames - 1; if (cpi->twopass.static_scene_max_gf_interval > cpi->oxcf.lag_in_frames - 1) cpi->twopass.static_scene_max_gf_interval = cpi->oxcf.lag_in_frames - 1; } - if (cpi->max_gf_interval > cpi->twopass.static_scene_max_gf_interval) - cpi->max_gf_interval = cpi->twopass.static_scene_max_gf_interval; + if (cpi->rc.max_gf_interval > cpi->twopass.static_scene_max_gf_interval) + cpi->rc.max_gf_interval = cpi->twopass.static_scene_max_gf_interval; } static int64_t rescale(int val, int64_t num, int denom) { @@ -1192,21 +1095,21 @@ static void init_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { vp9_change_config(ptr, oxcf); // Initialize active best and worst q and average q values. - cpi->active_worst_quality = cpi->oxcf.worst_allowed_q; - cpi->active_best_quality = cpi->oxcf.best_allowed_q; - cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q; + cpi->rc.active_worst_quality = cpi->oxcf.worst_allowed_q; + cpi->rc.active_best_quality = cpi->oxcf.best_allowed_q; + cpi->rc.avg_frame_qindex = cpi->oxcf.worst_allowed_q; // Initialise the starting buffer levels - cpi->buffer_level = cpi->oxcf.starting_buffer_level; - cpi->bits_off_target = cpi->oxcf.starting_buffer_level; + cpi->rc.buffer_level = cpi->oxcf.starting_buffer_level; + cpi->rc.bits_off_target = cpi->oxcf.starting_buffer_level; - cpi->rolling_target_bits = cpi->av_per_frame_bandwidth; - cpi->rolling_actual_bits = cpi->av_per_frame_bandwidth; - cpi->long_rolling_target_bits = cpi->av_per_frame_bandwidth; - cpi->long_rolling_actual_bits = cpi->av_per_frame_bandwidth; + cpi->rc.rolling_target_bits = cpi->rc.av_per_frame_bandwidth; + cpi->rc.rolling_actual_bits = cpi->rc.av_per_frame_bandwidth; + cpi->rc.long_rolling_target_bits = cpi->rc.av_per_frame_bandwidth; + cpi->rc.long_rolling_actual_bits = cpi->rc.av_per_frame_bandwidth; - cpi->total_actual_bits = 0; - cpi->total_target_vs_actual = 0; + cpi->rc.total_actual_bits = 0; + cpi->rc.total_target_vs_actual = 0; cpi->static_mb_pct = 0; @@ -1270,7 +1173,7 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { cpi->oxcf.lossless = oxcf->lossless; cpi->mb.e_mbd.itxm_add = cpi->oxcf.lossless ? vp9_iwht4x4_add : vp9_idct4x4_add; - cpi->baseline_gf_interval = DEFAULT_GF_INTERVAL; + cpi->rc.baseline_gf_interval = DEFAULT_GF_INTERVAL; cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; @@ -1325,20 +1228,18 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { vp9_new_framerate(cpi, cpi->oxcf.framerate); // Set absolute upper and lower quality limits - cpi->worst_quality = cpi->oxcf.worst_allowed_q; - cpi->best_quality = cpi->oxcf.best_allowed_q; + cpi->rc.worst_quality = cpi->oxcf.worst_allowed_q; + cpi->rc.best_quality = cpi->oxcf.best_allowed_q; // active values should only be modified if out of new range - cpi->active_worst_quality = clamp(cpi->active_worst_quality, + cpi->rc.active_worst_quality = clamp(cpi->rc.active_worst_quality, cpi->oxcf.best_allowed_q, cpi->oxcf.worst_allowed_q); - cpi->active_best_quality = clamp(cpi->active_best_quality, + cpi->rc.active_best_quality = clamp(cpi->rc.active_best_quality, cpi->oxcf.best_allowed_q, cpi->oxcf.worst_allowed_q); - cpi->buffered_mode = cpi->oxcf.optimal_buffer_level > 0; - cpi->cq_target_quality = cpi->oxcf.cq_level; cm->mcomp_filter_type = DEFAULT_INTERP_FILTER; @@ -1363,9 +1264,9 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { update_frame_size(cpi); if (cpi->oxcf.fixed_q >= 0) { - cpi->last_q[0] = cpi->oxcf.fixed_q; - cpi->last_q[1] = cpi->oxcf.fixed_q; - cpi->last_boosted_qindex = cpi->oxcf.fixed_q; + cpi->rc.last_q[0] = cpi->oxcf.fixed_q; + cpi->rc.last_q[1] = cpi->oxcf.fixed_q; + cpi->rc.last_boosted_qindex = cpi->oxcf.fixed_q; } cpi->speed = cpi->oxcf.cpu_used; @@ -1593,16 +1494,12 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) { init_pick_mode_context(cpi); cm->current_video_frame = 0; - cpi->kf_overspend_bits = 0; - cpi->kf_bitrate_adjustment = 0; - cpi->frames_till_gf_update_due = 0; - cpi->gf_overspend_bits = 0; - cpi->non_gf_bitrate_adjustment = 0; + cpi->rc.frames_till_gf_update_due = 0; // Set reference frame sign bias for ALTREF frame to 1 (for now) cm->ref_frame_sign_bias[ALTREF_FRAME] = 1; - cpi->baseline_gf_interval = DEFAULT_GF_INTERVAL; + cpi->rc.baseline_gf_interval = DEFAULT_GF_INTERVAL; cpi->gold_is_last = 0; cpi->alt_is_last = 0; @@ -1702,19 +1599,18 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) { cpi->first_time_stamp_ever = INT64_MAX; - cpi->frames_till_gf_update_due = 0; - cpi->key_frame_count = 1; + cpi->rc.frames_till_gf_update_due = 0; + cpi->rc.key_frame_count = 1; - cpi->ni_av_qi = cpi->oxcf.worst_allowed_q; - cpi->ni_tot_qi = 0; - cpi->ni_frames = 0; - cpi->tot_q = 0.0; - cpi->avg_q = vp9_convert_qindex_to_q(cpi->oxcf.worst_allowed_q); - cpi->total_byte_count = 0; + cpi->rc.ni_av_qi = cpi->oxcf.worst_allowed_q; + cpi->rc.ni_tot_qi = 0; + cpi->rc.ni_frames = 0; + cpi->rc.tot_q = 0.0; + cpi->rc.avg_q = vp9_convert_qindex_to_q(cpi->oxcf.worst_allowed_q); - cpi->rate_correction_factor = 1.0; - cpi->key_frame_rate_correction_factor = 1.0; - cpi->gf_rate_correction_factor = 1.0; + cpi->rc.rate_correction_factor = 1.0; + cpi->rc.key_frame_rate_correction_factor = 1.0; + cpi->rc.gf_rate_correction_factor = 1.0; cpi->twopass.est_max_qcorrection_factor = 1.0; cal_nmvjointsadcost(cpi->mb.nmvjointsadcost); @@ -1731,7 +1627,7 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) { cal_nmvsadcosts_hp(cpi->mb.nmvsadcost_hp); for (i = 0; i < KEY_FRAME_CONTEXT; i++) - cpi->prior_key_frame_distance[i] = (int)cpi->output_framerate; + cpi->rc.prior_key_frame_distance[i] = (int)cpi->output_framerate; #ifdef OUTPUT_YUV_SRC yuv_file = fopen("bd.yuv", "ab"); @@ -2389,7 +2285,7 @@ static void scale_and_extend_frame(YV12_BUFFER_CONFIG *src_fb, static void update_alt_ref_frame_stats(VP9_COMP *cpi) { // this frame refreshes means next frames don't unless specified by user - cpi->frames_since_golden = 0; + cpi->rc.frames_since_golden = 0; #if CONFIG_MULTIPLE_ARF if (!cpi->multi_arf_enabled) @@ -2405,7 +2301,7 @@ static void update_golden_frame_stats(VP9_COMP *cpi) { if (cpi->refresh_golden_frame) { // this frame refreshes means next frames don't unless specified by user cpi->refresh_golden_frame = 0; - cpi->frames_since_golden = 0; + cpi->rc.frames_since_golden = 0; // ******** Fixed Q test code only ************ // If we are going to use the ALT reference for the next group of frames @@ -2413,12 +2309,12 @@ static void update_golden_frame_stats(VP9_COMP *cpi) { if (cpi->oxcf.fixed_q >= 0 && cpi->oxcf.play_alternate && !cpi->refresh_alt_ref_frame) { cpi->source_alt_ref_pending = 1; - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; + cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval; // TODO(ivan): For SVC encoder, GF automatic update is disabled by using // a large GF_interval. if (cpi->use_svc) { - cpi->frames_till_gf_update_due = INT_MAX; + cpi->rc.frames_till_gf_update_due = INT_MAX; } } @@ -2426,18 +2322,18 @@ static void update_golden_frame_stats(VP9_COMP *cpi) { cpi->source_alt_ref_active = 0; // Decrement count down till next gf - if (cpi->frames_till_gf_update_due > 0) - cpi->frames_till_gf_update_due--; + if (cpi->rc.frames_till_gf_update_due > 0) + cpi->rc.frames_till_gf_update_due--; } else if (!cpi->refresh_alt_ref_frame) { // Decrement count down till next gf - if (cpi->frames_till_gf_update_due > 0) - cpi->frames_till_gf_update_due--; + if (cpi->rc.frames_till_gf_update_due > 0) + cpi->rc.frames_till_gf_update_due--; if (cpi->frames_till_alt_ref_frame) cpi->frames_till_alt_ref_frame--; - cpi->frames_since_golden++; + cpi->rc.frames_since_golden++; } } @@ -2547,21 +2443,22 @@ static int recode_loop_test(VP9_COMP *cpi, cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) { // General over and under shoot tests - if (((cpi->projected_frame_size > high_limit) && (q < maxq)) || - ((cpi->projected_frame_size < low_limit) && (q > minq))) { + if (((cpi->rc.projected_frame_size > high_limit) && (q < maxq)) || + ((cpi->rc.projected_frame_size < low_limit) && (q > minq))) { force_recode = 1; } else if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { // Deal with frame undershoot and whether or not we are // below the automatically set cq level. if (q > cpi->cq_target_quality && - cpi->projected_frame_size < ((cpi->this_frame_target * 7) >> 3)) { + cpi->rc.projected_frame_size < + ((cpi->rc.this_frame_target * 7) >> 3)) { force_recode = 1; } else if (q > cpi->oxcf.cq_level && - cpi->projected_frame_size < cpi->min_frame_bandwidth && - cpi->active_best_quality > cpi->oxcf.cq_level) { + cpi->rc.projected_frame_size < cpi->rc.min_frame_bandwidth && + cpi->rc.active_best_quality > cpi->oxcf.cq_level) { // Severe undershoot and between auto and user cq level force_recode = 1; - cpi->active_best_quality = cpi->oxcf.cq_level; + cpi->rc.active_best_quality = cpi->oxcf.cq_level; } } } @@ -2728,25 +2625,26 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) { "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f" "%6d %6d %5d %5d %5d %8.2f %10d %10.3f" "%10.3f %8d %10d %10d %10d\n", - cpi->common.current_video_frame, cpi->this_frame_target, - cpi->projected_frame_size, 0, - (cpi->projected_frame_size - cpi->this_frame_target), - (int)cpi->total_target_vs_actual, - (int)(cpi->oxcf.starting_buffer_level - cpi->bits_off_target), - (int)cpi->total_actual_bits, cm->base_qindex, + cpi->common.current_video_frame, cpi->rc.this_frame_target, + cpi->rc.projected_frame_size, 0, + (cpi->rc.projected_frame_size - cpi->rc.this_frame_target), + (int)cpi->rc.total_target_vs_actual, + (int)(cpi->oxcf.starting_buffer_level - cpi->rc.bits_off_target), + (int)cpi->rc.total_actual_bits, cm->base_qindex, vp9_convert_qindex_to_q(cm->base_qindex), (double)vp9_dc_quant(cm->base_qindex, 0) / 4.0, - vp9_convert_qindex_to_q(cpi->active_best_quality), - vp9_convert_qindex_to_q(cpi->active_worst_quality), cpi->avg_q, - vp9_convert_qindex_to_q(cpi->ni_av_qi), + vp9_convert_qindex_to_q(cpi->rc.active_best_quality), + vp9_convert_qindex_to_q(cpi->rc.active_worst_quality), cpi->rc.avg_q, + vp9_convert_qindex_to_q(cpi->rc.ni_av_qi), vp9_convert_qindex_to_q(cpi->cq_target_quality), cpi->refresh_last_frame, cpi->refresh_golden_frame, - cpi->refresh_alt_ref_frame, cm->frame_type, cpi->gfu_boost, + cpi->refresh_alt_ref_frame, cm->frame_type, cpi->rc.gfu_boost, cpi->twopass.est_max_qcorrection_factor, (int)cpi->twopass.bits_left, cpi->twopass.total_left_stats.coded_error, (double)cpi->twopass.bits_left / (1 + cpi->twopass.total_left_stats.coded_error), - cpi->tot_recode_hits, recon_err, cpi->kf_boost, cpi->kf_zeromotion_pct); + cpi->tot_recode_hits, recon_err, cpi->rc.kf_boost, + cpi->kf_zeromotion_pct); fclose(f); @@ -2770,194 +2668,212 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) { } #endif -static int pick_q_and_adjust_q_bounds(VP9_COMP *cpi, - int * bottom_index, int * top_index) { - // Set an active best quality and if necessary active worst quality - int q = cpi->active_worst_quality; +static void encode_with_recode_loop(VP9_COMP *cpi, + unsigned long *size, + uint8_t *dest, + int q, + int bottom_index, + int top_index, + int frame_over_shoot_limit, + int frame_under_shoot_limit) { VP9_COMMON *const cm = &cpi->common; + int loop_count = 0; + int loop = 0; + int overshoot_seen = 0; + int undershoot_seen = 0; + int active_worst_qchanged = 0; + int q_low = bottom_index, q_high = top_index; + do { + vp9_clear_system_state(); // __asm emms; - if (frame_is_intra_only(cm)) { -#if !CONFIG_MULTIPLE_ARF - // Handle the special case for key frames forced when we have75 reached - // the maximum key frame interval. Here force the Q to a range - // based on the ambient Q to reduce the risk of popping. - if (cpi->this_key_frame_forced) { - int delta_qindex; - int qindex = cpi->last_boosted_qindex; - double last_boosted_q = vp9_convert_qindex_to_q(qindex); + vp9_set_quantizer(cpi, q); - delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q, - (last_boosted_q * 0.75)); - - cpi->active_best_quality = MAX(qindex + delta_qindex, - cpi->best_quality); - } else { - int high = 5000; - int low = 400; - double q_adj_factor = 1.0; - double q_val; - - // Baseline value derived from cpi->active_worst_quality and kf boost - cpi->active_best_quality = get_active_quality(q, cpi->kf_boost, - low, high, - kf_low_motion_minq, - kf_high_motion_minq); - - // Allow somewhat lower kf minq with small image formats. - if ((cm->width * cm->height) <= (352 * 288)) { - q_adj_factor -= 0.25; - } - - // Make a further adjustment based on the kf zero motion measure. - q_adj_factor += 0.05 - (0.001 * (double)cpi->kf_zeromotion_pct); - - // Convert the adjustment factor to a qindex delta - // on active_best_quality. - q_val = vp9_convert_qindex_to_q(cpi->active_best_quality); - cpi->active_best_quality += - vp9_compute_qdelta(cpi, q_val, (q_val * q_adj_factor)); - } -#else - double current_q; - // Force the KF quantizer to be 30% of the active_worst_quality. - current_q = vp9_convert_qindex_to_q(cpi->active_worst_quality); - cpi->active_best_quality = cpi->active_worst_quality - + vp9_compute_qdelta(cpi, current_q, current_q * 0.3); -#endif - } else if (!cpi->is_src_frame_alt_ref && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - int high = 2000; - int low = 400; - - // Use the lower of cpi->active_worst_quality and recent - // average Q as basis for GF/ARF best Q limit unless last frame was - // a key frame. - if (cpi->frames_since_key > 1 && - cpi->avg_frame_qindex < cpi->active_worst_quality) { - q = cpi->avg_frame_qindex; - } - // For constrained quality dont allow Q less than the cq level - if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { - if (q < cpi->cq_target_quality) - q = cpi->cq_target_quality; - if (cpi->frames_since_key > 1) { - cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, - low, high, - afq_low_motion_minq, - afq_high_motion_minq); + if (loop_count == 0) { + // Set up entropy context depending on frame type. The decoder mandates + // the use of the default context, index 0, for keyframes and inter + // frames where the error_resilient_mode or intra_only flag is set. For + // other inter-frames the encoder currently uses only two contexts; + // context 1 for ALTREF frames and context 0 for the others. + if (cm->frame_type == KEY_FRAME) { + vp9_setup_key_frame(cpi); } else { - cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, - low, high, - gf_low_motion_minq, - gf_high_motion_minq); - } - // Constrained quality use slightly lower active best. - cpi->active_best_quality = cpi->active_best_quality * 15 / 16; - - } else if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { - if (!cpi->refresh_alt_ref_frame) { - cpi->active_best_quality = cpi->cq_target_quality; - } else { - if (cpi->frames_since_key > 1) { - cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, - low, high, - afq_low_motion_minq, - afq_high_motion_minq); - } else { - cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, - low, high, - gf_low_motion_minq, - gf_high_motion_minq); + if (!cm->intra_only && !cm->error_resilient_mode) { + cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame; } + vp9_setup_inter_frame(cpi); } - } else { - cpi->active_best_quality = get_active_quality(q, cpi->gfu_boost, - low, high, - gf_low_motion_minq, - gf_high_motion_minq); } - } else { + + if (cpi->oxcf.aq_mode == VARIANCE_AQ) { + vp9_vaq_frame_setup(cpi); + } + + // transform / motion compensation build reconstruction frame + + vp9_encode_frame(cpi); + + // Update the skip mb flag probabilities based on the distribution + // seen in the last encoder iteration. + // update_base_skip_probs(cpi); + + vp9_clear_system_state(); // __asm emms; + + // Dummy pack of the bitstream using up to date stats to get an + // accurate estimate of output frame size to determine if we need + // to recode. + vp9_save_coding_context(cpi); + cpi->dummy_packing = 1; + vp9_pack_bitstream(cpi, dest, size); + cpi->rc.projected_frame_size = (*size) << 3; + vp9_restore_coding_context(cpi); + + if (frame_over_shoot_limit == 0) + frame_over_shoot_limit = 1; + active_worst_qchanged = 0; + if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { - cpi->active_best_quality = cpi->cq_target_quality; + loop = 0; } else { - cpi->active_best_quality = inter_minq[q]; - // 1-pass: for now, use the average Q for the active_best, if its lower - // than active_worst. - if (cpi->pass == 0 && (cpi->avg_frame_qindex < q)) - cpi->active_best_quality = inter_minq[cpi->avg_frame_qindex]; + // Special case handling for forced key frames + if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { + int last_q = q; + int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm)); - // For the constrained quality mode we don't want - // q to fall below the cq level. - if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (cpi->active_best_quality < cpi->cq_target_quality)) { - // If we are strongly undershooting the target rate in the last - // frames then use the user passed in cq value not the auto - // cq value. - if (cpi->rolling_actual_bits < cpi->min_frame_bandwidth) - cpi->active_best_quality = cpi->oxcf.cq_level; - else - cpi->active_best_quality = cpi->cq_target_quality; + int high_err_target = cpi->ambient_err; + int low_err_target = cpi->ambient_err >> 1; + + // Prevent possible divide by zero error below for perfect KF + kf_err += !kf_err; + + // The key frame is not good enough or we can afford + // to make it better without undue risk of popping. + if ((kf_err > high_err_target && + cpi->rc.projected_frame_size <= frame_over_shoot_limit) || + (kf_err > low_err_target && + cpi->rc.projected_frame_size <= frame_under_shoot_limit)) { + // Lower q_high + q_high = q > q_low ? q - 1 : q_low; + + // Adjust Q + q = (q * high_err_target) / kf_err; + q = MIN(q, (q_high + q_low) >> 1); + } else if (kf_err < low_err_target && + cpi->rc.projected_frame_size >= frame_under_shoot_limit) { + // The key frame is much better than the previous frame + // Raise q_low + q_low = q < q_high ? q + 1 : q_high; + + // Adjust Q + q = (q * low_err_target) / kf_err; + q = MIN(q, (q_high + q_low + 1) >> 1); + } + + // Clamp Q to upper and lower limits: + q = clamp(q, q_low, q_high); + + loop = q != last_q; + } else if (recode_loop_test( + cpi, frame_over_shoot_limit, frame_under_shoot_limit, + q, top_index, bottom_index)) { + // Is the projected frame size out of range and are we allowed + // to attempt to recode. + int last_q = q; + int retries = 0; + + // Frame size out of permitted range: + // Update correction factor & compute new Q to try... + + // Frame is too large + if (cpi->rc.projected_frame_size > cpi->rc.this_frame_target) { + // Raise Qlow as to at least the current value + q_low = q < q_high ? q + 1 : q_high; + + if (undershoot_seen || loop_count > 1) { + // Update rate_correction_factor unless + // cpi->rc.active_worst_quality has changed. + if (!active_worst_qchanged) + vp9_update_rate_correction_factors(cpi, 1); + + q = (q_high + q_low + 1) / 2; + } else { + // Update rate_correction_factor unless + // cpi->rc.active_worst_quality has changed. + if (!active_worst_qchanged) + vp9_update_rate_correction_factors(cpi, 0); + + q = vp9_regulate_q(cpi, cpi->rc.this_frame_target); + + while (q < q_low && retries < 10) { + vp9_update_rate_correction_factors(cpi, 0); + q = vp9_regulate_q(cpi, cpi->rc.this_frame_target); + retries++; + } + } + + overshoot_seen = 1; + } else { + // Frame is too small + q_high = q > q_low ? q - 1 : q_low; + + if (overshoot_seen || loop_count > 1) { + // Update rate_correction_factor unless + // cpi->rc.active_worst_quality has changed. + if (!active_worst_qchanged) + vp9_update_rate_correction_factors(cpi, 1); + + q = (q_high + q_low) / 2; + } else { + // Update rate_correction_factor unless + // cpi->rc.active_worst_quality has changed. + if (!active_worst_qchanged) + vp9_update_rate_correction_factors(cpi, 0); + + q = vp9_regulate_q(cpi, cpi->rc.this_frame_target); + + // Special case reset for qlow for constrained quality. + // This should only trigger where there is very substantial + // undershoot on a frame and the auto cq level is above + // the user passsed in value. + if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY && q < q_low) { + q_low = q; + } + + while (q > q_high && retries < 10) { + vp9_update_rate_correction_factors(cpi, 0); + q = vp9_regulate_q(cpi, cpi->rc.this_frame_target); + retries++; + } + } + + undershoot_seen = 1; + } + + // Clamp Q to upper and lower limits: + q = clamp(q, q_low, q_high); + + loop = q != last_q; + } else { + loop = 0; } } - } - // Clip the active best and worst quality values to limits - if (cpi->active_worst_quality > cpi->worst_quality) - cpi->active_worst_quality = cpi->worst_quality; + if (cpi->is_src_frame_alt_ref) + loop = 0; - if (cpi->active_best_quality < cpi->best_quality) - cpi->active_best_quality = cpi->best_quality; + if (loop) { + loop_count++; - if (cpi->active_best_quality > cpi->worst_quality) - cpi->active_best_quality = cpi->worst_quality; - - if (cpi->active_worst_quality < cpi->active_best_quality) - cpi->active_worst_quality = cpi->active_best_quality; - - // Limit Q range for the adaptive loop. - if (cm->frame_type == KEY_FRAME && !cpi->this_key_frame_forced) { - *top_index = - (cpi->active_worst_quality + cpi->active_best_quality * 3) / 4; - // If this is the first (key) frame in 1-pass, active best is the user - // best-allowed, and leave the top_index to active_worst. - if (cpi->pass == 0 && cpi->common.current_video_frame == 0) { - cpi->active_best_quality = cpi->oxcf.best_allowed_q; - *top_index = cpi->oxcf.worst_allowed_q; +#if CONFIG_INTERNAL_STATS + cpi->tot_recode_hits++; +#endif } - } else if (!cpi->is_src_frame_alt_ref && - (cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER) && - (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { - *top_index = - (cpi->active_worst_quality + cpi->active_best_quality) / 2; - } else { - *top_index = cpi->active_worst_quality; - } - *bottom_index = cpi->active_best_quality; - - if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { - q = cpi->active_best_quality; - // Special case code to try and match quality with forced key frames - } else if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { - q = cpi->last_boosted_qindex; - } else { - // Determine initial Q to try. - if (cpi->pass == 0) { - // 1-pass: for now, use per-frame-bw for target size of frame, scaled - // by |x| for key frame. - int scale = (cm->frame_type == KEY_FRAME) ? 5 : 1; - q = vp9_regulate_q(cpi, scale * cpi->av_per_frame_bandwidth); - } else { - q = vp9_regulate_q(cpi, cpi->this_frame_target); - } - if (q > *top_index) - q = *top_index; - } - - return q; + } while (loop); + cpi->rc.active_worst_qchanged = active_worst_qchanged; } + static void encode_frame_to_data_rate(VP9_COMP *cpi, unsigned long *size, - unsigned char *dest, + uint8_t *dest, unsigned int *frame_flags) { VP9_COMMON *const cm = &cpi->common; TX_SIZE t; @@ -2965,18 +2881,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, int frame_over_shoot_limit; int frame_under_shoot_limit; - int loop = 0; - int loop_count; - - int q_low; - int q_high; - int top_index; int bottom_index; - int active_worst_qchanged = 0; - - int overshoot_seen = 0; - int undershoot_seen = 0; SPEED_FEATURES *const sf = &cpi->sf; unsigned int max_mv_def = MIN(cpi->common.width, cpi->common.height); @@ -2999,7 +2905,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, // 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->per_frame_bandwidth = cpi->twopass.gf_bits; + 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); } @@ -3092,10 +2998,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, vp9_clear_system_state(); - q = pick_q_and_adjust_q_bounds(cpi, &bottom_index, &top_index); - - q_high = top_index; - q_low = bottom_index; + q = vp9_pick_q_and_adjust_q_bounds(cpi, &bottom_index, &top_index); vp9_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, &frame_over_shoot_limit); @@ -3105,24 +3008,22 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, if (cpi->multi_arf_enabled && (cm->frame_type != KEY_FRAME) && cpi->oxcf.end_usage != USAGE_CONSTANT_QUALITY) { double new_q; - double current_q = vp9_convert_qindex_to_q(cpi->active_worst_quality); + double current_q = vp9_convert_qindex_to_q(cpi->rc.active_worst_quality); int level = cpi->this_frame_weight; assert(level >= 0); // Set quantizer steps at 10% increments. new_q = current_q * (1.0 - (0.2 * (cpi->max_arf_level - level))); - q = cpi->active_worst_quality + vp9_compute_qdelta(cpi, current_q, new_q); + q = cpi->rc.active_worst_quality + + vp9_compute_qdelta(cpi, current_q, new_q); bottom_index = q; top_index = q; - q_low = q; - q_high = q; printf("frame:%d q:%d\n", cm->current_video_frame, q); } #endif - loop_count = 0; vp9_zero(cpi->rd_tx_select_threshes); if (!frame_is_intra_only(cm)) { @@ -3133,10 +3034,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, } #if CONFIG_VP9_POSTPROC - if (cpi->oxcf.noise_sensitivity > 0) { int l = 0; - switch (cpi->oxcf.noise_sensitivity) { case 1: l = 20; @@ -3155,201 +3054,22 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, l = 150; break; } - vp9_denoise(cpi->Source, cpi->Source, l); } - #endif #ifdef OUTPUT_YUV_SRC vp9_write_yuv_frame(cpi->Source); #endif - do { - vp9_clear_system_state(); // __asm emms; - - vp9_set_quantizer(cpi, q); - - if (loop_count == 0) { - // Set up entropy context depending on frame type. The decoder mandates - // the use of the default context, index 0, for keyframes and inter - // frames where the error_resilient_mode or intra_only flag is set. For - // other inter-frames the encoder currently uses only two contexts; - // context 1 for ALTREF frames and context 0 for the others. - if (cm->frame_type == KEY_FRAME) { - vp9_setup_key_frame(cpi); - } else { - if (!cm->intra_only && !cm->error_resilient_mode) { - cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame; - } - vp9_setup_inter_frame(cpi); - } - } - - if (cpi->oxcf.aq_mode == VARIANCE_AQ) { - vp9_vaq_frame_setup(cpi); - } - - // transform / motion compensation build reconstruction frame - - vp9_encode_frame(cpi); - - // Update the skip mb flag probabilities based on the distribution - // seen in the last encoder iteration. - // update_base_skip_probs(cpi); - - vp9_clear_system_state(); // __asm emms; - - // Dummy pack of the bitstream using up to date stats to get an - // accurate estimate of output frame size to determine if we need - // to recode. - vp9_save_coding_context(cpi); - cpi->dummy_packing = 1; - vp9_pack_bitstream(cpi, dest, size); - cpi->projected_frame_size = (*size) << 3; - vp9_restore_coding_context(cpi); - - if (frame_over_shoot_limit == 0) - frame_over_shoot_limit = 1; - active_worst_qchanged = 0; - - if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { - loop = 0; - } else { - // Special case handling for forced key frames - if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { - int last_q = q; - int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm)); - - int high_err_target = cpi->ambient_err; - int low_err_target = cpi->ambient_err >> 1; - - // Prevent possible divide by zero error below for perfect KF - kf_err += !kf_err; - - // The key frame is not good enough or we can afford - // to make it better without undue risk of popping. - if ((kf_err > high_err_target && - cpi->projected_frame_size <= frame_over_shoot_limit) || - (kf_err > low_err_target && - cpi->projected_frame_size <= frame_under_shoot_limit)) { - // Lower q_high - q_high = q > q_low ? q - 1 : q_low; - - // Adjust Q - q = (q * high_err_target) / kf_err; - q = MIN(q, (q_high + q_low) >> 1); - } else if (kf_err < low_err_target && - cpi->projected_frame_size >= frame_under_shoot_limit) { - // The key frame is much better than the previous frame - // Raise q_low - q_low = q < q_high ? q + 1 : q_high; - - // Adjust Q - q = (q * low_err_target) / kf_err; - q = MIN(q, (q_high + q_low + 1) >> 1); - } - - // Clamp Q to upper and lower limits: - q = clamp(q, q_low, q_high); - - loop = q != last_q; - } else if (recode_loop_test( - cpi, frame_over_shoot_limit, frame_under_shoot_limit, - q, top_index, bottom_index)) { - // Is the projected frame size out of range and are we allowed - // to attempt to recode. - int last_q = q; - int retries = 0; - - // Frame size out of permitted range: - // Update correction factor & compute new Q to try... - - // Frame is too large - if (cpi->projected_frame_size > cpi->this_frame_target) { - // Raise Qlow as to at least the current value - q_low = q < q_high ? q + 1 : q_high; - - if (undershoot_seen || loop_count > 1) { - // Update rate_correction_factor unless - // cpi->active_worst_quality has changed. - if (!active_worst_qchanged) - vp9_update_rate_correction_factors(cpi, 1); - - q = (q_high + q_low + 1) / 2; - } else { - // Update rate_correction_factor unless - // cpi->active_worst_quality has changed. - if (!active_worst_qchanged) - vp9_update_rate_correction_factors(cpi, 0); - - q = vp9_regulate_q(cpi, cpi->this_frame_target); - - while (q < q_low && retries < 10) { - vp9_update_rate_correction_factors(cpi, 0); - q = vp9_regulate_q(cpi, cpi->this_frame_target); - retries++; - } - } - - overshoot_seen = 1; - } else { - // Frame is too small - q_high = q > q_low ? q - 1 : q_low; - - if (overshoot_seen || loop_count > 1) { - // Update rate_correction_factor unless - // cpi->active_worst_quality has changed. - if (!active_worst_qchanged) - vp9_update_rate_correction_factors(cpi, 1); - - q = (q_high + q_low) / 2; - } else { - // Update rate_correction_factor unless - // cpi->active_worst_quality has changed. - if (!active_worst_qchanged) - vp9_update_rate_correction_factors(cpi, 0); - - q = vp9_regulate_q(cpi, cpi->this_frame_target); - - // Special case reset for qlow for constrained quality. - // This should only trigger where there is very substantial - // undershoot on a frame and the auto cq level is above - // the user passsed in value. - if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY && q < q_low) { - q_low = q; - } - - while (q > q_high && retries < 10) { - vp9_update_rate_correction_factors(cpi, 0); - q = vp9_regulate_q(cpi, cpi->this_frame_target); - retries++; - } - } - - undershoot_seen = 1; - } - - // Clamp Q to upper and lower limits: - q = clamp(q, q_low, q_high); - - loop = q != last_q; - } else { - loop = 0; - } - } - - if (cpi->is_src_frame_alt_ref) - loop = 0; - - if (loop) { - loop_count++; - -#if CONFIG_INTERNAL_STATS - cpi->tot_recode_hits++; -#endif - } - } while (loop); + encode_with_recode_loop(cpi, + size, + dest, + q, + bottom_index, + top_index, + frame_over_shoot_limit, + frame_under_shoot_limit); // Special case code to reduce pulsing when key frames are forced at a // fixed interval. Note the reconstruction error if it is the frame before @@ -3429,28 +3149,27 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, cm->last_frame_type = cm->frame_type; // Update rate control heuristics - cpi->total_byte_count += (*size); - cpi->projected_frame_size = (*size) << 3; + cpi->rc.projected_frame_size = (*size) << 3; // Post encode loop adjustment of Q prediction. - if (!active_worst_qchanged) + if (!cpi->rc.active_worst_qchanged) vp9_update_rate_correction_factors(cpi, (cpi->sf.recode_loop || cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) ? 2 : 0); - cpi->last_q[cm->frame_type] = cm->base_qindex; + cpi->rc.last_q[cm->frame_type] = cm->base_qindex; // Keep record of last boosted (KF/KF/ARF) Q value. // If the current frame is coded at a lower Q then we also update it. // 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 < cpi->last_boosted_qindex) || + if ((cm->base_qindex < cpi->rc.last_boosted_qindex) || ((cpi->static_mb_pct < 100) && ((cm->frame_type == KEY_FRAME) || cpi->refresh_alt_ref_frame || (cpi->refresh_golden_frame && !cpi->is_src_frame_alt_ref)))) { - cpi->last_boosted_qindex = cm->base_qindex; + cpi->rc.last_boosted_qindex = cm->base_qindex; } if (cm->frame_type == KEY_FRAME) { @@ -3459,7 +3178,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, // Keep a record of ambient average Q. if (cm->frame_type != KEY_FRAME) - cpi->avg_frame_qindex = (2 + 3 * cpi->avg_frame_qindex + + cpi->rc.avg_frame_qindex = (2 + 3 * cpi->rc.avg_frame_qindex + cm->base_qindex) >> 2; // Keep a record from which we can calculate the average Q excluding GF @@ -3467,61 +3186,64 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, if (cm->frame_type != KEY_FRAME && !cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame) { - cpi->ni_frames++; - cpi->tot_q += vp9_convert_qindex_to_q(q); - cpi->avg_q = cpi->tot_q / (double)cpi->ni_frames; + cpi->rc.ni_frames++; + cpi->rc.tot_q += vp9_convert_qindex_to_q(q); + cpi->rc.avg_q = cpi->rc.tot_q / (double)cpi->rc.ni_frames; // Calculate the average Q for normal inter frames (not key or GFU frames). - cpi->ni_tot_qi += q; - cpi->ni_av_qi = cpi->ni_tot_qi / cpi->ni_frames; + cpi->rc.ni_tot_qi += q; + cpi->rc.ni_av_qi = cpi->rc.ni_tot_qi / cpi->rc.ni_frames; } // Update the buffer level variable. // Non-viewable frames are a special case and are treated as pure overhead. if (!cm->show_frame) - cpi->bits_off_target -= cpi->projected_frame_size; + cpi->rc.bits_off_target -= cpi->rc.projected_frame_size; else - cpi->bits_off_target += cpi->av_per_frame_bandwidth - - cpi->projected_frame_size; + cpi->rc.bits_off_target += cpi->rc.av_per_frame_bandwidth - + cpi->rc.projected_frame_size; // Clip the buffer level at the maximum buffer size - if (cpi->bits_off_target > cpi->oxcf.maximum_buffer_size) - cpi->bits_off_target = cpi->oxcf.maximum_buffer_size; + if (cpi->rc.bits_off_target > cpi->oxcf.maximum_buffer_size) + cpi->rc.bits_off_target = cpi->oxcf.maximum_buffer_size; // Rolling monitors of whether we are over or underspending used to help // regulate min and Max Q in two pass. if (cm->frame_type != KEY_FRAME) { - cpi->rolling_target_bits = - ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4; - cpi->rolling_actual_bits = - ((cpi->rolling_actual_bits * 3) + cpi->projected_frame_size + 2) / 4; - cpi->long_rolling_target_bits = - ((cpi->long_rolling_target_bits * 31) + cpi->this_frame_target + 16) / 32; - cpi->long_rolling_actual_bits = - ((cpi->long_rolling_actual_bits * 31) + - cpi->projected_frame_size + 16) / 32; + cpi->rc.rolling_target_bits = + ((cpi->rc.rolling_target_bits * 3) + + cpi->rc.this_frame_target + 2) / 4; + cpi->rc.rolling_actual_bits = + ((cpi->rc.rolling_actual_bits * 3) + + cpi->rc.projected_frame_size + 2) / 4; + cpi->rc.long_rolling_target_bits = + ((cpi->rc.long_rolling_target_bits * 31) + + cpi->rc.this_frame_target + 16) / 32; + cpi->rc.long_rolling_actual_bits = + ((cpi->rc.long_rolling_actual_bits * 31) + + cpi->rc.projected_frame_size + 16) / 32; } // Actual bits spent - cpi->total_actual_bits += cpi->projected_frame_size; + cpi->rc.total_actual_bits += cpi->rc.projected_frame_size; // Debug stats - cpi->total_target_vs_actual += (cpi->this_frame_target - - cpi->projected_frame_size); + cpi->rc.total_target_vs_actual += (cpi->rc.this_frame_target - + cpi->rc.projected_frame_size); - cpi->buffer_level = cpi->bits_off_target; + cpi->rc.buffer_level = cpi->rc.bits_off_target; #ifndef DISABLE_RC_LONG_TERM_MEM // Update bits left to the kf and gf groups to account for overshoot or // undershoot on these frames if (cm->frame_type == KEY_FRAME) { - cpi->twopass.kf_group_bits += cpi->this_frame_target - - cpi->projected_frame_size; + cpi->twopass.kf_group_bits += cpi->rc.this_frame_target - + cpi->rc.projected_frame_size; cpi->twopass.kf_group_bits = MAX(cpi->twopass.kf_group_bits, 0); } else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) { - cpi->twopass.gf_group_bits += cpi->this_frame_target - - cpi->projected_frame_size; + cpi->twopass.gf_group_bits += cpi->rc.this_frame_target - + cpi->rc.projected_frame_size; cpi->twopass.gf_group_bits = MAX(cpi->twopass.gf_group_bits, 0); } @@ -3656,7 +3378,7 @@ static void Pass2Encode(VP9_COMP *cpi, unsigned long *size, encode_frame_to_data_rate(cpi, size, dest, frame_flags); // vp9_print_modes_and_motion_vectors(&cpi->common, "encode.stt"); #ifdef DISABLE_RC_LONG_TERM_MEM - cpi->twopass.bits_left -= cpi->this_frame_target; + cpi->twopass.bits_left -= cpi->rc.this_frame_target; #else cpi->twopass.bits_left -= 8 * *size; #endif @@ -3761,7 +3483,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, - cpi->next_frame_in_order; else #endif - frames_to_arf = cpi->frames_till_gf_update_due; + frames_to_arf = cpi->rc.frames_till_gf_update_due; assert(frames_to_arf < cpi->twopass.frames_to_key); @@ -3776,7 +3498,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, // Produce the filtered ARF frame. // TODO(agrange) merge these two functions. configure_arnr_filter(cpi, cm->current_video_frame + frames_to_arf, - cpi->gfu_boost); + 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); diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index c098b5ed8..8fa63854e 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -289,6 +289,59 @@ typedef struct { int use_fast_coef_updates; // 0: 2-loop, 1: 1-loop, 2: 1-loop reduced } SPEED_FEATURES; +typedef struct { + // Rate targetting variables + int this_frame_target; + int projected_frame_size; + int last_q[2]; // Separate values for Intra/Inter + int last_boosted_qindex; // Last boosted GF/KF/ARF q + + int gfu_boost; + int last_boost; + int kf_boost; + + double rate_correction_factor; + double key_frame_rate_correction_factor; + double gf_rate_correction_factor; + + unsigned int frames_since_golden; + int frames_till_gf_update_due; // Count down till next GF + + int max_gf_interval; + int baseline_gf_interval; + + int64_t key_frame_count; + int prior_key_frame_distance[KEY_FRAME_CONTEXT]; + int per_frame_bandwidth; // Current section per frame bandwidth target + int av_per_frame_bandwidth; // Average frame size target for clip + int min_frame_bandwidth; // Minimum allocation used for any frame + + int ni_av_qi; + int ni_tot_qi; + int ni_frames; + int avg_frame_qindex; + double tot_q; + double avg_q; + + int buffer_level; + int bits_off_target; + + int rolling_target_bits; + int rolling_actual_bits; + + int long_rolling_target_bits; + int long_rolling_actual_bits; + + int64_t total_actual_bits; + int total_target_vs_actual; // debug stats + + int worst_quality; + int active_worst_quality; + int best_quality; + int active_best_quality; + int active_worst_qchanged; +} RATE_CONTROL; + typedef struct VP9_COMP { DECLARE_ALIGNED(16, int16_t, y_quant[QINDEX_RANGE][8]); DECLARE_ALIGNED(16, int16_t, y_quant_shift[QINDEX_RANGE][8]); @@ -398,71 +451,17 @@ typedef struct VP9_COMP { CODING_CONTEXT coding_context; - // Rate targetting variables - int this_frame_target; - int projected_frame_size; - int last_q[2]; // Separate values for Intra/Inter - int last_boosted_qindex; // Last boosted GF/KF/ARF q - - double rate_correction_factor; - double key_frame_rate_correction_factor; - double gf_rate_correction_factor; - - unsigned int frames_since_golden; - int frames_till_gf_update_due; // Count down till next GF - - int gf_overspend_bits; // cumulative bits overspent because of GF boost - - int non_gf_bitrate_adjustment; // Following GF to recover extra bits spent - - int kf_overspend_bits; // Bits spent on key frames to be recovered on inters - int kf_bitrate_adjustment; // number of bits to recover on each inter frame. - int max_gf_interval; - int baseline_gf_interval; + int zbin_mode_boost; + int zbin_mode_boost_enabled; int active_arnr_frames; // <= cpi->oxcf.arnr_max_frames int active_arnr_strength; // <= cpi->oxcf.arnr_max_strength - int64_t key_frame_count; - int prior_key_frame_distance[KEY_FRAME_CONTEXT]; - int per_frame_bandwidth; // Current section per frame bandwidth target - int av_per_frame_bandwidth; // Average frame size target for clip - int min_frame_bandwidth; // Minimum allocation used for any frame - int inter_frame_target; double output_framerate; int64_t last_time_stamp_seen; int64_t last_end_time_stamp_seen; int64_t first_time_stamp_ever; - int ni_av_qi; - int ni_tot_qi; - int ni_frames; - int avg_frame_qindex; - double tot_q; - double avg_q; - - int zbin_mode_boost; - int zbin_mode_boost_enabled; - - int64_t total_byte_count; - - int buffered_mode; - - int buffer_level; - int bits_off_target; - - int rolling_target_bits; - int rolling_actual_bits; - - int long_rolling_target_bits; - int long_rolling_actual_bits; - - int64_t total_actual_bits; - int total_target_vs_actual; // debug stats - - int worst_quality; - int active_worst_quality; - int best_quality; - int active_best_quality; + RATE_CONTROL rc; int cq_target_quality; @@ -476,9 +475,6 @@ typedef struct VP9_COMP { vp9_coeff_probs_model frame_coef_probs[TX_SIZES][BLOCK_TYPES]; vp9_coeff_stats frame_branch_ct[TX_SIZES][BLOCK_TYPES]; - int gfu_boost; - int last_boost; - int kf_boost; int kf_zeromotion_pct; int gf_zeromotion_pct; @@ -502,7 +498,6 @@ typedef struct VP9_COMP { int speed; int compressor_speed; - int auto_worst_q; int cpu_used; int pass; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 0aa3a6893..1293e860f 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -35,6 +35,84 @@ static const unsigned int prior_key_frame_weight[KEY_FRAME_CONTEXT] = { 1, 2, 3, 4, 5 }; +// Tables relating active max Q to active min Q +static int kf_low_motion_minq[QINDEX_RANGE]; +static int kf_high_motion_minq[QINDEX_RANGE]; +static int gf_low_motion_minq[QINDEX_RANGE]; +static int gf_high_motion_minq[QINDEX_RANGE]; +static int inter_minq[QINDEX_RANGE]; +static int afq_low_motion_minq[QINDEX_RANGE]; +static int afq_high_motion_minq[QINDEX_RANGE]; + +// Functions to compute the active minq lookup table entries based on a +// formulaic approach to facilitate easier adjustment of the Q tables. +// The formulae were derived from computing a 3rd order polynomial best +// fit to the original data (after plotting real maxq vs minq (not q index)) +static int calculate_minq_index(double maxq, + double x3, double x2, double x1, double c) { + int i; + const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq + c, + maxq); + + // Special case handling to deal with the step from q2.0 + // down to lossless mode represented by q 1.0. + if (minqtarget <= 2.0) + return 0; + + for (i = 0; i < QINDEX_RANGE; i++) { + if (minqtarget <= vp9_convert_qindex_to_q(i)) + return i; + } + + return QINDEX_RANGE - 1; +} + +void vp9_init_minq_luts(void) { + int i; + + for (i = 0; i < QINDEX_RANGE; i++) { + const double maxq = vp9_convert_qindex_to_q(i); + + + kf_low_motion_minq[i] = calculate_minq_index(maxq, + 0.000001, + -0.0004, + 0.15, + 0.0); + kf_high_motion_minq[i] = calculate_minq_index(maxq, + 0.000002, + -0.0012, + 0.5, + 0.0); + + gf_low_motion_minq[i] = calculate_minq_index(maxq, + 0.0000015, + -0.0009, + 0.32, + 0.0); + gf_high_motion_minq[i] = calculate_minq_index(maxq, + 0.0000021, + -0.00125, + 0.50, + 0.0); + inter_minq[i] = calculate_minq_index(maxq, + 0.00000271, + -0.00113, + 0.75, + 0.0); + afq_low_motion_minq[i] = calculate_minq_index(maxq, + 0.0000015, + -0.0009, + 0.33, + 0.0); + afq_high_motion_minq[i] = calculate_minq_index(maxq, + 0.0000021, + -0.00125, + 0.55, + 0.0); + } +} + // These functions use formulaic calculations to make playing with the // quantizer tables easier. If necessary they can be replaced by lookup // tables if and when things settle down in the experimental bitstream @@ -118,7 +196,7 @@ void vp9_setup_key_frame(VP9_COMP *cpi) { vp9_setup_past_independence(cm); // interval before next GF - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; + cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval; /* All buffers are implicitly updated on key frames. */ cpi->refresh_golden_frame = 1; cpi->refresh_alt_ref_frame = 1; @@ -153,17 +231,17 @@ static void calc_iframe_target_size(VP9_COMP *cpi) { vp9_clear_system_state(); // __asm emms; // New Two pass RC - target = cpi->per_frame_bandwidth; + target = cpi->rc.per_frame_bandwidth; if (cpi->oxcf.rc_max_intra_bitrate_pct) { - int max_rate = cpi->per_frame_bandwidth + int max_rate = cpi->rc.per_frame_bandwidth * cpi->oxcf.rc_max_intra_bitrate_pct / 100; if (target > max_rate) target = max_rate; } - cpi->this_frame_target = target; + cpi->rc.this_frame_target = target; } @@ -174,21 +252,21 @@ static void calc_iframe_target_size(VP9_COMP *cpi) { // so we just use the interval determined in the two pass code. static void calc_gf_params(VP9_COMP *cpi) { // Set the gf interval - cpi->frames_till_gf_update_due = cpi->baseline_gf_interval; + cpi->rc.frames_till_gf_update_due = cpi->rc.baseline_gf_interval; } static void calc_pframe_target_size(VP9_COMP *cpi) { - const int min_frame_target = MAX(cpi->min_frame_bandwidth, - cpi->av_per_frame_bandwidth >> 5); + const int min_frame_target = MAX(cpi->rc.min_frame_bandwidth, + cpi->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 - cpi->per_frame_bandwidth = cpi->twopass.gf_bits; - cpi->this_frame_target = cpi->per_frame_bandwidth; + cpi->rc.per_frame_bandwidth = cpi->twopass.gf_bits; + cpi->rc.this_frame_target = cpi->rc.per_frame_bandwidth; } else { // Normal frames (gf,and inter) - cpi->this_frame_target = cpi->per_frame_bandwidth; + cpi->rc.this_frame_target = cpi->rc.per_frame_bandwidth; } // Check that the total sum of adjustments is not above the maximum allowed. @@ -197,41 +275,26 @@ static void calc_pframe_target_size(VP9_COMP *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. - if (cpi->this_frame_target < min_frame_target) - cpi->this_frame_target = min_frame_target; - - if (!cpi->refresh_alt_ref_frame) - // Note the baseline target data rate for this inter frame. - cpi->inter_frame_target = cpi->this_frame_target; + if (cpi->rc.this_frame_target < min_frame_target) + cpi->rc.this_frame_target = min_frame_target; // Adjust target frame size for Golden Frames: - if (cpi->frames_till_gf_update_due == 0) { - const int q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] - : cpi->oxcf.fixed_q; - + if (cpi->rc.frames_till_gf_update_due == 0) { cpi->refresh_golden_frame = 1; - calc_gf_params(cpi); - // If we are using alternate ref instead of gf then do not apply the boost // It will instead be applied to the altref update // Jims modified boost if (!cpi->source_alt_ref_active) { - if (cpi->oxcf.fixed_q < 0) { - // The spend on the GF is defined in the two pass code - // for two pass encodes - cpi->this_frame_target = cpi->per_frame_bandwidth; - } else { - cpi->this_frame_target = - (estimate_bits_at_q(1, q, cpi->common.MBs, 1.0) - * cpi->last_boost) / 100; - } + // The spend on the GF is defined in the two pass code + // for two pass encodes + cpi->rc.this_frame_target = cpi->rc.per_frame_bandwidth; } else { // If there is an active ARF at this location use the minimum // bits on this frame even if it is a constructed arf. // The active maximum quantizer insures that an appropriate // number of bits will be spent if needed for constructed ARFs. - cpi->this_frame_target = 0; + cpi->rc.this_frame_target = 0; } } } @@ -249,12 +312,12 @@ void vp9_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) { vp9_clear_system_state(); // __asm emms; if (cpi->common.frame_type == KEY_FRAME) { - rate_correction_factor = cpi->key_frame_rate_correction_factor; + rate_correction_factor = cpi->rc.key_frame_rate_correction_factor; } else { if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) - rate_correction_factor = cpi->gf_rate_correction_factor; + rate_correction_factor = cpi->rc.gf_rate_correction_factor; else - rate_correction_factor = cpi->rate_correction_factor; + rate_correction_factor = cpi->rc.rate_correction_factor; } // Work out how big we would have expected the frame to be at this Q given @@ -267,7 +330,7 @@ void vp9_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) { // Work out a size correction factor. if (projected_size_based_on_q > 0) correction_factor = - (100 * cpi->projected_frame_size) / projected_size_based_on_q; + (100 * cpi->rc.projected_frame_size) / projected_size_based_on_q; // More heavily damped adjustment used if we have been oscillating either side // of target. @@ -284,7 +347,7 @@ void vp9_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) { break; } - // if ( (correction_factor > 102) && (Q < cpi->active_worst_quality) ) + // if ( (correction_factor > 102) && (Q < cpi->rc.active_worst_quality) ) if (correction_factor > 102) { // We are not already at the worst allowable quality correction_factor = @@ -308,18 +371,18 @@ void vp9_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) { } if (cpi->common.frame_type == KEY_FRAME) { - cpi->key_frame_rate_correction_factor = rate_correction_factor; + cpi->rc.key_frame_rate_correction_factor = rate_correction_factor; } else { if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) - cpi->gf_rate_correction_factor = rate_correction_factor; + cpi->rc.gf_rate_correction_factor = rate_correction_factor; else - cpi->rate_correction_factor = rate_correction_factor; + cpi->rc.rate_correction_factor = rate_correction_factor; } } int vp9_regulate_q(VP9_COMP *cpi, int target_bits_per_frame) { - int q = cpi->active_worst_quality; + int q = cpi->rc.active_worst_quality; int i; int last_error = INT_MAX; @@ -329,12 +392,12 @@ int vp9_regulate_q(VP9_COMP *cpi, int target_bits_per_frame) { // Select the appropriate correction factor based upon type of frame. if (cpi->common.frame_type == KEY_FRAME) { - correction_factor = cpi->key_frame_rate_correction_factor; + correction_factor = cpi->rc.key_frame_rate_correction_factor; } else { if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) - correction_factor = cpi->gf_rate_correction_factor; + correction_factor = cpi->rc.gf_rate_correction_factor; else - correction_factor = cpi->rate_correction_factor; + correction_factor = cpi->rc.rate_correction_factor; } // Calculate required scaling factor based on target frame size and size of @@ -347,7 +410,7 @@ int vp9_regulate_q(VP9_COMP *cpi, int target_bits_per_frame) { target_bits_per_mb = (target_bits_per_frame << BPER_MB_NORMBITS) / cpi->common.MBs; - i = cpi->active_best_quality; + i = cpi->rc.active_best_quality; do { bits_per_mb_at_this_q = (int)vp9_bits_per_mb(cpi->common.frame_type, i, @@ -363,7 +426,214 @@ int vp9_regulate_q(VP9_COMP *cpi, int target_bits_per_frame) { } else { last_error = bits_per_mb_at_this_q - target_bits_per_mb; } - } while (++i <= cpi->active_worst_quality); + } while (++i <= cpi->rc.active_worst_quality); + + return q; +} + +static int get_active_quality(int q, + int gfu_boost, + int low, + int high, + int *low_motion_minq, + int *high_motion_minq) { + int active_best_quality; + if (gfu_boost > high) { + active_best_quality = low_motion_minq[q]; + } else if (gfu_boost < low) { + active_best_quality = high_motion_minq[q]; + } else { + const int gap = high - low; + const int offset = high - gfu_boost; + const int qdiff = high_motion_minq[q] - low_motion_minq[q]; + const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap; + active_best_quality = low_motion_minq[q] + adjustment; + } + return active_best_quality; +} + +int vp9_pick_q_and_adjust_q_bounds(VP9_COMP *cpi, + int * bottom_index, int * top_index) { + // Set an active best quality and if necessary active worst quality + int q = cpi->rc.active_worst_quality; + VP9_COMMON *const cm = &cpi->common; + + if (frame_is_intra_only(cm)) { +#if !CONFIG_MULTIPLE_ARF + // Handle the special case for key frames forced when we have75 reached + // the maximum key frame interval. Here force the Q to a range + // based on the ambient Q to reduce the risk of popping. + if (cpi->this_key_frame_forced) { + int delta_qindex; + int qindex = cpi->rc.last_boosted_qindex; + double last_boosted_q = vp9_convert_qindex_to_q(qindex); + + delta_qindex = vp9_compute_qdelta(cpi, last_boosted_q, + (last_boosted_q * 0.75)); + + cpi->rc.active_best_quality = MAX(qindex + delta_qindex, + cpi->rc.best_quality); + } else { + int high = 5000; + int low = 400; + double q_adj_factor = 1.0; + double q_val; + + // Baseline value derived from cpi->active_worst_quality and kf boost + cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.kf_boost, + low, high, + kf_low_motion_minq, + kf_high_motion_minq); + + // Allow somewhat lower kf minq with small image formats. + if ((cm->width * cm->height) <= (352 * 288)) { + q_adj_factor -= 0.25; + } + + // Make a further adjustment based on the kf zero motion measure. + q_adj_factor += 0.05 - (0.001 * (double)cpi->kf_zeromotion_pct); + + // Convert the adjustment factor to a qindex delta + // on active_best_quality. + q_val = vp9_convert_qindex_to_q(cpi->rc.active_best_quality); + cpi->rc.active_best_quality += + vp9_compute_qdelta(cpi, q_val, (q_val * q_adj_factor)); + } +#else + double current_q; + // Force the KF quantizer to be 30% of the active_worst_quality. + current_q = vp9_convert_qindex_to_q(cpi->rc.active_worst_quality); + cpi->rc.active_best_quality = cpi->rc.active_worst_quality + + vp9_compute_qdelta(cpi, current_q, current_q * 0.3); +#endif + } else if (!cpi->is_src_frame_alt_ref && + (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { + int high = 2000; + int low = 400; + + // Use the lower of cpi->rc.active_worst_quality and recent + // average Q as basis for GF/ARF best Q limit unless last frame was + // a key frame. + if (cpi->frames_since_key > 1 && + cpi->rc.avg_frame_qindex < cpi->rc.active_worst_quality) { + q = cpi->rc.avg_frame_qindex; + } + // For constrained quality dont allow Q less than the cq level + if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { + if (q < cpi->cq_target_quality) + q = cpi->cq_target_quality; + if (cpi->frames_since_key > 1) { + cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost, + low, high, + afq_low_motion_minq, + afq_high_motion_minq); + } else { + cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost, + low, high, + gf_low_motion_minq, + gf_high_motion_minq); + } + // Constrained quality use slightly lower active best. + cpi->rc.active_best_quality = cpi->rc.active_best_quality * 15 / 16; + + } else if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { + if (!cpi->refresh_alt_ref_frame) { + cpi->rc.active_best_quality = cpi->cq_target_quality; + } else { + if (cpi->frames_since_key > 1) { + cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost, + low, high, + afq_low_motion_minq, + afq_high_motion_minq); + } else { + cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost, + low, high, + gf_low_motion_minq, + gf_high_motion_minq); + } + } + } else { + cpi->rc.active_best_quality = get_active_quality(q, cpi->rc.gfu_boost, + low, high, + gf_low_motion_minq, + gf_high_motion_minq); + } + } else { + if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { + cpi->rc.active_best_quality = cpi->cq_target_quality; + } else { + cpi->rc.active_best_quality = inter_minq[q]; + // 1-pass: for now, use the average Q for the active_best, if its lower + // than active_worst. + if (cpi->pass == 0 && (cpi->rc.avg_frame_qindex < q)) + cpi->rc.active_best_quality = inter_minq[cpi->rc.avg_frame_qindex]; + + // For the constrained quality mode we don't want + // q to fall below the cq level. + if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && + (cpi->rc.active_best_quality < cpi->cq_target_quality)) { + // If we are strongly undershooting the target rate in the last + // frames then use the user passed in cq value not the auto + // cq value. + if (cpi->rc.rolling_actual_bits < cpi->rc.min_frame_bandwidth) + cpi->rc.active_best_quality = cpi->oxcf.cq_level; + else + cpi->rc.active_best_quality = cpi->cq_target_quality; + } + } + } + + // Clip the active best and worst quality values to limits + if (cpi->rc.active_worst_quality > cpi->rc.worst_quality) + cpi->rc.active_worst_quality = cpi->rc.worst_quality; + + if (cpi->rc.active_best_quality < cpi->rc.best_quality) + cpi->rc.active_best_quality = cpi->rc.best_quality; + + if (cpi->rc.active_best_quality > cpi->rc.worst_quality) + cpi->rc.active_best_quality = cpi->rc.worst_quality; + + if (cpi->rc.active_worst_quality < cpi->rc.active_best_quality) + cpi->rc.active_worst_quality = cpi->rc.active_best_quality; + + // Limit Q range for the adaptive loop. + if (cm->frame_type == KEY_FRAME && !cpi->this_key_frame_forced) { + *top_index = + (cpi->rc.active_worst_quality + cpi->rc.active_best_quality * 3) / 4; + // If this is the first (key) frame in 1-pass, active best is the user + // best-allowed, and leave the top_index to active_worst. + if (cpi->pass == 0 && cpi->common.current_video_frame == 0) { + cpi->rc.active_best_quality = cpi->oxcf.best_allowed_q; + *top_index = cpi->oxcf.worst_allowed_q; + } + } else if (!cpi->is_src_frame_alt_ref && + (cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER) && + (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) { + *top_index = + (cpi->rc.active_worst_quality + cpi->rc.active_best_quality) / 2; + } else { + *top_index = cpi->rc.active_worst_quality; + } + *bottom_index = cpi->rc.active_best_quality; + + if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { + q = cpi->rc.active_best_quality; + // Special case code to try and match quality with forced key frames + } else if ((cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced) { + q = cpi->rc.last_boosted_qindex; + } else { + // Determine initial Q to try. + if (cpi->pass == 0) { + // 1-pass: for now, use per-frame-bw for target size of frame, scaled + // by |x| for key frame. + int scale = (cm->frame_type == KEY_FRAME) ? 5 : 1; + q = vp9_regulate_q(cpi, scale * cpi->rc.av_per_frame_bandwidth); + } else { + q = vp9_regulate_q(cpi, cpi->rc.this_frame_target); + } + if (q > *top_index) + q = *top_index; + } return q; } @@ -378,7 +648,7 @@ static int estimate_keyframe_frequency(VP9_COMP *cpi) { /* First key frame at start of sequence is a special case. We have no * frequency data. */ - if (cpi->key_frame_count == 1) { + if (cpi->rc.key_frame_count == 1) { /* Assume a default of 1 kf every 2 seconds, or the max kf interval, * whichever is smaller. */ @@ -388,7 +658,7 @@ static int estimate_keyframe_frequency(VP9_COMP *cpi) { if (cpi->oxcf.auto_key && av_key_frame_frequency > key_freq) av_key_frame_frequency = cpi->oxcf.key_freq; - cpi->prior_key_frame_distance[KEY_FRAME_CONTEXT - 1] + cpi->rc.prior_key_frame_distance[KEY_FRAME_CONTEXT - 1] = av_key_frame_frequency; } else { unsigned int total_weight = 0; @@ -400,13 +670,13 @@ static int estimate_keyframe_frequency(VP9_COMP *cpi) { */ for (i = 0; i < KEY_FRAME_CONTEXT; i++) { if (i < KEY_FRAME_CONTEXT - 1) - cpi->prior_key_frame_distance[i] - = cpi->prior_key_frame_distance[i + 1]; + cpi->rc.prior_key_frame_distance[i] + = cpi->rc.prior_key_frame_distance[i + 1]; else - cpi->prior_key_frame_distance[i] = last_kf_interval; + cpi->rc.prior_key_frame_distance[i] = last_kf_interval; av_key_frame_frequency += prior_key_frame_weight[i] - * cpi->prior_key_frame_distance[i]; + * cpi->rc.prior_key_frame_distance[i]; total_weight += prior_key_frame_weight[i]; } @@ -421,33 +691,32 @@ void vp9_adjust_key_frame_context(VP9_COMP *cpi) { vp9_clear_system_state(); cpi->frames_since_key = 0; - cpi->key_frame_count++; + cpi->rc.key_frame_count++; } void vp9_compute_frame_size_bounds(VP9_COMP *cpi, int *frame_under_shoot_limit, int *frame_over_shoot_limit) { // Set-up bounds on acceptable frame size: - if (cpi->oxcf.fixed_q >= 0) { - // Fixed Q scenario: frame size never outranges target (there is no target!) + if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) { *frame_under_shoot_limit = 0; *frame_over_shoot_limit = INT_MAX; } else { if (cpi->common.frame_type == KEY_FRAME) { - *frame_over_shoot_limit = cpi->this_frame_target * 9 / 8; - *frame_under_shoot_limit = cpi->this_frame_target * 7 / 8; + *frame_over_shoot_limit = cpi->rc.this_frame_target * 9 / 8; + *frame_under_shoot_limit = cpi->rc.this_frame_target * 7 / 8; } else { if (cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) { - *frame_over_shoot_limit = cpi->this_frame_target * 9 / 8; - *frame_under_shoot_limit = cpi->this_frame_target * 7 / 8; + *frame_over_shoot_limit = cpi->rc.this_frame_target * 9 / 8; + *frame_under_shoot_limit = cpi->rc.this_frame_target * 7 / 8; } else { // Stron overshoot limit for constrained quality if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) { - *frame_over_shoot_limit = cpi->this_frame_target * 11 / 8; - *frame_under_shoot_limit = cpi->this_frame_target * 2 / 8; + *frame_over_shoot_limit = cpi->rc.this_frame_target * 11 / 8; + *frame_under_shoot_limit = cpi->rc.this_frame_target * 2 / 8; } else { - *frame_over_shoot_limit = cpi->this_frame_target * 11 / 8; - *frame_under_shoot_limit = cpi->this_frame_target * 5 / 8; + *frame_over_shoot_limit = cpi->rc.this_frame_target * 11 / 8; + *frame_under_shoot_limit = cpi->rc.this_frame_target * 5 / 8; } } } diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h index ddda7130c..57dcd3f15 100644 --- a/vp9/encoder/vp9_ratectrl.h +++ b/vp9/encoder/vp9_ratectrl.h @@ -27,6 +27,8 @@ void vp9_compute_frame_size_bounds(VP9_COMP *cpi, int *frame_under_shoot_limit, int *frame_over_shoot_limit); +void vp9_init_minq_luts(void); + // return of 0 means drop frame int vp9_pick_frame_size(VP9_COMP *cpi); @@ -35,5 +37,7 @@ int vp9_gfboost_qadjust(int qindex); int vp9_bits_per_mb(FRAME_TYPE frame_type, int qindex, double correction_factor); void vp9_setup_inter_frame(VP9_COMP *cpi); +int vp9_pick_q_and_adjust_q_bounds(VP9_COMP *cpi, + int * bottom_index, int * top_index); #endif // VP9_ENCODER_VP9_RATECTRL_H_ diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c index 3bffb12af..6d4075ed1 100644 --- a/vp9/encoder/vp9_temporal_filter.c +++ b/vp9/encoder/vp9_temporal_filter.c @@ -469,7 +469,7 @@ void configure_arnr_filter(VP9_COMP *cpi, const unsigned int this_frame, // 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. - half_gf_int = cpi->baseline_gf_interval >> 1; + half_gf_int = cpi->rc.baseline_gf_interval >> 1; frames_after_arf = (int)(cpi->twopass.total_stats.count - this_frame - 1); switch (cpi->oxcf.arnr_type) { @@ -507,7 +507,7 @@ void configure_arnr_filter(VP9_COMP *cpi, const unsigned int this_frame, cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd; // Adjust the strength based on active max q - q = ((int)vp9_convert_qindex_to_q(cpi->active_worst_quality) >> 1); + q = ((int)vp9_convert_qindex_to_q(cpi->rc.active_worst_quality) >> 1); if (q > 8) { cpi->active_arnr_strength = cpi->oxcf.arnr_strength; } else {