From: John Koleszar Date: Fri, 11 Nov 2011 18:47:20 +0000 (-0800) Subject: avoid resetting framerate during vpx_codec_enc_config_set() X-Git-Tag: 1.0_branch~220^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bdd35c13ccafaa87fbd7d27c2c413743b11b7746;p=profile%2Fivi%2Flibvpx.git avoid resetting framerate during vpx_codec_enc_config_set() The calculated frame_rate is a state variable in the codec, and shouldn't be maintained in the configuration struct. Move it to the main part of cpi so that it isn't clobbered when the configuration struct is updated. The initial framerate estimate is moved from the vp8_cx_iface.c wrapper into the body of init_config() in onyx_if.c, so that it is only called once and not reset on every call to vp8_change_config(). Change-Id: I8d9a3d1283330d1ee297d07e9d78d1f2875f2465 --- diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h index 28cbaed..3f04dab 100644 --- a/vp8/common/onyx.h +++ b/vp8/common/onyx.h @@ -104,7 +104,7 @@ extern "C" int Version; // 4 versions of bitstream defined 0 best quality/slowest decode, 3 lowest quality/fastest decode int Width; // width of data passed to the compressor int Height; // height of data passed to the compressor - double frame_rate; // set to passed in framerate + struct vpx_rational timebase; int target_bandwidth; // bandwidth to be used in kilobits per second int noise_sensitivity; // parameter used for applying pre processing blur: recommendation 0 diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index 23e3050..8d19d1e 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -1276,7 +1276,7 @@ void vp8_init_second_pass(VP8_COMP *cpi) // pass. vp8_new_frame_rate(cpi, 10000000.0 * cpi->twopass.total_stats->count / cpi->twopass.total_stats->duration); - cpi->output_frame_rate = cpi->oxcf.frame_rate; + cpi->output_frame_rate = cpi->frame_rate; cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats->duration * cpi->oxcf.target_bandwidth / 10000000.0) ; cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats->duration * two_pass_min_rate / 10000000.0); @@ -3061,7 +3061,7 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) // Calculate Average bits per frame. //av_bits_per_frame = cpi->twopass.bits_left/(double)(cpi->twopass.total_stats->count - cpi->common.current_video_frame); - av_bits_per_frame = cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate); + av_bits_per_frame = cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->frame_rate); //if ( av_bits_per_frame < 0.0 ) // av_bits_per_frame = 0.0 @@ -3123,7 +3123,7 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) } else { - int64_t clip_bits = (int64_t)(cpi->twopass.total_stats->count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate)); + int64_t clip_bits = (int64_t)(cpi->twopass.total_stats->count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->frame_rate)); int64_t over_spend = cpi->oxcf.starting_buffer_level - cpi->buffer_level; if ((last_kf_resampled && (kf_q > cpi->worst_quality)) || // If triggered last time the threshold for triggering again is reduced diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 1d00e67..6a51cda 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -1470,8 +1470,8 @@ void vp8_new_frame_rate(VP8_COMP *cpi, double framerate) if(framerate < .1) framerate = 30; - cpi->oxcf.frame_rate = framerate; - cpi->output_frame_rate = cpi->oxcf.frame_rate; + cpi->frame_rate = framerate; + cpi->output_frame_rate = framerate; cpi->per_frame_bandwidth = (int)(cpi->oxcf.target_bandwidth / cpi->output_frame_rate); cpi->av_per_frame_bandwidth = cpi->per_frame_bandwidth; @@ -1527,6 +1527,18 @@ static void init_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cm->version = oxcf->Version; vp8_setup_version(cm); + /* frame rate is not available on the first frame, as it's derived from + * the observed timestamps. The actual value used here doesn't matter + * too much, as it will adapt quickly. If the reciprocal of the timebase + * seems like a reasonable framerate, then use that as a guess, otherwise + * use 30. + */ + cpi->frame_rate = (double)(oxcf->timebase.den) / + (double)(oxcf->timebase.num); + + if (cpi->frame_rate > 180) + cpi->frame_rate = 30; + // change includes all joint functionality vp8_change_config(ptr, oxcf); @@ -1787,7 +1799,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf) cpi->oxcf.target_bandwidth, 1000); // Set up frame rate and related parameters rate control values. - vp8_new_frame_rate(cpi, cpi->oxcf.frame_rate); + vp8_new_frame_rate(cpi, cpi->frame_rate); // Set absolute upper and lower quality limits cpi->worst_quality = cpi->oxcf.worst_allowed_q; @@ -2408,7 +2420,7 @@ void vp8_remove_compressor(VP8_PTR *ptr) { extern int count_mb_seg[4]; FILE *f = fopen("modes.stt", "a"); - double dr = (double)cpi->oxcf.frame_rate * (double)bytes * (double)8 / (double)count / (double)1000 ; + double dr = (double)cpi->frame_rate * (double)bytes * (double)8 / (double)count / (double)1000 ; fprintf(f, "intra_mode in Intra Frames:\n"); fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d\n", y_modes[0], y_modes[1], y_modes[2], y_modes[3], y_modes[4]); fprintf(f, "UV:%8d, %8d, %8d, %8d\n", uv_modes[0], uv_modes[1], uv_modes[2], uv_modes[3]); @@ -4856,7 +4868,7 @@ static void Pass2Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, { double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth *cpi->oxcf.two_pass_vbrmin_section / 100); - cpi->twopass.bits_left += (int64_t)(two_pass_min_rate / cpi->oxcf.frame_rate); + cpi->twopass.bits_left += (int64_t)(two_pass_min_rate / cpi->frame_rate); } } #endif @@ -5092,7 +5104,7 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon if(interval > 10000000.0) interval = 10000000; - avg_duration = 10000000.0 / cpi->oxcf.frame_rate; + avg_duration = 10000000.0 / cpi->frame_rate; avg_duration *= (interval - avg_duration + this_duration); avg_duration /= interval; diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index a0828a4..fc4023f 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -418,6 +418,7 @@ typedef struct VP8_COMP int buffered_mode; + double frame_rate; int64_t buffer_level; int bits_off_target; diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index e8abf84..bc8d8c1 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -296,7 +296,7 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue) void vp8_auto_select_speed(VP8_COMP *cpi) { - int milliseconds_for_compress = (int)(1000000 / cpi->oxcf.frame_rate); + int milliseconds_for_compress = (int)(1000000 / cpi->frame_rate); milliseconds_for_compress = milliseconds_for_compress * (16 - cpi->oxcf.cpu_used) / 16; diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index 7260e94..4f21e14 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -271,14 +271,7 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf, oxcf->Width = cfg.g_w; oxcf->Height = cfg.g_h; - /* guess a frame rate if out of whack, use 30 */ - oxcf->frame_rate = (double)(cfg.g_timebase.den) / - (double)(cfg.g_timebase.num); - - if (oxcf->frame_rate > 180) - { - oxcf->frame_rate = 30; - } + oxcf->timebase = cfg.g_timebase; oxcf->error_resilient_mode = cfg.g_error_resilient;