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 @@
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 @@
// 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
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 @@
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;
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 @@
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_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 @@
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;