From 50bb209a80dd4db423e6efff14df02a5624721d1 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 27 Nov 2015 14:40:52 +0100 Subject: [PATCH] player: always disable display-sync on desyncs Instead of periodically trying to enable it again. There are two cases that can happen: 1. A random discontinuity messed everything up, 2. Things are just broken and will desync all the time Until now, it tried to deal with case 1 - but maybe this is really rare, and we don't really need to care about it. On the other hand, case 2 is kind of hard to diagnose if the user doesn't use the terminal. Seeking will reenable display-sync, so you can fix playback if case 1 happens, but still get predictable behavior in case 2. --- player/core.h | 1 + player/video.c | 34 ++++++++++++---------------------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/player/core.h b/player/core.h index c35e3d034b..04d4fb6126 100644 --- a/player/core.h +++ b/player/core.h @@ -269,6 +269,7 @@ typedef struct MPContext { // update_playback_speed() updates them from the other fields. double audio_speed, video_speed; bool display_sync_active; + bool display_sync_broken; int display_sync_drift_dir; // Timing error (in seconds) due to rounding on vsync boundaries double display_sync_error; diff --git a/player/video.c b/player/video.c index 1783ba7a62..561bb0b202 100644 --- a/player/video.c +++ b/player/video.c @@ -214,6 +214,7 @@ void reset_video_state(struct MPContext *mpctx) mpctx->mistimed_frames_total = 0; mpctx->drop_message_shown = 0; mpctx->display_sync_drift_dir = 0; + mpctx->display_sync_broken = false; mpctx->video_status = mpctx->d_video ? STATUS_SYNCING : STATUS_EOF; } @@ -949,7 +950,7 @@ static void handle_display_sync_frame(struct MPContext *mpctx, mpctx->display_sync_active = false; if (!VS_IS_DISP(mode)) - goto done; + return; bool resample = mode == VS_DISP_RESAMPLE || mode == VS_DISP_RESAMPLE_VDROP || mode == VS_DISP_RESAMPLE_NONE; bool drop = mode == VS_DISP_VDROP || mode == VS_DISP_RESAMPLE || @@ -957,16 +958,16 @@ static void handle_display_sync_frame(struct MPContext *mpctx, drop &= (opts->frame_dropping & 1); if (resample && using_spdif_passthrough(mpctx)) - goto done; + return; double vsync = vo_get_vsync_interval(vo) / 1e6; if (vsync <= 0) - goto done; + return; double adjusted_duration = mpctx->past_frames[0].approx_duration; adjusted_duration /= opts->playback_speed; if (adjusted_duration <= 0.001 || adjusted_duration > 0.5) - goto done; + return; mpctx->speed_factor_v = 1.0; if (mode != VS_DISP_VDROP) { @@ -977,18 +978,9 @@ static void handle_display_sync_frame(struct MPContext *mpctx, } double av_diff = mpctx->last_av_difference; - if (fabs(av_diff) > 0.5) - goto done; - - // At this point, we decided that we could use display sync for this frame. - // But if we switch too often between these modes, keep it disabled. In - // fact, we disable it if it just wants to switch between enable/disable - // more than once in the last N frames. - if (mpctx->num_past_frames > 1 && mpctx->past_frames[1].num_vsyncs < 0) { - for (int n = 1; n < mpctx->num_past_frames; n++) { - if (mpctx->past_frames[n].num_vsyncs >= 0) - goto done; - } + if (fabs(av_diff) > 0.5) { + mpctx->display_sync_broken = true; + return; } // Determine for how many vsyncs a frame should be displayed. This can be @@ -1062,8 +1054,11 @@ static void handle_display_sync_frame(struct MPContext *mpctx, MP_STATS(mpctx, "value %f aspeed", mpctx->speed_factor_a - 1); MP_STATS(mpctx, "value %f vspeed", mpctx->speed_factor_v - 1); +} -done: +static void schedule_frame(struct MPContext *mpctx, struct vo_frame *frame) +{ + handle_display_sync_frame(mpctx, frame); if (mpctx->num_past_frames > 1 && ((mpctx->past_frames[1].num_vsyncs >= 0) != mpctx->display_sync_active)) @@ -1071,11 +1066,6 @@ done: MP_VERBOSE(mpctx, "Video sync mode %s.\n", mpctx->display_sync_active ? "enabled" : "disabled"); } -} - -static void schedule_frame(struct MPContext *mpctx, struct vo_frame *frame) -{ - handle_display_sync_frame(mpctx, frame); if (!mpctx->display_sync_active) { mpctx->speed_factor_a = 1.0;