improve average framerate calculation
Change Ice204e86 identified a problem with bitrate undershoot due to low precision in the timestamps passed to the library. This patch takes a different approach by calculating the duration of this frame and passing it to the library, rather than using a fixed duration and letting the library average it out with higher precision timestamps. This part of the fix only applies to vpxenc. This patch also attempts to fix the problem for generic applications that may have made the same mistake vpxenc did. Instead of calculating this frame's duration by the difference of this frame's and the last frame's start time, we use the end times instead. This allows the framerate calculation to scavenge "unclaimed" time from the last frame. For instance: start | end | calculated duration ======+=======+==================== 0ms 33ms 33ms 33ms 66ms 33ms 66ms 99ms 33ms 100ms 133ms 34ms Change-Id: I92be4b3518e0bd530e97f90e69e75330a4c413fc
This commit is contained in:
parent
bd05d9e480
commit
f7e187d362
@ -4972,17 +4972,16 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
|
||||
|
||||
*frame_flags = cpi->source_frame_flags;
|
||||
|
||||
#if CONFIG_PSNR
|
||||
|
||||
if (cpi->source_time_stamp < cpi->first_time_stamp_ever)
|
||||
{
|
||||
cpi->first_time_stamp_ever = cpi->source_time_stamp;
|
||||
|
||||
#endif
|
||||
cpi->last_end_time_stamp_seen = cpi->source_time_stamp;
|
||||
}
|
||||
|
||||
// adjust frame rates based on timestamps given
|
||||
if (!cm->refresh_alt_ref_frame)
|
||||
{
|
||||
if (cpi->last_time_stamp_seen == 0)
|
||||
if (cpi->source_time_stamp == cpi->first_time_stamp_ever)
|
||||
{
|
||||
double this_fps = 10000000.000 / (cpi->source_end_time_stamp - cpi->source_time_stamp);
|
||||
|
||||
@ -4990,7 +4989,8 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
|
||||
}
|
||||
else
|
||||
{
|
||||
long long nanosecs = cpi->source_time_stamp - cpi->last_time_stamp_seen;
|
||||
long long nanosecs = cpi->source_end_time_stamp
|
||||
- cpi->last_end_time_stamp_seen;
|
||||
double this_fps = 10000000.000 / nanosecs;
|
||||
|
||||
vp8_new_frame_rate(cpi, (7 * cpi->oxcf.frame_rate + this_fps) / 8);
|
||||
@ -4998,6 +4998,7 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
|
||||
}
|
||||
|
||||
cpi->last_time_stamp_seen = cpi->source_time_stamp;
|
||||
cpi->last_end_time_stamp_seen = cpi->source_end_time_stamp;
|
||||
}
|
||||
|
||||
if (cpi->compressor_speed == 2)
|
||||
|
@ -399,6 +399,7 @@ typedef struct
|
||||
int inter_frame_target;
|
||||
double output_frame_rate;
|
||||
long long last_time_stamp_seen;
|
||||
long long last_end_time_stamp_seen;
|
||||
long long first_time_stamp_ever;
|
||||
|
||||
int ni_av_qi;
|
||||
|
10
vpxenc.c
10
vpxenc.c
@ -1188,7 +1188,7 @@ int main(int argc, const char **argv_)
|
||||
/* Change the default timebase to a high enough value so that the encoder
|
||||
* will always create strictly increasing timestamps.
|
||||
*/
|
||||
cfg.g_timebase.den = 100000;
|
||||
cfg.g_timebase.den = 1000;
|
||||
|
||||
/* Never use the library's default resolution, require it be parsed
|
||||
* from the file or set on the command line.
|
||||
@ -1544,7 +1544,7 @@ int main(int argc, const char **argv_)
|
||||
vpx_codec_iter_t iter = NULL;
|
||||
const vpx_codec_cx_pkt_t *pkt;
|
||||
struct vpx_usec_timer timer;
|
||||
int64_t frame_start;
|
||||
int64_t frame_start, next_frame_start;
|
||||
|
||||
if (!arg_limit || frames_in < arg_limit)
|
||||
{
|
||||
@ -1565,9 +1565,11 @@ int main(int argc, const char **argv_)
|
||||
|
||||
frame_start = (cfg.g_timebase.den * (int64_t)(frames_in - 1)
|
||||
* arg_framerate.den) / cfg.g_timebase.num / arg_framerate.num;
|
||||
next_frame_start = (cfg.g_timebase.den * (int64_t)(frames_in)
|
||||
* arg_framerate.den)
|
||||
/ cfg.g_timebase.num / arg_framerate.num;
|
||||
vpx_codec_encode(&encoder, frame_avail ? &raw : NULL, frame_start,
|
||||
cfg.g_timebase.den * arg_framerate.den
|
||||
/ cfg.g_timebase.num / arg_framerate.num,
|
||||
next_frame_start - frame_start,
|
||||
0, arg_deadline);
|
||||
vpx_usec_timer_mark(&timer);
|
||||
cx_time += vpx_usec_timer_elapsed(&timer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user