applemedia/gl: Update code to use ARC
authorNick Kallen <nickkallen@me.com>
Fri, 3 Feb 2017 13:46:39 +0000 (14:46 +0100)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:32:27 +0000 (19:32 +0000)
All code interacting with Objective-C objects should now use Automated
Reference Counting rather than manual memory management or Garbage
Collection. Because ARC prohibits C-structs from containing
references to Objective-C objects, all such fields are now typed
'gpointer'. Setting and gettings Objective-C fields on such a
struct now uses explicit __bridge_* calls to tell ARC about
object lifetimes.

https://bugzilla.gnome.org/show_bug.cgi?id=777847

14 files changed:
ext/gl/caopengllayersink.h
ext/gl/caopengllayersink.m
gst-libs/gst/gl/cocoa/Makefile.am
gst-libs/gst/gl/cocoa/gstglcaopengllayer.m
gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
gst-libs/gst/gl/cocoa/gstgldisplay_cocoa.m
gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
gst-libs/gst/gl/eagl/Makefile.am
gst-libs/gst/gl/eagl/gstglcontext_eagl.h
gst-libs/gst/gl/eagl/gstglcontext_eagl.m
gst-libs/gst/gl/eagl/gstglwindow_eagl.h
gst-libs/gst/gl/eagl/gstglwindow_eagl.m
tests/examples/gl/cocoa/Makefile.am
tests/examples/gl/cocoa/cocoa-videooverlay.m

index 3507154..25bc106 100644 (file)
@@ -61,7 +61,7 @@ struct _GstCAOpenGLLayerSink
     GstBuffer *next_buffer;
     GstBuffer *next_sync;
 
-    GstGLCAOpenGLLayer *layer;
+    gpointer layer;
 
     gboolean keep_aspect_ratio;
 
