From: Matthew Waters Date: Wed, 14 May 2014 07:59:52 +0000 (+1000) Subject: gl/eglimage: add eglimage context feature X-Git-Tag: 1.19.3~511^2~1989^2~1466 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=51fdeef98bbba035ef5fa7bb870fc4a4b957ecab;p=platform%2Fupstream%2Fgstreamer.git gl/eglimage: add eglimage context feature Allows us to selectively use EGLImages only when available https://bugzilla.gnome.org/show_bug.cgi?id=728234 --- diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c index b2a1d07..1311319 100644 --- a/ext/gl/gstglimagesink.c +++ b/ext/gl/gstglimagesink.c @@ -933,9 +933,12 @@ gst_glimage_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) gst_object_unref (allocator); #if GST_GL_HAVE_PLATFORM_EGL - allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE); - gst_query_add_allocation_param (query, allocator, ¶ms); - gst_object_unref (allocator); + if (gst_gl_context_check_feature (glimage_sink->context, + "EGL_KHR_image_base")) { + allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE); + gst_query_add_allocation_param (query, allocator, ¶ms); + gst_object_unref (allocator); + } #endif return TRUE; diff --git a/gst-libs/gst/gl/egl/gsteglimagememory.c b/gst-libs/gst/gl/egl/gsteglimagememory.c index 665f4cc..5a023a5 100644 --- a/gst-libs/gst/gl/egl/gsteglimagememory.c +++ b/gst-libs/gst/gl/egl/gsteglimagememory.c @@ -122,7 +122,7 @@ gst_egl_image_allocator_free_vfunc (GstAllocator * allocator, GstMemory * mem) /* Shared memory should not destroy all the data */ if (!mem->parent) { - eglDestroyImageKHR (emem->context->egl_display, emem->image); + emem->context->eglDestroyImage (emem->context->egl_display, emem->image); if (emem->user_data_destroy) emem->user_data_destroy (emem->context, emem->user_data); @@ -163,8 +163,18 @@ gst_egl_image_mem_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset) return FALSE; } -typedef GstAllocator GstEGLImageAllocator; -typedef GstAllocatorClass GstEGLImageAllocatorClass; +typedef struct _GstEGLImageAllocator GstEGLImageAllocator; +typedef struct _GstEGLImageAllocatorClass GstEGLImageAllocatorClass; + +struct _GstEGLImageAllocator +{ + GstAllocator parent; +}; + +struct _GstEGLImageAllocatorClass +{ + GstAllocatorClass parent_class; +}; GType gst_egl_image_allocator_get_type (void); G_DEFINE_TYPE (GstEGLImageAllocator, gst_egl_image_allocator, @@ -212,7 +222,7 @@ gst_egl_image_allocator_init_instance (gpointer data) return allocator; } -static GstAllocator * +static GstEGLImageAllocator * gst_egl_image_allocator_obtain (void) { static GOnce once = G_ONCE_INIT; @@ -221,7 +231,7 @@ gst_egl_image_allocator_obtain (void) g_return_val_if_fail (once.retval != NULL, NULL); - return GST_ALLOCATOR (g_object_ref (once.retval)); + return (GstEGLImageAllocator *) (g_object_ref (once.retval)); } void @@ -239,7 +249,7 @@ gst_egl_image_memory_del_gl_texture (GstGLContext * context, gpointer tex) } static GstMemory * -gst_egl_image_allocator_wrap (GstAllocator * allocator, +gst_egl_image_allocator_wrap (GstEGLImageAllocator * allocator, GstGLContextEGL * context, EGLImageKHR image, GstVideoGLTextureType type, GstMemoryFlags flags, gsize size, gpointer user_data, GstEGLImageDestroyNotify user_data_destroy) @@ -255,7 +265,7 @@ gst_egl_image_allocator_wrap (GstAllocator * allocator, mem = g_slice_new (GstEGLImageMemory); gst_memory_init (GST_MEMORY_CAST (mem), flags, - allocator, NULL, size, 0, 0, size); + GST_ALLOCATOR (allocator), NULL, size, 0, 0, size); gst_object_unref (allocator); @@ -339,12 +349,14 @@ gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info, EGLImageKHR image = EGL_NO_IMAGE_KHR; EGLClientBuffer client_buffer_tex[3] = { 0, 0, 0 }; GstVideoGLTextureType texture_types[] = { 0, 0, 0, 0 }; - GstAllocator *allocator = gst_egl_image_allocator_obtain (); + GstEGLImageAllocator *allocator = gst_egl_image_allocator_obtain (); GstGLContextEGL *context = GST_GL_CONTEXT_EGL (ctx); g_return_val_if_fail (ctx, FALSE); g_return_val_if_fail (info, FALSE); g_return_val_if_fail (buffer, FALSE); + g_return_val_if_fail (gst_gl_context_check_feature (ctx, + "EGL_KHR_image_base"), FALSE); memset (stride, 0, sizeof (stride)); memset (offset, 0, sizeof (offset)); @@ -408,7 +420,7 @@ gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info, gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, 0, stride, offset, &size, (GLuint *) & client_buffer_tex[0]); - image = eglCreateImageKHR (context->egl_display, + image = context->eglCreateImage (context->egl_display, context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[0], NULL); if (eglGetError () != EGL_SUCCESS) @@ -461,7 +473,7 @@ gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info, gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, 0, stride, offset, size, (GLuint *) & client_buffer_tex[i]); - image = eglCreateImageKHR (context->egl_display, + image = context->eglCreateImage (context->egl_display, context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[i], NULL); if (eglGetError () != EGL_SUCCESS) @@ -527,7 +539,7 @@ gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info, gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, i, stride, offset, size, (GLuint *) & client_buffer_tex[i]); - image = eglCreateImageKHR (context->egl_display, + image = context->eglCreateImage (context->egl_display, context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[i], NULL); if (eglGetError () != EGL_SUCCESS) diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.c b/gst-libs/gst/gl/egl/gstglcontext_egl.c index 06e7a9b..d3c8d96 100644 --- a/gst-libs/gst/gl/egl/gstglcontext_egl.c +++ b/gst-libs/gst/gl/egl/gstglcontext_egl.c @@ -53,6 +53,8 @@ static GstGLPlatform gst_gl_context_egl_get_gl_platform (GstGLContext * context); static gpointer gst_gl_context_egl_get_proc_address (GstGLContext * context, const gchar * name); +static gboolean gst_gl_context_egl_check_feature (GstGLContext * context, + const gchar * feature); G_DEFINE_TYPE (GstGLContextEGL, gst_gl_context_egl, GST_GL_TYPE_CONTEXT); @@ -78,6 +80,8 @@ gst_gl_context_egl_class_init (GstGLContextEGLClass * klass) GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_gl_platform); context_class->get_proc_address = GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_proc_address); + context_class->check_feature = + GST_DEBUG_FUNCPTR (gst_gl_context_egl_check_feature); } static void @@ -404,6 +408,23 @@ gst_gl_context_egl_create_context (GstGLContext * context, } } + /* EGLImage functions */ + if (GST_GL_CHECK_GL_VERSION (majorVersion, minorVersion, 1, 5)) { + egl->eglCreateImage = gst_gl_context_get_proc_address (context, + "eglCreateImage"); + egl->eglDestroyImage = gst_gl_context_get_proc_address (context, + "eglDestroyImage"); + } else if (gst_gl_check_extension ("EGL_KHR_image_base", egl_exts)) { + egl->eglCreateImage = gst_gl_context_get_proc_address (context, + "eglCreateImageKHR"); + egl->eglDestroyImage = gst_gl_context_get_proc_address (context, + "eglDestroyImageKHR"); + } + if (egl->eglCreateImage == NULL || egl->eglDestroyImage == NULL) { + egl->eglCreateImage = NULL; + egl->eglDestroyImage = NULL; + } + if (window) gst_object_unref (window); @@ -525,3 +546,16 @@ gst_gl_context_egl_get_proc_address (GstGLContext * context, const gchar * name) return result; } + +static gboolean +gst_gl_context_egl_check_feature (GstGLContext * context, const gchar * feature) +{ + GstGLContextEGL *context_egl = GST_GL_CONTEXT_EGL (context); + + if (g_strcmp0 (feature, "EGL_KHR_image_base") == 0) { + return context_egl->eglCreateImage != NULL && + context_egl->eglDestroyImage != NULL; + } + + return FALSE; +} diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.h b/gst-libs/gst/gl/egl/gstglcontext_egl.h index 5e84d3e..9601865 100644 --- a/gst-libs/gst/gl/egl/gstglcontext_egl.h +++ b/gst-libs/gst/gl/egl/gstglcontext_egl.h @@ -45,6 +45,10 @@ struct _GstGLContextEGL { EGLConfig egl_config; GstGLAPI gl_api; + + EGLImageKHR (*eglCreateImage) (EGLDisplay dpy, EGLContext ctx, EGLenum target, + EGLClientBuffer buffer, const EGLint *attrib_list); + EGLBoolean (*eglDestroyImage) (EGLDisplay dpy, EGLImageKHR image); }; struct _GstGLContextEGLClass { diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c index 2193d21..50db294 100644 --- a/gst-libs/gst/gl/gstglfilter.c +++ b/gst-libs/gst/gl/gstglfilter.c @@ -890,9 +890,11 @@ gst_gl_filter_propose_allocation (GstBaseTransform * trans, gst_object_unref (allocator); #if GST_GL_HAVE_PLATFORM_EGL - allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE); - gst_query_add_allocation_param (query, allocator, ¶ms); - gst_object_unref (allocator); + if (gst_gl_context_check_feature (filter->context, "EGL_KHR_image_base")) { + allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE); + gst_query_add_allocation_param (query, allocator, ¶ms); + gst_object_unref (allocator); + } #endif return TRUE;