diff options
author | wm4 <wm4@nowhere> | 2015-11-13 22:45:40 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-11-13 22:45:40 +0100 |
commit | d32c4c75ef1cf4d69474a0a0e8f8127e77910099 (patch) | |
tree | 355fdc7b230f4b544dfb5d23a8d174a347c793fb /player/core.h | |
parent | 624c9e46ce0bb4f547ffaf9cd6541700cea96ddb (diff) | |
download | mpv-d32c4c75ef1cf4d69474a0a0e8f8127e77910099.tar.bz2 mpv-d32c4c75ef1cf4d69474a0a0e8f8127e77910099.tar.xz |
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.
Diffstat (limited to 'player/core.h')
-rw-r--r-- | player/core.h | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/player/core.h b/player/core.h index 80bd08266c..fcdf0e3595 100644 --- a/player/core.h +++ b/player/core.h @@ -76,9 +76,6 @@ enum seek_precision { MPSEEK_VERY_EXACT, }; -// Comes from the assumption that some formats round timestamps to ms. -#define FRAME_DURATION_TOLERANCE 0.0011 - enum video_sync { VS_DEFAULT = 0, VS_DISP_RESAMPLE, @@ -97,6 +94,13 @@ enum video_sync { (x) == VS_DISP_VDROP || \ (x) == VS_DISP_NONE) +// Information about past video frames that have been sent to the VO. +struct frame_info { + double pts; + double duration; // PTS difference to next frame + double approx_duration; // possibly fixed/smoothed out duration +}; + struct track { enum stream_type type; @@ -264,7 +268,6 @@ typedef struct MPContext { double audio_speed, video_speed; bool display_sync_active; bool broken_fps_header; - double display_sync_frameduration; int display_sync_drift_dir; // Timing error (in seconds) due to rounding on vsync boundaries double display_sync_error; @@ -321,6 +324,10 @@ typedef struct MPContext { uint64_t vo_pts_history_seek_ts; uint64_t backstep_start_seek_ts; bool backstep_active; + // Past timestamps etc. (stupidly duplicated with vo_pts_history). + // The newest frame is at index 0. + struct frame_info *past_frames; + int num_past_frames; double next_heartbeat; double last_idle_tick; @@ -498,7 +505,6 @@ void mp_idle(struct MPContext *mpctx); void idle_loop(struct MPContext *mpctx); int handle_force_window(struct MPContext *mpctx, bool force); void add_frame_pts(struct MPContext *mpctx, double pts); -int get_past_frame_durations(struct MPContext *mpctx, double *fd, int num); void seek_to_last_frame(struct MPContext *mpctx); // scripting.c @@ -528,6 +534,6 @@ void write_video(struct MPContext *mpctx, double endpts); void mp_force_video_refresh(struct MPContext *mpctx); void uninit_video_out(struct MPContext *mpctx); void uninit_video_chain(struct MPContext *mpctx); -double stabilize_frame_duration(struct MPContext *mpctx, bool require_exact); +double calc_average_frame_duration(struct MPContext *mpctx); #endif /* MPLAYER_MP_CORE_H */ |