index 851a4e0..1e42034 100644 (file)
@@ -79,7 +79,7 @@ gst_ca_opengl_layer_sink_bin_get_property (GObject * object, guint prop_id,
 static void
 gst_ca_opengl_layer_sink_bin_init (GstCAOpenGLLayerSinkBin * self)
 {
-  GstGLCAOpenGLLayer *sink = g_object_new (GST_TYPE_CA_OPENGL_LAYER_SINK, NULL);
+  gpointer *sink = g_object_new (GST_TYPE_CA_OPENGL_LAYER_SINK, NULL);
 
   g_signal_connect (sink, "notify::layer", G_CALLBACK (_on_notify_layer), self);
 
@@ -266,6 +266,11 @@ gst_ca_opengl_layer_sink_finalize (GObject * object)
 
   g_mutex_clear (&ca_sink->drawing_lock);
 
+  if (ca_sink->layer) {
+    CFRelease(ca_sink->layer);
+    ca_sink->layer = NULL;
+  }
+
   GST_DEBUG ("finalized");
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -322,13 +327,16 @@ static void
 _create_layer (gpointer data)
 {
   GstCAOpenGLLayerSink *ca_sink = data;
+  id layer;
 
   if (!ca_sink->layer) {
-    ca_sink->layer = [[NSClassFromString(@"GstGLCAOpenGLLayer") alloc]
+    layer = [[NSClassFromString(@"GstGLCAOpenGLLayer") alloc]
         initWithGstGLContext:GST_GL_CONTEXT_COCOA (ca_sink->context)];
-    [ca_sink->layer setDrawCallback:(GstGLWindowCB)gst_ca_opengl_layer_sink_on_draw
+
+    ca_sink->layer = (__bridge_retained gpointer)layer;
+    [layer setDrawCallback:(GstGLWindowCB)gst_ca_opengl_layer_sink_on_draw
         data:ca_sink notify:NULL];
-    [ca_sink->layer setResizeCallback:(GstGLWindowResizeCB)gst_ca_opengl_layer_sink_on_resize
+    [layer setResizeCallback:(GstGLWindowResizeCB)gst_ca_opengl_layer_sink_on_resize
         data:ca_sink notify:NULL];
     g_object_notify (G_OBJECT (ca_sink), "layer");
   }
@@ -507,6 +515,10 @@ gst_ca_opengl_layer_sink_change_state (GstElement * element, GstStateChange tran
       break;
     }
     case GST_STATE_CHANGE_READY_TO_NULL:
+      if (ca_sink->layer) {
+        CFRelease(ca_sink->layer);
+        ca_sink->layer = NULL;
+      }
       break;
     default:
       break;
@@ -698,7 +710,7 @@ gst_ca_opengl_layer_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
   /* The layer will automatically call the draw callback to draw the new
    * content */
   [CATransaction begin];
-  [ca_sink->layer setNeedsDisplay];
+  [(__bridge GstGLCAOpenGLLayer *)(ca_sink->layer) setNeedsDisplay];
   [CATransaction commit];
 
   GST_TRACE ("post redisplay");
index db85682..d43adcb 100644 (file)
@@ -29,6 +29,7 @@ libgstgl_cocoa_la_CFLAGS = \
 libgstgl_cocoa_la_OBJCFLAGS = \
        -I$(top_srcdir)/gst-libs \
        -I$(top_builddir)/gst-libs \
+       -fobjc-arc \
        $(GL_OBJCFLAGS) \
        $(GST_PLUGINS_BASE_CFLAGS) \
        $(GST_BASE_CFLAGS) \
index 48fb63b..47690b4 100644 (file)
@@ -52,20 +52,18 @@ _init_debug (void)
     gst_object_unref (self->draw_context);
 
   GST_TRACE ("dealloc GstGLCAOpenGLLayer %p context %p", self, self->gst_gl_context);
-
-  [super dealloc];
 }
 
 static void
 _context_ready (gpointer data)
 {
-  GstGLCAOpenGLLayer *ca_layer = data;
+  GstGLCAOpenGLLayer *ca_layer = (__bridge GstGLCAOpenGLLayer *) data;
 
   g_atomic_int_set (&ca_layer->can_draw, 1);
 }
 
 - (id)initWithGstGLContext:(GstGLContextCocoa *)parent_gl_context {
-  [super init];
+  self = [super init];
 
   _init_debug();
 
@@ -75,7 +73,7 @@ _context_ready (gpointer data)
   self.needsDisplayOnBoundsChange = YES;
 
   gst_gl_window_send_message_async (GST_GL_CONTEXT (parent_gl_context)->window,
-      (GstGLWindowCB) _context_ready, self, NULL);
+      (GstGLWindowCB) _context_ready, (__bridge_retained gpointer)self, (GDestroyNotify)CFRelease);
 
   return self;
 }
@@ -177,7 +175,7 @@ _context_ready (gpointer data)
 - (void)setResizeCallback:(GstGLWindowResizeCB)cb data:(gpointer)data
       notify:(GDestroyNotify)notify {
   if (self->resize_notify)
-    self->resize_notify (self->resize_notify);
+    self->resize_notify (self->resize_data);
 
   self->resize_cb = cb;
   self->resize_data = data;
index d690b21..daaecaa 100644 (file)
@@ -174,7 +174,6 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
   GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
   GstGLAPI context_api = GST_GL_API_NONE;
   const GLint swapInterval = 1;
-  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   CGLPixelFormatObj fmt = NULL;
   CGLContextObj glContext;
   CGLPixelFormatAttribute attribs[] = {
@@ -274,7 +273,6 @@ gst_gl_context_cocoa_create_context (GstGLContext *context, GstGLAPI gl_api,
 
   if (window)
     gst_object_unref (window);
-  [pool release];
 
   return TRUE;
 
@@ -282,7 +280,6 @@ error:
   {
     if (window)
       gst_object_unref (window);
-    [pool release];
     return FALSE;
   }
 }
index f7c0252..cbdaa7e 100644 (file)
@@ -48,7 +48,6 @@ static GCond nsapp_cond;
 static gboolean
 gst_gl_display_cocoa_nsapp_iteration (gpointer data)
 {
-  NSAutoreleasePool *pool = nil;
   NSEvent *event = nil;
 
   if (![NSThread isMainThread]) {
@@ -56,7 +55,6 @@ gst_gl_display_cocoa_nsapp_iteration (gpointer data)
     return FALSE;
   }
 
-  pool = [[NSAutoreleasePool alloc] init];
 
   while ((event = ([NSApp nextEventMatchingMask:NSAnyEventMask
       untilDate:[NSDate dateWithTimeIntervalSinceNow:0.05]
@@ -64,16 +62,12 @@ gst_gl_display_cocoa_nsapp_iteration (gpointer data)
     [NSApp sendEvent:event];
   }
 
-  [pool release];
-
   return TRUE;
 }
 
 static void
 gst_gl_display_cocoa_open_and_attach_source (gpointer data)
 {
-  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
   if ([NSThread isMainThread]) {
     /* The sharedApplication class method initializes
      * the display environment and connects your program
@@ -89,8 +83,6 @@ gst_gl_display_cocoa_open_and_attach_source (gpointer data)
 
     GST_DEBUG ("NSApp iteration loop attached, id %d", nsapp_source_id);
   }
-
-  [pool release];
 }
 
 static gboolean
index d1be469..b7de2b5 100644 (file)
@@ -82,8 +82,8 @@ static void gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
 
 struct _GstGLWindowCocoaPrivate
 {
-  GstGLNSWindow *internal_win_id;
-  NSView *external_view;
+  gpointer internal_win_id;
+  gpointer external_view;
   gboolean visible;
   gint preferred_width;
   gint preferred_height;
@@ -93,7 +93,7 @@ struct _GstGLWindowCocoaPrivate
   /* atomic set when the internal NSView has been created */
   int view_ready;
 
-  dispatch_queue_t gl_queue;
+  gpointer gl_queue;
 };
 
 static void
@@ -128,15 +128,15 @@ gst_gl_window_cocoa_init (GstGLWindowCocoa * window)
 
   window->priv->preferred_width = 320;
   window->priv->preferred_height = 240;
-  window->priv->gl_queue =
-      dispatch_queue_create ("org.freedesktop.gstreamer.glwindow", NULL);
+  window->priv->gl_queue = (__bridge_retained gpointer)
+      (dispatch_queue_create ("org.freedesktop.gstreamer.glwindow", NULL));
 }
 
 static void
 gst_gl_window_cocoa_finalize (GObject * object)
 {
   GstGLWindowCocoa *window = GST_GL_WINDOW_COCOA (object);
-  dispatch_release (window->priv->gl_queue);
+  window->priv->gl_queue = NULL;
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -156,6 +156,7 @@ gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa)
 {
   GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
   GstGLWindow *window = GST_GL_WINDOW (window_cocoa);
+  GstGLNSWindow *internal_win_id;
   NSRect mainRect = [[NSScreen mainScreen] visibleFrame];
   gint h = priv->preferred_height;
   gint y = mainRect.size.height > h ? (mainRect.size.height - h) * 0.5 : 0;
@@ -168,14 +169,16 @@ gst_gl_window_cocoa_create_window (GstGLWindowCocoa *window_cocoa)
 
   gst_object_unref (context);
 
-  priv->internal_win_id = [[GstGLNSWindow alloc] initWithContentRect:rect styleMask: 
+  internal_win_id = [[GstGLNSWindow alloc] initWithContentRect:rect styleMask: 
       (NSTitledWindowMask | NSClosableWindowMask |
       NSResizableWindowMask | NSMiniaturizableWindowMask)
       backing: NSBackingStoreBuffered defer: NO screen: nil gstWin: window_cocoa];
 
-      GST_DEBUG ("NSWindow id: %"G_GUINTPTR_FORMAT, (guintptr) priv->internal_win_id);
+  priv->internal_win_id = (__bridge_retained gpointer)internal_win_id;
+
+  GST_DEBUG ("NSWindow id: %"G_GUINTPTR_FORMAT, (guintptr) priv->internal_win_id);
 
-  [priv->internal_win_id setContentView:glView];
+  [internal_win_id setContentView:glView];
 
   g_atomic_int_set (&window_cocoa->priv->view_ready, 1);
 
@@ -196,10 +199,11 @@ static void
 gst_gl_window_cocoa_close (GstGLWindow *window)
 {
   GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
+  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)window_cocoa->priv->internal_win_id;
 
-  [[window_cocoa->priv->internal_win_id contentView] removeFromSuperview];
-  [window_cocoa->priv->internal_win_id release];
-  window_cocoa->priv->internal_win_id = nil;
+  [[internal_win_id contentView] removeFromSuperview];
+  CFBridgingRelease(window_cocoa->priv->internal_win_id);
+  window_cocoa->priv->internal_win_id = NULL;
 }
 
 static guintptr
@@ -219,7 +223,7 @@ gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
 
   if (priv->internal_win_id) {
     if (handle) {
-      priv->external_view = (NSView *) handle;
+      priv->external_view = (gpointer)handle;
       priv->visible = TRUE;
     } else {
       /* bring back our internal window */
@@ -229,17 +233,22 @@ gst_gl_window_cocoa_set_window_handle (GstGLWindow * window, guintptr handle)
 
 
     dispatch_async (dispatch_get_main_queue (), ^{
-      NSView *view = [window_cocoa->priv->internal_win_id contentView];
-      [window_cocoa->priv->internal_win_id orderOut:window_cocoa->priv->internal_win_id];
+      GstGLNSWindow *internal_win_id =
+          (__bridge GstGLNSWindow *)window_cocoa->priv->internal_win_id;
+      NSView *external_view =
+          (__bridge NSView *)window_cocoa->priv->external_view;
 
-      [window_cocoa->priv->external_view addSubview: view];
+      NSView *view = [internal_win_id contentView];
+      [internal_win_id orderOut:internal_win_id];
 
-      [view setFrame: [window_cocoa->priv->external_view bounds]];
+      [external_view addSubview: view];
+
+      [view setFrame: [external_view bounds]];
       [view setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
     });
   } else {
     /* no internal window yet so delay it to the next drawing */
-    priv->external_view = (NSView*) handle;
+    priv->external_view = (gpointer)handle;
     priv->visible = FALSE;
   }
 }
@@ -249,11 +258,12 @@ _show_window (gpointer data)
 {
   GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (data);
   GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
+  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;
 
   GST_DEBUG_OBJECT (window_cocoa, "make the window available\n");
-  [priv->internal_win_id makeMainWindow];
-  [priv->internal_win_id orderFrontRegardless];
-  [priv->internal_win_id setViewsNeedDisplay:YES];
+  [internal_win_id makeMainWindow];
+  [internal_win_id orderFrontRegardless];
+  [internal_win_id setViewsNeedDisplay:YES];
 
   priv->visible = TRUE;
 }
@@ -283,11 +293,13 @@ gst_gl_window_cocoa_queue_resize (GstGLWindow * window)
 {
   GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
   GstGLNSView *view;
+  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
+  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;
 
   if (!g_atomic_int_get (&window_cocoa->priv->view_ready))
     return;
 
-  view = (GstGLNSView *)[window_cocoa->priv->internal_win_id contentView];
+  view = (GstGLNSView *)[internal_win_id contentView];
 
   [view->layer queueResize];
 }
@@ -297,13 +309,15 @@ gst_gl_window_cocoa_draw (GstGLWindow * window)
 {
   GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (window);
   GstGLNSView *view;
+  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
+  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;
 
   /* As the view is created asynchronously in the main thread we cannot know
    * exactly when it will be ready to draw to */
   if (!g_atomic_int_get (&window_cocoa->priv->view_ready))
     return;
 
-  view = (GstGLNSView *)[window_cocoa->priv->internal_win_id contentView];
+  view = (GstGLNSView *)[internal_win_id contentView];
 
   /* this redraws the GstGLCAOpenGLLayer which calls
    * gst_gl_window_cocoa_draw_thread(). Use an explicit CATransaction since we
@@ -329,8 +343,9 @@ gst_gl_cocoa_draw_cb (GstGLWindowCocoa *window_cocoa)
 {
   GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
   GstGLWindow *window = GST_GL_WINDOW (window_cocoa);
+  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;
 
-  if (window_cocoa->priv->internal_win_id && ![priv->internal_win_id isClosed]) {
+  if (internal_win_id && ![internal_win_id isClosed]) {
    GstGLWindow *window = GST_GL_WINDOW (window_cocoa);
 
     /* draw opengl scene in the back buffer */
@@ -342,12 +357,13 @@ gst_gl_cocoa_draw_cb (GstGLWindowCocoa *window_cocoa)
 static void
 gst_gl_cocoa_resize_cb (GstGLNSView * view, guint width, guint height)
 {
-  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   GstGLWindowCocoa *window_cocoa = view->window_cocoa;
   GstGLWindow *window = GST_GL_WINDOW (window_cocoa);
   GstGLContext *context = gst_gl_window_get_context (window);
+  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
+  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;
 
-  if (window_cocoa->priv->internal_win_id && ![window_cocoa->priv->internal_win_id isClosed]) {
+  if (internal_win_id && ![internal_win_id isClosed]) {
     const GstGLFuncs *gl;
     NSRect bounds = [view bounds];
     NSRect visibleRect = [view visibleRect];
@@ -376,7 +392,6 @@ gst_gl_cocoa_resize_cb (GstGLNSView * view, guint width, guint height)
   }
 
   gst_object_unref (context);
-  [pool release];
 }
 
 static void
@@ -386,6 +401,8 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
   GstGLWindowCocoa *window_cocoa = (GstGLWindowCocoa *) window;
   GstGLContext *context = gst_gl_window_get_context (window);
   GThread *thread = gst_gl_context_get_thread (context);
+  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
+  dispatch_queue_t gl_queue = (__bridge dispatch_queue_t)priv->gl_queue;
 
   if (thread == g_thread_self()) {
     /* this case happens for nested calls happening from inside the GCD queue */
@@ -394,7 +411,7 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
       destroy (data);
     gst_object_unref (context);
   } else {
-    dispatch_async (window_cocoa->priv->gl_queue, ^{
+    dispatch_async (gl_queue, ^{
       gst_gl_context_activate (context, TRUE);
       gst_object_unref (context);
       callback (data);
@@ -423,6 +440,9 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
 
   m_isClosed = NO;
   window_cocoa = cocoa;
+  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
+  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;
+  NSView *external_view = (__bridge NSView *)priv->external_view;
 
   self = [super initWithContentRect: contentRect
         styleMask: styleMask backing: bufferingType
@@ -436,7 +456,7 @@ gst_gl_window_cocoa_send_message_async (GstGLWindow * window,
 
   [self setBackgroundColor:[NSColor blackColor]];
 
-  [self orderOut:window_cocoa->priv->internal_win_id];
+  [self orderOut:internal_win_id];
 
   return self;
 }
@@ -473,8 +493,10 @@ close_window_cb (gpointer data)
 /* Called in the main thread which is never the gl thread */
 - (BOOL) windowShouldClose:(id)sender {
 
+  GstGLWindowCocoaPrivate *priv = window_cocoa->priv;
+  GstGLNSWindow *internal_win_id = (__bridge GstGLNSWindow *)priv->internal_win_id;
   GST_DEBUG ("user clicked the close button\n");
-  [window_cocoa->priv->internal_win_id setClosed];
+  [internal_win_id setClosed];
   gst_gl_window_send_message_async (GST_GL_WINDOW (window_cocoa),
       (GstGLWindowCB) close_window_cb, gst_object_ref (window_cocoa),
       (GDestroyNotify) gst_object_unref);
@@ -509,7 +531,7 @@ close_window_cb (gpointer data)
   [self->layer setDrawCallback:(GstGLWindowCB)gst_gl_cocoa_draw_cb
       data:window notify:NULL];
   [self->layer setResizeCallback:(GstGLWindowResizeCB)gst_gl_cocoa_resize_cb
-      data:self notify:NULL];
+      data:(__bridge_retained gpointer)self notify:(GDestroyNotify)CFRelease];
 
   [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawOnSetNeedsDisplay];
 
@@ -519,9 +541,7 @@ close_window_cb (gpointer data)
 }
 
 - (void) dealloc {
-  [self->layer release];
-
-  [super dealloc];
+  self->layer = nil;
 }
 
 - (void)renewGState {
index 03ef61f..e3bafb1 100644 (file)
@@ -21,6 +21,7 @@ libgstgl_eagl_la_CFLAGS = \
 libgstgl_eagl_la_OBJCFLAGS = \
        -I$(top_srcdir)/gst-libs \
        -I$(top_builddir)/gst-libs \
+       -fobj-arc \
        $(GL_CFLAGS) \
        $(GL_OBJCFLAGS) \
        $(GST_PLUGINS_BASE_CFLAGS) \
index cdfa10f..670adb5 100644 (file)
@@ -33,6 +33,11 @@ G_BEGIN_DECLS
 #define GST_IS_GL_CONTEXT_EAGL_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_GL_CONTEXT_EAGL))
 #define GST_GL_CONTEXT_EAGL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_GL_CONTEXT_EAGL, GstGLContextEaglClass))
 
+#define GS_GL_CONTEXT_EAGL_CONTEXT(obj) \
+    ((__bridge EAGLContext *)(obj->priv->eagl_context))
+#define GS_GL_CONTEXT_EAGL_LAYER(obj) \
+    ((__bridge CAEAGLLayer *)(obj->priv->eagl_layer))
+
 typedef struct _GstGLContextEagl        GstGLContextEagl;
 typedef struct _GstGLContextEaglPrivate GstGLContextEaglPrivate;
 typedef struct _GstGLContextEaglClass   GstGLContextEaglClass;
index 5eb9a29..d7294ba 100644 (file)
@@ -46,10 +46,10 @@ static GstGLPlatform gst_gl_context_eagl_get_gl_platform (GstGLContext *
 
 struct _GstGLContextEaglPrivate
 {
-  EAGLContext *eagl_context;
+  gpointer eagl_context;
 
   /* Used if we render to a window */
-  CAEAGLLayer *eagl_layer;
+  gpointer eagl_layer;
   GLuint framebuffer;
   GLuint color_renderbuffer;
   GLuint depth_renderbuffer;
@@ -106,7 +106,7 @@ gst_gl_context_eagl_resize (GstGLContextEagl * eagl_context)
   int width, height;
 
   glBindRenderbuffer (GL_RENDERBUFFER, eagl_context->priv->color_renderbuffer);
-  [eagl_context->priv->eagl_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:eagl_context->priv->eagl_layer];
+  [GS_GL_CONTEXT_EAGL_CONTEXT(eagl_context) renderbufferStorage:GL_RENDERBUFFER fromDrawable:GS_GL_CONTEXT_EAGL_LAYER(eagl_context)];
   glGetRenderbufferParameteriv (GL_RENDERBUFFER,
       GL_RENDERBUFFER_WIDTH, &width);
   glGetRenderbufferParameteriv (GL_RENDERBUFFER,
@@ -126,7 +126,7 @@ gst_gl_context_eagl_release_layer (GstGLContext * context)
   if (context_eagl->priv->eagl_layer) {
     gst_gl_context_eagl_activate (context, TRUE);
 
-    [context_eagl->priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:nil];
+    [GS_GL_CONTEXT_EAGL_CONTEXT(context_eagl) renderbufferStorage: GL_RENDERBUFFER fromDrawable:nil];
 
     glDeleteFramebuffers (1, &context_eagl->priv->framebuffer);
     context_eagl->priv->framebuffer = 0;
@@ -156,7 +156,7 @@ gst_gl_context_eagl_update_layer (GstGLContext * context)
   UIView *window_handle = nil;
   GstGLWindow *window = gst_gl_context_get_window (context);
   if (window)
-    window_handle = (UIView *) gst_gl_window_get_window_handle (window);
+    window_handle = (__bridge UIView *)((void *)gst_gl_window_get_window_handle (window));
 
   if (!window_handle) {
     GST_INFO_OBJECT (context, "window handle not set yet, not updating layer");
@@ -170,7 +170,7 @@ gst_gl_context_eagl_update_layer (GstGLContext * context)
     gst_gl_context_eagl_release_layer (context);
 
   eagl_layer = (CAEAGLLayer *)[window_handle layer];
-  [EAGLContext setCurrentContext:priv->eagl_context];
+  [EAGLContext setCurrentContext:GS_GL_CONTEXT_EAGL_CONTEXT(context_eagl)];
 
   /* Allocate framebuffer */
   glGenFramebuffers (1, &framebuffer);
@@ -178,7 +178,7 @@ gst_gl_context_eagl_update_layer (GstGLContext * context)
   /* Allocate color render buffer */
   glGenRenderbuffers (1, &color_renderbuffer);
   glBindRenderbuffer (GL_RENDERBUFFER, color_renderbuffer);
-  [priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:eagl_layer];
+  [GS_GL_CONTEXT_EAGL_CONTEXT(context_eagl) renderbufferStorage: GL_RENDERBUFFER fromDrawable:eagl_layer];
   glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
       GL_RENDERBUFFER, color_renderbuffer);
   /* Get renderbuffer width/height */
@@ -203,7 +203,7 @@ gst_gl_context_eagl_update_layer (GstGLContext * context)
   glBindRenderbuffer (GL_RENDERBUFFER, 0);
   glBindFramebuffer (GL_FRAMEBUFFER, 0);
 
-  priv->eagl_layer = eagl_layer;
+  priv->eagl_layer = (__bridge_retained gpointer)eagl_layer;
   priv->framebuffer = framebuffer;
   priv->color_renderbuffer = color_renderbuffer;
   priv->depth_renderbuffer = depth_renderbuffer;
@@ -222,16 +222,16 @@ gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
   EAGLSharegroup *share_group;
 
   if (other_context) {
-    EAGLContext *external_gl_context = (EAGLContext *)
+    EAGLContext *external_gl_context = (__bridge EAGLContext *)(void *)
         gst_gl_context_get_gl_context (other_context);
     share_group = [external_gl_context sharegroup];
   } else {
     share_group = nil;
   }
 
-  priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3 sharegroup:share_group];
+  priv->eagl_context = (__bridge_retained gpointer)[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3 sharegroup:share_group];
   if (!priv->eagl_context) {
-    priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:share_group];
+    priv->eagl_context = (__bridge_retained gpointer)[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:share_group];
   }
   if (!priv->eagl_context) {
     g_set_error_literal (error, GST_GL_CONTEXT_ERROR,
@@ -240,9 +240,6 @@ gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
     return FALSE;
   }
 
-  if (share_group)
-    [share_group release];
-
   priv->eagl_layer = NULL;
   priv->framebuffer = 0;
   priv->color_renderbuffer = 0;
@@ -266,8 +263,8 @@ gst_gl_context_eagl_destroy_context (GstGLContext * context)
 
   gst_gl_context_eagl_release_layer (context);
 
-  [context_eagl->priv->eagl_context release];
-  context_eagl->priv->eagl_context = nil;
+  CFRelease(context_eagl->priv->eagl_context);
+  context_eagl->priv->eagl_context = NULL;
 }
 
 static gboolean
@@ -284,7 +281,7 @@ gst_gl_context_eagl_choose_format (GstGLContext * context, GError ** error)
     return TRUE;
 
   if (window)
-    window_handle = (UIView *) gst_gl_window_get_window_handle (window);
+    window_handle = (__bridge UIView *)(void *)gst_gl_window_get_window_handle (window);
 
   if (!window_handle) {
     gst_object_unref (window);
@@ -341,7 +338,7 @@ gst_gl_context_eagl_swap_buffers (GstGLContext * context)
   if (!context_eagl->priv->eagl_layer)
     return;
 
-  [context_eagl->priv->eagl_context presentRenderbuffer:GL_RENDERBUFFER];
+  [GS_GL_CONTEXT_EAGL_CONTEXT(context_eagl) presentRenderbuffer:GL_RENDERBUFFER];
 }
 
 static gboolean
@@ -360,7 +357,7 @@ gst_gl_context_eagl_activate (GstGLContext * context, gboolean activate)
     }
 
     GST_DEBUG ("Attaching context to thread %p", g_thread_self ());
-    if ([EAGLContext setCurrentContext:context_eagl->priv->eagl_context] == NO) {
+    if ([EAGLContext setCurrentContext:GS_GL_CONTEXT_EAGL_CONTEXT(context_eagl)] == NO) {
       GST_ERROR ("Couldn't make context current");
       return FALSE;
     }
index f42296a..6c80963 100644 (file)
@@ -33,6 +33,11 @@ G_BEGIN_DECLS
 #define GST_IS_GL_WINDOW_EAGL_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_GL_WINDOW_EAGL))
 #define GST_GL_WINDOW_EAGL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_GL_WINDOW_EAGL, GstGLWindowEaglClass))
 
+#define GS_GL_WINDOW_EAGL_VIEW(obj) \
+    ((__bridge UIView *)(obj->priv->view))
+#define GS_GL_WINDOW_EAGL_QUEUE(obj) \
+    ((__bridge dispatch_queue_t)(obj->priv->gl_queue))
+
 typedef struct _GstGLWindowEagl        GstGLWindowEagl;
 typedef struct _GstGLWindowEaglPrivate GstGLWindowEaglPrivate;
 typedef struct _GstGLWindowEaglClass   GstGLWindowEaglClass;
index 7306120..fb70c01 100644 (file)
@@ -54,10 +54,10 @@ static void gst_gl_window_eagl_send_message_async (GstGLWindow * window,
 
 struct _GstGLWindowEaglPrivate
 {
-  UIView *view;
+  gpointer view;
   gint window_width, window_height;
   gint preferred_width, preferred_height;
-  dispatch_queue_t gl_queue;
+  gpointer gl_queue;
 };
 
 static void
@@ -88,14 +88,14 @@ gst_gl_window_eagl_init (GstGLWindowEagl * window)
 {
   window->priv = GST_GL_WINDOW_EAGL_GET_PRIVATE (window);
   window->priv->gl_queue =
-      dispatch_queue_create ("org.freedesktop.gstreamer.glwindow", NULL);
+      (__bridge_retained gpointer)dispatch_queue_create ("org.freedesktop.gstreamer.glwindow", NULL);
 }
 
 static void
 gst_gl_window_eagl_finalize (GObject * object)
 {
   GstGLWindowEagl *window = GST_GL_WINDOW_EAGL (object);
-  dispatch_release (window->priv->gl_queue);
+  CFRelease(window->priv->gl_queue);
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -128,7 +128,7 @@ gst_gl_window_eagl_set_window_handle (GstGLWindow * window, guintptr handle)
   window_eagl = GST_GL_WINDOW_EAGL (window);
   context = gst_gl_window_get_context (window);
 
-  window_eagl->priv->view = (UIView *) handle;
+  window_eagl->priv->view = (gpointer)handle;
   GST_INFO_OBJECT (context, "handle set, updating layer");
   gst_gl_context_eagl_update_layer (context);
 
@@ -159,10 +159,10 @@ gst_gl_window_eagl_send_message_async (GstGLWindow * window,
       destroy (data);
     gst_object_unref (context);
   } else {
-    dispatch_async (window_eagl->priv->gl_queue, ^{
+    dispatch_async ((__bridge dispatch_queue_t)(window_eagl->priv->gl_queue), ^{
       gst_gl_context_activate (context, TRUE);
-      gst_object_unref (context);
       callback (data);
+      gst_object_unref (context);
       if (destroy)
         destroy (data);
     });
@@ -184,7 +184,7 @@ draw_cb (gpointer data)
     CGSize size;
     CAEAGLLayer *eagl_layer;
 
-    eagl_layer = (CAEAGLLayer *)[window_eagl->priv->view layer];
+    eagl_layer = (CAEAGLLayer *)[GS_GL_WINDOW_EAGL_VIEW(window_eagl) layer];
     size = eagl_layer.frame.size;
 
     if (window->queue_resize || window_eagl->priv->window_width != size.width ||
index 3690546..9148f8a 100755 (executable)
@@ -5,6 +5,7 @@ noinst_PROGRAMS = cocoa-videooverlay
 cocoa_videooverlay_SOURCES = cocoa-videooverlay.m
 
 cocoa_videooverlay_OBJCFLAGS=-Wno-error=unused-command-line-argument \
+    -fobjc-arc \
     -I$(top_srcdir)/gst-libs -I$(top_builddir)/gst-libs \
     $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
     $(GL_CFLAGS) $(GL_OBJCFLAGS)
index a783c56..cc209d8 100755 (executable)
@@ -121,8 +121,6 @@ static GstBusSyncReply create_window (GstBus* bus, GstMessage* message, MainWind
 
 static void end_stream_cb(GstBus* bus, GstMessage* message, MainWindow* window)
 {
-  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
   g_print ("end of stream\n");
 
   gst_element_set_state ([window pipeline], GST_STATE_NULL);
@@ -130,8 +128,6 @@ static void end_stream_cb(GstBus* bus, GstMessage* message, MainWindow* window)
   g_main_loop_quit ([window loop]);
 
   [window performSelectorOnMainThread:@selector(customClose) withObject:nil waitUntilDone:YES];
-
-  [pool release];
 }
 
 static gpointer thread_func (MainWindow* window)
@@ -162,11 +158,9 @@ int main(int argc, char **argv)
   gboolean ok=FALSE;
   GstBus *bus=NULL;
   GThread *loop_thread=NULL;
-  NSAutoreleasePool *pool=nil;
   NSRect rect;
   MainWindow *window=nil;
 
-  pool = [[NSAutoreleasePool alloc] init];
   [NSApplication sharedApplication];
 
   g_print("app created\n");
@@ -202,14 +196,15 @@ int main(int argc, char **argv)
 
   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
   gst_bus_add_signal_watch (bus);
-  g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), window);
-  g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), window);
-  g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), window);
-  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, window, NULL);
+  /* NOTE: window is not bridge_retained because its lifetime is just this function */
+  g_signal_connect(bus, "message::error", G_CALLBACK(end_stream_cb), (__bridge gpointer)window);
+  g_signal_connect(bus, "message::warning", G_CALLBACK(end_stream_cb), (__bridge gpointer)window);
+  g_signal_connect(bus, "message::eos", G_CALLBACK(end_stream_cb), (__bridge gpointer)window);
+  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, (__bridge gpointer)window, NULL);
   gst_object_unref (bus);
 
   loop_thread = g_thread_new (NULL,
-      (GThreadFunc) thread_func, window);
+      (GThreadFunc) thread_func, (__bridge gpointer)window);
 
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
 
@@ -225,9 +220,5 @@ int main(int argc, char **argv)
 
   g_thread_join (loop_thread);
 
-  [window release];
-
-  [pool release];
-
   return 0;
 }