summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2016-11-17 02:41:14 +1100
committerMatthew Waters <matthew@centricular.com>2016-11-17 14:06:21 +1100
commit8c2118823b3d42840cc6f48cbdc0e1b342f90b80 (patch)
treea2df2330ff70f0ec31fc2a9e379e62f6c9879b49 /gst-libs
parentf2e9190229094cd5b329dfb12aa8cd6468c19cbc (diff)
gl/egl: remove EGLImage functions from egl context
By adding the necessary GstEGLImage entry points to create a GstEGLImage from a GstGLMemory. https://bugzilla.gnome.org/show_bug.cgi?id=774518
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/gl/egl/gsteglimage.c250
-rw-r--r--gst-libs/gst/gl/egl/gsteglimage.h7
-rw-r--r--gst-libs/gst/gl/egl/gstglcontext_egl.c31
-rw-r--r--gst-libs/gst/gl/egl/gstglcontext_egl.h6
-rw-r--r--gst-libs/gst/gl/egl/gstglmemoryegl.c20
5 files changed, 194 insertions, 120 deletions
diff --git a/gst-libs/gst/gl/egl/gsteglimage.c b/gst-libs/gst/gl/egl/gsteglimage.c
index cc6c4bdae..24dacdc33 100644
--- a/gst-libs/gst/gl/egl/gsteglimage.c
+++ b/gst-libs/gst/gl/egl/gsteglimage.c
@@ -39,6 +39,7 @@
#endif
#include "gsteglimage.h"
+#include <gst/gl/egl/gstgldisplay_egl.h>
#include <string.h>
#if GST_GL_HAVE_DMABUF
@@ -176,7 +177,8 @@ gst_egl_image_new_wrapped (GstGLContext * context, EGLImageKHR image,
GstEGLImage *img = NULL;
g_return_val_if_fail (context != NULL, NULL);
- g_return_val_if_fail (GST_IS_GL_CONTEXT_EGL (context), NULL);
+ g_return_val_if_fail ((gst_gl_context_get_gl_platform (context) &
+ GST_GL_PLATFORM_EGL) != 0, NULL);
g_return_val_if_fail (image != EGL_NO_IMAGE_KHR, NULL);
img = g_new0 (GstEGLImage, 1);
@@ -195,6 +197,165 @@ gst_egl_image_new_wrapped (GstGLContext * context, EGLImageKHR image,
return img;
}
+static EGLImageKHR
+_gst_egl_image_create (GstGLContext * context, guint target,
+ EGLClientBuffer buffer, guintptr * attribs)
+{
+ EGLDisplay egl_display = EGL_DEFAULT_DISPLAY;
+ EGLContext egl_context = EGL_NO_CONTEXT;
+ EGLImageKHR img = EGL_NO_IMAGE_KHR;
+ GstGLDisplayEGL *display_egl;
+ gint plat_major, plat_minor;
+ guint attrib_len = 0;
+
+ gst_gl_context_get_gl_platform_version (context, &plat_major, &plat_minor);
+
+ display_egl = gst_gl_display_egl_from_gl_display (context->display);
+ if (!display_egl) {
+ GST_WARNING_OBJECT (context, "Failed to retrieve GstGLDisplayEGL from %"
+ GST_PTR_FORMAT, context->display);
+ return EGL_NO_IMAGE_KHR;
+ }
+ egl_display =
+ (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (display_egl));
+ gst_object_unref (display_egl);
+
+#if GST_GL_HAVE_DMABUF
+ if (target != EGL_LINUX_DMA_BUF_EXT)
+ egl_context = (EGLContext) gst_gl_context_get_gl_context (context);
+#endif
+
+ if (attribs)
+ while (attribs[attrib_len++] != EGL_NONE) {
+ }
+#ifdef EGL_VERSION_1_5
+ if (GST_GL_CHECK_GL_VERSION (plat_major, plat_minor, 1, 5)) {
+ EGLImageKHR (*gst_eglCreateImage) (EGLDisplay dpy, EGLContext ctx,
+ EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list);
+ EGLAttrib *egl_attribs = NULL;
+ guint i;
+
+ gst_eglCreateImage = gst_gl_context_get_proc_address (context,
+ "eglCreateImage");
+ if (!gst_eglCreateImage) {
+ GST_ERROR_OBJECT (context, "\"eglCreateImage\" not exposed by the "
+ "implementation as required by EGL >= 1.5");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ if (attribs) {
+ egl_attribs = g_new0 (EGLAttrib, attrib_len);
+ for (i = 0; i < attrib_len; i++)
+ egl_attribs[i] = (EGLAttrib) attribs[i];
+ }
+
+ img = gst_eglCreateImage (egl_display, egl_context, target, buffer,
+ egl_attribs);
+
+ g_free (egl_attribs);
+ } else
+#endif
+ {
+ EGLImageKHR (*gst_eglCreateImageKHR) (EGLDisplay dpy, EGLContext ctx,
+ EGLenum target, EGLClientBuffer buffer, const EGLint * attrib_list);
+ EGLint *egl_attribs = NULL;
+ gint i;
+
+ gst_eglCreateImageKHR = gst_gl_context_get_proc_address (context,
+ "eglCreateImageKHR");
+ if (!gst_eglCreateImageKHR) {
+ GST_WARNING_OBJECT (context, "\"eglCreateImageKHR\" not exposed by the "
+ "implementation");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ if (attribs) {
+ egl_attribs = g_new0 (EGLint, attrib_len);
+ for (i = 0; i < attrib_len; i++)
+ egl_attribs[i] = (EGLint) attribs[i];
+ }
+
+ img = gst_eglCreateImageKHR (egl_display, egl_context, target, buffer,
+ egl_attribs);
+
+ g_free (egl_attribs);
+ }
+
+ return img;
+}
+
+static void
+_gst_egl_image_destroy (GstGLContext * context, EGLImageKHR image)
+{
+ EGLBoolean (*gst_eglDestroyImage) (EGLDisplay dpy, EGLImageKHR image);
+ EGLDisplay egl_display = EGL_DEFAULT_DISPLAY;
+ GstGLDisplayEGL *display_egl;
+
+ gst_eglDestroyImage = gst_gl_context_get_proc_address (context,
+ "eglDestroyImage");
+ if (!gst_eglDestroyImage) {
+ gst_eglDestroyImage = gst_gl_context_get_proc_address (context,
+ "eglDestroyImageKHR");
+ if (!gst_eglDestroyImage) {
+ GST_ERROR_OBJECT (context, "\"eglDestroyImage\" not exposed by the "
+ "implementation");
+ return;
+ }
+ }
+
+ display_egl = gst_gl_display_egl_from_gl_display (context->display);
+ if (!display_egl) {
+ GST_WARNING_OBJECT (context, "Failed to retrieve GstGLDisplayEGL from %"
+ GST_PTR_FORMAT, context->display);
+ return;
+ }
+ egl_display =
+ (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (display_egl));
+ gst_object_unref (display_egl);
+
+ if (!gst_eglDestroyImage (egl_display, image))
+ GST_WARNING_OBJECT (context, "eglDestroyImage failed");
+}
+
+static void
+_destroy_egl_image (GstEGLImage * image, gpointer user_data)
+{
+ _gst_egl_image_destroy (image->context, image->image);
+}
+
+/**
+ * gst_egl_image_from_texture:
+ * @context: a #GstGLContext (must be an EGL context)
+ * @gl_mem: a #GstGLMemory
+ * @attribs: additional attributes to add to the eglCreateImage() call.
+ *
+ * Returns: (transfer full): a #GstEGLImage wrapping @gl_mem or %NULL on failure
+ */
+GstEGLImage *
+gst_egl_image_from_texture (GstGLContext * context, GstGLMemory * gl_mem,
+ guintptr * attribs)
+{
+ EGLenum egl_target;
+ EGLImageKHR img;
+
+ if (gl_mem->tex_target != GST_GL_TEXTURE_TARGET_2D) {
+ GST_FIXME_OBJECT (context, "Only know how to create EGLImage's from 2D "
+ "textures");
+ return NULL;
+ }
+
+ egl_target = EGL_GL_TEXTURE_2D_KHR;
+
+ img = _gst_egl_image_create (context, egl_target,
+ (EGLClientBuffer) (guintptr) gl_mem->tex_id, attribs);
+ if (!img)
+ return NULL;
+
+ return gst_egl_image_new_wrapped (context, img, gl_mem->tex_type,
+ GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL,
+ NULL, (GstEGLImageDestroyNotify) _destroy_egl_image);
+}
+
#if GST_GL_HAVE_DMABUF
/*
* GStreamer format descriptions differ from DRM formats as the representation
@@ -266,12 +427,6 @@ _drm_fourcc_from_info (GstVideoInfo * info, int plane)
}
}
-static void
-_destroy_egl_image (GstEGLImage * image, gpointer user_data)
-{
- image->context->eglDestroyImage (image->context->egl_display, image->image);
-}
-
/**
* gst_egl_image_from_dmabuf:
* @context: a #GstGLContext (must be an EGL context)
@@ -286,15 +441,11 @@ GstEGLImage *
gst_egl_image_from_dmabuf (GstGLContext * context,
gint dmabuf, GstVideoInfo * in_info, gint plane, gsize offset)
{
- GstGLContextEGL *ctx_egl = GST_GL_CONTEXT_EGL (context);
- gint fourcc;
- gint atti = 0;
- EGLint attribs[13];
-#ifdef EGL_VERSION_1_5
- EGLAttrib attribs_1_5[13];
-#endif
- EGLImageKHR img = EGL_NO_IMAGE_KHR;
GstVideoGLTextureType type;
+ guintptr attribs[13];
+ EGLImageKHR img;
+ gint atti = 0;
+ gint fourcc;
fourcc = _drm_fourcc_from_info (in_info, plane);
type =
@@ -306,55 +457,26 @@ gst_egl_image_from_dmabuf (GstGLContext * context,
GST_VIDEO_INFO_COMP_WIDTH (in_info, plane),
GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane));
-#ifdef EGL_VERSION_1_5
- if (GST_GL_CHECK_GL_VERSION (ctx_egl->egl_major, ctx_egl->egl_minor, 1, 5)) {
- attribs_1_5[atti++] = EGL_WIDTH;
- attribs_1_5[atti++] = GST_VIDEO_INFO_COMP_WIDTH (in_info, plane);
- attribs_1_5[atti++] = EGL_HEIGHT;
- attribs_1_5[atti++] = GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane);
- attribs_1_5[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
- attribs_1_5[atti++] = fourcc;
- attribs_1_5[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
- attribs_1_5[atti++] = dmabuf;
- attribs_1_5[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
- attribs_1_5[atti++] = offset;
- attribs_1_5[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
- attribs_1_5[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, plane);
- attribs_1_5[atti] = EGL_NONE;
-
- for (int i = 0; i < atti; i++)
- GST_LOG ("attr %i: %" G_GINTPTR_FORMAT, i, attribs_1_5[i]);
-
- g_assert (atti == 12);
-
- img = ctx_egl->eglCreateImage (ctx_egl->egl_display, EGL_NO_CONTEXT,
- EGL_LINUX_DMA_BUF_EXT, NULL, attribs_1_5);
-
- } else
-#endif
- {
- attribs[atti++] = EGL_WIDTH;
- attribs[atti++] = GST_VIDEO_INFO_COMP_WIDTH (in_info, plane);
- attribs[atti++] = EGL_HEIGHT;
- attribs[atti++] = GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane);
- attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
- attribs[atti++] = fourcc;
- attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
- attribs[atti++] = dmabuf;
- attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
- attribs[atti++] = offset;
- attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
- attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, plane);
- attribs[atti] = EGL_NONE;
-
- for (int i = 0; i < atti; i++)
- GST_LOG ("attr %i: %08X", i, attribs[i]);
-
- g_assert (atti == 12);
-
- img = ctx_egl->eglCreateImageKHR (ctx_egl->egl_display, EGL_NO_CONTEXT,
- EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
- }
+ attribs[atti++] = EGL_WIDTH;
+ attribs[atti++] = GST_VIDEO_INFO_COMP_WIDTH (in_info, plane);
+ attribs[atti++] = EGL_HEIGHT;
+ attribs[atti++] = GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane);
+ attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
+ attribs[atti++] = fourcc;
+ attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
+ attribs[atti++] = dmabuf;
+ attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
+ attribs[atti++] = offset;
+ attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
+ attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, plane);
+ attribs[atti] = EGL_NONE;
+
+ for (int i = 0; i < atti; i++)
+ GST_LOG ("attr %i: %" G_GINTPTR_FORMAT, i, attribs[i]);
+
+ g_assert (atti == 12);
+
+ img = _gst_egl_image_create (context, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
if (!img) {
GST_WARNING ("eglCreateImage failed: %s",
gst_egl_get_error_string (eglGetError ()));
diff --git a/gst-libs/gst/gl/egl/gsteglimage.h b/gst-libs/gst/gl/egl/gsteglimage.h
index 46ee4ffdc..0b93e1007 100644
--- a/gst-libs/gst/gl/egl/gsteglimage.h
+++ b/gst-libs/gst/gl/egl/gsteglimage.h
@@ -27,7 +27,7 @@
#include <gst/video/video.h>
#include <gst/gl/gl.h>
-#include <gst/gl/egl/gstglcontext_egl.h>
+#include <gst/gl/egl/gstegl.h>
G_BEGIN_DECLS
@@ -51,7 +51,7 @@ struct _GstEGLImage
{
GstMiniObject parent;
- GstGLContextEGL *context;
+ GstGLContext *context;
EGLImageKHR image;
GstVideoGLTextureType type;
/* FIXME: remove this and use the affine transformation meta instead */
@@ -73,6 +73,9 @@ GstEGLImage * gst_egl_image_new_wrapped (GstGLContext *
EGLImageKHR gst_egl_image_get_image (GstEGLImage * image);
GstVideoGLTextureOrientation gst_egl_image_get_orientation (GstEGLImage * image);
+GstEGLImage * gst_egl_image_from_texture (GstGLContext * context,
+ GstGLMemory * gl_mem,
+ guintptr * attribs);
#if GST_GL_HAVE_DMABUF
GstEGLImage * gst_egl_image_from_dmabuf (GstGLContext * context,
gint dmabuf,
diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.c b/gst-libs/gst/gl/egl/gstglcontext_egl.c
index 78c14a367..25cd8a8d7 100644
--- a/gst-libs/gst/gl/egl/gstglcontext_egl.c
+++ b/gst-libs/gst/gl/egl/gstglcontext_egl.c
@@ -557,27 +557,6 @@ gst_gl_context_egl_create_context (GstGLContext * context,
goto failure;
}
}
-
- /* EGLImage functions */
- if (GST_GL_CHECK_GL_VERSION (egl_major, egl_minor, 1, 5)) {
- egl->eglCreateImage = gst_gl_context_get_proc_address (context,
- "eglCreateImage");
- egl->eglDestroyImage = gst_gl_context_get_proc_address (context,
- "eglDestroyImage");
- if (egl->eglCreateImage == NULL || egl->eglDestroyImage == NULL) {
- egl->eglCreateImage = NULL;
- egl->eglDestroyImage = NULL;
- }
- } else if (gst_gl_check_extension ("EGL_KHR_image_base", egl->egl_exts)) {
- egl->eglCreateImageKHR = gst_gl_context_get_proc_address (context,
- "eglCreateImageKHR");
- egl->eglDestroyImage = gst_gl_context_get_proc_address (context,
- "eglDestroyImageKHR");
- if (egl->eglCreateImageKHR == NULL || egl->eglDestroyImage == NULL) {
- egl->eglCreateImageKHR = NULL;
- egl->eglDestroyImage = NULL;
- }
- }
egl->egl_major = egl_major;
egl->egl_minor = egl_minor;
@@ -787,16 +766,6 @@ 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) {
- if (GST_GL_CHECK_GL_VERSION (context_egl->egl_major, context_egl->egl_minor,
- 1, 5))
- return context_egl->eglCreateImage != NULL
- && context_egl->eglDestroyImage != NULL;
- else
- return context_egl->eglCreateImageKHR != NULL &&
- context_egl->eglDestroyImage != NULL;
- }
-
return gst_gl_check_extension (feature, context_egl->egl_exts);
}
diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.h b/gst-libs/gst/gl/egl/gstglcontext_egl.h
index e85126180..32293a5e4 100644
--- a/gst-libs/gst/gl/egl/gstglcontext_egl.h
+++ b/gst-libs/gst/gl/egl/gstglcontext_egl.h
@@ -68,12 +68,6 @@ struct _GstGLContextEGL
const gchar *egl_exts;
- EGLImageKHR (*eglCreateImageKHR) (EGLDisplay dpy, EGLContext ctx, EGLenum target,
- EGLClientBuffer buffer, const EGLint *attrib_list);
- EGLImageKHR (*eglCreateImage) (EGLDisplay dpy, EGLContext ctx, EGLenum target,
- EGLClientBuffer buffer, const EGLAttrib *attrib_list);
- EGLBoolean (*eglDestroyImage) (EGLDisplay dpy, EGLImageKHR image);
-
/* Cached handle */
EGLNativeWindowType window_handle;
};
diff --git a/gst-libs/gst/gl/egl/gstglmemoryegl.c b/gst-libs/gst/gl/egl/gstglmemoryegl.c
index 3cd194140..fd7d25c60 100644
--- a/gst-libs/gst/gl/egl/gstglmemoryegl.c
+++ b/gst-libs/gst/gl/egl/gstglmemoryegl.c
@@ -174,17 +174,10 @@ _gl_mem_egl_alloc (GstGLBaseMemoryAllocator * allocator,
return mem;
}
-static void
-_destroy_egl_image (GstEGLImage * image, gpointer user_data)
-{
- image->context->eglDestroyImage (image->context->egl_display, image->image);
-}
-
static gboolean
_gl_mem_create (GstGLMemoryEGL * gl_mem, GError ** error)
{
GstGLContext *context = gl_mem->mem.mem.context;
- GstGLContextEGL *ctx_egl = GST_GL_CONTEXT_EGL (context);
const GstGLFuncs *gl = context->gl_vtable;
GstGLBaseMemoryAllocatorClass *alloc_class;
@@ -200,21 +193,14 @@ _gl_mem_create (GstGLMemoryEGL * gl_mem, GError ** error)
return FALSE;
if (gl_mem->image == NULL) {
- EGLImageKHR image = ctx_egl->eglCreateImageKHR (ctx_egl->egl_display,
- ctx_egl->egl_context, EGL_GL_TEXTURE_2D_KHR,
- (EGLClientBuffer) (guintptr) gl_mem->mem.tex_id, NULL);
-
- GST_TRACE ("Generating EGLImage handle:%p from a texture:%u",
- gl_mem->image, gl_mem->mem.tex_id);
+ gl_mem->image = gst_egl_image_from_texture (context,
+ (GstGLMemory *) gl_mem, NULL);
- if (eglGetError () != EGL_SUCCESS) {
+ if (!gl_mem->image) {
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
"Failed to create EGLImage");
return FALSE;
}
-
- gl_mem->image = gst_egl_image_new_wrapped (context, image, 0, 0,
- NULL, (GstEGLImageDestroyNotify) _destroy_egl_image);
} else {
gl->ActiveTexture (GL_TEXTURE0 + gl_mem->mem.plane);
gl->BindTexture (GL_TEXTURE_2D, gl_mem->mem.tex_id);