From b8c369053b8baffc2181b7b362262269f9e346e6 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Wed, 30 May 2012 11:29:49 +0100 Subject: [PATCH] Rate control fix. This fix addresses some problems with very complex clips like handling of flashes on clips like crew (which was made worse by an earlier patch (derf and std-hd)). Most clips a small effect but some between 1 & 2% Derf +0.039, +0.211% YT +0.042, +0.083% Change-Id: I65fc7c13afc31482040068544dd65b8808f5cb4a --- vp8/encoder/firstpass.c | 38 +++++++++++++++++++++++++++++--------- vp8/encoder/onyx_int.h | 2 ++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index 0d1574c..8c7818c 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -634,7 +634,14 @@ void vp8_first_pass(VP8_COMP *cpi) xd->pre.u_buffer = lst_yv12->u_buffer + recon_uvoffset; xd->pre.v_buffer = lst_yv12->v_buffer + recon_uvoffset; - sr_coded_error += gf_motion_error; + // In accumulating a score for the older reference frame + // take the best of the motion predicted score and + // the intra coded error (just as will be done for) + // accumulation of "coded_error" for the last frame. + if ( gf_motion_error < this_error ) + sr_coded_error += gf_motion_error; + else + sr_coded_error += this_error; } else sr_coded_error += motion_error; @@ -799,12 +806,18 @@ void vp8_first_pass(VP8_COMP *cpi) } // Copy the previous Last Frame back into gf and and arf buffers if - // the prediction is good enough. - if ((cm->current_video_frame > 0) && - (cpi->twopass.this_frame_stats->pcnt_inter > 0.20)) + // the prediction is good enough... but also dont allow it to lag too far + if ((cpi->twopass.sr_update_lag > 3) || + ((cm->current_video_frame > 0) && + (cpi->twopass.this_frame_stats->pcnt_inter > 0.20) && + ((cpi->twopass.this_frame_stats->intra_error / + cpi->twopass.this_frame_stats->coded_error) > 2.0))) { vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12); + cpi->twopass.sr_update_lag = 1; } + else + cpi->twopass.sr_update_lag ++; // swap frame pointers so last frame refers to the frame we just compressed vp8_swap_yv12_buffer(lst_yv12, new_yv12); @@ -921,6 +934,11 @@ static double calc_correction_factor( VP8_COMP *cpi, correction_factor = correction_factor * sr_correction; #endif + // Clip range + correction_factor = + (correction_factor < 0.05) + ? 0.05 : (correction_factor > 2.0) ? 2.0 : correction_factor; + return correction_factor; } @@ -1214,6 +1232,9 @@ void vp8_init_second_pass(VP8_COMP *cpi) cpi->twopass.kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs; cpi->twopass.gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs; + // This variable monitors how far behind the second ref update is lagging + cpi->twopass.sr_update_lag = 1; + // Scan the first pass file and calculate an average Intra / Inter error score ratio for the sequence { double sum_iiratio = 0.0; @@ -1277,15 +1298,14 @@ static double get_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_fra (cpi->common.MBs); second_ref_decay = 1.0 - (mb_sr_err_diff / 512.0); second_ref_decay = pow( second_ref_decay, 0.5 ); + if ( second_ref_decay < 0.85 ) + second_ref_decay = 0.85; + else if ( second_ref_decay > 1.0 ) + second_ref_decay = 1.0; if ( second_ref_decay < prediction_decay_rate ) prediction_decay_rate = second_ref_decay; - if ( prediction_decay_rate < 0.85 ) - prediction_decay_rate = 0.85; - else if ( prediction_decay_rate > 1.0 ) - prediction_decay_rate = 1.0; - return prediction_decay_rate; } diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 2644e7e..b181a60 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -598,6 +598,8 @@ typedef struct VP8_COMP int gf_group_bits; // Projected Bits available for a group of frames including 1 GF or ARF int gf_bits; // Bits for the golden frame or ARF - 2 pass only int alt_extra_bits; + + int sr_update_lag; double est_max_qcorrection_factor; } twopass; -- 2.7.4