From d32c4c75ef1cf4d69474a0a0e8f8127e77910099 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 13 Nov 2015 22:45:40 +0100 Subject: player: refactor display-sync frame duration calculations Get rid of get_past_frame_durations(), which was a bit too messy. Add a past_frames array, which contains the same information in a more reasonable way. This also means that we can get the exact current and past frame durations without going through awful stuff. (The main problem is that vo_pts_history contains future frames as well, which is needed for frame backstepping etc., but gets in the way here.) Also disable the automatic disabling of display-sync if the frame duration changes, and extend the frame durations allowed for display sync. To allow arbitrarily high durations, vo.c needs to be changed to pause and potentially redraw OSD while showing a single frame, so they're still limited. In an attempt to deal with VFR, calculate the overall speed using the average FPS. The frame scheduling itself does not use the average FPS, but the duration of the current frame. This does not work too well, but provides a good base for further improvements. Where this commit actually helps a lot is dealing with rounded timestamps, e.g. if the container framerate is wrong or unknown, or if the muxer wrote incorrectly rounded timestamps. While the rounding errors apparently can't be get rid of completely in the general case, this is still much better than e.g. disabling display-sync completely just because some frame durations go out of bounds. --- player/playloop.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'player/playloop.c') diff --git a/player/playloop.c b/player/playloop.c index f5463e2622..643f290c48 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -693,27 +693,6 @@ void add_frame_pts(struct MPContext *mpctx, double pts) mpctx->vo_pts_history_pts[0] = pts; } -// Return the last (at most num) frame duration in fd[]. Return the number of -// entries written to fd[] (range [0, num]). fd[0] is the most recent frame. -int get_past_frame_durations(struct MPContext *mpctx, double *fd, int num) -{ - double next_pts = mpctx->vo_pts_history_pts[0]; - if (mpctx->vo_pts_history_seek[0] != mpctx->vo_pts_history_seek_ts || - next_pts == MP_NOPTS_VALUE) - return 0; - int num_ret = 0; - for (int n = 1; n < MAX_NUM_VO_PTS && num_ret < num; n++) { - double frame_pts = mpctx->vo_pts_history_pts[n]; - // Discontinuity -> refuse to return a value. - if (mpctx->vo_pts_history_seek[n] != mpctx->vo_pts_history_seek_ts || - next_pts <= frame_pts || frame_pts == MP_NOPTS_VALUE) - break; - fd[num_ret++] = next_pts - frame_pts; - next_pts = frame_pts; - } - return num_ret; -} - static double find_previous_pts(struct MPContext *mpctx, double pts) { for (int n = 0; n < MAX_NUM_VO_PTS - 1; n++) { -- cgit v1.2.3