diff options
author | Matthew Waters <matthew@centricular.com> | 2017-07-16 01:17:04 +1000 |
---|---|---|
committer | Matthew Waters <matthew@centricular.com> | 2017-07-16 12:50:31 +1000 |
commit | 24e3cbf13bcc91fee3a88f7d7e70308256954fb2 (patch) | |
tree | 4edf163f3acae62084f3a47ce7715f0dcf902b7b /gst-libs/gst/gl | |
parent | 1656d8000d2c1988b1170bc671d48f42b0f91f4c (diff) |
gl/cocoa: keep refs over async operations
Avoids dereferencing dead objects
What happens in the autovideosink case is that context 1 is created and
destroyed before all the async operations hae executed on the associated
window. When the delayed operations execute, they then reference dead
objects and crash.
We fix this by keeping refs over all async operations so the object
cannot be deleted while async operations are in flight.
https://bugzilla.gnome.org/show_bug.cgi?id=782379
Diffstat (limited to 'gst-libs/gst/gl')
-rw-r--r-- | gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h | 2 | ||||
-rw-r--r-- | gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m | 2 | ||||
-rw-r--r-- | gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m | 22 |
3 files changed, 19 insertions, 7 deletions
diff --git a/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h b/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h index ae7abc8a6..9a9bef25b 100644 --- a/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h +++ b/gst-libs/gst/gl/cocoa/gstgl_cocoa_private.h @@ -59,7 +59,7 @@ struct _GstGLContextCocoaPrivate gboolean gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa); -void _invoke_on_main (GstGLWindowCB func, gpointer data); +void _invoke_on_main (GstGLWindowCB func, gpointer data, GDestroyNotify notify); G_END_DECLS diff --git a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m index 9e2f1e4f5..b3ba59e9c 100644 --- a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m +++ b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m @@ -259,7 +259,7 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api, context_cocoa->priv->gl_context = glContext; _invoke_on_main ((GstGLWindowCB) gst_gl_window_cocoa_create_window, - window_cocoa); + gst_object_ref (window_cocoa), (GDestroyNotify) gst_object_unref); if (!context_cocoa->priv->gl_context) { goto error; diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m index 7c01702f4..40d6bc281 100644 --- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m +++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m @@ -175,9 +175,16 @@ gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa) NSRect rect = NSMakeRect (0, y, priv->preferred_width, priv->preferred_height); NSRect windowRect = NSMakeRect (0, y, priv->preferred_width, priv->preferred_height); GstGLContext *context = gst_gl_window_get_context (window); - GstGLContextCocoa *context_cocoa = GST_GL_CONTEXT_COCOA (context); - GstGLCAOpenGLLayer *layer = [[GstGLCAOpenGLLayer alloc] initWithGstGLContext:context_cocoa]; - GstGLNSView *glView = [[GstGLNSView alloc] initWithFrameLayer:window_cocoa rect:windowRect layer:layer]; + GstGLContextCocoa *context_cocoa; + GstGLCAOpenGLLayer *layer; + GstGLNSView *glView; + + if (!context) + return FALSE; + + context_cocoa = GST_GL_CONTEXT_COCOA (context); + layer = [[GstGLCAOpenGLLayer alloc] initWithGstGLContext:context_cocoa]; + glView = [[GstGLNSView alloc] initWithFrameLayer:window_cocoa rect:windowRect layer:layer]; gst_object_unref (context); @@ -296,7 +303,8 @@ gst_gl_window_cocoa_show (GstGLWindow * window) } if (!priv->external_view && !priv->visible) - _invoke_on_main ((GstGLWindowCB) _show_window, window); + _invoke_on_main ((GstGLWindowCB) _show_window, gst_object_ref (window), + (GDestroyNotify) gst_object_unref); } } @@ -575,13 +583,17 @@ close_window_cb (gpointer data) @end void -_invoke_on_main (GstGLWindowCB func, gpointer data) +_invoke_on_main (GstGLWindowCB func, gpointer data, GDestroyNotify notify) { if ([NSThread isMainThread]) { func (data); + if (notify) + notify (data); } else { dispatch_async (dispatch_get_main_queue (), ^{ func (data); + if (notify) + notify (data); }); } } |