plugins: add initial support for EGL.

Add initial support for EGL through GstVideoGLTextureUploadMeta.

Fix gst_vaapi_ensure_display() to allocate a GstVaapiDisplay off the
downstream supplied GstGLContext configuration, i.e. use its native
display handle to create a GstVaapiDisplay of type X11 or Wayland ;
and use the desired OpenGL API to allocate the GstVaapiDisplayEGL
wrapper.

https://bugzilla.gnome.org/show_bug.cgi?id=741079
This commit is contained in:
Gwenole Beauchesne 2015-02-20 15:29:17 +01:00
parent 44013fdaf0
commit 60e96e80cc
7 changed files with 161 additions and 27 deletions

View file

@ -535,6 +535,11 @@ AM_CONDITIONAL([USE_GST_GL_HELPERS], [test $HAVE_GSTGL -eq 1])
AC_DEFINE_UNQUOTED([USE_GST_GL_HELPERS], [$HAVE_GSTGL],
[Defined to 1 if GStreamer OpenGL helper libraries are available])
if test "$enable_egl" = "yes" -a $HAVE_GSTGL -ne 1; then
AC_MSG_WARN([GStreamer/GL helper libraries not found, disabling EGL support])
enable_egl="no"
fi
case $GST_API_VERSION in
0.10) lt_bias=gst0_vaapi_lt_current_bias;;
1.0) lt_bias=gst1_vaapi_lt_current_bias;;

View file

@ -26,6 +26,11 @@ libgstvaapi_LIBS += \
$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_API_VERSION).la
endif
if USE_EGL
libgstvaapi_LIBS += \
$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-egl-$(GST_API_VERSION).la
endif
if USE_WAYLAND
libgstvaapi_CFLAGS += \
$(WAYLAND_CFLAGS) \
@ -116,6 +121,14 @@ libgstvaapi_source_h += $(libgstvaapi_glx_source_h)
endif
endif
libgstvaapi_egl_source_c =
libgstvaapi_egl_source_h =
if USE_EGL
libgstvaapi_source_c += $(libgstvaapi_egl_source_c)
libgstvaapi_source_h += $(libgstvaapi_egl_source_h)
endif
libgstvaapi_1_2p_source_c = \
gstvaapivideometa_texture.c \
$(NULL)
@ -256,7 +269,7 @@ CLEANFILES = \
EXTRA_DIST = \
$(libgstvaapi_enc_source_c) \
$(libgstvaapi_enc_source_h) \
$(libgstvaapi_jpegenc_source_c) \
$(libgstvaapi_jpegenc_source_c) \
$(libgstvaapi_jpegenc_source_h) \
$(libgstvaapi_vp8enc_source_c) \
$(libgstvaapi_vp8enc_source_h) \
@ -264,6 +277,8 @@ EXTRA_DIST = \
$(libgstvaapi_x11_source_h) \
$(libgstvaapi_glx_source_c) \
$(libgstvaapi_glx_source_h) \
$(libgstvaapi_egl_source_c) \
$(libgstvaapi_egl_source_h) \
$(libgstvaapi_1_2p_source_c) \
$(libgstvaapi_1_2p_source_h) \
$(libgstvaapi_1_0p_source_c) \

View file

@ -36,7 +36,7 @@
#include "gstvaapidecode.h"
#include "gstvaapipluginutil.h"
#include "gstvaapivideobuffer.h"
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
#include "gstvaapivideometa_texture.h"
#endif
#if GST_CHECK_VERSION(1,0,0)
@ -342,7 +342,7 @@ gst_vaapidecode_push_decoded_frame(GstVideoDecoder *vdec,
}
}
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
if (decode->has_texture_upload_meta)
gst_buffer_ensure_texture_upload_meta(out_frame->output_buffer);
#endif
@ -528,7 +528,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query)
gst_query_parse_allocation(query, &caps, &need_pool);
decode->has_texture_upload_meta = FALSE;
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
decode->has_texture_upload_meta =
gst_vaapi_find_preferred_caps_feature(GST_VIDEO_DECODER_SRC_PAD(vdec),
GST_VIDEO_FORMAT_ENCODED) ==

View file

