summaryrefslogtreecommitdiffstats
path: root/player/core.h
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-11-13 22:45:40 +0100
committerwm4 <wm4@nowhere>2015-11-13 22:45:40 +0100
commitd32c4c75ef1cf4d69474a0a0e8f8127e77910099 (patch)
tree355fdc7b230f4b544dfb5d23a8d174a347c793fb /player/core.h
parent624c9e46ce0bb4f547ffaf9cd6541700cea96ddb (diff)
downloadmpv-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.h18
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 */