mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:16:13 +00:00
gl: win32: fix crash when finalizing GstGLContext
gst_gl_context_finalize() is calling gst_gl_window_win32_quit() which was posting a message. But then window_proc takes window's context and get a NULL. Now that we've got a GMainLoop we can do like other backends and simply call g_main_loop_quit(). This also remove duplicated code to release the parent window and potential crash there because parent_proc could be NULL if we never created the internal window. That could happen for example if setting state to READY then setting a window_handle, and go back to NULL state. https://bugzilla.gnome.org/show_bug.cgi?id=749601
This commit is contained in:
parent
db0380a9ee
commit
77e1e70fdc
1 changed files with 39 additions and 65 deletions
|
@ -26,8 +26,6 @@
|
||||||
#include "gstglwindow_win32.h"
|
#include "gstglwindow_win32.h"
|
||||||
#include "win32_message_source.h"
|
#include "win32_message_source.h"
|
||||||
|
|
||||||
#define WM_GST_GL_WINDOW_QUIT (WM_APP+1)
|
|
||||||
|
|
||||||
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam,
|
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam,
|
||||||
LPARAM lParam);
|
LPARAM lParam);
|
||||||
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam,
|
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam,
|
||||||
|
@ -71,6 +69,7 @@ static void gst_gl_window_win32_send_message_async (GstGLWindow * window,
|
||||||
GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
|
GstGLWindowCB callback, gpointer data, GDestroyNotify destroy);
|
||||||
gboolean gst_gl_window_win32_open (GstGLWindow * window, GError ** error);
|
gboolean gst_gl_window_win32_open (GstGLWindow * window, GError ** error);
|
||||||
void gst_gl_window_win32_close (GstGLWindow * window);
|
void gst_gl_window_win32_close (GstGLWindow * window);
|
||||||
|
static void release_parent_win_id (GstGLWindowWin32 * window_win32);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gl_window_win32_finalize (GObject * object)
|
gst_gl_window_win32_finalize (GObject * object)
|
||||||
|
@ -161,9 +160,21 @@ gst_gl_window_win32_close (GstGLWindow * window)
|
||||||
{
|
{
|
||||||
GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window);
|
GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window);
|
||||||
|
|
||||||
|
release_parent_win_id (window_win32);
|
||||||
|
|
||||||
|
if (window_win32->internal_win_id) {
|
||||||
|
RemoveProp (window_win32->internal_win_id, "gl_window");
|
||||||
|
if (!DestroyWindow (window_win32->internal_win_id))
|
||||||
|
GST_WARNING ("failed to destroy window %" G_GUINTPTR_FORMAT
|
||||||
|
", 0x%x", (guintptr) window_win32->internal_win_id,
|
||||||
|
(unsigned int) GetLastError ());
|
||||||
|
}
|
||||||
|
|
||||||
g_source_destroy (window_win32->msg_source);
|
g_source_destroy (window_win32->msg_source);
|
||||||
g_source_unref (window_win32->msg_source);
|
g_source_unref (window_win32->msg_source);
|
||||||
window_win32->msg_source = NULL;
|
window_win32->msg_source = NULL;
|
||||||
|
|
||||||
|
window_win32->is_closed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -206,6 +217,28 @@ set_parent_win_id (GstGLWindowWin32 * window_win32)
|
||||||
rect.bottom, FALSE);
|
rect.bottom, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
release_parent_win_id (GstGLWindowWin32 * window_win32)
|
||||||
|
{
|
||||||
|
WNDPROC parent_proc;
|
||||||
|
|
||||||
|
if (!window_win32->parent_win_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
parent_proc = GetProp (window_win32->parent_win_id, "gl_window_parent_proc");
|
||||||
|
if (!parent_proc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GST_DEBUG ("release parent %" G_GUINTPTR_FORMAT,
|
||||||
|
(guintptr) window_win32->parent_win_id);
|
||||||
|
|
||||||
|
SetWindowLongPtr (window_win32->parent_win_id, GWLP_WNDPROC,
|
||||||
|
(LONG_PTR) parent_proc);
|
||||||
|
SetParent (window_win32->internal_win_id, NULL);
|
||||||
|
|
||||||
|
RemoveProp (window_win32->parent_win_id, "gl_window_parent_proc");
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_gl_window_win32_create_window (GstGLWindowWin32 * window_win32,
|
gst_gl_window_win32_create_window (GstGLWindowWin32 * window_win32,
|
||||||
GError ** error)
|
GError ** error)
|
||||||
|
@ -304,7 +337,6 @@ static void
|
||||||
gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
|
gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
|
||||||
{
|
{
|
||||||
GstGLWindowWin32 *window_win32;
|
GstGLWindowWin32 *window_win32;
|
||||||
HWND parent_id;
|
|
||||||
|
|
||||||
window_win32 = GST_GL_WINDOW_WIN32 (window);
|
window_win32 = GST_GL_WINDOW_WIN32 (window);
|
||||||
|
|
||||||
|
@ -313,27 +345,12 @@ gst_gl_window_win32_set_window_handle (GstGLWindow * window, guintptr id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* retrieve parent if previously set */
|
|
||||||
parent_id = window_win32->parent_win_id;
|
|
||||||
|
|
||||||
if (window_win32->visible) {
|
if (window_win32->visible) {
|
||||||
ShowWindow (window_win32->internal_win_id, SW_HIDE);
|
ShowWindow (window_win32->internal_win_id, SW_HIDE);
|
||||||
window_win32->visible = FALSE;
|
window_win32->visible = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent_id) {
|
release_parent_win_id (window_win32);
|
||||||
WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc");
|
|
||||||
|
|
||||||
GST_DEBUG ("release parent %" G_GUINTPTR_FORMAT, (guintptr) parent_id);
|
|
||||||
|
|
||||||
g_return_if_fail (parent_proc);
|
|
||||||
|
|
||||||
SetWindowLongPtr (parent_id, GWLP_WNDPROC, (LONG_PTR) parent_proc);
|
|
||||||
SetParent (window_win32->internal_win_id, NULL);
|
|
||||||
|
|
||||||
RemoveProp (parent_id, "gl_window_parent_proc");
|
|
||||||
}
|
|
||||||
|
|
||||||
window_win32->parent_win_id = (HWND) id;
|
window_win32->parent_win_id = (HWND) id;
|
||||||
set_parent_win_id (window_win32);
|
set_parent_win_id (window_win32);
|
||||||
}
|
}
|
||||||
|
@ -398,18 +415,11 @@ gst_gl_window_win32_run (GstGLWindow * window)
|
||||||
static void
|
static void
|
||||||
gst_gl_window_win32_quit (GstGLWindow * window)
|
gst_gl_window_win32_quit (GstGLWindow * window)
|
||||||
{
|
{
|
||||||
GstGLWindowWin32 *window_win32;
|
GstGLWindowWin32 *window_win32 = GST_GL_WINDOW_WIN32 (window);
|
||||||
|
|
||||||
|
|
||||||
window_win32 = GST_GL_WINDOW_WIN32 (window);
|
|
||||||
window_win32->priv->thread = NULL;
|
window_win32->priv->thread = NULL;
|
||||||
|
g_main_loop_quit (window_win32->loop);
|
||||||
if (window_win32 && window_win32->internal_win_id) {
|
|
||||||
LRESULT res =
|
|
||||||
PostMessage (window_win32->internal_win_id, WM_GST_GL_WINDOW_QUIT,
|
|
||||||
(WPARAM) 0, (LPARAM) 0);
|
|
||||||
GST_DEBUG ("end loop requested");
|
|
||||||
g_return_if_fail (SUCCEEDED (res));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _GstGLMessage
|
typedef struct _GstGLMessage
|
||||||
|
@ -515,42 +525,6 @@ window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
window->close (window->close_data);
|
window->close (window->close_data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_GST_GL_WINDOW_QUIT:
|
|
||||||
{
|
|
||||||
HWND parent_id = 0;
|
|
||||||
|
|
||||||
GST_TRACE ("WM_GST_GL_WINDOW_QUIT");
|
|
||||||
|
|
||||||
parent_id = window_win32->parent_win_id;
|
|
||||||
if (parent_id) {
|
|
||||||
WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc");
|
|
||||||
|
|
||||||
g_assert (parent_proc);
|
|
||||||
|
|
||||||
SetWindowLongPtr (parent_id, GWLP_WNDPROC, (LONG_PTR) parent_proc);
|
|
||||||
SetParent (hWnd, NULL);
|
|
||||||
|
|
||||||
RemoveProp (parent_id, "gl_window_parent_proc");
|
|
||||||
}
|
|
||||||
|
|
||||||
window_win32->is_closed = TRUE;
|
|
||||||
RemoveProp (hWnd, "gl_window");
|
|
||||||
|
|
||||||
if (window_win32->internal_win_id) {
|
|
||||||
if (!DestroyWindow (window_win32->internal_win_id))
|
|
||||||
GST_WARNING ("failed to destroy window %" G_GUINTPTR_FORMAT
|
|
||||||
", 0x%x", (guintptr) hWnd, (unsigned int) GetLastError ());
|
|
||||||
}
|
|
||||||
|
|
||||||
PostQuitMessage (0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_QUIT:
|
|
||||||
{
|
|
||||||
if (window_win32->loop)
|
|
||||||
g_main_loop_quit (window_win32->loop);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WM_CAPTURECHANGED:
|
case WM_CAPTURECHANGED:
|
||||||
{
|
{
|
||||||
GST_DEBUG ("WM_CAPTURECHANGED");
|
GST_DEBUG ("WM_CAPTURECHANGED");
|
||||||
|
|
Loading…
Reference in a new issue