summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2013-02-21 13:39:28 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2013-03-03 12:31:04 +0100
commit4dd09a12dd2051fd38a183a8665c14ffd6548ed8 (patch)
treeea5a9175405b0e18085ee608f464d6a09f055ae4 /gst-libs
parenta63ed8cfc75d7b118ed44b97ef4725ee7790fd8b (diff)
downloadgstreamer-plugins-bad-4dd09a12dd2051fd38a183a8665c14ffd6548ed8.tar.gz
egl: Add infrastructure for EGLImage handling
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/Makefile.am7
-rw-r--r--gst-libs/gst/egl/Makefile.am91
-rw-r--r--gst-libs/gst/egl/egl.c298
-rw-r--r--gst-libs/gst/egl/egl.h73
4 files changed, 467 insertions, 2 deletions
diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am
index 2868042aa..c1b3081e6 100644
--- a/gst-libs/gst/Makefile.am
+++ b/gst-libs/gst/Makefile.am
@@ -1,8 +1,11 @@
+if HAVE_EGL
+EGL_DIR = egl
+endif
SUBDIRS = interfaces signalprocessor video basecamerabinsrc codecparsers \
- insertbin
+ insertbin $(EGL_DIR)
noinst_HEADERS = gst-i18n-plugin.h gettext.h glib-compat-private.h
-DIST_SUBDIRS = interfaces signalprocessor video basecamerabinsrc codecparsers \
+DIST_SUBDIRS = interfaces egl signalprocessor video basecamerabinsrc codecparsers \
insertbin
diff --git a/gst-libs/gst/egl/Makefile.am b/gst-libs/gst/egl/Makefile.am
new file mode 100644
index 000000000..c89fcb518
--- /dev/null
+++ b/gst-libs/gst/egl/Makefile.am
@@ -0,0 +1,91 @@
+lib_LTLIBRARIES = libgstegl-@GST_API_VERSION@.la
+
+libgstegl_@GST_API_VERSION@_la_SOURCES = egl.c
+
+libgstegl_@GST_API_VERSION@includedir = \
+ $(includedir)/gstreamer-@GST_API_VERSION@/gst/egl
+
+libgstegl_@GST_API_VERSION@include_HEADERS = egl.h
+
+libgstegl_@GST_API_VERSION@_la_CFLAGS = \
+ $(GST_PLUGINS_BAD_CFLAGS) \
+ $(GST_CFLAGS) \
+ $(EGL_CFLAGS)
+
+libgstegl_@GST_API_VERSION@_la_LIBADD = \
+ $(GST_LIBS) \
+ $(EGL_LIBS)
+
+libgstegl_@GST_API_VERSION@_la_LDFLAGS = \
+ $(GST_LIB_LDFLAGS) \
+ $(GST_ALL_LDFLAGS) \
+ $(GST_LT_LDFLAGS)
+
+
+if HAVE_INTROSPECTION
+BUILT_GIRSOURCES = GstEGL-@GST_API_VERSION@.gir
+
+gir_headers=$(patsubst %,$(srcdir)/%, $(libgstegl_@GST_API_VERSION@include_HEADERS))
+gir_headers+=$(patsubst %,$(builddir)/%, $(built_headers))
+gir_sources=$(patsubst %,$(srcdir)/%, $(libgstegl_@GST_API_VERSION@_la_SOURCES))
+gir_sources+=$(patsubst %,$(builddir)/%, $(built_sources))
+
+GstEGL-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstegl-@GST_API_VERSION@.la
+ $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+ GST_PLUGIN_SYSTEM_PATH_1_0="" GST_PLUGIN_PATH_1_0="" GST_REGISTRY_UPDATE=no \
+ $(INTROSPECTION_SCANNER) -v --namespace GstEGL \
+ --nsversion=@GST_API_VERSION@ \
+ --strip-prefix=Gst \
+ --warn-all \
+ --c-include "gst/egl/egl.h" \
+ -I$(top_srcdir)/gst-libs \
+ -I$(top_builddir)/gst-libs \
+ --add-include-path=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-@GST_API_VERSION@` \
+ --add-include-path=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-base-@GST_API_VERSION@` \
+ --library=libgstegl-@GST_API_VERSION@.la \
+ --include=Gst-@GST_API_VERSION@ \
+ --libtool="$(top_builddir)/libtool" \
+ --pkg gstreamer-@GST_API_VERSION@ \
+ --pkg-export gstreamer-egl-@GST_API_VERSION@ \
+ --add-init-section="gst_init(NULL,NULL);" \
+ -DGST_USE_UNSTABLE_API \
+ --output $@ \
+ $(gir_headers) \
+ $(gir_sources)
+
+# INTROSPECTION_GIRDIR/INTROSPECTION_TYPELIBDIR aren't the right place to
+# install anything - we need to install inside our prefix.
+girdir = $(datadir)/gir-1.0
+gir_DATA = $(BUILT_GIRSOURCES)
+
+typelibsdir = $(libdir)/girepository-1.0/
+
+typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
+
+%.typelib: %.gir $(INTROSPECTION_COMPILER)
+ $(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+ $(INTROSPECTION_COMPILER) \
+ --includedir=$(srcdir) \
+ --includedir=$(builddir) \
+ --includedir=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-@GST_API_VERSION@` \
+ --includedir=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-base-@GST_API_VERSION@` \
+ $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
+
+CLEANFILES = $(BUILT_GIRSOURCES) $(typelibs_DATA)
+endif
+
+Android.mk: $(BUILT_SOURCES) Makefile.am
+ androgenizer -:PROJECT libgstegl -:STATIC libgstegl-@GST_API_VERSION@ \
+ -:TAGS eng debug \
+ -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
+ -:SOURCES $(libgstegl_@GST_API_VERSION@_la_SOURCES) \
+ $(built_sources) \
+ -:CFLAGS $(DEFS) $(libgstegl_@GST_API_VERSION@_la_CFLAGS) \
+ -:LDFLAGS $(libgstegl_@GST_API_VERSION@_la_LDFLAGS) \
+ $(libgstegl@GST_API_VERSION@_la_LIBADD) \
+ -ldl \
+ -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/egl \
+ -:HEADERS $(libgsteglinclude_HEADERS) \
+ $(built_headers) \
+ -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
+ > $@
diff --git a/gst-libs/gst/egl/egl.c b/gst-libs/gst/egl/egl.c
new file mode 100644
index 000000000..bbebae6a4
--- /dev/null
+++ b/gst-libs/gst/egl/egl.c
@@ -0,0 +1,298 @@
+/*
+ * GStreamer EGL Library
+ * Copyright (C) 2012 Collabora Ltd.
+ * @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * *
+ * 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
+
+#define EGL_EGLEXT_PROTOTYPES
+
+#include <gst/egl/egl.h>
+
+typedef struct
+{
+ GstMemory parent;
+
+ GstEGLDisplay *display;
+ EGLImageKHR image;
+ GstEGLImageType type;
+
+ gpointer user_data;
+ GDestroyNotify user_data_destroy;
+} GstEGLImageMemory;
+
+#define GST_EGL_IMAGE_MEMORY(mem) ((GstEGLImageMemory*)(mem))
+
+gboolean
+gst_egl_image_memory_can_map (void)
+{
+ return FALSE;
+}
+
+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);
+
+ return GST_EGL_IMAGE_MEMORY (mem)->image;
+}
+
+GstEGLDisplay *
+gst_egl_image_memory_get_display (GstMemory * mem)
+{
+ g_return_val_if_fail (gst_is_egl_image_memory (mem), EGL_NO_IMAGE_KHR);
+
+ return gst_egl_display_ref (GST_EGL_IMAGE_MEMORY (mem)->display);
+}
+
+GstEGLImageType
+gst_egl_image_memory_get_type (GstMemory * mem)
+{
+ g_return_val_if_fail (gst_is_egl_image_memory (mem),
+ GST_EGL_IMAGE_MEMORY_TYPE_INVALID);
+
+ return GST_EGL_IMAGE_MEMORY (mem)->type;
+}
+
+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;
+ EGLDisplay display;
+
+ display = gst_egl_display_get (emem->display);
+ eglDestroyImageKHR (display, emem->image);
+
+ if (emem->user_data_destroy)
+ emem->user_data_destroy (emem->user_data);
+
+ gst_egl_display_unref (emem->display);
+
+ 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 GstAllocator GstEGLImageAllocator;
+typedef GstAllocatorClass GstEGLImageAllocatorClass;
+
+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)
+{
+ return g_object_new (gst_egl_image_allocator_get_type (), NULL);
+}
+
+GstAllocator *
+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 GST_ALLOCATOR (g_object_ref (once.retval));
+}
+
+GstMemory *
+gst_egl_image_allocator_alloc (GstAllocator * allocator,
+ GstEGLDisplay * display, GstEGLImageType type, gint width, gint height,
+ gsize * size)
+{
+ return NULL;
+}
+
+GstMemory *
+gst_egl_image_allocator_wrap (GstAllocator * allocator,
+ GstEGLDisplay * display, EGLImageKHR image, GstEGLImageType type,
+ gsize size, gpointer user_data, GDestroyNotify user_data_destroy)
+{
+ GstEGLImageMemory *mem;
+
+ g_return_val_if_fail (display != NULL, NULL);
+ g_return_val_if_fail (image != EGL_NO_IMAGE_KHR, NULL);
+ g_return_val_if_fail (type != GST_EGL_IMAGE_MEMORY_TYPE_INVALID, NULL);
+
+ if (!allocator) {
+ allocator = gst_egl_image_allocator_obtain ();
+ }
+
+ mem = g_slice_new (GstEGLImageMemory);
+ gst_memory_init (GST_MEMORY_CAST (mem), GST_MEMORY_FLAG_NO_SHARE, allocator,
+ NULL, size, 0, 0, 0);
+
+ mem->display = gst_egl_display_ref (display);
+ mem->image = image;
+ mem->type = type;
+
+ mem->user_data = user_data;
+ mem->user_data_destroy = user_data_destroy;
+
+ return GST_MEMORY_CAST (mem);
+}
+
+struct _GstEGLDisplay
+{
+ EGLDisplay display;
+ volatile gint refcount;
+};
+
+GstEGLDisplay *
+gst_egl_display_new (EGLDisplay display)
+{
+ GstEGLDisplay *gdisplay;
+
+ gdisplay = g_slice_new (GstEGLDisplay);
+ gdisplay->display = display;
+ gdisplay->refcount = 1;
+
+ return gdisplay;
+}
+
+GstEGLDisplay *
+gst_egl_display_ref (GstEGLDisplay * display)
+{
+ g_return_val_if_fail (display != NULL, NULL);
+
+ g_atomic_int_inc (&display->refcount);
+
+ return display;
+}
+
+void
+gst_egl_display_unref (GstEGLDisplay * display)
+{
+ g_return_if_fail (display != NULL);
+
+ if (g_atomic_int_dec_and_test (&display->refcount)) {
+ if (display != EGL_NO_DISPLAY)
+ eglTerminate (display->display);
+ g_slice_free (GstEGLDisplay, display);
+ }
+}
+
+EGLDisplay
+gst_egl_display_get (GstEGLDisplay * display)
+{
+ g_return_val_if_fail (display != NULL, NULL);
+
+ return display->display;
+}
+
+#if 0
+void
+gst_buffer_pool_config_set_egl_image_supports_multiple_images (GstStructure *
+ config, gboolean supported)
+{
+ g_return_if_fail (config != NULL);
+
+ gst_structure_set (config,
+ "egl-image-supports-multiple-images", G_TYPE_BOOLEAN, supported, NULL);
+}
+
+gboolean
+gst_buffer_pool_config_get_egl_image_supports_multiple_images (GstStructure *
+ config, gboolean * supported)
+{
+ g_return_val_if_fail (config != NULL, FALSE);
+ g_return_val_if_fail (supported != NULL, FALSE);
+
+ return gst_structure_get (config,
+ "egl-image-supports-multiple-images", G_TYPE_BOOLEAN, supported, NULL);
+}
+#endif
diff --git a/gst-libs/gst/egl/egl.h b/gst-libs/gst/egl/egl.h
new file mode 100644
index 000000000..ac5dfe285
--- /dev/null
+++ b/gst-libs/gst/egl/egl.h
@@ -0,0 +1,73 @@
+/*
+ * GStreamer EGL Library
+ * Copyright (C) 2012 Collabora Ltd.
+ * @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * *
+ * 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_H__
+#define __GST_EGL_H__
+
+#include <gst/gst.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#define GST_EGL_IMAGE_MEMORY_TYPE "EGLImage"
+
+typedef enum {
+ GST_EGL_IMAGE_MEMORY_TYPE_INVALID = -1,
+ /* GL formats */
+ GST_EGL_IMAGE_MEMORY_TYPE_LUMINANCE = 0x0000,
+ GST_EGL_IMAGE_MEMORY_TYPE_LUMINANCE_ALPHA,
+ GST_EGL_IMAGE_MEMORY_TYPE_RGB16,
+ GST_EGL_IMAGE_MEMORY_TYPE_RGB,
+ GST_EGL_IMAGE_MEMORY_TYPE_RGBA,
+ /* YUV formats */
+ /* GST_EGL_IMAGE_MEMORY_TYPE_YUV420P = 0x1000, */
+ /* Other */
+ GST_EGL_IMAGE_MEMORY_TYPE_OTHER = 0xffff
+} GstEGLImageType;
+
+typedef struct _GstEGLDisplay GstEGLDisplay;
+
+/* EGLImage GstMemory handling */
+gboolean gst_egl_image_memory_can_map (void);
+gboolean gst_is_egl_image_memory (GstMemory * mem);
+EGLImageKHR gst_egl_image_memory_get_image (GstMemory * mem);
+GstEGLDisplay * gst_egl_image_memory_get_display (GstMemory * mem);
+GstEGLImageType gst_egl_image_memory_get_type (GstMemory * mem);
+
+/* Generic EGLImage allocator that doesn't support mapping, copying or anything */
+GstAllocator * gst_egl_image_allocator_obtain (void);
+GstMemory * gst_egl_image_allocator_alloc (GstAllocator * allocator, GstEGLDisplay * display, GstEGLImageType type, gint width, gint height, gsize * size);
+GstMemory * gst_egl_image_allocator_wrap (GstAllocator * allocator, GstEGLDisplay * display, EGLImageKHR image, GstEGLImageType type, gsize size, gpointer user_data, GDestroyNotify user_data_destroy);
+
+/* EGLDisplay wrapper with refcount, connection is closed after last ref is gone */
+GstEGLDisplay * gst_egl_display_new (EGLDisplay display);
+GstEGLDisplay * gst_egl_display_ref (GstEGLDisplay * display);
+void gst_egl_display_unref (GstEGLDisplay * display);
+EGLDisplay gst_egl_display_get (GstEGLDisplay * display);
+
+#define GST_BUFFER_POOL_OPTION_EGL_IMAGE "GstBufferPoolOptionEGLImage"
+
+#if 0
+/* setting a bufferpool config */
+void gst_buffer_pool_config_set_egl_image_supports_multiple_images (GstStructure *config, gboolean supported);
+gboolean gst_buffer_pool_config_get_egl_image_supports_multiple_images (GstStructure *config, gboolean *supported);
+#endif
+
+#endif /* __GST_EGL_H__ */