@ -655,7 +655,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
gboolean need_pool, update_pool;
gboolean has_video_meta = FALSE;
gboolean has_video_alignment = FALSE;
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
gboolean has_texture_upload_meta = FALSE;
guint idx;
#endif
@ -679,7 +679,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
has_video_meta = gst_query_find_allocation_meta (query,
GST_VIDEO_META_API_TYPE, NULL);
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
has_texture_upload_meta = gst_query_find_allocation_meta (query,
GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx);
@ -751,7 +751,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
if (has_texture_upload_meta)
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META);
@ -765,7 +765,7 @@ gst_vaapi_plugin_base_decide_allocation (GstVaapiPluginBase * plugin,
}
/* GstVideoGLTextureUploadMeta (OpenGL) */
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META
&& !has_texture_upload_meta) {
config = gst_buffer_pool_get_config (pool);
@ -1023,6 +1023,11 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin,
case GST_GL_PLATFORM_GLX:
display_type = GST_VAAPI_DISPLAY_TYPE_GLX;
break;
#endif
#if USE_EGL
case GST_GL_PLATFORM_EGL:
display_type = GST_VAAPI_DISPLAY_TYPE_EGL;
break;
#endif
default:
display_type = plugin->display_type;

View file

@ -33,6 +33,9 @@
#if USE_GLX
# include <gst/vaapi/gstvaapidisplay_glx.h>
#endif
#if USE_EGL
# include <gst/vaapi/gstvaapidisplay_egl.h>
#endif
#if USE_WAYLAND
# include <gst/vaapi/gstvaapidisplay_wayland.h>
#endif
@ -58,36 +61,48 @@ static const char *display_types[] = {
NULL
};
typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFunc) (const gchar *);
typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFromHandleFunc) (gpointer);
typedef struct
{
const gchar *type_str;
GstVaapiDisplayType type;
GstVaapiDisplay *(*create_display) (const gchar *);
GstVaapiDisplayCreateFunc create_display;
GstVaapiDisplayCreateFromHandleFunc create_display_from_handle;
} DisplayMap;
/* *INDENT-OFF* */
static const DisplayMap g_display_map[] = {
#if USE_WAYLAND
{"wayland",
GST_VAAPI_DISPLAY_TYPE_WAYLAND,
gst_vaapi_display_wayland_new},
GST_VAAPI_DISPLAY_TYPE_WAYLAND,
gst_vaapi_display_wayland_new,
(GstVaapiDisplayCreateFromHandleFunc)
gst_vaapi_display_wayland_new_with_display},
#endif
#if USE_GLX
{"glx",
GST_VAAPI_DISPLAY_TYPE_GLX,
gst_vaapi_display_glx_new},
GST_VAAPI_DISPLAY_TYPE_GLX,
gst_vaapi_display_glx_new,
(GstVaapiDisplayCreateFromHandleFunc)
gst_vaapi_display_glx_new_with_display},
#endif
#if USE_X11
{"x11",
GST_VAAPI_DISPLAY_TYPE_X11,
gst_vaapi_display_x11_new},
GST_VAAPI_DISPLAY_TYPE_X11,
gst_vaapi_display_x11_new,
(GstVaapiDisplayCreateFromHandleFunc)
gst_vaapi_display_x11_new_with_display},
#endif
#if USE_DRM
{"drm",
GST_VAAPI_DISPLAY_TYPE_DRM,
gst_vaapi_display_drm_new},
GST_VAAPI_DISPLAY_TYPE_DRM,
gst_vaapi_display_drm_new},
#endif
{NULL,}
};
/* *INDENT-ON* */
static GstVaapiDisplay *
gst_vaapi_create_display (GstVaapiDisplayType display_type,
@ -107,6 +122,98 @@ gst_vaapi_create_display (GstVaapiDisplayType display_type,
return display;
}
static GstVaapiDisplay *
gst_vaapi_create_display_from_handle (GstVaapiDisplayType display_type,
gpointer handle)
{
GstVaapiDisplay *display;
const DisplayMap *m;
if (display_type == GST_VAAPI_DISPLAY_TYPE_ANY)
return NULL;
for (m = g_display_map; m->type_str != NULL; m++) {
if (m->type == display_type) {
display = m->create_display_from_handle ?
m->create_display_from_handle (handle) : NULL;
return display;
}
}
return NULL;
}
static GstVaapiDisplay *
gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object)
{
#if USE_GST_GL_HELPERS
GstGLContext *const gl_context = GST_GL_CONTEXT (gl_context_object);
GstGLDisplay *const gl_display = gst_gl_context_get_display (gl_context);
GstVaapiDisplay *display, *out_display;
GstVaapiDisplayType display_type;
switch (gst_gl_display_get_handle_type (gl_display)) {
#if USE_X11
case GST_GL_DISPLAY_TYPE_X11:
display_type = GST_VAAPI_DISPLAY_TYPE_X11;
break;
#endif
#if USE_WAYLAND
case GST_GL_DISPLAY_TYPE_WAYLAND:
display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND;
break;
#endif
default:
display_type = GST_VAAPI_DISPLAY_TYPE_ANY;
break;
}
if (!display_type)
return NULL;
display = gst_vaapi_create_display_from_handle (display_type,
GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display)));
if (!display)
return NULL;
switch (gst_gl_context_get_gl_platform (gl_context)) {
#if USE_EGL
case GST_GL_PLATFORM_EGL:{
guint gles_version;
switch (gst_gl_context_get_gl_api (gl_context)) {
case GST_GL_API_GLES1:
gles_version = 1;
goto create_egl_display;
case GST_GL_API_GLES2:
gles_version = 2;
goto create_egl_display;
case GST_GL_API_OPENGL:
case GST_GL_API_OPENGL3:
gles_version = 0;
create_egl_display:
out_display = gst_vaapi_display_egl_new (display, gles_version);
break;
default:
out_display = NULL;
break;
}
if (!out_display)
return NULL;
gst_vaapi_display_egl_set_gl_context (GST_VAAPI_DISPLAY_EGL (out_display),
GSIZE_TO_POINTER (gst_gl_context_get_gl_context (gl_context)));
break;
}
#endif
default:
out_display = gst_vaapi_display_ref (display);
break;
}
gst_vaapi_display_unref (display);
return out_display;
#endif
GST_ERROR ("unsupported GStreamer version %s", GST_API_VERSION_S);
return NULL;
}
gboolean
gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type)
{
@ -126,7 +233,10 @@ gst_vaapi_ensure_display (gpointer element, GstVaapiDisplayType type)
return TRUE;
/* If no neighboor, or application not interested, use system default */
display = gst_vaapi_create_display (type, plugin->display_name);
if (plugin->gl_context)
display = gst_vaapi_create_display_from_gl_context (plugin->gl_context);
else
display = gst_vaapi_create_display (type, plugin->display_name);
if (!display)
return FALSE;

View file

@ -24,7 +24,7 @@
#include "gstvaapivideobufferpool.h"
#include "gstvaapivideobuffer.h"
#include "gstvaapivideomemory.h"
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
#include "gstvaapivideometa_texture.h"
#endif
@ -288,7 +288,7 @@ gst_vaapi_video_buffer_pool_alloc_buffer (GstBufferPool * pool,
}
}
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
if (priv->has_texture_upload_meta)
gst_buffer_add_texture_upload_meta (buffer);
#endif

