From 7eb66d82ca46377f602b512df789fc21ac20c277 Mon Sep 17 00:00:00 2001 From: Paul Wilkins <paulwilkins@google.com> Date: Wed, 30 May 2012 12:54:34 +0100 Subject: [PATCH] Merge of further two pass rc clean up and adjustments. Changes to calculation of sr_coded_error to include 0,0 case. Experimental use of sr_coded_error in calculating correction factor for estimating the allowable Q range. Reinstated some code needed for calculating section_intra_rating. Add flash detection in calculation of KF boost Increased tolerance in testing candidate key frames (needed with longer motion search as this tends to slightly increase inter %. Zbin changes for 8x8. Other minor adjustments, refactoring and bug fixes. Reinstated some motion break out clauses in boost loop as their removal hurt a few 50fps clips badly in the std set. It may be possible to remove them again later if a better way can be found of preventing overly long gf intervals. Change-Id: Iee686d0c31072828bb1ccd2bc63f5f1c7c548ea2 --- vp8/encoder/firstpass.c | 180 +++++++++++++++++++++++----------------- vp8/encoder/quantize.c | 17 ++-- 2 files changed, 112 insertions(+), 85 deletions(-) diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index a89ef12496..dad028757a 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -412,8 +412,8 @@ static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x, int_mv ref_mv_full; int tmp_err; - int step_param = 3; //3; // Dont search over full range for first pass - int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; //3; + int step_param = 3; + int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; int n; vp8_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16]; int new_mv_mode_penalty = 256; @@ -619,6 +619,10 @@ void vp8_first_pass(VP8_COMP *cpi) // Experimental search in an older reference frame if (cm->current_video_frame > 1) { + // Simple 0,0 motion with no mv overhead + zz_motion_search( cpi, x, gld_yv12, + &gf_motion_error, recon_yoffset ); + first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv.as_mv, gld_yv12, &gf_motion_error, recon_yoffset); @@ -772,6 +776,7 @@ void vp8_first_pass(VP8_COMP *cpi) fps.MVrv = 0.0; fps.MVcv = 0.0; fps.mv_in_out_count = 0.0; + fps.new_mv_count = 0.0; fps.count = 1.0; fps.pcnt_inter = 1.0 * (double)intercount / cm->MBs; @@ -894,9 +899,7 @@ static long long estimate_modemvcost(VP8_COMP *cpi, return 0; } -static double calc_correction_factor( VP8_COMP *cpi, - FIRSTPASS_STATS * fpstats, - double err_per_mb, +static double calc_correction_factor( double err_per_mb, double err_divisor, double pt_low, double pt_high, @@ -905,9 +908,6 @@ static double calc_correction_factor( VP8_COMP *cpi, double power_term; double error_term = err_per_mb / err_divisor; double correction_factor; - double sr_err_diff; - double sr_correction; - // Adjustment based on actual quantizer to power term. power_term = (vp8_convert_qindex_to_q(Q) * 0.01) + pt_low; @@ -916,24 +916,9 @@ static double calc_correction_factor( VP8_COMP *cpi, // Adjustments to error term // TBD - // Calculate a correction factor based on error per mb + // Calculate correction factor correction_factor = pow(error_term, power_term); -#if 0 - // Look at the drop in prediction quality between the last frame - // and the GF buffer (which contained an older frame). - sr_err_diff = - (fpstats->sr_coded_error - fpstats->coded_error) / - (fpstats->count * cpi->common.MBs * 32); - sr_correction = pow( sr_err_diff, 0.5 ); - if ( sr_correction < 0.5 ) - sr_correction = 0.5; - else if ( sr_correction > 1.25 ) - sr_correction = 1.25; - - correction_factor = correction_factor * sr_correction; -#endif - // Clip range correction_factor = (correction_factor < 0.05) @@ -982,6 +967,8 @@ static int estimate_max_q(VP8_COMP *cpi, int target_norm_bits_per_mb; double section_err = (fpstats->coded_error / fpstats->count); + double sr_err_diff; + double sr_correction; double err_per_mb = section_err / num_mbs; double err_correction_factor; double corr_high; @@ -998,6 +985,18 @@ static int estimate_max_q(VP8_COMP *cpi, ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs); + // Look at the drop in prediction quality between the last frame + // and the GF buffer (which contained an older frame). + sr_err_diff = + (fpstats->sr_coded_error - fpstats->coded_error) / + (fpstats->count * cpi->common.MBs); + sr_correction = (sr_err_diff / 32.0); + sr_correction = pow( sr_correction, 0.25 ); + if ( sr_correction < 0.75 ) + sr_correction = 0.75; + else if ( sr_correction > 1.25 ) + sr_correction = 1.25; + // Calculate a corrective factor based on a rolling ratio of bits spent // vs target bits if ((cpi->rolling_target_bits > 0) && @@ -1043,11 +1042,9 @@ static int estimate_max_q(VP8_COMP *cpi, { int bits_per_mb_at_this_q; - // Error per MB based correction factor err_correction_factor = - calc_correction_factor(cpi, fpstats, err_per_mb, - ERR_DIVISOR, 0.40, 0.90, Q) * - speed_correction * + calc_correction_factor(err_per_mb, ERR_DIVISOR, 0.4, 0.90, Q) * + sr_correction * speed_correction * cpi->twopass.est_max_qcorrection_factor; if ( err_correction_factor < 0.05 ) @@ -1107,6 +1104,8 @@ static int estimate_cq( VP8_COMP *cpi, double section_err = (fpstats->coded_error / fpstats->count); double err_per_mb = section_err / num_mbs; double err_correction_factor; + double sr_err_diff; + double sr_correction; double corr_high; double speed_correction = 1.0; double clip_iiratio; @@ -1115,12 +1114,6 @@ static int estimate_cq( VP8_COMP *cpi, double intra_pct = 1.0 - inter_pct; int overhead_bits_per_mb; - if (0) - { - FILE *f = fopen("epmp.stt", "a"); - fprintf(f, "%10.2f\n", err_per_mb ); - fclose(f); - } target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs @@ -1139,6 +1132,18 @@ static int estimate_cq( VP8_COMP *cpi, speed_correction = 1.25; } + // Look at the drop in prediction quality between the last frame + // and the GF buffer (which contained an older frame). + sr_err_diff = + (fpstats->sr_coded_error - fpstats->coded_error) / + (fpstats->count * cpi->common.MBs); + sr_correction = (sr_err_diff / 32.0); + sr_correction = pow( sr_correction, 0.25 ); + if ( sr_correction < 0.75 ) + sr_correction = 0.75; + else if ( sr_correction > 1.25 ) + sr_correction = 1.25; + // II ratio correction factor for clip as a whole clip_iiratio = cpi->twopass.total_stats->intra_error / DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats->coded_error); @@ -1153,9 +1158,8 @@ static int estimate_cq( VP8_COMP *cpi, // Error per MB based correction factor err_correction_factor = - calc_correction_factor(cpi, fpstats, err_per_mb, - 100.0, 0.40, 0.90, Q) * - speed_correction * clip_iifactor; + calc_correction_factor(err_per_mb, 100.0, 0.4, 0.90, Q) * + sr_correction * speed_correction * clip_iifactor; if ( err_correction_factor < 0.05 ) err_correction_factor = 0.05; @@ -1165,9 +1169,8 @@ static int estimate_cq( VP8_COMP *cpi, bits_per_mb_at_this_q = vp8_bits_per_mb(INTER_FRAME, Q) + overhead_bits_per_mb; - bits_per_mb_at_this_q = - (int)( .5 + err_correction_factor * - (double)bits_per_mb_at_this_q); + bits_per_mb_at_this_q = (int)(.5 + err_correction_factor * + (double)bits_per_mb_at_this_q); // Mode and motion overhead // As Q rises in real encode loop rd code will force overhead down @@ -1280,7 +1283,8 @@ void vp8_end_second_pass(VP8_COMP *cpi) // This function gives and estimate of how badly we believe // the prediction quality is decaying from frame to frame. -static double get_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame) +static double get_prediction_decay_rate( VP8_COMP *cpi, + FIRSTPASS_STATS *next_frame) { double prediction_decay_rate; double second_ref_decay; @@ -1289,7 +1293,7 @@ static double get_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_fra double mb_sr_err_diff; // Initial basis is the % mbs inter coded - prediction_decay_rate = pow(next_frame->pcnt_inter, 0.5); + prediction_decay_rate = next_frame->pcnt_inter; // Look at the observed drop in prediction quality between the last frame // and the GF buffer (which contains an older frame). @@ -1378,16 +1382,6 @@ static BOOL detect_flash( VP8_COMP *cpi, int offset ) (next_frame.pcnt_second_ref >= 0.5 ) ) { flash_detected = TRUE; - - /*if (1) - { - FILE *f = fopen("flash.stt", "a"); - fprintf(f, "%8.0f %6.2f %6.2f\n", - next_frame.frame, - next_frame.pcnt_inter, - next_frame.pcnt_second_ref); - fclose(f); - }*/ } } @@ -1654,7 +1648,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) unsigned int allow_alt_ref = cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames; - int alt_boost = 0; int f_boost = 0; int b_boost = 0; BOOL flash_detected; @@ -1693,7 +1686,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) // Accumulate error score of frames in this gf group mod_frame_err = calculate_modified_err(cpi, this_frame); - gf_group_err += mod_frame_err; if (EOF == input_stats(cpi, &next_frame)) @@ -1782,12 +1774,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) } } - cpi->gfu_boost = boost_score; - - // Alterrnative boost calculation for alt ref - alt_boost = calc_arf_boost( cpi, 0, (i-1), (i-1), &f_boost, &b_boost ); - - // Set the interval till the next gf or arf. + // Set the interval till the next gf or arf. cpi->baseline_gf_interval = i; // Should we use the alternate refernce frame @@ -1800,15 +1787,17 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) (next_frame.pcnt_second_ref > 0.5)) && ((mv_in_out_accumulator / (double)i > -0.2) || (mv_in_out_accumulator > -2.0)) && - ((b_boost + f_boost) > 100) ) + (boost_score > 100)) { - cpi->gfu_boost = alt_boost; + // Alterrnative boost calculation for alt ref + cpi->gfu_boost = calc_arf_boost( cpi, 0, (i-1), (i-1), &f_boost, &b_boost ); cpi->source_alt_ref_pending = TRUE; configure_arnr_filter( cpi, this_frame ); } else { + cpi->gfu_boost = (int)boost_score; cpi->source_alt_ref_pending = FALSE; } @@ -1992,6 +1981,28 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) else cpi->twopass.alt_extra_bits = 0; } + + if (cpi->common.frame_type != KEY_FRAME) + { + FIRSTPASS_STATS sectionstats; + + zero_stats(§ionstats); + reset_fpf_position(cpi, start_pos); + + for (i = 0 ; i < cpi->baseline_gf_interval ; i++) + { + input_stats(cpi, &next_frame); + accumulate_stats(§ionstats, &next_frame); + } + + avg_stats(§ionstats); + + cpi->twopass.section_intra_rating = + sectionstats.intra_error / + DOUBLE_DIVIDE_CHECK(sectionstats.coded_error); + + reset_fpf_position(cpi, start_pos); + } } // Allocate bits to a normal frame that is neither a gf an arf or a key frame. @@ -2034,12 +2045,6 @@ static void assign_std_frame_bits(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) target_frame_size += cpi->min_frame_bandwidth; // Add in the minimum number of bits that is set aside for every frame. - // Every other frame gets a few extra bits - if ( (cpi->common.frames_since_golden & 0x01) && - (cpi->frames_till_gf_update_due > 0) ) - { - target_frame_size += cpi->twopass.alt_extra_bits; - } cpi->per_frame_bandwidth = target_frame_size; // Per frame bit target for this frame } @@ -2257,7 +2262,7 @@ static BOOL test_candidate_kf(VP8_COMP *cpi, FIRSTPASS_STATS *last_frame, FIRST (next_frame->pcnt_second_ref < 0.10) && ((this_frame->pcnt_inter < 0.05) || ( - ((this_frame->pcnt_inter - this_frame->pcnt_neutral) < .25) && + ((this_frame->pcnt_inter - this_frame->pcnt_neutral) < .35) && ((this_frame->intra_error / DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < 2.5) && ((fabs(last_frame->coded_error - this_frame->coded_error) / DOUBLE_DIVIDE_CHECK(this_frame->coded_error) > .40) || (fabs(last_frame->intra_error - this_frame->intra_error) / DOUBLE_DIVIDE_CHECK(this_frame->intra_error) > .40) || @@ -2529,7 +2534,7 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) boost_score = 0.0; loop_decay_rate = 1.00; // Starting decay rate - for (i = 0; i < cpi->twopass.frames_to_key; i++) + for (i = 0 ; i < cpi->twopass.frames_to_key ; i++) { double r; @@ -2555,10 +2560,12 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) } // How fast is prediction quality decaying - loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame); - - decay_accumulator = decay_accumulator * loop_decay_rate; - decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator; + 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 < 0.1 ? 0.1 : decay_accumulator; + } boost_score += (decay_accumulator * r); @@ -2571,6 +2578,25 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) old_boost_score = boost_score; } + { + FIRSTPASS_STATS sectionstats; + + zero_stats(§ionstats); + reset_fpf_position(cpi, start_position); + + for (i = 0 ; i < cpi->twopass.frames_to_key ; i++) + { + input_stats(cpi, &next_frame); + accumulate_stats(§ionstats, &next_frame); + } + + avg_stats(§ionstats); + + cpi->twopass.section_intra_rating = + sectionstats.intra_error + / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error); + } + // Reset the first pass file position reset_fpf_position(cpi, start_position); @@ -2593,7 +2619,7 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) if (kf_boost < 250) // Min KF boost kf_boost = 250; - // Make a not of baseline boost and the zero motion + // Make a note of baseline boost and the zero motion // accumulator value for use elsewhere. cpi->kf_boost = kf_boost; cpi->kf_zeromotion_pct = (int)(zero_motion_accumulator * 100.0); @@ -2606,8 +2632,8 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) // allocation it would have received based on its own error score vs // the error score remaining // Special case if the sequence appears almost totaly static - // as measured by the decay accumulator. In this case we want to - // spend almost all of the bits on the key frame. + // In this case we want to spend almost all of the bits on the + // key frame. // cpi->twopass.frames_to_key-1 because key frame itself is taken // care of by kf_boost. if ( zero_motion_accumulator >= 0.99 ) diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c index 37e5b6d374..c0b1be3241 100644 --- a/vp8/encoder/quantize.c +++ b/vp8/encoder/quantize.c @@ -297,17 +297,18 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) int zbin_boost[16] = { 0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 44, 44}; - int zbin_boost_8x8[64] = { 0, 0, 8, 10, 12, 14, 16, 20, - 24, 28, 32, 36, 40, 44, 48, 52, - 56, 60, 64, 68, 72, 76, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80 }; + int zbin_boost_8x8[64] = { 0, 0, 0, 8, 8, 8, 10, 12, + 14, 16, 18, 20, 22, 24, 26, 28, + 30, 32, 34, 36, 38, 40, 42, 44, + 46, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48 }; int qrounding_factor = 48; + for (Q = 0; Q < QINDEX_RANGE; Q++) { int qzbin_factor = (vp8_dc_quant(Q,0) < 148) ? 84 : 80; -- GitLab