diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h index 28cbaed98611b78bf3ab5f367d29d798372490db..3f04dab4c39932f501b76d8a34974f15a37c1de1 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 23e30508a5ceb13ac801647e859c093ce6c83065..8d19d1efda1e9d917646b4d6f7f5befc188b5003 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 1d00e677797dcde61c47a5700806cb12e555125b..6a51cdaccff3a1c384d5945fdb03c82522518540 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 a0828a479a29916f955657d6521f9db216c85911..fc4023f77fadb06647d77b43a1b2db967073ec59 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 e8abf848c8695071495536667143397772f54d0c..bc8d8c1b647d5a2d69c18033d9ba1c09c00d6ff7 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 7260e942b1e0d6950c8a7f440d31d8553f9ec704..4f21e1456863f258e30d0739ff37a0ae9991da48 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;