View file

@ -25,20 +25,18 @@
*/
#include "gst/vaapi/sysdeps.h"
#include "gst/vaapi/ogl_compat.h"
#include "gstvaapivideometa.h"
#include "gstvaapivideometa_texture.h"
#include "gstvaapipluginutil.h"
#if USE_GLX
#include <GL/gl.h>
#include <gst/vaapi/gstvaapitexture_glx.h>
#endif
#define DEFAULT_FORMAT GST_VIDEO_FORMAT_RGBA
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#include "gstvaapivideometa_texture.h"
#if GST_CHECK_VERSION(1,1,0) && (USE_GLX || USE_EGL)
struct _GstVaapiVideoMetaTexture
{
GstVaapiTexture *texture;
@ -148,8 +146,9 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta,
gst_vaapi_texture_get_id (meta_texture->texture) != texture_id[0]) {
/* FIXME: should we assume target? */
GstVaapiTexture *const texture =
gst_vaapi_texture_glx_new_wrapped (dpy, texture_id[0],
GL_TEXTURE_2D, meta_texture->gl_format);
gst_vaapi_texture_new_wrapped (dpy, texture_id[0],
GL_TEXTURE_2D, meta_texture->gl_format, meta_texture->width,
meta_texture->height);
gst_vaapi_texture_replace (&meta_texture->texture, texture);
if (!texture)
return FALSE;