diff options
authorwm4 <wm4@nowhere>2016-08-07 14:06:54 +0200
committerwm4 <wm4@nowhere>2016-08-07 14:14:32 +0200
commit32cc190a552551cc7e7150e8603b6a75e0a6d94f (patch)
parent39ae261cc59598426b6e6beea2c849a6c8a9d20f (diff)
player: fix display-sync timing if audio take long on resume
In display-sync mode, the very first video frame is idiotically fully timed, even though audio has not been synced yet at this point, and the video frame is more like a "preview" frame. But since it's fully timed, an underflow is detected if audio takes longer than the display time of the frame (we send the second frame only after audio is done). The timing code will try to compensate for the determined desync, but it really shouldn't. So explicitly discard the timing info in this specific case. On the other hand, if the first frame still hasn't finished display, we can pretend everything is ok. This is a hack - ideally, we either would send a frame without timing info (and then send it again or so when playback starts properly), or we would add real pause support to the VO, and pause it during syncing.
3 files changed, 15 insertions, 0 deletions
diff --git a/player/video.c b/player/video.c
index e3295b623a..9790f34966 100644
--- a/player/video.c
+++ b/player/video.c
@@ -1209,6 +1209,12 @@ static void handle_display_sync_frame(struct MPContext *mpctx,
// Likewise, we know sync is off, but is going to be compensated.
time_left += drop_repeat * vsync;
+ // If syncing took too long, disregard timing of the first frame.
+ if (mpctx->num_past_frames == 2 && time_left < 0) {
+ vo_discard_timing_info(vo);
+ time_left = 0;
+ }
if (drop_repeat) {
mpctx->mistimed_frames_total += 1;
MP_STATS(mpctx, "mistimed");
diff --git a/video/out/vo.c b/video/out/vo.c
index 2804687e5e..aa92d349e5 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -1096,6 +1096,14 @@ double vo_get_delay(struct vo *vo)
return res ? (res - mp_time_us()) / 1e6 : 0;
+void vo_discard_timing_info(struct vo *vo)
+ struct vo_internal *in = vo->in;
+ pthread_mutex_lock(&in->lock);
+ reset_vsync_timings(vo);
+ pthread_mutex_unlock(&in->lock);
int64_t vo_get_delayed_count(struct vo *vo)
struct vo_internal *in = vo->in;
diff --git a/video/out/vo.h b/video/out/vo.h
index 511954c153..a5280e5611 100644
--- a/video/out/vo.h
+++ b/video/out/vo.h
@@ -366,6 +366,7 @@ double vo_get_estimated_vsync_interval(struct vo *vo);
double vo_get_estimated_vsync_jitter(struct vo *vo);
double vo_get_display_fps(struct vo *vo);
double vo_get_delay(struct vo *vo);
+void vo_discard_timing_info(struct vo *vo);
void vo_wakeup(struct vo *vo);
void vo_wait_default(struct vo *vo, int64_t until_time);