From 28f73fb582b5bd1913dc97fb019fa11035e44c2b Mon Sep 17 00:00:00 2001 From: gb Date: Tue, 30 Mar 2010 13:01:34 +0000 Subject: [PATCH] Enable build without VA/GLX extensions. i.e. fallback to TFP + FBO. --- configure.ac | 43 +++++-- gst-libs/gst/vaapi/gstvaapicompat.h | 6 + gst-libs/gst/vaapi/gstvaapidisplay_glx.c | 1 + gst-libs/gst/vaapi/gstvaapidisplay_glx.h | 1 - gst-libs/gst/vaapi/gstvaapitexture.c | 197 ++++++++++++++++++++++++++----- tests/test-display.c | 6 + 6 files changed, 209 insertions(+), 45 deletions(-) diff --git a/configure.ac b/configure.ac index e6ed60c..f008506 100644 --- a/configure.ac +++ b/configure.ac @@ -75,6 +75,11 @@ AC_ARG_ENABLE(glx, [enable OpenGL/X11 @<:@default=yes@:>@]), [], [enable_glx="yes"]) +AC_ARG_ENABLE(vaapi-glx, + AC_HELP_STRING([--enable-vaapi-glx], + [enable VA/GLX extensions @<:@default=yes@:>@]), + [], [enable_vaapi_glx="yes"]) + AC_ARG_ENABLE(vaapisink-glx, AC_HELP_STRING([--enable-vaapisink-glx], [enable OpenGL/X11 to vaapisink @<:@default=yes@:>@]), @@ -220,15 +225,20 @@ if test "$ac_cv_have_vaapi_x11" = "no"; then fi AC_SUBST(LIBVA_X11_PKGNAME) -dnl ... VA-API >= 0.31 or -sds -LIBVA_GLX_PKGNAME="libva-glx" -PKG_CHECK_MODULES(LIBVA_GLX, [$LIBVA_GLX_PKGNAME], - [ac_cv_have_vaapi_glx="yes"], - [ac_cv_have_vaapi_glx="no"] -) -if test "$ac_cv_have_vaapi_glx" = "no"; then - AC_MSG_WARN([could not find VA/GLX extensions. Disabling GLX support]) - USE_GLX=0 +dnl ... VA-API >= 0.31 or -sds (VA/GLX extensions) +USE_VAAPI_GLX=0 +if test $USE_GLX -eq 1; then + if test "$enable_vaapi_glx" = "yes"; then + LIBVA_GLX_PKGNAME="libva-glx" + PKG_CHECK_MODULES(LIBVA_GLX, [$LIBVA_GLX_PKGNAME], + [ac_cv_have_vaapi_glx="yes" USE_VAAPI_GLX=1], + [ac_cv_have_vaapi_glx="no"] + ) + fi + if test $USE_VAAPI_GLX -eq 0; then + AC_MSG_WARN([VA/GLX not found or disabled. Fallbacking to TFP+FBO]) + LIBVA_GLX_PKGNAME="$LIBVA_X11_PKGNAME" + fi fi AC_SUBST(LIBVA_GLX_PKGNAME) @@ -242,9 +252,14 @@ else USE_VAAPISINK_GLX=0 fi -AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled]) +AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, + [Defined to 1 if GLX is enabled]) AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1) +AC_DEFINE_UNQUOTED(USE_VAAPI_GLX, $USE_VAAPI_GLX, + [Defined to 1 if VA/GLX is enabled]) +AM_CONDITIONAL(USE_VAAPI_GLX, test $USE_VAAPI_GLX -eq 1) + AC_DEFINE_UNQUOTED(USE_VAAPISINK_GLX, $USE_VAAPISINK_GLX, [Defined to 1 to enable GLX support to vaapisink]) AM_CONDITIONAL(USE_VAAPISINK_GLX, test $USE_VAAPISINK_GLX -eq 1) @@ -303,10 +318,14 @@ pkgconfig/gstreamer-vaapi-x11.pc.in ]) dnl Print summary +conf_glx=$(test $USE_GLX -eq 1 && echo yes || echo no) +conf_vaapi_glx=$(test $USE_VAAPI_GLX -eq 1 && echo yes || echo no) +conf_vaapisink_glx=$(test $USE_VAAPISINK_GLX -eq 1 && echo yes || echo no) echo echo $PACKAGE configuration summary: echo echo VA-API version ................... : $VA_VERSION_STR -echo GLX support ...................... : $(test $USE_GLX -eq 1 && echo yes || echo no) -echo Build vaapisink with OpenGL ...... : $(test $USE_VAAPISINK_GLX -eq 1 && echo yes || echo no) +echo GLX support ...................... : $conf_glx +echo VA/GLX support ................... : $conf_vaapi_glx +echo VaapiSink/GL ..................... : $conf_vaapisink_glx echo diff --git a/gst-libs/gst/vaapi/gstvaapicompat.h b/gst-libs/gst/vaapi/gstvaapicompat.h index fb7d212..158cc78 100644 --- a/gst-libs/gst/vaapi/gstvaapicompat.h +++ b/gst-libs/gst/vaapi/gstvaapicompat.h @@ -28,6 +28,12 @@ # include #endif +#if USE_VAAPI_GLX +# include +#else +# define vaGetDisplayGLX(dpy) vaGetDisplay(dpy) +#endif + /* Check for VA version */ #ifndef VA_CHECK_VERSION #define VA_MAJOR_VERSION 0 diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c index 7a078cf..c4722d3 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.c @@ -24,6 +24,7 @@ */ #include "config.h" +#include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapidisplay_glx.h" diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h index 6206f1e..6f43368 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_glx.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_glx.h @@ -23,7 +23,6 @@ #include #include -#include #include G_BEGIN_DECLS diff --git a/gst-libs/gst/vaapi/gstvaapitexture.c b/gst-libs/gst/vaapi/gstvaapitexture.c index b86f842..2022c29 100644 --- a/gst-libs/gst/vaapi/gstvaapitexture.c +++ b/gst-libs/gst/vaapi/gstvaapitexture.c @@ -24,10 +24,11 @@ */ #include "config.h" -#include #include "gstvaapitexture.h" +#include "gstvaapicompat.h" #include "gstvaapiutils.h" #include "gstvaapiutils_glx.h" +#include "gstvaapidisplay_glx.h" #include "gstvaapiobject_priv.h" #define DEBUG 1 @@ -41,13 +42,15 @@ G_DEFINE_TYPE(GstVaapiTexture, gst_vaapi_texture, GST_VAAPI_TYPE_OBJECT); GstVaapiTexturePrivate)) struct _GstVaapiTexturePrivate { - GLenum target; - GLenum format; - guint width; - guint height; - void *gl_surface; - guint foreign_texture : 1; - guint is_constructed : 1; + GLenum target; + GLenum format; + guint width; + guint height; + void *gl_surface; + GLPixmapObject *pixo; + GLFramebufferObject *fbo; + guint foreign_texture : 1; + guint is_constructed : 1; }; enum { @@ -60,27 +63,87 @@ enum { }; static void -gst_vaapi_texture_destroy(GstVaapiTexture *texture) +_gst_vaapi_texture_destroy_objects(GstVaapiTexture *texture) { GstVaapiTexturePrivate * const priv = texture->priv; - const GLuint texture_id = GST_VAAPI_OBJECT_ID(texture); - VAStatus status; +#if USE_VAAPI_GLX GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); if (priv->gl_surface) { - status = vaDestroySurfaceGLX( + vaDestroySurfaceGLX( GST_VAAPI_OBJECT_VADISPLAY(texture), priv->gl_surface ); priv->gl_surface = NULL; } + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); +#else + if (priv->fbo) { + gl_destroy_framebuffer_object(priv->fbo); + priv->fbo = NULL; + } + + if (priv->pixo) { + gl_destroy_pixmap_object(priv->pixo); + priv->pixo = NULL; + } +#endif +} + +static void +gst_vaapi_texture_destroy(GstVaapiTexture *texture) +{ + GstVaapiTexturePrivate * const priv = texture->priv; + const GLuint texture_id = GST_VAAPI_OBJECT_ID(texture); + + _gst_vaapi_texture_destroy_objects(texture); if (texture_id) { if (!priv->foreign_texture) glDeleteTextures(1, &texture_id); GST_VAAPI_OBJECT_ID(texture) = 0; } +} + +static gboolean +_gst_vaapi_texture_create_objects(GstVaapiTexture *texture, GLuint texture_id) +{ + GstVaapiTexturePrivate * const priv = texture->priv; + +#if USE_VAAPI_GLX + VAStatus status; + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + status = vaCreateSurfaceGLX( + GST_VAAPI_OBJECT_VADISPLAY(texture), + priv->target, + texture_id, + &priv->gl_surface + ); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!vaapi_check_status(status, "vaCreateSurfaceGLX()")) + return FALSE; +#else + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + priv->pixo = gl_create_pixmap_object( + GST_VAAPI_OBJECT_XDISPLAY(texture), + priv->width, + priv->height + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!priv->pixo) + return FALSE; + + priv->fbo = gl_create_framebuffer_object( + priv->target, + texture_id, + priv->width, + priv->height + ); + if (!priv->fbo) + return FALSE; +#endif + return TRUE; } static gboolean @@ -88,7 +151,6 @@ gst_vaapi_texture_create(GstVaapiTexture *texture) { GstVaapiTexturePrivate * const priv = texture->priv; GLuint texture_id; - VAStatus status; if (priv->foreign_texture) texture_id = GST_VAAPI_OBJECT_ID(texture); @@ -106,17 +168,7 @@ gst_vaapi_texture_create(GstVaapiTexture *texture) GST_VAAPI_OBJECT_ID(texture) = texture_id; } - GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); - status = vaCreateSurfaceGLX( - GST_VAAPI_OBJECT_VADISPLAY(texture), - priv->target, - texture_id, - &priv->gl_surface - ); - GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - if (!vaapi_check_status(status, "vaCreateSurfaceGLX()")) - return FALSE; - return TRUE; + return _gst_vaapi_texture_create_objects(texture, texture_id); } static void @@ -259,6 +311,8 @@ gst_vaapi_texture_init(GstVaapiTexture *texture) priv->width = 0; priv->height = 0; priv->gl_surface = NULL; + priv->pixo = NULL; + priv->fbo = NULL; priv->foreign_texture = FALSE; priv->is_constructed = FALSE; } @@ -486,29 +540,108 @@ gst_vaapi_texture_get_size( * * Return value: %TRUE on success */ -gboolean -gst_vaapi_texture_put_surface( +static gboolean +_gst_vaapi_texture_put_surface( GstVaapiTexture *texture, GstVaapiSurface *surface, guint flags ) { + GstVaapiTexturePrivate * const priv = texture->priv; VAStatus status; - g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), FALSE); - g_return_val_if_fail(texture->priv->is_constructed, FALSE); - g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); - +#if USE_VAAPI_GLX GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); status = vaCopySurfaceGLX( GST_VAAPI_OBJECT_VADISPLAY(texture), - texture->priv->gl_surface, + priv->gl_surface, GST_VAAPI_OBJECT_ID(surface), from_GstVaapiSurfaceRenderFlags(flags) ); GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); - if (!vaapi_check_status(status, "vaCopySurfaceGLX()")) return FALSE; +#else + guint surface_width, surface_height; + GLTextureState ts; + gboolean success = FALSE; + + gst_vaapi_surface_get_size(surface, &surface_width, &surface_height); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + status = vaPutSurface( + GST_VAAPI_OBJECT_VADISPLAY(texture), + GST_VAAPI_OBJECT_ID(surface), + priv->pixo->pixmap, + 0, 0, surface_width, surface_height, + 0, 0, priv->width, priv->height, + NULL, 0, + from_GstVaapiSurfaceRenderFlags(flags) + ); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!vaapi_check_status(status, "vaPutSurface() [TFP]")) + return FALSE; + + if (!gl_bind_texture(&ts, priv->target, GST_VAAPI_OBJECT_ID(texture))) + return FALSE; + + success = gl_bind_framebuffer_object(priv->fbo); + if (!success) { + GST_DEBUG("could not bind FBO"); + goto out_unbind_texture; + } + + success = gst_vaapi_surface_sync(surface); + if (!success) { + GST_DEBUG("could not render surface to pixmap"); + goto out_unbind_fbo; + } + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + success = gl_bind_pixmap_object(priv->pixo); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!success) { + GST_DEBUG("could not bind GLX pixmap"); + goto out_unbind_fbo; + } + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBegin(GL_QUADS); + { + glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0 ); + glTexCoord2f(0.0f, 1.0f); glVertex2i(0, priv->height); + glTexCoord2f(1.0f, 1.0f); glVertex2i(priv->width, priv->height); + glTexCoord2f(1.0f, 0.0f); glVertex2i(priv->width, 0 ); + } + glEnd(); + + GST_VAAPI_OBJECT_LOCK_DISPLAY(texture); + success = gl_unbind_pixmap_object(priv->pixo); + GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture); + if (!success) { + GST_DEBUG("could not release GLX pixmap"); + goto out_unbind_fbo; + } + +out_unbind_fbo: + success = gl_unbind_framebuffer_object(priv->fbo); +out_unbind_texture: + gl_unbind_texture(&ts); + return success; +#endif return TRUE; } + +gboolean +gst_vaapi_texture_put_surface( + GstVaapiTexture *texture, + GstVaapiSurface *surface, + guint flags +) +{ + g_return_val_if_fail(GST_VAAPI_IS_TEXTURE(texture), FALSE); + g_return_val_if_fail(texture->priv->is_constructed, FALSE); + g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); + + return _gst_vaapi_texture_put_surface(texture, surface, flags); +} diff --git a/tests/test-display.c b/tests/test-display.c index 87ca968..54b136e 100644 --- a/tests/test-display.c +++ b/tests/test-display.c @@ -26,6 +26,12 @@ #include #endif +#if USE_VAAPI_GLX +# include +#else +# define vaGetDisplayGLX(dpy) vaGetDisplay(dpy) +#endif + static void print_caps(GstCaps *caps, const gchar *name) { -- 2.7.4