mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
gl/eglimage: add eglimage context feature
Allows us to selectively use EGLImages only when available https://bugzilla.gnome.org/show_bug.cgi?id=728234
This commit is contained in:
parent
b30023f571
commit
37c08c58c5
5 changed files with 72 additions and 17 deletions
|
@ -933,9 +933,12 @@ gst_glimage_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
|
||||||
gst_object_unref (allocator);
|
gst_object_unref (allocator);
|
||||||
|
|
||||||
#if GST_GL_HAVE_PLATFORM_EGL
|
#if GST_GL_HAVE_PLATFORM_EGL
|
||||||
allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
|
if (gst_gl_context_check_feature (glimage_sink->context,
|
||||||
gst_query_add_allocation_param (query, allocator, ¶ms);
|
"EGL_KHR_image_base")) {
|
||||||
gst_object_unref (allocator);
|
allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
|
||||||
|
gst_query_add_allocation_param (query, allocator, ¶ms);
|
||||||
|
gst_object_unref (allocator);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -122,7 +122,7 @@ gst_egl_image_allocator_free_vfunc (GstAllocator * allocator, GstMemory * mem)
|
||||||
|
|
||||||
/* Shared memory should not destroy all the data */
|
/* Shared memory should not destroy all the data */
|
||||||
if (!mem->parent) {
|
if (!mem->parent) {
|
||||||
eglDestroyImageKHR (emem->context->egl_display, emem->image);
|
emem->context->eglDestroyImage (emem->context->egl_display, emem->image);
|
||||||
|
|
||||||
if (emem->user_data_destroy)
|
if (emem->user_data_destroy)
|
||||||
emem->user_data_destroy (emem->context, emem->user_data);
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef GstAllocator GstEGLImageAllocator;
|
typedef struct _GstEGLImageAllocator GstEGLImageAllocator;
|
||||||
typedef GstAllocatorClass GstEGLImageAllocatorClass;
|
typedef struct _GstEGLImageAllocatorClass GstEGLImageAllocatorClass;
|
||||||
|
|
||||||
|
struct _GstEGLImageAllocator
|
||||||
|
{
|
||||||
|
GstAllocator parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstEGLImageAllocatorClass
|
||||||
|
{
|
||||||
|
GstAllocatorClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
GType gst_egl_image_allocator_get_type (void);
|
GType gst_egl_image_allocator_get_type (void);
|
||||||
G_DEFINE_TYPE (GstEGLImageAllocator, gst_egl_image_allocator,
|
G_DEFINE_TYPE (GstEGLImageAllocator, gst_egl_image_allocator,
|
||||||
|
@ -212,7 +222,7 @@ gst_egl_image_allocator_init_instance (gpointer data)
|
||||||
return allocator;
|
return allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstAllocator *
|
static GstEGLImageAllocator *
|
||||||
gst_egl_image_allocator_obtain (void)
|
gst_egl_image_allocator_obtain (void)
|
||||||
{
|
{
|
||||||
static GOnce once = G_ONCE_INIT;
|
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);
|
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
|
void
|
||||||
|
@ -239,7 +249,7 @@ gst_egl_image_memory_del_gl_texture (GstGLContext * context, gpointer tex)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstMemory *
|
static GstMemory *
|
||||||
gst_egl_image_allocator_wrap (GstAllocator * allocator,
|
gst_egl_image_allocator_wrap (GstEGLImageAllocator * allocator,
|
||||||
GstGLContextEGL * context, EGLImageKHR image, GstVideoGLTextureType type,
|
GstGLContextEGL * context, EGLImageKHR image, GstVideoGLTextureType type,
|
||||||
GstMemoryFlags flags, gsize size, gpointer user_data,
|
GstMemoryFlags flags, gsize size, gpointer user_data,
|
||||||
GstEGLImageDestroyNotify user_data_destroy)
|
GstEGLImageDestroyNotify user_data_destroy)
|
||||||
|
@ -255,7 +265,7 @@ gst_egl_image_allocator_wrap (GstAllocator * allocator,
|
||||||
|
|
||||||
mem = g_slice_new (GstEGLImageMemory);
|
mem = g_slice_new (GstEGLImageMemory);
|
||||||
gst_memory_init (GST_MEMORY_CAST (mem), flags,
|
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);
|
gst_object_unref (allocator);
|
||||||
|
|
||||||
|
@ -339,12 +349,14 @@ gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info,
|
||||||
EGLImageKHR image = EGL_NO_IMAGE_KHR;
|
EGLImageKHR image = EGL_NO_IMAGE_KHR;
|
||||||
EGLClientBuffer client_buffer_tex[3] = { 0, 0, 0 };
|
EGLClientBuffer client_buffer_tex[3] = { 0, 0, 0 };
|
||||||
GstVideoGLTextureType texture_types[] = { 0, 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);
|
GstGLContextEGL *context = GST_GL_CONTEXT_EGL (ctx);
|
||||||
|
|
||||||
g_return_val_if_fail (ctx, FALSE);
|
g_return_val_if_fail (ctx, FALSE);
|
||||||
g_return_val_if_fail (info, FALSE);
|
g_return_val_if_fail (info, FALSE);
|
||||||
g_return_val_if_fail (buffer, 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 (stride, 0, sizeof (stride));
|
||||||
memset (offset, 0, sizeof (offset));
|
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,
|
gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, 0, stride,
|
||||||
offset, &size, (GLuint *) & client_buffer_tex[0]);
|
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],
|
context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[0],
|
||||||
NULL);
|
NULL);
|
||||||
if (eglGetError () != EGL_SUCCESS)
|
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,
|
gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, 0,
|
||||||
stride, offset, size, (GLuint *) & client_buffer_tex[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],
|
context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[i],
|
||||||
NULL);
|
NULL);
|
||||||
if (eglGetError () != EGL_SUCCESS)
|
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,
|
gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, i,
|
||||||
stride, offset, size, (GLuint *) & client_buffer_tex[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],
|
context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[i],
|
||||||
NULL);
|
NULL);
|
||||||
if (eglGetError () != EGL_SUCCESS)
|
if (eglGetError () != EGL_SUCCESS)
|
||||||
|
|
|
@ -53,6 +53,8 @@ static GstGLPlatform gst_gl_context_egl_get_gl_platform (GstGLContext *
|
||||||
context);
|
context);
|
||||||
static gpointer gst_gl_context_egl_get_proc_address (GstGLContext * context,
|
static gpointer gst_gl_context_egl_get_proc_address (GstGLContext * context,
|
||||||
const gchar * name);
|
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);
|
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);
|
GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_gl_platform);
|
||||||
context_class->get_proc_address =
|
context_class->get_proc_address =
|
||||||
GST_DEBUG_FUNCPTR (gst_gl_context_egl_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
|
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)
|
if (window)
|
||||||
gst_object_unref (window);
|
gst_object_unref (window);
|
||||||
|
|
||||||
|
@ -525,3 +546,16 @@ gst_gl_context_egl_get_proc_address (GstGLContext * context, const gchar * name)
|
||||||
|
|
||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,10 @@ struct _GstGLContextEGL {
|
||||||
EGLConfig egl_config;
|
EGLConfig egl_config;
|
||||||
|
|
||||||
GstGLAPI gl_api;
|
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 {
|
struct _GstGLContextEGLClass {
|
||||||
|
|
|
@ -890,9 +890,11 @@ gst_gl_filter_propose_allocation (GstBaseTransform * trans,
|
||||||
gst_object_unref (allocator);
|
gst_object_unref (allocator);
|
||||||
|
|
||||||
#if GST_GL_HAVE_PLATFORM_EGL
|
#if GST_GL_HAVE_PLATFORM_EGL
|
||||||
allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
|
if (gst_gl_context_check_feature (filter->context, "EGL_KHR_image_base")) {
|
||||||
gst_query_add_allocation_param (query, allocator, ¶ms);
|
allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
|
||||||
gst_object_unref (allocator);
|
gst_query_add_allocation_param (query, allocator, ¶ms);
|
||||||
|
gst_object_unref (allocator);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in a new issue