mirror of https://github.com/mpv-player/mpv
player: slightly adjust framerate guessing heuristic
Some files not only use rounded timestamps, but they also do it incorrectly. They may jitter between up to 4 specific frame durations. In this case, I found a file that mostly used 41ms and 42ms, but also had 40ms and 43ms outliers (often but not always following each other). This breaks the assumption of the framerate estimation code that the frame duration can deviate up to 1ms. If it jitters around 4 possible frame durations, the maximum deviation is 3ms. Increase it accordingly. The change might make playback of "true VFR" video via display-sync mode worse, but it's not like it was particularly good in the first place. Also, the check whether to usen the container FPS needs to be stricter. In the worst case, num_dur is 1, which doesn't really indicate any evidence that the framerate is correct. Only if there are "enough" frames the deviation check will become meaningful. 16 is an arbitrary value that has been designated "enough" by myself. Also otuput the frame duration values for --dump-stats.
This commit is contained in:
parent
ae3bbc4f63
commit
d223959cda
|
@ -1291,11 +1291,10 @@ static void calculate_frame_duration(struct MPContext *mpctx)
|
|||
|
||||
// The following code tries to compensate for rounded Matroska timestamps
|
||||
// by "unrounding" frame durations, or if not possible, approximating them.
|
||||
// These formats usually round on 1ms. (Some muxers do this incorrectly,
|
||||
// and might be off by 2ms or more, and compensate for it later by an
|
||||
// equal rounding error into the opposite direction. Don't try to deal
|
||||
// with them; too much potential damage to timing.)
|
||||
double tolerance = 0.0011;
|
||||
// These formats usually round on 1ms. Some muxers do this incorrectly,
|
||||
// and might go off by 1ms more, and compensate for it later by an equal
|
||||
// rounding error into the opposite direction.
|
||||
double tolerance = 0.001 * 3 + 0.0001;
|
||||
|
||||
double total = 0;
|
||||
int num_dur = 0;
|
||||
|
@ -1314,7 +1313,7 @@ static void calculate_frame_duration(struct MPContext *mpctx)
|
|||
// Note that even if each timestamp is within rounding tolerance, it
|
||||
// could literally not add up (e.g. if demuxer FPS is rounded itself).
|
||||
if (fabs(duration - demux_duration) < tolerance &&
|
||||
fabs(total - demux_duration * num_dur) < tolerance)
|
||||
fabs(total - demux_duration * num_dur) < tolerance && num_dur >= 16)
|
||||
{
|
||||
approx_duration = demux_duration;
|
||||
}
|
||||
|
@ -1322,6 +1321,9 @@ static void calculate_frame_duration(struct MPContext *mpctx)
|
|||
|
||||
mpctx->past_frames[0].duration = duration;
|
||||
mpctx->past_frames[0].approx_duration = approx_duration;
|
||||
|
||||
MP_STATS(mpctx, "value %f frame-duration", MPMAX(0, duration));
|
||||
MP_STATS(mpctx, "value %f frame-duration-approx", MPMAX(0, approx_duration));
|
||||
}
|
||||
|
||||
void write_video(struct MPContext *mpctx)
|
||||
|
|
Loading…
Reference in New Issue