summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-08-22 15:28:05 +0200
committerwm4 <wm4@nowhere>2014-08-22 15:36:48 +0200
commit4c25b000b5e521c67608284cf23972e2f651e9d3 (patch)
tree6c46376827fb68320777f7529855141e8699b1aa
parent75005ec06d13655340439450cd4663bdf7978411 (diff)
downloadmpv-4c25b000b5e521c67608284cf23972e2f651e9d3.tar.bz2
mpv-4c25b000b5e521c67608284cf23972e2f651e9d3.tar.xz
player: fix recent speed change regression
Commit 5afc025c broke this. The reason is that mpctx->delay is updated when a new video frame is added. This value is also needed to resync audio, but it will be for the wrong PTS. They must be consistent with each other, and if they aren't, initial sync will be off by N video frames, which results at least in worse user experience. This can be reproduced by for example heavily switching between normal and 2x speed, or similar. Fix by readding the video_next_pts field (keeping its use minimal, instead of reverting the commit that removed it).
-rw-r--r--player/audio.c4
-rw-r--r--player/core.h2
-rw-r--r--player/video.c2
3 files changed, 6 insertions, 2 deletions
diff --git a/player/audio.c b/player/audio.c
index df80fcd161..3a691fed09 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -329,8 +329,8 @@ static bool get_sync_samples(struct MPContext *mpctx, int *skip)
double sync_pts = MP_NOPTS_VALUE;
if (sync_to_video) {
- if (mpctx->video_pts != MP_NOPTS_VALUE) {
- sync_pts = mpctx->video_pts;
+ if (mpctx->video_next_pts != MP_NOPTS_VALUE) {
+ sync_pts = mpctx->video_next_pts;
} else if (mpctx->video_status < STATUS_READY) {
return false; // wait until we know a video PTS
}
diff --git a/player/core.h b/player/core.h
index 6c69e5e261..2c5328df38 100644
--- a/player/core.h
+++ b/player/core.h
@@ -275,6 +275,8 @@ typedef struct MPContext {
* (or at least queued to be flipped by VO) */
double video_pts;
double last_seek_pts;
+ // Mostly unused; for proper audio resync on speed changes.
+ double video_next_pts;
// As video_pts, but is not reset when seeking away. (For the very short
// period of time until a new frame is decoded and shown.)
double last_vo_pts;
diff --git a/player/video.c b/player/video.c
index b7d3f27cbe..6a8fade027 100644
--- a/player/video.c
+++ b/player/video.c
@@ -215,6 +215,7 @@ void reset_video_state(struct MPContext *mpctx)
mpctx->delay = 0;
mpctx->time_frame = 0;
mpctx->video_pts = MP_NOPTS_VALUE;
+ mpctx->video_next_pts = MP_NOPTS_VALUE;
mpctx->total_avsync_change = 0;
mpctx->drop_frame_cnt = 0;
mpctx->dropped_frames = 0;
@@ -552,6 +553,7 @@ static int video_output_image(struct MPContext *mpctx, double endpts)
MP_WARN(mpctx, "Jump in video pts: %f -> %f\n", last_pts, pts);
frame_time = 0;
}
+ mpctx->video_next_pts = pts;
if (mpctx->d_audio)
mpctx->delay -= frame_time;
if (mpctx->video_status >= STATUS_READY) {