egl: Add infrastructure for EGLImage handling

This commit is contained in:
Sebastian Dröge 2013-02-21 13:39:28 +01:00
parent a63ed8cfc7
commit 4dd09a12dd
8 changed files with 526 additions and 3 deletions

View file

@ -424,6 +424,30 @@ else
AG_GST_DISABLE_PLUGIN(dccp) AG_GST_DISABLE_PLUGIN(dccp)
fi fi
dnl *** gst-libs/gst/egl ***
PKG_CHECK_MODULES(EGL, egl, HAVE_EGL="yes", [
HAVE_EGL="no"
old_LIBS=$LIBS
old_CFLAGS=$CFLAGS
AC_CHECK_LIB([EGL], [eglGetProcAddress],
[
AC_CHECK_HEADER([EGL/egl.h],
[
HAVE_EGL="yes"
EGL_LIBS="-lEGL"
EGL_CFLAGS=""
]
)
]
)
LIBS=$old_LIBS
CFLAGS=$old_CFLAGS
]
)
AC_SUBST(EGL_LIBS)
AC_SUBST(EGL_CFLAGS)
AM_CONDITIONAL(HAVE_EGL, test x"$HAVE_EGL" = x"yes")
dnl *** sys plug-ins *** dnl *** sys plug-ins ***
dnl DirectSound dnl DirectSound
@ -2274,6 +2298,7 @@ gst/yadif/Makefile
gst-libs/Makefile gst-libs/Makefile
gst-libs/gst/Makefile gst-libs/gst/Makefile
gst-libs/gst/basecamerabinsrc/Makefile gst-libs/gst/basecamerabinsrc/Makefile
gst-libs/gst/egl/Makefile
gst-libs/gst/insertbin/Makefile gst-libs/gst/insertbin/Makefile
gst-libs/gst/interfaces/Makefile gst-libs/gst/interfaces/Makefile
gst-libs/gst/signalprocessor/Makefile gst-libs/gst/signalprocessor/Makefile
@ -2391,6 +2416,8 @@ pkgconfig/gstreamer-insertbin.pc
pkgconfig/gstreamer-insertbin-uninstalled.pc pkgconfig/gstreamer-insertbin-uninstalled.pc
pkgconfig/gstreamer-basevideo.pc pkgconfig/gstreamer-basevideo.pc
pkgconfig/gstreamer-basevideo-uninstalled.pc pkgconfig/gstreamer-basevideo-uninstalled.pc
pkgconfig/gstreamer-egl.pc
pkgconfig/gstreamer-egl-uninstalled.pc
tools/Makefile tools/Makefile
m4/Makefile m4/Makefile
win32/common/config.h win32/common/config.h

View file

@ -1,8 +1,11 @@
if HAVE_EGL
EGL_DIR = egl
endif
SUBDIRS = interfaces signalprocessor video basecamerabinsrc codecparsers \ SUBDIRS = interfaces signalprocessor video basecamerabinsrc codecparsers \
insertbin insertbin $(EGL_DIR)
noinst_HEADERS = gst-i18n-plugin.h gettext.h glib-compat-private.h 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 insertbin

View file

@ -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 \
> $@

298
gst-libs/gst/egl/egl.c Normal file
View file

@ -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

73
gst-libs/gst/egl/egl.h Normal file
View file

@ -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__ */

View file

@ -1,3 +1,4 @@
### all of the standard pc files we need to generate ### all of the standard pc files we need to generate
pcverfiles = \ pcverfiles = \
gstreamer-plugins-bad-@GST_API_VERSION@.pc \ gstreamer-plugins-bad-@GST_API_VERSION@.pc \
@ -11,6 +12,11 @@ pcverfiles_uninstalled = \
gstreamer-insertbin-@GST_API_VERSION@-uninstalled.pc \ gstreamer-insertbin-@GST_API_VERSION@-uninstalled.pc \
gstreamer-basevideo-@GST_API_VERSION@-uninstalled.pc gstreamer-basevideo-@GST_API_VERSION@-uninstalled.pc
if HAVE_EGL
pcverfiles += gstreamer-egl-@GST_API_VERSION@.pc
pcverfiles_uninstalled += gstreamer-egl-@GST_API_VERSION@-uninstalled.pc
endif
all-local: $(pcverfiles) $(pcverfiles_uninstalled) all-local: $(pcverfiles) $(pcverfiles_uninstalled)
cp_verbose = $(cp_verbose_$(V)) cp_verbose = $(cp_verbose_$(V))
@ -31,7 +37,8 @@ pcinfiles = \
gstreamer-plugins-bad.pc.in gstreamer-plugins-bad-uninstalled.pc.in \ gstreamer-plugins-bad.pc.in gstreamer-plugins-bad-uninstalled.pc.in \
gstreamer-codecparsers.pc.in gstreamer-codecparsers-uninstalled.pc.in \ gstreamer-codecparsers.pc.in gstreamer-codecparsers-uninstalled.pc.in \
gstreamer-insertbin.pc.in gstreamer-insertbin-uninstalled.pc.in \ gstreamer-insertbin.pc.in gstreamer-insertbin-uninstalled.pc.in \
gstreamer-basevideo.pc.in gstreamer-basevideo-uninstalled.pc.in gstreamer-basevideo.pc.in gstreamer-basevideo-uninstalled.pc.in \
gstreamer-egl.pc.in gstreamer-egl-uninstalled.pc.in
DISTCLEANFILES = $(pcinfiles:.in=) DISTCLEANFILES = $(pcinfiles:.in=)
EXTRA_DIST = $(pcinfiles) EXTRA_DIST = $(pcinfiles)

View file

@ -0,0 +1,12 @@
prefix=
exec_prefix=
libdir=${pcfiledir}/../gst-libs/gst/egl
includedir=${pcfiledir}/../gst-libs
Name: GStreamer EGL, Uninstalled
Description: GStreamer EGL Library, uninstalled
Requires: gstreamer-@GST_API_VERSION@
Version: @VERSION@
Libs: -L${libdir} ${libdir}/libgstegl-@GST_API_VERSION@.la @EGL_LIBS@
Cflags: -I${includedir} @EGL_CFLAGS@

View file

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@/gstreamer-@GST_API_VERSION@
Name: GStreamer EGL
Description: GStreamer EGL library
Requires: gstreamer-@GST_API_VERSION@
Version: @VERSION@
Libs: -L${libdir} -lgstegl-@GST_API_VERSION@ @EGL_LIBS@
Cflags: -I${includedir} @EGL_CFLAGS@