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 43904be40c..246904fdfc 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 776a6b0f39..6aa56a4b11 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 341c79e485..84b07c99c9 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))); }