ref: bdd35c13ccafaa87fbd7d27c2c413743b11b7746
parent: 2a6daa72f0f04ee674f14a7d5c7ee7693fc87aa2
author: John Koleszar <jkoleszar@google.com>
date: Fri Nov 11 05:47:20 EST 2011
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
--- a/vp8/common/onyx.h
+++ b/vp8/common/onyx.h
@@ -104,7 +104,7 @@
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
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -1276,7 +1276,7 @@
// 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 @@
// 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 @@
}
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
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -1470,8 +1470,8 @@
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 @@
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 @@
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 @@
{
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 @@
{
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 @@
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;
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -418,6 +418,7 @@
int buffered_mode;
+ double frame_rate;
int64_t buffer_level;
int bits_off_target;
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -296,7 +296,7 @@
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;
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -271,14 +271,7 @@
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;
--
⑨