diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index ae263caf72db8c9162bfc9020e4aea6d1346ebfe..f2e004608d4c07360f77a6b474bcb2aa0adf801d 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -38,7 +38,7 @@ #define IIFACTOR 12.5 #define IIKFACTOR1 12.5 #define IIKFACTOR2 15.0 -#define RMAX 128.0 +#define RMAX 512.0 #define GF_RMAX 96.0 #define ERR_DIVISOR 150.0 #define MIN_DECAY_FACTOR 0.1 @@ -2352,7 +2352,6 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { double decay_accumulator = 1.0; double zero_motion_accumulator = 1.0; double boost_score = 0; - double old_boost_score = 0.0; double loop_decay_rate; double kf_mod_err = 0.0; @@ -2524,22 +2523,13 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { boost_score = 0.0; loop_decay_rate = 1.00; // Starting decay rate + // Scan through the kf group collating various stats. for (i = 0; i < cpi->twopass.frames_to_key; i++) { double r; if (EOF == input_stats(cpi, &next_frame)) break; - if (next_frame.intra_error > cpi->twopass.kf_intra_err_min) - r = (IIKFACTOR2 * next_frame.intra_error / - DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); - else - r = (IIKFACTOR2 * cpi->twopass.kf_intra_err_min / - DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); - - if (r > RMAX) - r = RMAX; - // Monitor for static sections. if ((next_frame.pcnt_inter - next_frame.pcnt_motion) < zero_motion_accumulator) { @@ -2547,22 +2537,28 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { (next_frame.pcnt_inter - next_frame.pcnt_motion); } - // How fast is prediction quality decaying - if (!detect_flash(cpi, 0)) { - loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); - decay_accumulator = decay_accumulator * loop_decay_rate; - decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR - ? MIN_DECAY_FACTOR : decay_accumulator; - } + // For the first few frames collect data to decide kf boost. + if (i <= (cpi->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)); + else + r = (IIKFACTOR2 * cpi->twopass.kf_intra_err_min / + DOUBLE_DIVIDE_CHECK(next_frame.coded_error)); - boost_score += (decay_accumulator * r); + if (r > RMAX) + r = RMAX; - if ((i > MIN_GF_INTERVAL) && - ((boost_score - old_boost_score) < 6.25)) { - break; - } + // How fast is prediction quality decaying + if (!detect_flash(cpi, 0)) { + loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); + decay_accumulator = decay_accumulator * loop_decay_rate; + decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR + ? MIN_DECAY_FACTOR : decay_accumulator; + } - old_boost_score = boost_score; + boost_score += (decay_accumulator * r); + } } { @@ -2592,8 +2588,8 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { int allocation_chunks; int alt_kf_bits; - if (kf_boost < (cpi->twopass.frames_to_key * 5)) - kf_boost = (cpi->twopass.frames_to_key * 5); + if (kf_boost < (cpi->twopass.frames_to_key * 3)) + kf_boost = (cpi->twopass.frames_to_key * 3); if (kf_boost < 300) // Min KF boost kf_boost = 300; diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 9997e188ca8e27b0e69d30cf3a6e60011b3d5c3c..85ac5231d4ca874cf4d1aa0a6fc29137f5a6610d 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -177,15 +177,16 @@ static void init_minq_luts(void) { kf_low_motion_minq[i] = calculate_minq_index(maxq, - 0.0000003, - -0.000015, - 0.074, + 0.000001, + -0.0004, + 0.15, 0.0); kf_high_motion_minq[i] = calculate_minq_index(maxq, - 0.0000004, - -0.000125, - 0.14, + 0.000002, + -0.0012, + 0.5, 0.0); + gf_low_motion_minq[i] = calculate_minq_index(maxq, 0.0000015, -0.0009, @@ -2757,31 +2758,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, q = cpi->active_worst_quality; if (cm->frame_type == KEY_FRAME) { -#if CONFIG_MULTIPLE_ARF - double current_q; -#endif - int high = 2000; - int low = 400; - - if (cpi->kf_boost > high) { - cpi->active_best_quality = kf_low_motion_minq[q]; - } else if (cpi->kf_boost < low) { - cpi->active_best_quality = kf_high_motion_minq[q]; - } else { - const int gap = high - low; - const int offset = high - cpi->kf_boost; - const int qdiff = kf_high_motion_minq[q] - kf_low_motion_minq[q]; - const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap; - - cpi->active_best_quality = kf_low_motion_minq[q] + adjustment; - } - - // Make an adjustment based on the % static - // The main impact of this is at lower Q to prevent overly large key - // frames unless a lot of the image is static. - if (cpi->kf_zeromotion_pct < 64) - cpi->active_best_quality += 4 - (cpi->kf_zeromotion_pct >> 4); - +#if !CONFIG_MULTIPLE_ARF // Special case for key frames forced because we have reached // the maximum key frame interval. Here force the Q to a range // based on the ambient Q to reduce the risk of popping @@ -2794,8 +2771,43 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, (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 + if (cpi->kf_boost > high) { + cpi->active_best_quality = kf_low_motion_minq[q]; + } else if (cpi->kf_boost < low) { + cpi->active_best_quality = kf_high_motion_minq[q]; + } else { + const int gap = high - low; + const int offset = high - cpi->kf_boost; + const int qdiff = kf_high_motion_minq[q] - kf_low_motion_minq[q]; + const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap; + + cpi->active_best_quality = kf_low_motion_minq[q] + adjustment; + } + + + // 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 += + compute_qdelta(cpi, q_val, (q_val * q_adj_factor)); } -#if CONFIG_MULTIPLE_ARF +#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