summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-02-21 14:18:30 +0100
committerwm4 <wm4@nowhere>2017-02-21 15:39:40 +0100
commit3cd29ca0318cfab04d155ea8323e7b4c84010b79 (patch)
treeee401f17b41eccb2e383ac4e87543ee65ba49db5
parente85d06baadeda6b63f315adfcdbdd7c56cd8cf9f (diff)
downloadmpv-3cd29ca0318cfab04d155ea8323e7b4c84010b79.tar.bz2
mpv-3cd29ca0318cfab04d155ea8323e7b4c84010b79.tar.xz
player: reduce blocking on VO when switching pause
When pausing, we sent BOCTRL_PAUSE and VOCTRL_RESTORE_SCREENSAVER. These essentially wait until the video frame has been rendered. This is a problem with the opengl-cb, if GL rendering is done in the same thread as libmpv uses. Unfortunately, it's allowed to use opengl-cb this way. Logically speaking, it's a deadlock situation, which is resolved with a timeout. This can lead to quite ugly effects, like the on-pause frame not being rendered until the timeout has passed. It has been interpreted as video continuing to play. Resolve this by simply not blocking on pause. Make the screensaver controls async, and handle sending VOCTRL_PAUSE in the VO thread. (All this could be avoided by redoing the internal VO API.) Also see #4152.
-rw-r--r--player/playloop.c4
-rw-r--r--video/out/vo.c9
2 files changed, 10 insertions, 3 deletions
diff --git a/player/playloop.c b/player/playloop.c
index e73ad61788..de3e0aea9a 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -180,8 +180,8 @@ void update_screensaver_state(struct MPContext *mpctx)
bool saver_state = mpctx->opts->pause || !mpctx->opts->stop_screensaver ||
!mpctx->playback_initialized;
- vo_control(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER
- : VOCTRL_KILL_SCREENSAVER, NULL);
+ vo_control_async(mpctx->video_out, saver_state ? VOCTRL_RESTORE_SCREENSAVER
+ : VOCTRL_KILL_SCREENSAVER, NULL);
}
void add_step_frame(struct MPContext *mpctx, int dir)
diff --git a/video/out/vo.c b/video/out/vo.c
index f0c865d269..3eb338d2d7 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -581,6 +581,9 @@ void vo_control_async(struct vo *vo, int request, void *data)
case VOCTRL_UPDATE_PLAYBACK_STATE:
d[2] = ta_xdup_ptrtype(d, (struct voctrl_playback_state *)data);
break;
+ case VOCTRL_KILL_SCREENSAVER:
+ case VOCTRL_RESTORE_SCREENSAVER:
+ break;
default:
abort(); // requires explicit support
}
@@ -933,9 +936,13 @@ static void *vo_thread(void *ptr)
bool redraw = in->request_redraw;
bool send_reset = in->send_reset;
in->send_reset = false;
+ bool send_pause = in->paused != vo_paused;
+ vo_paused = in->paused;
pthread_mutex_unlock(&in->lock);
if (send_reset)
vo->driver->control(vo, VOCTRL_RESET, NULL);
+ if (send_pause)
+ vo->driver->control(vo, vo_paused ? VOCTRL_PAUSE : VOCTRL_RESUME, NULL);
if (wait_until > now && redraw) {
do_redraw(vo); // now is a good time
continue;
@@ -958,9 +965,9 @@ void vo_set_paused(struct vo *vo, bool paused)
if (in->paused && in->dropped_frame)
in->request_redraw = true;
reset_vsync_timings(vo);
+ wakeup_locked(vo);
}
pthread_mutex_unlock(&in->lock);
- vo_control(vo, paused ? VOCTRL_PAUSE : VOCTRL_RESUME, NULL);
}
int64_t vo_get_drop_count(struct vo *vo)