diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c index ea49e266b1..758177b664 100644 --- a/ext/gl/gstglimagesink.c +++ b/ext/gl/gstglimagesink.c @@ -94,10 +94,6 @@ #include "gstglimagesink.h" #include "gstglsinkbin.h" -#if GST_GL_HAVE_PLATFORM_EGL -#include -#endif - #include GST_DEBUG_CATEGORY (gst_debug_glimage_sink); diff --git a/ext/gl/gstglmixer.c b/ext/gl/gstglmixer.c index 3fc7fce2c8..764a53c33e 100644 --- a/ext/gl/gstglmixer.c +++ b/ext/gl/gstglmixer.c @@ -28,10 +28,6 @@ #include "gstglmixer.h" -#if GST_GL_HAVE_PLATFORM_EGL -#include -#endif - #define gst_gl_mixer_parent_class parent_class G_DEFINE_ABSTRACT_TYPE (GstGLMixer, gst_gl_mixer, GST_TYPE_GL_BASE_MIXER); diff --git a/ext/gl/gstglstereosplit.c b/ext/gl/gstglstereosplit.c index 5a1f574cfe..1eaa440b22 100644 --- a/ext/gl/gstglstereosplit.c +++ b/ext/gl/gstglstereosplit.c @@ -38,10 +38,6 @@ #include "gstglstereosplit.h" -#if GST_GL_HAVE_PLATFORM_EGL -#include -#endif - #define GST_CAT_DEFAULT gst_gl_stereosplit_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); diff --git a/gst-libs/gst/gl/egl/Makefile.am b/gst-libs/gst/gl/egl/Makefile.am index 878f16cbaa..e164eb0301 100644 --- a/gst-libs/gst/gl/egl/Makefile.am +++ b/gst-libs/gst/gl/egl/Makefile.am @@ -6,7 +6,7 @@ libgstgl_egl_la_SOURCES = \ gstgldisplay_egl.c \ gstglcontext_egl.c \ gstglmemoryegl.c \ - gsteglimagememory.c + gsteglimage.c noinst_HEADERS = @@ -15,7 +15,7 @@ libgstgl_eglinclude_HEADERS = \ gstgldisplay_egl.h \ gstglcontext_egl.h \ gstglmemoryegl.h \ - gsteglimagememory.h \ + gsteglimage.h \ gstegl.h libgstgl_egl_la_CFLAGS = \ diff --git a/gst-libs/gst/gl/egl/gsteglimage.c b/gst-libs/gst/gl/egl/gsteglimage.c new file mode 100644 index 0000000000..7e6dfd642d --- /dev/null +++ b/gst-libs/gst/gl/egl/gsteglimage.c @@ -0,0 +1,291 @@ +/* + * GStreamer + * Copyright (C) 2012 Collabora Ltd. + * @author: Sebastian Dröge + * Copyright (C) 2014 Julien Isorce + * Copyright (C) 2016 Matthew Waters + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gsteglimage.h" +#include + +#if GST_GL_HAVE_DMABUF +#include +#include + +#ifndef DRM_FORMAT_R8 +#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') +#endif + +#ifndef DRM_FORMAT_RG88 +#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') +#endif + +#ifndef DRM_FORMAT_GR88 +#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') +#endif +#endif + +#ifndef EGL_LINUX_DMA_BUF_EXT +#define EGL_LINUX_DMA_BUF_EXT 0x3270 +#endif + +#ifndef EGL_LINUX_DRM_FOURCC_EXT +#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 +#endif + +#ifndef EGL_DMA_BUF_PLANE0_FD_EXT +#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 +#endif + +#ifndef EGL_DMA_BUF_PLANE0_OFFSET_EXT +#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 +#endif + +#ifndef EGL_DMA_BUF_PLANE0_PITCH_EXT +#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 +#endif + +GST_DEBUG_CATEGORY_STATIC (GST_CAT_EGL_IMAGE); +#define GST_CAT_DEFAULT GST_CAT_EGL_IMAGE + +GST_DEFINE_MINI_OBJECT_TYPE (GstEGLImage, gst_egl_image); + +static void +_init_debug (void) +{ + static volatile gsize _init = 0; + + if (g_once_init_enter (&_init)) { + GST_DEBUG_CATEGORY_INIT (GST_CAT_EGL_IMAGE, "gleglimage", 0, + "EGLImage wrapper"); + + g_once_init_leave (&_init, 1); + } +} + +EGLImageKHR +gst_egl_image_get_image (GstEGLImage * image) +{ + g_return_val_if_fail (GST_IS_EGL_IMAGE (image), EGL_NO_IMAGE_KHR); + + return image->image; +} + +GstVideoGLTextureOrientation +gst_egl_image_get_orientation (GstEGLImage * image) +{ + g_return_val_if_fail (GST_IS_EGL_IMAGE (image), + GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL); + + return image->orientation; +} + +static void +_gst_egl_image_free_thread (GstGLContext * context, GstEGLImage * image) +{ + if (image->destroy_notify) + image->destroy_notify (image, image->destroy_data); +} + +static void +_gst_egl_image_free (GstMiniObject * object) +{ + GstEGLImage *image = GST_EGL_IMAGE (object); + + if (image->context) { + gst_gl_context_thread_add (GST_GL_CONTEXT (image->context), + (GstGLContextThreadFunc) _gst_egl_image_free_thread, image); + gst_object_unref (image->context); + } +} + +static GstMiniObject * +_gst_egl_image_copy (GstMiniObject * obj) +{ + return gst_mini_object_ref (obj); +} + +GstEGLImage * +gst_egl_image_new_wrapped (GstGLContext * context, EGLImageKHR image, + GstVideoGLTextureType type, GstVideoGLTextureOrientation orientation, + gpointer user_data, GstEGLImageDestroyNotify user_data_destroy) +{ + 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 (image != EGL_NO_IMAGE_KHR, NULL); + + img = g_new0 (GstEGLImage, 1); + gst_mini_object_init (GST_MINI_OBJECT_CAST (img), 0, GST_TYPE_EGL_IMAGE, + (GstMiniObjectCopyFunction) _gst_egl_image_copy, NULL, + (GstMiniObjectFreeFunction) _gst_egl_image_free); + + img->context = gst_object_ref (context); + img->image = image; + img->type = type; + img->orientation = orientation; + + img->destroy_data = user_data; + img->destroy_notify = user_data_destroy; + + return img; +} + +#if GST_GL_HAVE_DMABUF +/* + * GStreamer format descriptions differ from DRM formats as the representation + * is relative to a register, hence in native endianness. To reduce the driver + * requirement, we only import with a subset of texture formats and use + * shaders to convert. This way we avoid having to use external texture + * target. + */ +static int +_drm_fourcc_from_info (GstVideoInfo * info, int plane) +{ + GstVideoFormat format = GST_VIDEO_INFO_FORMAT (info); +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + const gint rgba_fourcc = DRM_FORMAT_ABGR8888; + const gint rgb_fourcc = DRM_FORMAT_BGR888; + const gint rg_fourcc = DRM_FORMAT_GR88; +#else + const gint rgba_fourcc = DRM_FORMAT_RGBA8888; + const gint rgb_fourcc = DRM_FORMAT_RGB888; + const gint rg_fourcc = DRM_FORMAT_RG88; +#endif + + _init_debug (); + + GST_DEBUG ("Getting DRM fourcc for %s plane %i", + gst_video_format_to_string (format), plane); + + switch (format) { + case GST_VIDEO_FORMAT_RGB16: + case GST_VIDEO_FORMAT_BGR16: + return DRM_FORMAT_RGB565; + + case GST_VIDEO_FORMAT_RGB: + case GST_VIDEO_FORMAT_BGR: + return rgb_fourcc; + + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_ARGB: + case GST_VIDEO_FORMAT_xRGB: + case GST_VIDEO_FORMAT_ABGR: + case GST_VIDEO_FORMAT_xBGR: + case GST_VIDEO_FORMAT_AYUV: + return rgba_fourcc; + + case GST_VIDEO_FORMAT_GRAY8: + return DRM_FORMAT_R8; + + case GST_VIDEO_FORMAT_YUY2: + case GST_VIDEO_FORMAT_UYVY: + case GST_VIDEO_FORMAT_GRAY16_LE: + case GST_VIDEO_FORMAT_GRAY16_BE: + return rg_fourcc; + + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_NV21: + return plane == 0 ? DRM_FORMAT_R8 : rg_fourcc; + + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_Y41B: + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_Y444: + return DRM_FORMAT_R8; + + default: + GST_ERROR ("Unsupported format for DMABuf."); + return -1; + } +} + +static void +_destroy_egl_image (GstEGLImage * image, gpointer user_data) +{ + image->context->eglDestroyImage (image->context->egl_display, image->image); +} + +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]; + EGLImageKHR img = EGL_NO_IMAGE_KHR; + GstVideoGLTextureType type; + + fourcc = _drm_fourcc_from_info (in_info, plane); + type = + gst_gl_texture_type_from_format (context, GST_VIDEO_INFO_FORMAT (in_info), + plane); + + GST_DEBUG ("fourcc %.4s (%d) plane %d (%dx%d)", + (char *) &fourcc, fourcc, plane, + GST_VIDEO_INFO_COMP_WIDTH (in_info, plane), + GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane)); + + 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->eglCreateImage (ctx_egl->egl_display, EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, NULL, attribs); + + if (!img) { + GST_WARNING ("eglCreateImage failed: %s", + gst_gl_context_egl_get_error_string (eglGetError ())); + return NULL; + } + + return gst_egl_image_new_wrapped (context, img, type, + GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, + (GstEGLImageDestroyNotify) _destroy_egl_image, NULL); +} +#endif /* GST_GL_HAVE_DMABUF */ diff --git a/gst-libs/gst/gl/egl/gsteglimage.h b/gst-libs/gst/gl/egl/gsteglimage.h new file mode 100644 index 0000000000..2d2e0758fe --- /dev/null +++ b/gst-libs/gst/gl/egl/gsteglimage.h @@ -0,0 +1,106 @@ +/* + * GStreamer + * Copyright (C) 2012 Collabora Ltd. + * @author: Sebastian Dröge + * Copyright (C) 2014 Julien Isorce + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GST_EGL_IMAGE_H_ +#define _GST_EGL_IMAGE_H_ + +#include +#include + +#include +#include + +G_BEGIN_DECLS + +GType gst_egl_image_get_type (void); +#define GST_TYPE_EGL_IMAGE (gst_egl_image_get_type()) +#define GST_IS_EGL_IMAGE(obj) (GST_IS_MINI_OBJECT_TYPE(obj, GST_TYPE_EGL_IMAGE)) +#define GST_EGL_IMAGE_CAST(obj) ((GstEGLImage *)(obj)) +#define GST_EGL_IMAGE(obj) (GST_EGL_IMAGE_CAST(obj)) + +typedef struct _GstEGLImage GstEGLImage; + +typedef void (*GstEGLImageDestroyNotify) (GstEGLImage * image, + gpointer data); + +struct _GstEGLImage +{ + GstMiniObject parent; + + GstGLContextEGL *context; + EGLImageKHR image; + GstVideoGLTextureType type; + /* FIXME: remove this and use the affine transformation meta instead */ + GstVideoGLTextureOrientation orientation; + + /* */ + gpointer destroy_data; + GstEGLImageDestroyNotify destroy_notify; +}; + +GstEGLImage * gst_egl_image_new_wrapped (GstGLContext * context, + EGLImageKHR image, + GstVideoGLTextureType type, + GstVideoGLTextureOrientation orientation, + gpointer user_data, + GstEGLImageDestroyNotify user_data_destroy); +EGLImageKHR gst_egl_image_get_image (GstEGLImage * image); +GstVideoGLTextureOrientation gst_egl_image_get_orientation (GstEGLImage * image); + +#if GST_GL_HAVE_DMABUF +GstEGLImage * gst_egl_image_from_dmabuf (GstGLContext * context, + gint dmabuf, + GstVideoInfo * in_info, + gint plane, + gsize offset); +#endif + +/** + * gst_egl_image_ref: + * @image: a #GstEGLImage. + * + * Increases the refcount of the given image by one. + * + * Returns: (transfer full): @image + */ +static inline GstEGLImage * +gst_egl_image_ref (GstEGLImage * image) +{ + return (GstEGLImage *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (image)); +} + +/** + * gst_buffer_unref: + * @buf: (transfer full): a #GstBuffer. + * + * Decreases the refcount of the image. If the refcount reaches 0, the image + * with the associated metadata and memory will be freed. + */ +static inline void +gst_egl_image_unref (GstEGLImage * image) +{ + gst_mini_object_unref (GST_MINI_OBJECT_CAST (image)); +} + +G_END_DECLS + +#endif /* _GST_EGL_IMAGE_H_ */ diff --git a/gst-libs/gst/gl/egl/gsteglimagememory.c b/gst-libs/gst/gl/egl/gsteglimagememory.c deleted file mode 100644 index 4b0f3e6cb8..0000000000 --- a/gst-libs/gst/gl/egl/gsteglimagememory.c +++ /dev/null @@ -1,761 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2012 Collabora Ltd. - * @author: Sebastian Dröge - * Copyright (C) 2014 Julien Isorce - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gsteglimagememory.h" -#include - -#if GST_GL_HAVE_DMABUF -#include -#include - -#ifndef DRM_FORMAT_R8 -#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') -#endif - -#ifndef DRM_FORMAT_RG88 -#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') -#endif - -#ifndef DRM_FORMAT_GR88 -#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') -#endif -#endif - -#ifndef EGL_LINUX_DMA_BUF_EXT -#define EGL_LINUX_DMA_BUF_EXT 0x3270 -#endif - -#ifndef EGL_LINUX_DRM_FOURCC_EXT -#define EGL_LINUX_DRM_FOURCC_EXT 0x3271 -#endif - -#ifndef EGL_DMA_BUF_PLANE0_FD_EXT -#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 -#endif - -#ifndef EGL_DMA_BUF_PLANE0_OFFSET_EXT -#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 -#endif - -#ifndef EGL_DMA_BUF_PLANE0_PITCH_EXT -#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 -#endif - -GST_DEBUG_CATEGORY_STATIC (GST_CAT_EGL_IMAGE_MEMORY); -#define GST_CAT_DEFAULT GST_CAT_EGL_IMAGE_MEMORY - -#define GST_EGL_IMAGE_MEMORY(mem) ((GstEGLImageMemory*)(mem)) - -gboolean -gst_is_egl_image_memory (GstMemory * mem) -{ - g_return_val_if_fail (mem != NULL, FALSE); - g_return_val_if_fail (mem->allocator != NULL, FALSE); - - return g_strcmp0 (mem->allocator->mem_type, GST_EGL_IMAGE_MEMORY_TYPE) == 0; -} - -EGLImageKHR -gst_egl_image_memory_get_image (GstMemory * mem) -{ - g_return_val_if_fail (gst_is_egl_image_memory (mem), EGL_NO_IMAGE_KHR); - - if (mem->parent) - mem = mem->parent; - - return GST_EGL_IMAGE_MEMORY (mem)->image; -} - -EGLDisplay -gst_egl_image_memory_get_display (GstMemory * mem) -{ - g_return_val_if_fail (gst_is_egl_image_memory (mem), NULL); - - if (mem->parent) - mem = mem->parent; - - return GST_EGL_IMAGE_MEMORY (mem)->context->egl_display; -} - -GstVideoGLTextureOrientation -gst_egl_image_memory_get_orientation (GstMemory * mem) -{ - g_return_val_if_fail (gst_is_egl_image_memory (mem), - GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL); - - if (mem->parent) - mem = mem->parent; - - return GST_EGL_IMAGE_MEMORY (mem)->orientation; -} - -void -gst_egl_image_memory_set_orientation (GstMemory * mem, - GstVideoGLTextureOrientation orientation) -{ - g_return_if_fail (gst_is_egl_image_memory (mem)); - - if (mem->parent) - mem = mem->parent; - - GST_EGL_IMAGE_MEMORY (mem)->orientation = orientation; -} - -static GstMemory * -gst_egl_image_allocator_alloc_vfunc (GstAllocator * allocator, gsize size, - GstAllocationParams * params) -{ - g_warning - ("Use gst_egl_image_allocator_alloc() to allocate from this allocator"); - - return NULL; -} - -static void -gst_egl_image_allocator_free_vfunc (GstAllocator * allocator, GstMemory * mem) -{ - GstEGLImageMemory *emem = (GstEGLImageMemory *) mem; - - g_return_if_fail (gst_is_egl_image_memory (mem)); - - /* Shared memory should not destroy all the data */ - if (!mem->parent) { - emem->context->eglDestroyImage (emem->context->egl_display, emem->image); - - if (emem->user_data_destroy) - emem->user_data_destroy (emem->context, emem->user_data); - - gst_object_unref (emem->context); - emem->context = NULL; - } - - g_slice_free (GstEGLImageMemory, emem); -} - -static gpointer -gst_egl_image_mem_map (GstMemory * mem, gsize maxsize, GstMapFlags flags) -{ - return NULL; -} - -static void -gst_egl_image_mem_unmap (GstMemory * mem) -{ -} - -static GstMemory * -gst_egl_image_mem_share (GstMemory * mem, gssize offset, gssize size) -{ - return NULL; -} - -static GstMemory * -gst_egl_image_mem_copy (GstMemory * mem, gssize offset, gssize size) -{ - return NULL; -} - -static gboolean -gst_egl_image_mem_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset) -{ - return FALSE; -} - -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, - GST_TYPE_ALLOCATOR); - -#define GST_TYPE_EGL_IMAGE_ALLOCATOR (gst_egl_image_mem_allocator_get_type()) -#define GST_IS_EGL_IMAGE_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EGL_IMAGE_ALLOCATOR)) - -static void -gst_egl_image_allocator_class_init (GstEGLImageAllocatorClass * klass) -{ - GstAllocatorClass *allocator_class = (GstAllocatorClass *) klass; - - allocator_class->alloc = gst_egl_image_allocator_alloc_vfunc; - allocator_class->free = gst_egl_image_allocator_free_vfunc; -} - -static void -gst_egl_image_allocator_init (GstEGLImageAllocator * allocator) -{ - GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); - - alloc->mem_type = GST_EGL_IMAGE_MEMORY_TYPE; - alloc->mem_map = gst_egl_image_mem_map; - alloc->mem_unmap = gst_egl_image_mem_unmap; - alloc->mem_share = gst_egl_image_mem_share; - alloc->mem_copy = gst_egl_image_mem_copy; - alloc->mem_is_span = gst_egl_image_mem_is_span; - - GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); -} - -static gpointer -gst_egl_image_allocator_init_instance (gpointer data) -{ - GstAllocator *allocator = - g_object_new (gst_egl_image_allocator_get_type (), NULL); - - GST_DEBUG_CATEGORY_INIT (GST_CAT_EGL_IMAGE_MEMORY, "eglimagememory", 0, - "EGLImage Memory"); - - gst_allocator_register (GST_EGL_IMAGE_MEMORY_TYPE, - gst_object_ref (allocator)); - - return allocator; -} - -static GstEGLImageAllocator * -gst_egl_image_allocator_obtain (void) -{ - static GOnce once = G_ONCE_INIT; - - g_once (&once, gst_egl_image_allocator_init_instance, NULL); - - g_return_val_if_fail (once.retval != NULL, NULL); - - return (GstEGLImageAllocator *) (g_object_ref (once.retval)); -} - -void -gst_egl_image_memory_init (void) -{ - gst_egl_image_allocator_obtain (); -} - -static void -gst_egl_image_memory_del_gl_texture (GstGLContext * context, gpointer tex) -{ - GLuint textures[1] = { GPOINTER_TO_UINT (tex) }; - - gst_gl_context_del_texture (context, textures); -} - -static GstMemory * -gst_egl_image_allocator_wrap (GstEGLImageAllocator * allocator, - GstGLContextEGL * context, EGLImageKHR image, GstVideoGLTextureType type, - GstMemoryFlags flags, gsize size, gpointer user_data, - GstEGLImageDestroyNotify user_data_destroy) -{ - GstEGLImageMemory *mem = NULL; - - g_return_val_if_fail (context != NULL, NULL); - g_return_val_if_fail (image != EGL_NO_IMAGE_KHR, NULL); - - if (!allocator) { - allocator = gst_egl_image_allocator_obtain (); - } - - mem = g_slice_new (GstEGLImageMemory); - gst_memory_init (GST_MEMORY_CAST (mem), flags, - GST_ALLOCATOR (allocator), NULL, size, 0, 0, size); - - gst_object_unref (allocator); - - mem->context = gst_object_ref (context); - mem->image = image; - mem->type = type; - mem->orientation = GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL; - - mem->user_data = user_data; - mem->user_data_destroy = user_data_destroy; - - return GST_MEMORY_CAST (mem); -} - -#if 0 -static GstMemory * -gst_egl_image_allocator_alloc (GstAllocator * allocator, - GstGLContextEGL * context, GstVideoGLTextureType type, gint width, - gint height, gsize size) -{ - /* EGL_NO_CONTEXT */ - return NULL; -} -#endif - -static gboolean -gst_eglimage_to_gl_texture_upload_meta (GstVideoGLTextureUploadMeta * - meta, guint texture_id[4]) -{ - gint i = 0; - gint n = 0; - - g_return_val_if_fail (meta != NULL, FALSE); - g_return_val_if_fail (texture_id != NULL, FALSE); - - GST_DEBUG ("Uploading for meta with textures %i,%i,%i,%i", texture_id[0], - texture_id[1], texture_id[2], texture_id[3]); - - n = gst_buffer_n_memory (meta->buffer); - - for (i = 0; i < n; i++) { - GstMemory *mem = gst_buffer_peek_memory (meta->buffer, i); - const GstGLFuncs *gl = NULL; - - if (!gst_is_egl_image_memory (mem)) { - GST_WARNING ("memory %p does not hold an EGLImage", mem); - return FALSE; - } - - gl = GST_GL_CONTEXT (GST_EGL_IMAGE_MEMORY (mem)->context)->gl_vtable; - - gl->ActiveTexture (GL_TEXTURE0 + i); - gl->BindTexture (GL_TEXTURE_2D, texture_id[i]); - gl->EGLImageTargetTexture2D (GL_TEXTURE_2D, - gst_egl_image_memory_get_image (mem)); - } - - if (GST_IS_GL_BUFFER_POOL (meta->buffer->pool)) - gst_gl_buffer_pool_replace_last_buffer (GST_GL_BUFFER_POOL (meta->buffer-> - pool), meta->buffer); - - - return TRUE; -} - -#if GST_GL_HAVE_DMABUF -/* - * GStreamer format descriptions differ from DRM formats as the representation - * is relative to a register, hence in native endianness. To reduce the driver - * requirement, we only import with a subset of texture formats and use - * shaders to convert. This way we avoid having to use external texture - * target. - */ -static int -_drm_fourcc_from_info (GstVideoInfo * info, int plane) -{ - GstVideoFormat format = GST_VIDEO_INFO_FORMAT (info); -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - const gint rgba_fourcc = DRM_FORMAT_ABGR8888; - const gint rgb_fourcc = DRM_FORMAT_BGR888; - const gint rg_fourcc = DRM_FORMAT_GR88; -#else - const gint rgba_fourcc = DRM_FORMAT_RGBA8888; - const gint rgb_fourcc = DRM_FORMAT_RGB888; - const gint rg_fourcc = DRM_FORMAT_RG88; -#endif - - GST_DEBUG ("Getting DRM fourcc for %s plane %i", - gst_video_format_to_string (format), plane); - - switch (format) { - case GST_VIDEO_FORMAT_RGB16: - case GST_VIDEO_FORMAT_BGR16: - return DRM_FORMAT_RGB565; - - case GST_VIDEO_FORMAT_RGB: - case GST_VIDEO_FORMAT_BGR: - return rgb_fourcc; - - case GST_VIDEO_FORMAT_RGBA: - case GST_VIDEO_FORMAT_RGBx: - case GST_VIDEO_FORMAT_BGRA: - case GST_VIDEO_FORMAT_BGRx: - case GST_VIDEO_FORMAT_ARGB: - case GST_VIDEO_FORMAT_xRGB: - case GST_VIDEO_FORMAT_ABGR: - case GST_VIDEO_FORMAT_xBGR: - case GST_VIDEO_FORMAT_AYUV: - return rgba_fourcc; - - case GST_VIDEO_FORMAT_GRAY8: - return DRM_FORMAT_R8; - - case GST_VIDEO_FORMAT_YUY2: - case GST_VIDEO_FORMAT_UYVY: - case GST_VIDEO_FORMAT_GRAY16_LE: - case GST_VIDEO_FORMAT_GRAY16_BE: - return rg_fourcc; - - case GST_VIDEO_FORMAT_NV12: - case GST_VIDEO_FORMAT_NV21: - return plane == 0 ? DRM_FORMAT_R8 : rg_fourcc; - - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - case GST_VIDEO_FORMAT_Y41B: - case GST_VIDEO_FORMAT_Y42B: - case GST_VIDEO_FORMAT_Y444: - return DRM_FORMAT_R8; - - default: - GST_ERROR ("Unsupported format for DMABuf."); - return -1; - } -} - -GstMemory * -gst_egl_image_memory_from_dmabuf (GstGLContext * context, - gint dmabuf, GstVideoInfo * in_info, gint plane, gsize offset) -{ - GstGLContextEGL *ctx_egl = GST_GL_CONTEXT_EGL (context); - GstEGLImageAllocator *allocator; - gint fourcc; - gint atti = 0; - EGLint attribs[13]; - EGLImageKHR img = EGL_NO_IMAGE_KHR; - - allocator = gst_egl_image_allocator_obtain (); - fourcc = _drm_fourcc_from_info (in_info, plane); - - GST_DEBUG ("fourcc %.4s (%d) plane %d (%dx%d)", - (char *) &fourcc, fourcc, plane, - GST_VIDEO_INFO_COMP_WIDTH (in_info, plane), - GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane)); - - 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->eglCreateImage (ctx_egl->egl_display, EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, NULL, attribs); - - if (!img) { - GST_WARNING_OBJECT (allocator, "eglCreateImage failed: %s", - gst_gl_context_egl_get_error_string (eglGetError ())); - return NULL; - } - - return gst_egl_image_allocator_wrap (allocator, ctx_egl, img, 0, 0, - in_info->size, NULL, NULL); -} -#endif /* GST_GL_HAVE_DMABUF */ - -static gboolean -_gst_egl_image_memory_setup_buffer_thread (GstGLContext * ctx, - GstVideoInfo * info, GstBuffer * buffer) -{ - gint i = 0; - gint stride[3]; - gsize offset[3]; - GstMemory *mem[3] = { NULL, NULL, NULL }; - guint n_mem = 0; - GstMemoryFlags flags = 0; - EGLImageKHR image = EGL_NO_IMAGE_KHR; - EGLClientBuffer client_buffer_tex[3] = { 0, 0, 0 }; - GstVideoGLTextureType texture_types[] = { 0, 0, 0, 0 }; - 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)); - - flags |= GST_MEMORY_FLAG_NOT_MAPPABLE; - flags |= GST_MEMORY_FLAG_NO_SHARE; - - switch (GST_VIDEO_INFO_FORMAT (info)) { - case GST_VIDEO_FORMAT_RGB: - case GST_VIDEO_FORMAT_BGR: - case GST_VIDEO_FORMAT_RGB16: - case GST_VIDEO_FORMAT_RGBA: - case GST_VIDEO_FORMAT_BGRA: - case GST_VIDEO_FORMAT_ARGB: - case GST_VIDEO_FORMAT_ABGR: - case GST_VIDEO_FORMAT_RGBx: - case GST_VIDEO_FORMAT_BGRx: - case GST_VIDEO_FORMAT_xRGB: - case GST_VIDEO_FORMAT_xBGR: - case GST_VIDEO_FORMAT_AYUV: - { - gsize size = 0; - - switch (GST_VIDEO_INFO_FORMAT (info)) { - case GST_VIDEO_FORMAT_RGB: - case GST_VIDEO_FORMAT_BGR: - case GST_VIDEO_FORMAT_RGB16: - { - texture_types[0] = GST_VIDEO_GL_TEXTURE_TYPE_RGB; - break; - } - case GST_VIDEO_FORMAT_RGBA: - case GST_VIDEO_FORMAT_BGRA: - case GST_VIDEO_FORMAT_ARGB: - case GST_VIDEO_FORMAT_ABGR: - case GST_VIDEO_FORMAT_RGBx: - case GST_VIDEO_FORMAT_BGRx: - case GST_VIDEO_FORMAT_xRGB: - case GST_VIDEO_FORMAT_xBGR: - case GST_VIDEO_FORMAT_AYUV: - { - texture_types[0] = GST_VIDEO_GL_TEXTURE_TYPE_RGBA; - break; - } - default: - g_assert_not_reached (); - break; - } -#if 0 - mem[0] = - gst_egl_image_allocator_alloc (allocator, context, - texture_types[0], GST_VIDEO_INFO_WIDTH (info), - GST_VIDEO_INFO_HEIGHT (info), size); - if (mem[0]) { - stride[0] = size / GST_VIDEO_INFO_HEIGHT (info); - n_mem = 1; - GST_MINI_OBJECT_FLAG_SET (mem[0], GST_MEMORY_FLAG_NO_SHARE); - } else -#endif - { - gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, 0, stride, - offset, &size, (GLuint *) & client_buffer_tex[0]); - - image = context->eglCreateImage (context->egl_display, - context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[0], - NULL); - if (eglGetError () != EGL_SUCCESS) - goto mem_error; - - mem[0] = - gst_egl_image_allocator_wrap (allocator, context, - image, texture_types[0], flags, size, client_buffer_tex[0], - (GstEGLImageDestroyNotify) gst_egl_image_memory_del_gl_texture); - n_mem = 1; - } - break; - } - - case GST_VIDEO_FORMAT_NV12: - case GST_VIDEO_FORMAT_NV21: - { - gsize size[2]; - - texture_types[0] = GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE; - texture_types[1] = GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA; -#if 0 - mem[0] = - gst_egl_image_allocator_alloc (allocator, context, - texture_types[0], GST_VIDEO_INFO_COMP_WIDTH (info, - 0), GST_VIDEO_INFO_COMP_HEIGHT (info, 0), size[0]); - mem[1] = - gst_egl_image_allocator_alloc (allocator, context, - texture_types[1], - GST_VIDEO_INFO_COMP_WIDTH (info, 1), - GST_VIDEO_INFO_COMP_HEIGHT (info, 1), size[1]); - - if (mem[0] && mem[1]) { - stride[0] = size[0] / GST_VIDEO_INFO_HEIGHT (info); - offset[1] = size[0]; - stride[1] = size[1] / GST_VIDEO_INFO_HEIGHT (info); - n_mem = 2; - GST_MINI_OBJECT_FLAG_SET (mem[0], GST_MEMORY_FLAG_NO_SHARE); - GST_MINI_OBJECT_FLAG_SET (mem[1], GST_MEMORY_FLAG_NO_SHARE); - } else { - if (mem[0]) - gst_memory_unref (mem[0]); - if (mem[1]) - gst_memory_unref (mem[1]); - mem[0] = mem[1] = NULL; - } -#endif - { - for (i = 0; i < 2; i++) { - gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, 0, - stride, offset, size, (GLuint *) & client_buffer_tex[i]); - - image = context->eglCreateImage (context->egl_display, - context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[i], - NULL); - if (eglGetError () != EGL_SUCCESS) - goto mem_error; - - mem[i] = - gst_egl_image_allocator_wrap (allocator, context, - image, texture_types[i], flags, size[i], client_buffer_tex[i], - (GstEGLImageDestroyNotify) gst_egl_image_memory_del_gl_texture); - } - - n_mem = 2; - } - break; - } - case GST_VIDEO_FORMAT_I420: - case GST_VIDEO_FORMAT_YV12: - case GST_VIDEO_FORMAT_Y444: - case GST_VIDEO_FORMAT_Y42B: - case GST_VIDEO_FORMAT_Y41B: - { - gsize size[3]; - - texture_types[0] = GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE; - texture_types[1] = GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE; - texture_types[2] = GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE; -#if 0 - mem[0] = - gst_egl_image_allocator_alloc (allocator, context, - texture_types[0], GST_VIDEO_INFO_COMP_WIDTH (info, - 0), GST_VIDEO_INFO_COMP_HEIGHT (info, 0), size[0]); - mem[1] = - gst_egl_image_allocator_alloc (allocator, context, - texture_types[1], GST_VIDEO_INFO_COMP_WIDTH (info, - 1), GST_VIDEO_INFO_COMP_HEIGHT (info, 1), size[1]); - mem[2] = - gst_egl_image_allocator_alloc (allocator, context, - texture_types[2], GST_VIDEO_INFO_COMP_WIDTH (info, - 2), GST_VIDEO_INFO_COMP_HEIGHT (info, 2), size[2]); - - if (mem[0] && mem[1] && mem[2]) { - stride[0] = size[0] / GST_VIDEO_INFO_HEIGHT (info); - offset[1] = size[0]; - stride[1] = size[1] / GST_VIDEO_INFO_HEIGHT (info); - offset[2] = size[1]; - stride[2] = size[2] / GST_VIDEO_INFO_HEIGHT (info); - n_mem = 3; - GST_MINI_OBJECT_FLAG_SET (mem[0], GST_MEMORY_FLAG_NO_SHARE); - GST_MINI_OBJECT_FLAG_SET (mem[1], GST_MEMORY_FLAG_NO_SHARE); - GST_MINI_OBJECT_FLAG_SET (mem[2], GST_MEMORY_FLAG_NO_SHARE); - } else { - if (mem[0]) - gst_memory_unref (mem[0]); - if (mem[1]) - gst_memory_unref (mem[1]); - if (mem[2]) - gst_memory_unref (mem[2]); - mem[0] = mem[1] = mem[2] = NULL; - } -#endif - { - for (i = 0; i < 3; i++) { - gst_gl_generate_texture_full (GST_GL_CONTEXT (context), info, i, - stride, offset, size, (GLuint *) & client_buffer_tex[i]); - - image = context->eglCreateImage (context->egl_display, - context->egl_context, EGL_GL_TEXTURE_2D_KHR, client_buffer_tex[i], - NULL); - if (eglGetError () != EGL_SUCCESS) - goto mem_error; - - mem[i] = - gst_egl_image_allocator_wrap (allocator, context, - image, texture_types[i], flags, size[i], client_buffer_tex[i], - (GstEGLImageDestroyNotify) gst_egl_image_memory_del_gl_texture); - } - - n_mem = 3; - } - break; - } - default: - g_assert_not_reached (); - break; - } - - gst_buffer_add_video_meta_full (buffer, 0, GST_VIDEO_INFO_FORMAT (info), - GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), - GST_VIDEO_INFO_N_PLANES (info), offset, stride); - - gst_buffer_add_video_gl_texture_upload_meta (buffer, - gst_egl_image_memory_get_orientation (mem[0]), n_mem, texture_types, - gst_eglimage_to_gl_texture_upload_meta, NULL, NULL, NULL); - - for (i = 0; i < n_mem; i++) - gst_buffer_append_memory (buffer, mem[i]); - - return TRUE; - -mem_error: - { - GST_CAT_ERROR (GST_CAT_DEFAULT, "Failed to create EGLImage"); - - for (i = 0; i < 3; i++) { - if (client_buffer_tex[i]) - gst_gl_context_del_texture (ctx, (GLuint *) & client_buffer_tex[i]); - if (mem[i]) - gst_memory_unref (mem[i]); - } - - return FALSE; - } -} - -struct egl_image_setup_buffer -{ - gboolean ret; - GstVideoInfo *info; - GstBuffer *buffer; -}; - -static void -_setup_buffer (GstGLContext * ctx, struct egl_image_setup_buffer *data) -{ - data->ret = _gst_egl_image_memory_setup_buffer_thread (ctx, data->info, - data->buffer); -} - -gboolean -gst_egl_image_memory_setup_buffer (GstGLContext * ctx, GstVideoInfo * info, - GstBuffer * buffer) -{ - struct egl_image_setup_buffer data = { 0, }; - - data.info = info; - data.buffer = buffer; - - gst_gl_context_thread_add (ctx, (GstGLContextThreadFunc) _setup_buffer, - &data); - - return data.ret; -} diff --git a/gst-libs/gst/gl/egl/gsteglimagememory.h b/gst-libs/gst/gl/egl/gsteglimagememory.h deleted file mode 100644 index aced24706c..0000000000 --- a/gst-libs/gst/gl/egl/gsteglimagememory.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2012 Collabora Ltd. - * @author: Sebastian Dröge - * Copyright (C) 2014 Julien Isorce - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GST_EGL_IMAGE_MEMORY_H_ -#define _GST_EGL_IMAGE_MEMORY_H_ - -#include -#include -#include -#include - -#include -#include "gstglcontext_egl.h" - -G_BEGIN_DECLS - -typedef void (*GstEGLImageDestroyNotify) (GstGLContextEGL * context, - gpointer data); - -typedef struct _GstEGLImageMemory GstEGLImageMemory; - -#define GST_EGL_IMAGE_MEMORY_TYPE "EGLImage" - -#define GST_CAPS_FEATURE_MEMORY_EGL_IMAGE "memory:EGLImage" - -struct _GstEGLImageMemory -{ - GstMemory parent; - - GstGLContextEGL *context; - EGLImageKHR image; - GstVideoGLTextureType type; - GstVideoGLTextureOrientation orientation; - - gpointer user_data; - GstEGLImageDestroyNotify user_data_destroy; -}; - -void gst_egl_image_memory_init (void); -gboolean gst_egl_image_memory_setup_buffer (GstGLContext * context, GstVideoInfo * info, GstBuffer * buffer); -gboolean gst_is_egl_image_memory (GstMemory * mem); -EGLImageKHR gst_egl_image_memory_get_image (GstMemory * mem); -EGLDisplay gst_egl_image_memory_get_display (GstMemory * mem); -GstVideoGLTextureOrientation gst_egl_image_memory_get_orientation (GstMemory * mem); -void gst_egl_image_memory_set_orientation (GstMemory * mem, - GstVideoGLTextureOrientation orientation); - -#if GST_GL_HAVE_DMABUF -GstMemory * gst_egl_image_memory_from_dmabuf (GstGLContext * context, - gint dmabuf, GstVideoInfo * in_info, gint plane, gsize offset); -#endif - -G_END_DECLS - -#endif /* _GST_GL_MEMORY_H_ */ diff --git a/gst-libs/gst/gl/egl/gstgldisplay_egl.c b/gst-libs/gst/gl/egl/gstgldisplay_egl.c index 20816c229b..c0c8022d33 100644 --- a/gst-libs/gst/gl/egl/gstgldisplay_egl.c +++ b/gst-libs/gst/gl/egl/gstgldisplay_egl.c @@ -23,7 +23,7 @@ #endif #include -#include +#include #include GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug); @@ -51,7 +51,6 @@ gst_gl_display_egl_init (GstGLDisplayEGL * display_egl) display->type = GST_GL_DISPLAY_TYPE_EGL; display_egl->foreign_display = FALSE; - gst_egl_image_memory_init (); gst_gl_memory_egl_init_once (); } diff --git a/gst-libs/gst/gl/egl/gstglmemoryegl.c b/gst-libs/gst/gl/egl/gstglmemoryegl.c index c489b8dbe1..6f04d252e9 100644 --- a/gst-libs/gst/gl/egl/gstglmemoryegl.c +++ b/gst-libs/gst/gl/egl/gstglmemoryegl.c @@ -59,7 +59,7 @@ gst_gl_memory_egl_get_image (GstGLMemoryEGL * mem) { g_return_val_if_fail (gst_is_gl_memory_egl (GST_MEMORY_CAST (mem)), EGL_NO_IMAGE_KHR); - return _gl_mem_get_parent (mem)->image; + return gst_egl_image_get_image (_gl_mem_get_parent (mem)->image); } EGLDisplay @@ -76,16 +76,7 @@ gst_gl_memory_egl_get_orientation (GstGLMemoryEGL * mem) g_return_val_if_fail (gst_is_gl_memory_egl (GST_MEMORY_CAST (mem)), GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL); - return _gl_mem_get_parent (mem)->orientation; -} - -void -gst_gl_memory_egl_set_orientation (GstGLMemoryEGL * mem, - GstVideoGLTextureOrientation orientation) -{ - g_return_if_fail (gst_is_gl_memory_egl (GST_MEMORY_CAST (mem))); - - _gl_mem_get_parent (mem)->orientation = orientation; + return gst_egl_image_get_orientation (_gl_mem_get_parent (mem)->image); } static GstMemory * @@ -101,11 +92,8 @@ _gl_mem_alloc (GstAllocator * allocator, gsize size, static void _gl_mem_destroy (GstGLMemoryEGL * mem) { - /* Shared memory should not destroy all the data */ - if (!mem->mem.mem.mem.parent) { - GstGLContextEGL *context = GST_GL_CONTEXT_EGL (mem->mem.mem.context); - context->eglDestroyImage (context->egl_display, mem->image); - } + if (mem->image) + gst_egl_image_unref (mem->image); GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class)->destroy ((GstGLBaseMemory *) mem); @@ -131,13 +119,22 @@ _gl_mem_egl_alloc (GstGLBaseMemoryAllocator * allocator, g_return_val_if_fail (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO, NULL); - g_return_val_if_fail ((alloc_flags & - GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) == 0, NULL); g_return_val_if_fail ((alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM) == 0, NULL); + if (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) { + g_return_val_if_fail (GST_IS_EGL_IMAGE (params->parent.gl_handle), NULL); + } mem = g_new0 (GstGLMemoryEGL, 1); - mem->image = EGL_NO_IMAGE_KHR; + if (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) { + if (params->target != GST_GL_TEXTURE_TARGET_2D) { + g_free (mem); + GST_CAT_ERROR (GST_CAT_GL_MEMORY, "GstGLMemoryEGL only supports wrapping " + "2D textures"); + return NULL; + } + mem->image = gst_egl_image_ref (params->parent.gl_handle); + } _gl_mem_init (mem, GST_ALLOCATOR_CAST (allocator), NULL, params->parent.context, params->target, params->parent.alloc_params, @@ -147,10 +144,18 @@ _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) { - GstGLContextEGL *context = GST_GL_CONTEXT_EGL (gl_mem->mem.mem.context); + GstGLContext *context = gl_mem->mem.mem.context; + GstGLContextEGL *ctx_egl = GST_GL_CONTEXT_EGL (context); + const GstGLFuncs *gl = context->gl_vtable; GstGLBaseMemoryAllocatorClass *alloc_class; if (!gst_gl_context_check_feature (GST_GL_CONTEXT (context), @@ -164,17 +169,27 @@ _gl_mem_create (GstGLMemoryEGL * gl_mem, GError ** error) if (!alloc_class->create ((GstGLBaseMemory *) gl_mem, error)) return FALSE; - gl_mem->image = context->eglCreateImage (context->egl_display, - context->egl_context, EGL_GL_TEXTURE_2D_KHR, - (EGLClientBuffer) gl_mem->mem.tex_id, NULL); + if (gl_mem->image == NULL) { + EGLImageKHR image = ctx_egl->eglCreateImage (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); + GST_TRACE ("Generating EGLImage handle:%p from a texture:%u", + gl_mem->image, gl_mem->mem.tex_id); - if (eglGetError () != EGL_SUCCESS) { - g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED, - "Failed to create EGLImage"); - return FALSE; + if (eglGetError () != EGL_SUCCESS) { + 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, + (GstEGLImageDestroyNotify) _destroy_egl_image, NULL); + } else { + gl->ActiveTexture (GL_TEXTURE0 + gl_mem->mem.plane); + gl->BindTexture (GL_TEXTURE_2D, gl_mem->mem.tex_id); + gl->EGLImageTargetTexture2D (GL_TEXTURE_2D, + gst_egl_image_get_image (GST_EGL_IMAGE (gl_mem->image))); } return TRUE; diff --git a/gst-libs/gst/gl/egl/gstglmemoryegl.h b/gst-libs/gst/gl/egl/gstglmemoryegl.h index 7256d331ef..c05ef82264 100644 --- a/gst-libs/gst/gl/egl/gstglmemoryegl.h +++ b/gst-libs/gst/gl/egl/gstglmemoryegl.h @@ -29,7 +29,8 @@ #include #include -#include "gstglcontext_egl.h" +#include +#include #include @@ -45,12 +46,6 @@ GType gst_gl_memory_egl_allocator_get_type(void); #define GST_GL_MEMORY_EGL_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GL_MEMORY_EGL_ALLOCATOR, GstGLAllocatorClass)) #define GST_GL_MEMORY_EGL_ALLOCATOR_CAST(obj) ((GstGLMemoryEGLAllocator *)(obj)) -typedef void (*GstEGLImageDestroyNotify) (GstGLContextEGL * context, - gpointer data); - -typedef struct _GstEGLImageMemory GstEGLImageMemory; - - /** * GstGLMemoryEGL: * @@ -60,8 +55,7 @@ struct _GstGLMemoryEGL { GstGLMemory mem; - EGLImageKHR image; - GstVideoGLTextureOrientation orientation; + GstEGLImage *image; }; /** @@ -80,9 +74,6 @@ EGLDisplay gst_gl_memory_egl_get_display (GstGLMemoryEGL * mem); GstVideoGLTextureOrientation gst_gl_memory_egl_get_orientation (GstGLMemoryEGL * mem); -void gst_gl_memory_egl_set_orientation (GstGLMemoryEGL * mem, - GstVideoGLTextureOrientation orientation); - /** * GstGLAllocator * diff --git a/gst-libs/gst/gl/gstglbufferpool.c b/gst-libs/gst/gl/gstglbufferpool.c index 5a2a820293..222baba741 100644 --- a/gst-libs/gst/gl/gstglbufferpool.c +++ b/gst-libs/gst/gl/gstglbufferpool.c @@ -26,10 +26,6 @@ #include "gstglbufferpool.h" #include "gstglutils.h" -#if GST_GL_HAVE_PLATFORM_EGL -#include -#endif - /** * SECTION:gstglbufferpool * @short_description: buffer pool for #GstGLMemory objects @@ -51,8 +47,6 @@ struct _GstGLBufferPoolPrivate GstCaps *caps; gboolean add_videometa; gboolean add_glsyncmeta; - gboolean want_eglimage; - GstBuffer *last_buffer; }; static void gst_gl_buffer_pool_finalize (GObject * object); @@ -132,16 +126,6 @@ gst_gl_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) priv->add_glsyncmeta = gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_GL_SYNC_META); -#if GST_GL_HAVE_PLATFORM_EGL - if (priv->allocator) { - priv->want_eglimage = - (g_strcmp0 (priv->allocator->mem_type, GST_EGL_IMAGE_MEMORY_TYPE) == 0); - } else -#endif - { - priv->want_eglimage = FALSE; - } - if (priv->gl_params) gst_gl_allocation_params_free ((GstGLAllocationParams *) priv->gl_params); priv->gl_params = (GstGLVideoAllocationParams *) @@ -276,19 +260,6 @@ gst_gl_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, if (!(buf = gst_buffer_new ())) { goto no_buffer; } -#if GST_GL_HAVE_PLATFORM_EGL - if (priv->want_eglimage) { - /* alloc and append memories, also add video_meta and - * texture_upload_meta */ - if (!gst_egl_image_memory_setup_buffer (glpool->context, - priv->gl_params->v_info, buf)) - goto egl_image_mem_create_failed; - - *buffer = buf; - - return GST_FLOW_OK; - } -#endif alloc = GST_GL_MEMORY_ALLOCATOR (priv->allocator); if (!gst_gl_memory_setup_buffer (alloc, buf, priv->gl_params, NULL, 0)) @@ -312,48 +283,6 @@ mem_create_failed: GST_WARNING_OBJECT (pool, "Could not create GL Memory"); return GST_FLOW_ERROR; } - -#if GST_GL_HAVE_PLATFORM_EGL -egl_image_mem_create_failed: - { - GST_WARNING_OBJECT (pool, "Could not create EGLImage Memory"); - return GST_FLOW_ERROR; - } -#endif -} - - -static GstFlowReturn -gst_gl_buffer_pool_acquire_buffer (GstBufferPool * bpool, - GstBuffer ** buffer, GstBufferPoolAcquireParams * params) -{ - GstFlowReturn ret = GST_FLOW_OK; - GstGLBufferPool *glpool = NULL; - - ret = - GST_BUFFER_POOL_CLASS - (gst_gl_buffer_pool_parent_class)->acquire_buffer (bpool, buffer, params); - if (ret != GST_FLOW_OK || !*buffer) - return ret; - - glpool = GST_GL_BUFFER_POOL (bpool); - - /* XXX: Don't return the memory we just rendered, glEGLImageTargetTexture2DOES() - * keeps the EGLImage unmappable until the next one is uploaded - */ - if (glpool->priv->want_eglimage && *buffer - && *buffer == glpool->priv->last_buffer) { - GstBuffer *oldbuf = *buffer; - - ret = - GST_BUFFER_POOL_CLASS - (gst_gl_buffer_pool_parent_class)->acquire_buffer (bpool, - buffer, params); - gst_object_replace ((GstObject **) & oldbuf->pool, (GstObject *) glpool); - gst_buffer_unref (oldbuf); - } - - return ret; } /** @@ -376,24 +305,6 @@ gst_gl_buffer_pool_new (GstGLContext * context) return GST_BUFFER_POOL_CAST (pool); } -/** - * gst_gl_buffer_pool_replace_last_buffer: - * @pool: a #GstGLBufferPool - * @buffer: a #GstBuffer - * - * Set @pool<-- -->s last buffer to @buffer for #GstGLPlatform<-- -->s that - * require it. - */ -void -gst_gl_buffer_pool_replace_last_buffer (GstGLBufferPool * pool, - GstBuffer * buffer) -{ - g_return_if_fail (pool != NULL); - g_return_if_fail (buffer != NULL); - - gst_buffer_replace (&pool->priv->last_buffer, buffer); -} - static void gst_gl_buffer_pool_class_init (GstGLBufferPoolClass * klass) { @@ -407,7 +318,6 @@ gst_gl_buffer_pool_class_init (GstGLBufferPoolClass * klass) gstbufferpool_class->get_options = gst_gl_buffer_pool_get_options; gstbufferpool_class->set_config = gst_gl_buffer_pool_set_config; gstbufferpool_class->alloc_buffer = gst_gl_buffer_pool_alloc; - gstbufferpool_class->acquire_buffer = gst_gl_buffer_pool_acquire_buffer; gstbufferpool_class->start = gst_gl_buffer_pool_start; } @@ -423,8 +333,6 @@ gst_gl_buffer_pool_init (GstGLBufferPool * pool) priv->caps = NULL; priv->add_videometa = TRUE; priv->add_glsyncmeta = FALSE; - priv->want_eglimage = FALSE; - priv->last_buffer = FALSE; } static void @@ -435,8 +343,6 @@ gst_gl_buffer_pool_finalize (GObject * object) GST_LOG_OBJECT (pool, "finalize GL buffer pool %p", pool); - gst_buffer_replace (&pool->priv->last_buffer, NULL); - if (priv->caps) gst_caps_unref (priv->caps); diff --git a/gst-libs/gst/gl/gstglbufferpool.h b/gst-libs/gst/gl/gstglbufferpool.h index ee133662f5..2f964a872f 100644 --- a/gst-libs/gst/gl/gstglbufferpool.h +++ b/gst-libs/gst/gl/gstglbufferpool.h @@ -61,8 +61,6 @@ struct _GstGLBufferPoolClass }; GstBufferPool *gst_gl_buffer_pool_new (GstGLContext * context); -void gst_gl_buffer_pool_replace_last_buffer (GstGLBufferPool * pool, - GstBuffer * buffer); GstGLAllocationParams * gst_buffer_pool_config_get_gl_allocation_params (GstStructure * config); void gst_buffer_pool_config_set_gl_allocation_params (GstStructure * config, diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index ee6a4b5873..00cb3877ca 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -67,7 +67,7 @@ #endif #if GST_GL_HAVE_PLATFORM_EGL #include -#include +#include #include #endif @@ -144,7 +144,6 @@ gst_gl_display_init (GstGLDisplay * display) gst_gl_memory_pbo_init_once (); #if GST_GL_HAVE_PLATFORM_EGL - gst_egl_image_memory_init (); gst_gl_memory_egl_init_once (); #endif } diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c index 79deefcbef..7c4e25409f 100644 --- a/gst-libs/gst/gl/gstglfilter.c +++ b/gst-libs/gst/gl/gstglfilter.c @@ -28,10 +28,6 @@ #include "gstglfilter.h" -#if GST_GL_HAVE_PLATFORM_EGL -#include "egl/gsteglimagememory.h" -#endif - #define GST_CAT_DEFAULT gst_gl_filter_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c index f172bfe849..87f230c4aa 100644 --- a/gst-libs/gst/gl/gstglupload.c +++ b/gst-libs/gst/gl/gstglupload.c @@ -28,7 +28,6 @@ #include "gstglupload.h" #if GST_GL_HAVE_PLATFORM_EGL -#include "egl/gsteglimagememory.h" #include "egl/gstglmemoryegl.h" #endif @@ -445,230 +444,12 @@ static const UploadMethod _gl_memory_upload = { &_gl_memory_upload_free }; -#if GST_GL_HAVE_PLATFORM_EGL -struct EGLImageUpload -{ - GstGLUpload *upload; - GstBuffer *buffer; - GstBuffer **outbuf; - GstGLVideoAllocationParams *params; -}; - -static gpointer -_egl_image_upload_new (GstGLUpload * upload) -{ - struct EGLImageUpload *image = g_new0 (struct EGLImageUpload, 1); - - image->upload = upload; - - return image; -} - -static GstCaps * -_egl_image_upload_transform_caps (GstGLContext * context, - GstPadDirection direction, GstCaps * caps) -{ - GstCapsFeatures *passthrough = - gst_caps_features_from_string - (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION); - GstCaps *ret; - - if (direction == GST_PAD_SINK) { - GstCaps *tmp; - - ret = - _set_caps_features_with_passthrough (caps, - GST_CAPS_FEATURE_MEMORY_GL_MEMORY, passthrough); - - tmp = _caps_intersect_texture_target (ret, 1 << GST_GL_TEXTURE_TARGET_2D); - gst_caps_unref (ret); - ret = tmp; - } else { - gint i, n; - - ret = - _set_caps_features_with_passthrough (caps, - GST_CAPS_FEATURE_MEMORY_EGL_IMAGE, passthrough); - gst_caps_set_simple (ret, "format", G_TYPE_STRING, "RGBA", NULL); - - n = gst_caps_get_size (ret); - for (i = 0; i < n; i++) { - GstStructure *s = gst_caps_get_structure (ret, i); - - gst_structure_remove_fields (s, "texture-target", NULL); - } - } - - gst_caps_features_free (passthrough); - - return ret; -} - -static gboolean -_egl_image_upload_accept (gpointer impl, GstBuffer * buffer, GstCaps * in_caps, - GstCaps * out_caps) -{ - struct EGLImageUpload *image = impl; - GstCapsFeatures *features; - gboolean ret = TRUE; - int i; - - features = gst_caps_get_features (in_caps, 0); - if (!gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_EGL_IMAGE)) - ret = FALSE; - - features = gst_caps_get_features (out_caps, 0); - if (!gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) - ret = FALSE; - - if (!ret) - return FALSE; - - if (image->params) - gst_gl_allocation_params_free ((GstGLAllocationParams *) image->params); - if (!(image->params = - gst_gl_video_allocation_params_new (image->upload->context, NULL, - &image->upload->priv->in_info, -1, NULL, - GST_GL_TEXTURE_TARGET_2D))) - return FALSE; - - if (buffer) { - GstVideoInfo *in_info = &image->upload->priv->in_info; - guint expected_memories = GST_VIDEO_INFO_N_PLANES (in_info); - - /* Support stereo views for separated multiview mode */ - if (GST_VIDEO_INFO_MULTIVIEW_MODE (in_info) == - GST_VIDEO_MULTIVIEW_MODE_SEPARATED) - expected_memories *= GST_VIDEO_INFO_VIEWS (in_info); - - if (gst_buffer_n_memory (buffer) != expected_memories) - return FALSE; - - for (i = 0; i < expected_memories; i++) { - GstMemory *mem = gst_buffer_peek_memory (buffer, i); - - if (!gst_is_egl_image_memory (mem)) - return FALSE; - } - } - - return TRUE; -} - -static void -_egl_image_upload_propose_allocation (gpointer impl, GstQuery * decide_query, - GstQuery * query) -{ - struct EGLImageUpload *image = impl; - GstCaps *caps; - GstCapsFeatures *features; - - gst_query_parse_allocation (query, &caps, NULL); - features = gst_caps_get_features (caps, 0); - - /* Only offer our custom allocator if that type of memory was negotiated. */ - if (gst_caps_features_contains (features, - GST_CAPS_FEATURE_MEMORY_EGL_IMAGE) && - gst_gl_context_check_feature (image->upload->context, - "EGL_KHR_image_base")) { - GstAllocationParams params; - GstAllocator *allocator; - - gst_allocation_params_init (¶ms); - - allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE); - gst_query_add_allocation_param (query, allocator, ¶ms); - gst_object_unref (allocator); - } -} - -static void -_egl_image_upload_perform_gl_thread (GstGLContext * context, - struct EGLImageUpload *image) -{ - GstGLMemoryAllocator *allocator; - guint i, n; - - allocator = - GST_GL_MEMORY_ALLOCATOR (gst_allocator_find - (GST_GL_MEMORY_PBO_ALLOCATOR_NAME)); - - /* FIXME: buffer pool */ - *image->outbuf = gst_buffer_new (); - gst_buffer_add_parent_buffer_meta (*image->outbuf, image->buffer); - - gst_gl_memory_setup_buffer (allocator, *image->outbuf, image->params, NULL, - 0); - gst_object_unref (allocator); - - n = gst_buffer_n_memory (image->buffer); - for (i = 0; i < n; i++) { - GstMemory *mem = gst_buffer_peek_memory (image->buffer, i); - GstGLMemory *out_gl_mem = - (GstGLMemory *) gst_buffer_peek_memory (*image->outbuf, i); - const GstGLFuncs *gl = NULL; - - gl = GST_GL_CONTEXT (((GstEGLImageMemory *) mem)->context)->gl_vtable; - - gl->ActiveTexture (GL_TEXTURE0 + i); - gl->BindTexture (GL_TEXTURE_2D, out_gl_mem->tex_id); - gl->EGLImageTargetTexture2D (GL_TEXTURE_2D, - gst_egl_image_memory_get_image (mem)); - } -} - -static GstGLUploadReturn -_egl_image_upload_perform (gpointer impl, GstBuffer * buffer, - GstBuffer ** outbuf) -{ - struct EGLImageUpload *image = impl; - - image->buffer = buffer; - image->outbuf = outbuf; - - gst_gl_context_thread_add (image->upload->context, - (GstGLContextThreadFunc) _egl_image_upload_perform_gl_thread, image); - - if (!*image->outbuf) - return GST_GL_UPLOAD_ERROR; - - return GST_GL_UPLOAD_DONE; -} - -static void -_egl_image_upload_free (gpointer impl) -{ - struct EGLImageUpload *image = impl; - - if (image->params) - gst_gl_allocation_params_free ((GstGLAllocationParams *) image->params); - - g_free (impl); -} - -static GstStaticCaps _egl_image_upload_caps = -GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_EGL_IMAGE, "RGBA")); - -static const UploadMethod _egl_image_upload = { - "EGLImage", - 0, - &_egl_image_upload_caps, - &_egl_image_upload_new, - &_egl_image_upload_transform_caps, - &_egl_image_upload_accept, - &_egl_image_upload_propose_allocation, - &_egl_image_upload_perform, - &_egl_image_upload_free -}; -#endif /* GST_GL_HAVE_PLATFORM_EGL */ - #if GST_GL_HAVE_DMABUF struct DmabufUpload { GstGLUpload *upload; - GstMemory *eglimage[GST_VIDEO_MAX_PLANES]; + GstEGLImage *eglimage[GST_VIDEO_MAX_PLANES]; GstBuffer *outbuf; GstGLVideoAllocationParams *params; }; @@ -740,7 +521,7 @@ _eglimage_quark (gint plane) return quark[plane]; } -static GstMemory * +static GstEGLImage * _get_cached_eglimage (GstMemory * mem, gint plane) { return gst_mini_object_get_qdata (GST_MINI_OBJECT (mem), @@ -748,10 +529,10 @@ _get_cached_eglimage (GstMemory * mem, gint plane) } static void -_set_cached_eglimage (GstMemory * mem, GstMemory * eglimage, gint plane) +_set_cached_eglimage (GstMemory * mem, GstEGLImage * eglimage, gint plane) { return gst_mini_object_set_qdata (GST_MINI_OBJECT (mem), - _eglimage_quark (plane), eglimage, (GDestroyNotify) gst_memory_unref); + _eglimage_quark (plane), eglimage, (GDestroyNotify) gst_egl_image_unref); } static gboolean @@ -801,9 +582,9 @@ _dma_buf_upload_accept (gpointer impl, GstBuffer * buffer, GstCaps * in_caps, if (dmabuf->params) gst_gl_allocation_params_free ((GstGLAllocationParams *) dmabuf->params); if (!(dmabuf->params = - gst_gl_video_allocation_params_new (dmabuf->upload->context, NULL, - &dmabuf->upload->priv->in_info, -1, NULL, - GST_GL_TEXTURE_TARGET_2D))) + gst_gl_video_allocation_params_new_wrapped_gl_handle (dmabuf->upload-> + context, NULL, &dmabuf->upload->priv->in_info, -1, NULL, + GST_GL_TEXTURE_TARGET_2D, NULL, NULL, NULL))) return FALSE; /* Find and validate all memories */ @@ -837,7 +618,7 @@ _dma_buf_upload_accept (gpointer impl, GstBuffer * buffer, GstCaps * in_caps, /* otherwise create one and cache it */ dmabuf->eglimage[i] = - gst_egl_image_memory_from_dmabuf (dmabuf->upload->context, + gst_egl_image_from_dmabuf (dmabuf->upload->context, gst_dmabuf_memory_get_fd (mems[i]), in_info, i, mems_skip[i]); if (!dmabuf->eglimage[i]) @@ -861,36 +642,16 @@ _dma_buf_upload_perform_gl_thread (GstGLContext * context, struct DmabufUpload *dmabuf) { GstGLMemoryAllocator *allocator; - guint i, n; allocator = GST_GL_MEMORY_ALLOCATOR (gst_allocator_find - (GST_GL_MEMORY_PBO_ALLOCATOR_NAME)); + (GST_GL_MEMORY_EGL_ALLOCATOR_NAME)); /* FIXME: buffer pool */ dmabuf->outbuf = gst_buffer_new (); - gst_gl_memory_setup_buffer (allocator, dmabuf->outbuf, dmabuf->params, NULL, - 0); + gst_gl_memory_setup_buffer (allocator, dmabuf->outbuf, dmabuf->params, + (gpointer *) dmabuf->eglimage, gst_buffer_n_memory (dmabuf->outbuf)); gst_object_unref (allocator); - - n = gst_buffer_n_memory (dmabuf->outbuf); - for (i = 0; i < n; i++) { - const GstGLFuncs *gl = NULL; - GstGLMemory *gl_mem = - (GstGLMemory *) gst_buffer_peek_memory (dmabuf->outbuf, i); - - if (!dmabuf->eglimage[i]) { - g_clear_pointer (&dmabuf->outbuf, gst_buffer_unref); - return; - } - - gl = GST_GL_CONTEXT (((GstEGLImageMemory *) gl_mem)->context)->gl_vtable; - - gl->ActiveTexture (GL_TEXTURE0 + i); - gl->BindTexture (GL_TEXTURE_2D, gl_mem->tex_id); - gl->EGLImageTargetTexture2D (GL_TEXTURE_2D, - gst_egl_image_memory_get_image (dmabuf->eglimage[i])); - } } static GstGLUploadReturn @@ -1397,9 +1158,6 @@ static const UploadMethod _raw_data_upload = { }; static const UploadMethod *upload_methods[] = { &_gl_memory_upload, -#if GST_GL_HAVE_PLATFORM_EGL - &_egl_image_upload, -#endif #if GST_GL_HAVE_DMABUF &_dma_buf_upload, #endif