diff options
Diffstat (limited to 'vp8/encoder/firstpass.c')
-rw-r--r-- | vp8/encoder/firstpass.c | 204 |
1 files changed, 171 insertions, 33 deletions
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index da4d740cb..32a39c5f2 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -58,6 +58,7 @@ extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE]; #define KF_MB_INTRA_MIN 300 #define GF_MB_INTRA_MIN 200 + #define DOUBLE_DIVIDE_CHECK(X) ((X)<0?(X)-.000001:(X)+.000001) #define POW1 (double)cpi->oxcf.two_pass_vbrbias/100.0 @@ -67,6 +68,18 @@ static int vscale_lookup[7] = {0, 1, 1, 2, 2, 3, 3}; static int hscale_lookup[7] = {0, 0, 1, 1, 2, 2, 3}; +const int cq_level[QINDEX_RANGE] = +{ + 0,0,1,1,2,3,3,4,4,5,6,6,7,8,8,9, + 9,10,11,11,12,13,13,14,15,15,16,17,17,18,19,20, + 20,21,22,22,23,24,24,25,26,27,27,28,29,30,30,31, + 32,33,33,34,35,36,36,37,38,39,39,40,41,42,42,43, + 44,45,46,46,47,48,49,50,50,51,52,53,54,55,55,56, + 57,58,59,60,60,61,62,63,64,65,66,67,67,68,69,70, + 71,72,73,74,75,75,76,77,78,79,80,81,82,83,84,85, + 86,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100 +}; + void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame); int vp8_input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps); @@ -249,7 +262,6 @@ extern size_t vp8_firstpass_stats_sz(unsigned int mb_count) * macroblock. */ size_t stats_sz; - FIRSTPASS_STATS stats; stats_sz = sizeof(FIRSTPASS_STATS) + mb_count; stats_sz = (stats_sz + 7) & ~7; @@ -376,8 +388,6 @@ unsigned char *vp8_fpmm_get_pos(VP8_COMP *cpi) } void vp8_fpmm_reset_pos(VP8_COMP *cpi, unsigned char *target_pos) { - int Offset; - cpi->fp_motion_map_stats = target_pos; } @@ -907,7 +917,7 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_ double pow_lowq = 0.40; if (section_target_bandwitdh <= 0) - return MAXQ; + return cpi->maxq_max_limit; // Highest value allowed target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs); @@ -943,10 +953,12 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_ // Correction factor used for Q values >= 20 corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq); - corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high; + corr_high = (corr_high < 0.05) + ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high; - // Try and pick a Q that should be high enough to encode the content at the given rate. - for (Q = 0; Q < MAXQ; Q++) + // Try and pick a max Q that will be high enough to encode the + // content at the given rate. + for (Q = cpi->maxq_min_limit; Q < cpi->maxq_max_limit; Q++) { int bits_per_mb_at_this_q; @@ -965,6 +977,28 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_ break; } + // Restriction on active max q for constrained quality mode. + if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && + (Q < cpi->cq_target_quality) ) + //(Q < cpi->oxcf.cq_level;) ) + { + Q = cpi->cq_target_quality; + //Q = cpi->oxcf.cq_level; + } + + // Adjust maxq_min_limit and maxq_max_limit limits based on + // averaga q observed in clip for non kf/gf.arf frames + // Give average a chance to settle though. + if ( (cpi->ni_frames > + ((unsigned int)cpi->total_stats->count >> 8)) && + (cpi->ni_frames > 150) ) + { + cpi->maxq_max_limit = ((cpi->ni_av_qi + 32) < cpi->worst_quality) + ? (cpi->ni_av_qi + 32) : cpi->worst_quality; + cpi->maxq_min_limit = ((cpi->ni_av_qi - 32) > cpi->best_quality) + ? (cpi->ni_av_qi - 32) : cpi->best_quality; + } + return Q; } static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width) @@ -1113,6 +1147,79 @@ static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_ta return Q; } + +// For cq mode estimate a cq level that matches the observed +// complexity and data rate. +static int estimate_cq(VP8_COMP *cpi, double section_err, + int section_target_bandwitdh, int Height, int Width) +{ + int Q; + int num_mbs = ((Height * Width) / (16 * 16)); + int target_norm_bits_per_mb; + + double err_per_mb = section_err / num_mbs; + double correction_factor; + double corr_high; + double speed_correction = 1.0; + double pow_highq = 0.90; + double pow_lowq = 0.40; + double clip_iiratio; + double clip_iifactor; + + target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) + ? (512 * section_target_bandwitdh) / num_mbs + : 512 * (section_target_bandwitdh / num_mbs); + + // Corrections for higher compression speed settings + // (reduced compression expected) + if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1)) + { + if (cpi->oxcf.cpu_used <= 5) + speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04); + else + speed_correction = 1.25; + } + // II ratio correction factor for clip as a whole + clip_iiratio = cpi->total_stats->intra_error / + DOUBLE_DIVIDE_CHECK(cpi->total_stats->coded_error); + clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025); + if (clip_iifactor < 0.80) + clip_iifactor = 0.80; + + // Correction factor used for Q values >= 20 + corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq); + corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high; + + // Try and pick a Q that can encode the content at the given rate. + for (Q = 0; Q < MAXQ; Q++) + { + int bits_per_mb_at_this_q; + + if (Q < 50) + { + correction_factor = + pow( err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01)); + + correction_factor = (correction_factor < 0.05) ? 0.05 + : (correction_factor > 5.0) ? 5.0 + : correction_factor; + } + else + correction_factor = corr_high; + + bits_per_mb_at_this_q = + (int)( .5 + correction_factor * + speed_correction * + clip_iifactor * + (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0); + + if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) + break; + } + + return cq_level[Q]; +} + extern void vp8_new_frame_rate(VP8_COMP *cpi, double framerate); void vp8_init_second_pass(VP8_COMP *cpi) @@ -1268,7 +1375,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) // what level of boost is appropriate for the GF or ARF that will be coded with the group i = 0; - while (((i < cpi->max_gf_interval) || ((cpi->frames_to_key - i) < MIN_GF_INTERVAL)) && (i < cpi->frames_to_key)) + while (((i < cpi->static_scene_max_gf_interval) || ((cpi->frames_to_key - i) < MIN_GF_INTERVAL)) && (i < cpi->frames_to_key)) { double r; double this_frame_mvr_ratio; @@ -1378,18 +1485,20 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) boost_score += (decay_accumulator * r); // Break out conditions. - if ( /* i>4 || */ + if ( /* i>4 || */ + // Break at cpi->max_gf_interval unless almost totally static + (i >= cpi->max_gf_interval && (loop_decay_rate < 0.99)) || ( - (i > MIN_GF_INTERVAL) && // Dont break out with a very short interval - ((cpi->frames_to_key - i) >= MIN_GF_INTERVAL) && // Dont break out very close to a key frame + // Dont break out with a very short interval + (i > MIN_GF_INTERVAL) && + // Dont break out very close to a key frame + ((cpi->frames_to_key - i) >= MIN_GF_INTERVAL) && ((boost_score > 20.0) || (next_frame.pcnt_inter < 0.75)) && ((mv_ratio_accumulator > 100.0) || (abs_mv_in_out_accumulator > 3.0) || (mv_in_out_accumulator < -2.0) || - ((boost_score - old_boost_score) < 2.0) - ) - ) - ) + ((boost_score - old_boost_score) < 2.0)) + ) ) { boost_score = old_boost_score; break; @@ -1766,7 +1875,9 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) vp8_avg_stats(§ionstats); - cpi->section_intra_rating = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error); + cpi->section_intra_rating = + sectionstats.intra_error / + DOUBLE_DIVIDE_CHECK(sectionstats.coded_error); Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error); //if( (Ratio > 11) ) //&& (sectionstats.pcnt_second_ref < .20) ) @@ -1993,21 +2104,48 @@ void vp8_second_pass(VP8_COMP *cpi) if (cpi->common.current_video_frame == 0) { - // guess at 2nd pass q cpi->est_max_qcorrection_factor = 1.0; - tmp_q = estimate_max_q(cpi, (cpi->total_coded_error_left / frames_left), (int)(cpi->bits_left / frames_left), cpi->common.Height, cpi->common.Width); - if (tmp_q < cpi->worst_quality) - { - cpi->active_worst_quality = tmp_q; - cpi->ni_av_qi = tmp_q; - } - else + // Experimental code to try and set a cq_level in constrained + // quality mode. + if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY ) { - cpi->active_worst_quality = cpi->worst_quality; - cpi->ni_av_qi = cpi->worst_quality; + int est_cq; + + est_cq = + estimate_cq( cpi, + (cpi->total_coded_error_left / frames_left), + (int)(cpi->bits_left / frames_left), + cpi->common.Height, cpi->common.Width); + + cpi->cq_target_quality = cpi->oxcf.cq_level; + if ( est_cq > cpi->cq_target_quality ) + cpi->cq_target_quality = est_cq; } + + // guess at maxq needed in 2nd pass + cpi->maxq_max_limit = cpi->worst_quality; + cpi->maxq_min_limit = cpi->best_quality; + tmp_q = estimate_max_q( cpi, + (cpi->total_coded_error_left / frames_left), + (int)(cpi->bits_left / frames_left), + cpi->common.Height, + cpi->common.Width); + + // Limit the maxq value returned subsequently. + // This increases the risk of overspend or underspend if the initial + // estimate for the clip is bad, but helps prevent excessive + // variation in Q, especially near the end of a clip + // where for example a small overspend may cause Q to crash + cpi->maxq_max_limit = ((tmp_q + 32) < cpi->worst_quality) + ? (tmp_q + 32) : cpi->worst_quality; + cpi->maxq_min_limit = ((tmp_q - 32) > cpi->best_quality) + ? (tmp_q - 32) : cpi->best_quality; + + cpi->active_worst_quality = tmp_q; + cpi->ni_av_qi = tmp_q; } + // The last few frames of a clip almost always have to few or too many // bits and for the sake of over exact rate control we dont want to make // radical adjustments to the allowed quantizer range just to use up a @@ -2029,13 +2167,6 @@ void vp8_second_pass(VP8_COMP *cpi) cpi->active_worst_quality --; cpi->active_worst_quality = ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4; - - // Clamp to user set limits - if (cpi->active_worst_quality > cpi->worst_quality) - cpi->active_worst_quality = cpi->worst_quality; - else if (cpi->active_worst_quality < cpi->best_quality) - cpi->active_worst_quality = cpi->best_quality; - } cpi->frames_to_key --; @@ -2157,6 +2288,9 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) cpi->common.frame_type = KEY_FRAME; + // is this a forced key frame by interval + cpi->this_key_frame_forced = cpi->next_key_frame_forced; + // Clear the alt ref active flag as this can never be active on a key frame cpi->source_alt_ref_active = FALSE; @@ -2219,7 +2353,11 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) kf_group_err /= 2.0; kf_group_intra_err /= 2.0; kf_group_coded_err /= 2.0; + + cpi->next_key_frame_forced = TRUE; } + else + cpi->next_key_frame_forced = FALSE; // Special case for the last frame of the file if (cpi->stats_in >= cpi->stats_in_end) |