Commit 93e1d6ad authored by Thomas Guillem's avatar Thomas Guillem Committed by Jean-Baptiste Kempf

video_output: fix controls and events not processed

This issue is easily reproducible with VDPAU activated, with a 60fps ts file,
see #14199.

With this sample, The video_output Thread is looping in ThreadDisplayPicture
way more often than with other videos. Consequently, vout_ManageWrapper and
ThreadControl are not called enough. As a result, subtitles are processed too
late, the mouse isn't able to hide/unhide, we can be stuck in fullscreen mode,
or second click on video to pop up the menu doesn't work.

To fix this issue: don't loop in ThreadDisplayPicture and don't wait in
vout_control_Pop if a picture was previously displayed.

Fixes #14199
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 40b90380
...@@ -177,19 +177,16 @@ void vout_control_PushString(vout_control_t *ctrl, int type, const char *string) ...@@ -177,19 +177,16 @@ void vout_control_PushString(vout_control_t *ctrl, int type, const char *string)
} }
int vout_control_Pop(vout_control_t *ctrl, vout_control_cmd_t *cmd, int vout_control_Pop(vout_control_t *ctrl, vout_control_cmd_t *cmd,
mtime_t deadline, mtime_t timeout) mtime_t deadline)
{ {
vlc_mutex_lock(&ctrl->lock); vlc_mutex_lock(&ctrl->lock);
if (ctrl->cmd.i_size <= 0) { if (ctrl->cmd.i_size <= 0) {
ctrl->is_processing = false; ctrl->is_processing = false;
vlc_cond_broadcast(&ctrl->wait_acknowledge); vlc_cond_broadcast(&ctrl->wait_acknowledge);
const mtime_t max_deadline = mdate() + timeout;
const mtime_t wait_deadline = deadline <= VLC_TS_INVALID ? max_deadline : __MIN(deadline, max_deadline);
/* Spurious wakeups are perfectly fine */ /* Spurious wakeups are perfectly fine */
if (ctrl->can_sleep) if (deadline > VLC_TS_INVALID && ctrl->can_sleep)
vlc_cond_timedwait(&ctrl->wait_request, &ctrl->lock, wait_deadline); vlc_cond_timedwait(&ctrl->wait_request, &ctrl->lock, deadline);
} }
bool has_cmd; bool has_cmd;
......
...@@ -130,7 +130,7 @@ void vout_control_PushString(vout_control_t *, int type, const char *string); ...@@ -130,7 +130,7 @@ void vout_control_PushString(vout_control_t *, int type, const char *string);
void vout_control_Wake(vout_control_t *); void vout_control_Wake(vout_control_t *);
/* control inside of the vout thread */ /* control inside of the vout thread */
int vout_control_Pop(vout_control_t *, vout_control_cmd_t *, mtime_t deadline, mtime_t timeout); int vout_control_Pop(vout_control_t *, vout_control_cmd_t *, mtime_t deadline);
void vout_control_Dead(vout_control_t *); void vout_control_Dead(vout_control_t *);
#endif #endif
...@@ -1558,16 +1558,23 @@ static void *Thread(void *object) ...@@ -1558,16 +1558,23 @@ static void *Thread(void *object)
}; };
mtime_t deadline = VLC_TS_INVALID; mtime_t deadline = VLC_TS_INVALID;
bool wait = false;
for (;;) { for (;;) {
vout_control_cmd_t cmd; vout_control_cmd_t cmd;
/* FIXME remove thoses ugly timeouts */
while (!vout_control_Pop(&sys->control, &cmd, deadline, 100000)) if (wait)
{
const mtime_t max_deadline = mdate() + 100000;
deadline = deadline <= VLC_TS_INVALID ? max_deadline : __MIN(deadline, max_deadline);
} else {
deadline = VLC_TS_INVALID;
}
while (!vout_control_Pop(&sys->control, &cmd, deadline))
if (ThreadControl(vout, cmd)) if (ThreadControl(vout, cmd))
return NULL; return NULL;
deadline = VLC_TS_INVALID; deadline = VLC_TS_INVALID;
while (!ThreadDisplayPicture(vout, &deadline)) wait = ThreadDisplayPicture(vout, &deadline) != VLC_SUCCESS;
;
const bool picture_interlaced = sys->displayed.is_interlaced; const bool picture_interlaced = sys->displayed.is_interlaced;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment