From e557e93f3b4e922f9dd6fc5dcc04284522a693e8 Mon Sep 17 00:00:00 2001 From: Nick Kallen Date: Sun, 26 Feb 2017 10:24:46 +0100 Subject: [PATCH] applemedia: ensure all textures are released before texturecache is released It was previously possible for videotexturecache to be finalized before all of its textures. Finalizing outstanding textures in this circumstance leads to a crash. This patch ensure resources are freed in the proper order. https://bugzilla.gnome.org/show_bug.cgi?id=779247 --- sys/applemedia/videotexturecache.m | 44 ++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/sys/applemedia/videotexturecache.m b/sys/applemedia/videotexturecache.m index 8315a3bba0..02b53c7920 100644 --- a/sys/applemedia/videotexturecache.m +++ b/sys/applemedia/videotexturecache.m @@ -42,6 +42,13 @@ typedef struct _ContextThreadData GstMemory *memory; } ContextThreadData; +typedef struct _TextureWrapper +{ + CVOpenGLESTextureCacheRef *cache; + CVOpenGLESTextureRef texture; + +} TextureWrapper; + GstVideoTextureCache * gst_video_texture_cache_new (GstGLContext * ctx) { @@ -129,6 +136,12 @@ gst_video_texture_cache_set_format (GstVideoTextureCache * cache, } #if HAVE_IOS +void gst_video_texture_cache_release_texture(TextureWrapper *data) { + CFRelease(data->texture); + CFRelease(data->cache); + g_free(data); +} + static void _do_create_memory (GstGLContext * context, ContextThreadData * data) { @@ -141,6 +154,7 @@ _do_create_memory (GstGLContext * context, ContextThreadData * data) GstGLTextureTarget gl_target; GstAppleCoreVideoMemory *memory; GstIOSGLMemory *gl_memory; + GstVideoGLTextureType textype; switch (GST_VIDEO_INFO_FORMAT (&cache->input_info)) { case GST_VIDEO_FORMAT_BGRA: @@ -151,16 +165,10 @@ _do_create_memory (GstGLContext * context, ContextThreadData * data) GL_RGBA, GL_UNSIGNED_BYTE, 0, &texture) != kCVReturnSuccess) goto error; - gl_target = gst_gl_texture_target_from_gl (CVOpenGLESTextureGetTarget (texture)); - memory = gst_apple_core_video_memory_new_wrapped (gpixbuf, plane, size); - gl_memory = gst_ios_gl_memory_new_wrapped (context, memory, - gl_target, GST_VIDEO_GL_TEXTURE_TYPE_RGBA, - CVOpenGLESTextureGetName (texture), - &cache->input_info, - 0, NULL, texture, (GDestroyNotify) CFRelease); - break; + textype = GST_VIDEO_GL_TEXTURE_TYPE_RGBA; + plane = 0; + goto success; case GST_VIDEO_FORMAT_NV12: { - GstVideoGLTextureType textype; GLenum texifmt, texfmt; if (plane == 0) @@ -177,21 +185,27 @@ _do_create_memory (GstGLContext * context, ContextThreadData * data) texfmt, GL_UNSIGNED_BYTE, plane, &texture) != kCVReturnSuccess) goto error; - gl_target = gst_gl_texture_target_from_gl (CVOpenGLESTextureGetTarget (texture)); - memory = gst_apple_core_video_memory_new_wrapped (gpixbuf, plane, size); - gl_memory = gst_ios_gl_memory_new_wrapped (context, memory, - gl_target, textype, CVOpenGLESTextureGetName (texture), &cache->input_info, - plane, NULL, texture, (GDestroyNotify) CFRelease); - break; + goto success; } default: g_warn_if_reached (); goto error; } +success: { + TextureWrapper *texture_data = g_new(TextureWrapper, 1); + texture_data->cache = CFRetain(cache->cache); + texture_data->texture = texture; + gl_target = gst_gl_texture_target_from_gl (CVOpenGLESTextureGetTarget (texture)); + memory = gst_apple_core_video_memory_new_wrapped (gpixbuf, plane, size); + gl_memory = gst_ios_gl_memory_new_wrapped (context, memory, + gl_target, textype, CVOpenGLESTextureGetName (texture), &cache->input_info, + plane, NULL, texture_data, (GDestroyNotify) gst_video_texture_cache_release_texture); + data->memory = GST_MEMORY_CAST (gl_memory); return; +} error: data->memory = NULL;