From 359e361881ba7b24633f17f0b96f3ac99d527fdd Mon Sep 17 00:00:00 2001
From: Philipp Zabel
Date: Thu, 13 Feb 2020 10:28:40 +0100
Subject: [PATCH] gl/egl: support direct dmabuf import with external-oes only
formats
Allow creating EGL images from DMA buffers in formats that the driver
only supports for the external-oes texture target.
Pass the intended texture target to gst_egl_image_from_dmabuf_direct so
that _gst_egl_image_check_dmabuf_direct can decide whether to create an
EGL image for a format that can only be targeted at external-oes
textures by the driver. Allow creating GstGLMemoryEGL objects from these
DMA buffers.
---
gst-libs/gst/gl/egl/gsteglimage.c | 44 +++++++++++++++++++++++++++++++-----
gst-libs/gst/gl/egl/gsteglimage.h | 6 +++++
gst-libs/gst/gl/egl/gstglmemoryegl.c | 12 ++++++----
3 files changed, 52 insertions(+), 10 deletions(-)
diff --git a/gst-libs/gst/gl/egl/gsteglimage.c b/gst-libs/gst/gl/egl/gsteglimage.c
index 43904be..246904f 100644
--- a/gst-libs/gst/gl/egl/gsteglimage.c
+++ b/gst-libs/gst/gl/egl/gsteglimage.c
@@ -714,7 +714,8 @@ _drm_direct_fourcc_from_info (GstVideoInfo * info)
}
static gboolean
-_gst_egl_image_check_dmabuf_direct (GstGLContext * context, int fourcc)
+_gst_egl_image_check_dmabuf_direct (GstGLContext * context, int fourcc,
+ GstGLTextureTarget target)
{
EGLDisplay egl_display = EGL_DEFAULT_DISPLAY;
GstGLDisplayEGL *display_egl;
@@ -800,7 +801,7 @@ _gst_egl_image_check_dmabuf_direct (GstGLContext * context, int fourcc)
GST_DEBUG ("driver only supports external import of fourcc %"
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
}
- ret = !external_only[i];
+ ret = !external_only[i] || (target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES);
g_free (modifiers);
g_free (external_only);
return ret;
@@ -814,11 +815,12 @@ _gst_egl_image_check_dmabuf_direct (GstGLContext * context, int fourcc)
}
/**
- * gst_egl_image_from_dmabuf_direct:
+ * gst_egl_image_from_dmabuf_direct_target:
* @context: a #GstGLContext (must be an EGL context)
* @fd: Array of DMABuf file descriptors
* @offset: Array of offsets, relative to the DMABuf
* @in_info: the #GstVideoInfo
+ * @target: GL texture target this GstEGLImage is intended for
*
* Creates an EGL image that imports the dmabuf FD. The dmabuf data
* is passed directly as the format described in in_info. This is
@@ -831,10 +833,13 @@ _gst_egl_image_check_dmabuf_direct (GstGLContext * context, int fourcc)
* a single plane.
*
* Returns: a #GstEGLImage wrapping @dmabuf or %NULL on failure
+ *
+ * Since: 1.18
*/
GstEGLImage *
-gst_egl_image_from_dmabuf_direct (GstGLContext * context,
- gint * fd, gsize * offset, GstVideoInfo * in_info)
+gst_egl_image_from_dmabuf_direct_target (GstGLContext * context,
+ gint * fd, gsize * offset, GstVideoInfo * in_info,
+ GstGLTextureTarget target)
{
EGLImageKHR img;
@@ -856,7 +861,7 @@ gst_egl_image_from_dmabuf_direct (GstGLContext * context,
if (fourcc == -1)
return NULL;
- if (!_gst_egl_image_check_dmabuf_direct (context, fourcc))
+ if (!_gst_egl_image_check_dmabuf_direct (context, fourcc, target))
return NULL;
with_modifiers = gst_gl_context_check_feature (context,
@@ -980,6 +985,33 @@ gst_egl_image_from_dmabuf_direct (GstGLContext * context,
(GstEGLImageDestroyNotify) _destroy_egl_image);
}
+/**
+ * gst_egl_image_from_dmabuf_direct:
+ * @context: a #GstGLContext (must be an EGL context)
+ * @fd: Array of DMABuf file descriptors
+ * @offset: Array of offsets, relative to the DMABuf
+ * @in_info: the #GstVideoInfo
+ *
+ * Creates an EGL image that imports the dmabuf FD. The dmabuf data
+ * is passed directly as the format described in in_info. This is
+ * useful if the hardware is capable of performing color space conversions
+ * internally. The appropriate DRM format is picked, and the EGL image
+ * is created with this DRM format.
+ *
+ * Another notable difference to gst_egl_image_from_dmabuf()
+ * is that this function creates one EGL image for all planes, not one for
+ * a single plane.
+ *
+ * Returns: a #GstEGLImage wrapping @dmabuf or %NULL on failure
+ */
+GstEGLImage *
+gst_egl_image_from_dmabuf_direct (GstGLContext * context,
+ gint * fd, gsize * offset, GstVideoInfo * in_info)
+{
+ return gst_egl_image_from_dmabuf_direct_target (context, fd, offset, in_info,
+ GST_GL_TEXTURE_TARGET_2D);
+}
+
gboolean
gst_egl_image_export_dmabuf (GstEGLImage * image, int *fd, gint * stride,
gsize * offset)
diff --git a/gst-libs/gst/gl/egl/gsteglimage.h b/gst-libs/gst/gl/egl/gsteglimage.h
index 776a6b0..6aa56a4 100644
--- a/gst-libs/gst/gl/egl/gsteglimage.h
+++ b/gst-libs/gst/gl/egl/gsteglimage.h
@@ -93,6 +93,12 @@ GstEGLImage * gst_egl_image_from_dmabuf_direct (GstGLContext *
gint *fd,
gsize *offset,
GstVideoInfo * in_info);
+GST_GL_API
+GstEGLImage * gst_egl_image_from_dmabuf_direct_target (GstGLContext * context,
+ gint *fd,
+ gsize *offset,
+ GstVideoInfo * in_info,
+ GstGLTextureTarget target);
GST_GL_API
gboolean gst_egl_image_export_dmabuf (GstEGLImage *image, int *fd, gint *stride, gsize *offset);
diff --git a/gst-libs/gst/gl/egl/gstglmemoryegl.c b/gst-libs/gst/gl/egl/gstglmemoryegl.c
index 341c79e..84b07c9 100644
--- a/gst-libs/gst/gl/egl/gstglmemoryegl.c
+++ b/gst-libs/gst/gl/egl/gstglmemoryegl.c
@@ -147,12 +147,14 @@ _gl_mem_egl_alloc (GstGLBaseMemoryAllocator * allocator,
mem = g_new0 (GstGLMemoryEGL, 1);
if (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) {
- if (params->target != GST_GL_TEXTURE_TARGET_2D) {
+ if (params->target != GST_GL_TEXTURE_TARGET_2D &&
+ params->target != GST_GL_TEXTURE_TARGET_EXTERNAL_OES) {
g_free (mem);
GST_CAT_ERROR (GST_CAT_GL_MEMORY, "GstGLMemoryEGL only supports wrapping "
- "2D textures");
+ "2D and external-oes textures");
return NULL;
}
+ mem->mem.tex_target = params->target;
mem->image = gst_egl_image_ref (params->parent.gl_handle);
}
@@ -197,9 +199,11 @@ _gl_mem_create (GstGLMemoryEGL * gl_mem, GError ** error)
return FALSE;
}
} else {
+ guint gl_target = gst_gl_texture_target_to_gl (gl_mem->mem.tex_target);
+
gl->ActiveTexture (GL_TEXTURE0 + gl_mem->mem.plane);
- gl->BindTexture (GL_TEXTURE_2D, gl_mem->mem.tex_id);
- gl->EGLImageTargetTexture2D (GL_TEXTURE_2D,
+ gl->BindTexture (gl_target, gl_mem->mem.tex_id);
+ gl->EGLImageTargetTexture2D (gl_target,
gst_egl_image_get_image (GST_EGL_IMAGE (gl_mem->image)));
}
--
2.7.4