video: do not disable display-sync on A/V desync

On a audio/video desync by more than 0.5 seconds, display-sync mode was
disabled, and not enabled again (until playback restart, e.g. a seek).

The idea was that it this only happens when this playback mode is broken
and can't perform well anyway (A/V desync is a clear indication that
something is very wrong). Instead of behaving like a god damn POS, it
should revert to the more robust audio-sync mode.

Unfortunately, this could happen sporadically due to temporary system
performance problems, such as toggling fullscreen. Users didn't like
this, and asked for a function to disable it, or to recover in some
other way.

This mechanism is questionable anyway. If an ignorant user enables
display-sync, and encounters problems with it (without being able to
determine that display-sync is messing up), the player will still behave
like a POS on every playback, and even after every seek. It might
actually be helpful to fail more consistently. Also, I've found that
it's sill relatively reliable anyway even without this mechanism.

So just remove the fallback.

Fixes: #7048
This commit is contained in:
wm4 2019-10-17 19:23:35 +02:00
parent 2fcd5271eb
commit 273cc3055c
3 changed files with 20 additions and 13 deletions

View File

@ -5789,10 +5789,24 @@ Miscellaneous
making a some idealized assumptions, which may not always apply in reality.
Behavior can depend on the VO and the system's video and audio drivers.
Media files must use constant framerate. Section-wise VFR might work as well
with some container formats (but not e.g. mkv). If the sync code detects
severe A/V desync, or the framerate cannot be detected, the player
automatically reverts to ``audio`` mode for some time or permanently. These
modes also require a vsync blocked presentation mode. For OpenGL, this
with some container formats (but not e.g. mkv).
Under some circumstances, the player automatically reverts to ``audio`` mode
for some time or permanently. This can happen on very low framerate video,
or if the framerate cannot be detected.
Also in display-sync modes it can happen that interruptions to video
playback (such as toggling fullscreen mode, or simply resizing the window)
will skip the video frames that should have been displayed, while ``audio``
mode will display them after the renderer has resumed (typically resulting
in a short A/V desync and the video "catching up").
Before mpv 0.30.0, there was a fallback to ``audio`` mode on severe A/V
desync. This was changed for the sake of not sporadically stopping. Now,
``display-desync`` does what it promises and may desync with audio by an
arbitrary amount, until it is manually fixed with a seek.
These modes also require a vsync blocked presentation mode. For OpenGL, this
translates to ``--opengl-swapinterval=1``. For Vulkan, it translates to
``--vulkan-swap-mode=fifo`` (or ``fifo-relaxed``).

View File

@ -338,7 +338,6 @@ 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;

View File

@ -118,7 +118,6 @@ 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->vo_chain ? STATUS_SYNCING : STATUS_EOF;
}
@ -781,7 +780,7 @@ static void handle_display_sync_frame(struct MPContext *mpctx,
mpctx->display_sync_active = false;
if (!VS_IS_DISP(mode) || mpctx->display_sync_broken)
if (!VS_IS_DISP(mode))
return;
bool resample = mode == VS_DISP_RESAMPLE || mode == VS_DISP_RESAMPLE_VDROP ||
mode == VS_DISP_RESAMPLE_NONE;
@ -809,12 +808,6 @@ static void handle_display_sync_frame(struct MPContext *mpctx,
mpctx->speed_factor_v = best;
}
double av_diff = mpctx->last_av_difference;
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
// e.g. 2 for 30hz on a 60hz display. It can also be 0 if the video
// framerate is higher than the display framerate.
@ -830,6 +823,7 @@ static void handle_display_sync_frame(struct MPContext *mpctx,
mpctx->display_sync_error, mpctx->display_sync_error / vsync,
mpctx->display_sync_error / frame_duration);
double av_diff = mpctx->last_av_difference;
MP_STATS(mpctx, "value %f avdiff", av_diff);
// Intended number of additional display frames to drop (<0) or repeat (>0)