mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
gst-play: Remove timer GSource from Win32 keyboard handler
Use WaitForMultipleObjects to handle keyboard input only if pending keyboard input exists.
This commit is contained in:
parent
ed651022cb
commit
60d58038df
1 changed files with 91 additions and 16 deletions
|
@ -134,21 +134,27 @@ gst_play_kb_set_key_handler (GstPlayKbFunc kb_func, gpointer user_data)
|
||||||
|
|
||||||
#elif defined(G_OS_WIN32)
|
#elif defined(G_OS_WIN32)
|
||||||
|
|
||||||
static GSource *source = NULL;
|
typedef struct
|
||||||
|
{
|
||||||
|
GThread *thread;
|
||||||
|
HANDLE event_handle;
|
||||||
|
HANDLE console_handle;
|
||||||
|
gboolean closing;
|
||||||
|
GMutex lock;
|
||||||
|
} Win32KeyHandler;
|
||||||
|
|
||||||
|
static Win32KeyHandler *win32_handler = NULL;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_play_kb_source_cb (gpointer user_data)
|
gst_play_kb_source_cb (Win32KeyHandler * handler)
|
||||||
{
|
{
|
||||||
HANDLE h_input = GetStdHandle (STD_INPUT_HANDLE);
|
HANDLE h_input = handler->console_handle;
|
||||||
INPUT_RECORD buffer;
|
INPUT_RECORD buffer;
|
||||||
DWORD n;
|
DWORD n;
|
||||||
|
|
||||||
if (PeekConsoleInput (h_input, &buffer, 1, &n) && n == 1) {
|
if (PeekConsoleInput (h_input, &buffer, 1, &n) && n == 1) {
|
||||||
ReadConsoleInput (h_input, &buffer, 1, &n);
|
ReadConsoleInput (h_input, &buffer, 1, &n);
|
||||||
|
|
||||||
if (!kb_callback)
|
|
||||||
return G_SOURCE_REMOVE;
|
|
||||||
|
|
||||||
if (buffer.EventType == KEY_EVENT && !buffer.Event.KeyEvent.bKeyDown) {
|
if (buffer.EventType == KEY_EVENT && !buffer.Event.KeyEvent.bKeyDown) {
|
||||||
gchar key_val[2] = { 0 };
|
gchar key_val[2] = { 0 };
|
||||||
|
|
||||||
|
@ -173,7 +179,41 @@ gst_play_kb_source_cb (gpointer user_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
gst_play_kb_win32_thread (gpointer user_data)
|
||||||
|
{
|
||||||
|
Win32KeyHandler *handler = (Win32KeyHandler *) user_data;
|
||||||
|
HANDLE handles[2];
|
||||||
|
|
||||||
|
handles[0] = handler->event_handle;
|
||||||
|
handles[1] = handler->console_handle;
|
||||||
|
|
||||||
|
if (!kb_callback)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (TRUE) {
|
||||||
|
DWORD ret = WaitForMultipleObjects (2, handles, FALSE, INFINITE);
|
||||||
|
|
||||||
|
if (ret == WAIT_FAILED) {
|
||||||
|
GST_WARNING ("WaitForMultipleObject Failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_lock (&handler->lock);
|
||||||
|
if (handler->closing) {
|
||||||
|
g_mutex_unlock (&handler->lock);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
g_mutex_unlock (&handler->lock);
|
||||||
|
|
||||||
|
g_idle_add ((GSourceFunc) gst_play_kb_source_cb, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -186,18 +226,53 @@ gst_play_kb_set_key_handler (GstPlayKbFunc kb_func, gpointer user_data)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source) {
|
if (win32_handler) {
|
||||||
g_source_destroy (source);
|
g_mutex_lock (&win32_handler->lock);
|
||||||
g_source_unref (source);
|
win32_handler->closing = TRUE;
|
||||||
source = NULL;
|
g_mutex_unlock (&win32_handler->lock);
|
||||||
|
|
||||||
|
SetEvent (win32_handler->event_handle);
|
||||||
|
g_thread_join (win32_handler->thread);
|
||||||
|
CloseHandle (win32_handler->event_handle);
|
||||||
|
|
||||||
|
g_mutex_clear (&win32_handler->lock);
|
||||||
|
g_free (win32_handler);
|
||||||
|
win32_handler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kb_func) {
|
if (kb_func) {
|
||||||
/* check input per 50 ms */
|
SECURITY_ATTRIBUTES sec_attrs;
|
||||||
source = g_timeout_source_new (50);
|
|
||||||
g_source_set_callback (source,
|
sec_attrs.nLength = sizeof (SECURITY_ATTRIBUTES);
|
||||||
(GSourceFunc) gst_play_kb_source_cb, NULL, NULL);
|
sec_attrs.lpSecurityDescriptor = NULL;
|
||||||
g_source_attach (source, NULL);
|
sec_attrs.bInheritHandle = FALSE;
|
||||||
|
|
||||||
|
win32_handler = g_new0 (Win32KeyHandler, 1);
|
||||||
|
|
||||||
|
/* create cancellable event handle */
|
||||||
|
win32_handler->event_handle = CreateEvent (&sec_attrs, TRUE, FALSE, NULL);
|
||||||
|
|
||||||
|
if (!win32_handler->event_handle) {
|
||||||
|
GST_WARNING ("Couldn't create event handle");
|
||||||
|
g_free (win32_handler);
|
||||||
|
win32_handler = NULL;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
win32_handler->console_handle = GetStdHandle (STD_INPUT_HANDLE);
|
||||||
|
if (!win32_handler->console_handle) {
|
||||||
|
GST_WARNING ("Couldn't get console handle");
|
||||||
|
CloseHandle (win32_handler->event_handle);
|
||||||
|
g_free (win32_handler);
|
||||||
|
win32_handler = NULL;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_init (&win32_handler->lock);
|
||||||
|
win32_handler->thread =
|
||||||
|
g_thread_new ("gst-play-kb", gst_play_kb_win32_thread, win32_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
kb_callback = kb_func;
|
kb_callback = kb_func;
|
||||||
|
|
Loading…
Reference in a new issue