Enable build without VA/GLX extensions. i.e. fallback to TFP + FBO.
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Tue, 30 Mar 2010 13:01:34 +0000 (13:01 +0000)
committergb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Tue, 30 Mar 2010 13:01:34 +0000 (13:01 +0000)
configure.ac
gst-libs/gst/vaapi/gstvaapicompat.h
gst-libs/gst/vaapi/gstvaapidisplay_glx.c
gst-libs/gst/vaapi/gstvaapidisplay_glx.h
gst-libs/gst/vaapi/gstvaapitexture.c
tests/test-display.c

index e6ed60c..f008506 100644 (file)
@@ -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
index fb7d212..158cc78 100644 (file)
 # include <va/va.h>
 #endif
 
+#if USE_VAAPI_GLX
+# include <va/va_glx.h>
+#else
+# define vaGetDisplayGLX(dpy) vaGetDisplay(dpy)
+#endif
+
 /* Check for VA version */
 #ifndef VA_CHECK_VERSION
 #define VA_MAJOR_VERSION 0
index 7a078cf..c4722d3 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include "config.h"
+#include "gstvaapicompat.h"
 #include "gstvaapiutils.h"
 #include "gstvaapidisplay_glx.h"
 
index 6206f1e..6f43368 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <GL/gl.h>
 #include <GL/glx.h>
-#include <va/va_glx.h>
 #include <gst/vaapi/gstvaapidisplay_x11.h>
 
 G_BEGIN_DECLS
index b86f842..2022c29 100644 (file)
  */
 
 #include "config.h"
-#include <va/va_glx.h>
 #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);
+}
index 87ca968..54b136e 100644 (file)
 #include <gst/vaapi/gstvaapidisplay_glx.h>
 #endif
 
+#if USE_VAAPI_GLX
+# include <va/va_glx.h>
+#else
+# define vaGetDisplayGLX(dpy) vaGetDisplay(dpy)
+#endif
+
 static void
 print_caps(GstCaps *caps, const gchar *name)
 {