mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 19:20:35 +00:00
Add initial VA/GLX support.
This commit is contained in:
parent
511463c699
commit
89a99d828c
12 changed files with 1289 additions and 14 deletions
47
configure.ac
47
configure.ac
|
@ -70,6 +70,11 @@ AC_PROG_CC
|
|||
AM_PROG_CC_C_O
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_ARG_ENABLE(glx,
|
||||
AC_HELP_STRING([--enable-glx],
|
||||
[enable OpenGL/X11 @<:@default=yes@:>@]),
|
||||
[], [enable_glx="yes"])
|
||||
|
||||
dnl Check for __attribute__((visibility()))
|
||||
AC_CACHE_CHECK([whether __attribute__((visibility())) is supported],
|
||||
vaapi_cv_visibility_attribute,
|
||||
|
@ -150,11 +155,28 @@ AC_SUBST(plugindir)
|
|||
dnl Check for X11
|
||||
PKG_CHECK_MODULES(X11, [x11])
|
||||
|
||||
dnl Check for OpenGL
|
||||
USE_GLX=1
|
||||
if test "$enable_glx" != "yes"; then
|
||||
USE_GLX=0
|
||||
fi
|
||||
OPENGL_CFLAGS=""
|
||||
OPENGL_LIBS=""
|
||||
AC_CHECK_HEADERS([GL/gl.h GL/glext.h GL/glx.h], [], [USE_GLX=0], [
|
||||
#ifdef HAVE_GL_GL_H
|
||||
# include <GL/gl.h>
|
||||
#endif
|
||||
])
|
||||
AC_CHECK_LIB(GL, glXCreateContext, [OPENGL_LIBS="-lGL -ldl"], [USE_GLX=0])
|
||||
AC_SUBST(OPENGL_CFLAGS)
|
||||
AC_SUBST(OPENGL_LIBS)
|
||||
|
||||
dnl Check for VA-API
|
||||
LIBVA_PKGNAME="libva"
|
||||
PKG_CHECK_MODULES(LIBVA, [$LIBVA_PKGNAME])
|
||||
AC_SUBST(LIBVA_PKGNAME)
|
||||
|
||||
dnl ... original VA-API 0.29
|
||||
AC_CACHE_CHECK([for old VA-API 0.29],
|
||||
ac_cv_have_vaapi_old, [
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
|
@ -173,6 +195,7 @@ if test "$ac_cv_have_vaapi_old" = "yes"; then
|
|||
LIBVA_EXTRA_CFLAGS="$LIBVA_CFLAGS -DGST_VAAPI_USE_OLD_VAAPI_0_29"
|
||||
fi
|
||||
|
||||
dnl ... VA-API >= 0.31 or -sds
|
||||
LIBVA_X11_PKGNAME="libva-x11"
|
||||
PKG_CHECK_MODULES(LIBVA_X11, [$LIBVA_X11_PKGNAME],
|
||||
[ac_cv_have_vaapi_x11="yes"],
|
||||
|
@ -189,9 +212,24 @@ 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
|
||||
fi
|
||||
AC_SUBST(LIBVA_GLX_PKGNAME)
|
||||
|
||||
AC_SUBST(LIBVA_EXTRA_CFLAGS)
|
||||
AC_SUBST(LIBVA_EXTRA_LIBS)
|
||||
|
||||
AC_DEFINE_UNQUOTED(USE_GLX, $USE_GLX, [Defined to 1 if GLX is enabled])
|
||||
AM_CONDITIONAL(USE_GLX, test $USE_GLX -eq 1)
|
||||
|
||||
VA_VERSION=`$PKG_CONFIG --modversion libva`
|
||||
VA_MAJOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f1`
|
||||
VA_MINOR_VERSION=`echo "$VA_VERSION" | cut -d'.' -f2`
|
||||
|
@ -231,8 +269,12 @@ debian.upstream/libgstvaapi-x11.install.in
|
|||
gst-libs/gst/Makefile
|
||||
gst-libs/gst/vaapi/Makefile
|
||||
pkgconfig/Makefile
|
||||
pkgconfig/gstreamer-vaapi.pc
|
||||
pkgconfig/gstreamer-vaapi-x11.pc
|
||||
pkgconfig/gstreamer-vaapi-$GST_MAJORMINOR.pc:\
|
||||
pkgconfig/gstreamer-vaapi.pc.in
|
||||
pkgconfig/gstreamer-vaapi-glx-$GST_MAJORMINOR.pc:\
|
||||
pkgconfig/gstreamer-vaapi-glx.pc.in
|
||||
pkgconfig/gstreamer-vaapi-x11-$GST_MAJORMINOR.pc:\
|
||||
pkgconfig/gstreamer-vaapi-x11.pc.in
|
||||
sys/Makefile
|
||||
sys/vaapiconvert/Makefile
|
||||
sys/vaapisink/Makefile
|
||||
|
@ -244,4 +286,5 @@ 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
|
||||
|
|
|
@ -3,6 +3,10 @@ lib_LTLIBRARIES = \
|
|||
libgstvaapi-x11-@GST_MAJORMINOR@.la \
|
||||
$(NULL)
|
||||
|
||||
if USE_GLX
|
||||
lib_LTLIBRARIES += libgstvaapi-glx-@GST_MAJORMINOR@.la
|
||||
endif
|
||||
|
||||
libgstvaapi_includedir = \
|
||||
$(includedir)/gstreamer-@GST_MAJORMINOR@/gst/vaapi
|
||||
|
||||
|
@ -68,6 +72,26 @@ libgstvaapi_x11_source_priv_h = \
|
|||
gstvaapiutils_x11.h \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_glx_source_c = \
|
||||
gstvaapidisplay_glx.c \
|
||||
gstvaapiutils.c \
|
||||
gstvaapiutils_glx.c \
|
||||
gstvaapiutils_x11.c \
|
||||
gstvaapiwindow_glx.c \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_glx_source_h = \
|
||||
gstvaapicompat.h \
|
||||
gstvaapidisplay_glx.h \
|
||||
gstvaapiwindow_glx.h \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_glx_source_priv_h = \
|
||||
gstvaapiutils.h \
|
||||
gstvaapiutils_glx.h \
|
||||
gstvaapiutils_x11.h \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_@GST_MAJORMINOR@_la_SOURCES = \
|
||||
$(libgstvaapi_source_c) \
|
||||
$(libgstvaapi_source_priv_h) \
|
||||
|
@ -118,6 +142,31 @@ libgstvaapi_x11_@GST_MAJORMINOR@_la_LIBADD = \
|
|||
libgstvaapi-@GST_MAJORMINOR@.la \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_glx_@GST_MAJORMINOR@_la_SOURCES = \
|
||||
$(libgstvaapi_glx_source_c) \
|
||||
$(libgstvaapi_glx_source_priv_h) \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_glx_@GST_MAJORMINOR@include_HEADERS = \
|
||||
$(libgstvaapi_glx_source_h) \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_glx_@GST_MAJORMINOR@includedir = \
|
||||
$(libgstvaapi_includedir)
|
||||
|
||||
libgstvaapi_glx_@GST_MAJORMINOR@_la_CFLAGS = \
|
||||
-I$(top_srcdir)/gst-libs \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(GST_BASE_CFLAGS) \
|
||||
$(LIBVA_GLX_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_glx_@GST_MAJORMINOR@_la_LIBADD = \
|
||||
$(GLIB_LIBS) \
|
||||
$(LIBVA_GLX_LIBS) \
|
||||
libgstvaapi-x11-@GST_MAJORMINOR@.la \
|
||||
$(NULL)
|
||||
|
||||
# Extra clean files so that maintainer-clean removes *everything*
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
|
|
99
gst-libs/gst/vaapi/gstvaapidisplay_glx.c
Normal file
99
gst-libs/gst/vaapi/gstvaapidisplay_glx.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* gstvaapidisplay_glx.c - VA/GLX display abstraction
|
||||
*
|
||||
* gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapidisplay_glx
|
||||
* @short_description: VA/GLX display abstraction
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gstvaapiutils.h"
|
||||
#include "gstvaapidisplay_glx.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
G_DEFINE_TYPE(GstVaapiDisplayGLX,
|
||||
gst_vaapi_display_glx,
|
||||
GST_VAAPI_TYPE_DISPLAY_X11);
|
||||
|
||||
static void
|
||||
gst_vaapi_display_glx_finalize(GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS(gst_vaapi_display_glx_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static VADisplay
|
||||
gst_vaapi_display_glx_get_va_display(GstVaapiDisplay *display)
|
||||
{
|
||||
return vaGetDisplayGLX(GST_VAAPI_DISPLAY_XDISPLAY(display));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_glx_class_init(GstVaapiDisplayGLXClass *klass)
|
||||
{
|
||||
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
|
||||
GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass);
|
||||
|
||||
object_class->finalize = gst_vaapi_display_glx_finalize;
|
||||
dpy_class->get_display = gst_vaapi_display_glx_get_va_display;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_display_glx_init(GstVaapiDisplayGLX *display)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_glx_new:
|
||||
* @display_name: the X11 display name
|
||||
*
|
||||
* Opens an X11 #Display using @display_name and returns a newly
|
||||
* allocated #GstVaapiDisplay object. The X11 display will be cloed
|
||||
* when the reference count of the object reaches zero.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_glx_new(const gchar *display_name)
|
||||
{
|
||||
return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX,
|
||||
"display-name", display_name,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_display_glx_new_with_display:
|
||||
* @x11_display: an X11 #Display
|
||||
*
|
||||
* Creates a #GstVaapiDisplay based on the X11 @x11_display
|
||||
* display. The caller still owns the display and must call
|
||||
* XCloseDisplay() when all #GstVaapiDisplay references are
|
||||
* released. Doing so too early can yield undefined behaviour.
|
||||
*
|
||||
* Return value: a newly allocated #GstVaapiDisplay object
|
||||
*/
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_glx_new_with_display(Display *x11_display)
|
||||
{
|
||||
return g_object_new(GST_VAAPI_TYPE_DISPLAY_GLX,
|
||||
"x11-display", x11_display,
|
||||
NULL);
|
||||
}
|
90
gst-libs/gst/vaapi/gstvaapidisplay_glx.h
Normal file
90
gst-libs/gst/vaapi/gstvaapidisplay_glx.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* gstvaapidisplay_glx.h - VA/GLX display abstraction
|
||||
*
|
||||
* gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_DISPLAY_GLX_H
|
||||
#define GST_VAAPI_DISPLAY_GLX_H
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include <va/va_glx.h>
|
||||
#include <gst/vaapi/gstvaapidisplay_x11.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_TYPE_DISPLAY_GLX \
|
||||
(gst_vaapi_display_glx_get_type())
|
||||
|
||||
#define GST_VAAPI_DISPLAY_GLX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
GST_VAAPI_TYPE_DISPLAY_GLX, \
|
||||
GstVaapiDisplayGLX))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_GLX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
||||
GST_VAAPI_TYPE_DISPLAY_GLX, \
|
||||
GstVaapiDisplayGLXClass))
|
||||
|
||||
#define GST_VAAPI_IS_DISPLAY_GLX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_DISPLAY_GLX))
|
||||
|
||||
#define GST_VAAPI_IS_DISPLAY_GLX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_DISPLAY_GLX))
|
||||
|
||||
#define GST_VAAPI_DISPLAY_GLX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((obj), \
|
||||
GST_VAAPI_TYPE_DISPLAY_GLX, \
|
||||
GstVaapiDisplayGLXClass))
|
||||
|
||||
typedef struct _GstVaapiDisplayGLX GstVaapiDisplayGLX;
|
||||
typedef struct _GstVaapiDisplayGLXClass GstVaapiDisplayGLXClass;
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayGLX:
|
||||
*
|
||||
* VA/GLX display wrapper.
|
||||
*/
|
||||
struct _GstVaapiDisplayGLX {
|
||||
/*< private >*/
|
||||
GstVaapiDisplayX11 parent_instance;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayGLXClass:
|
||||
*
|
||||
* VA/GLX display wrapper clas.
|
||||
*/
|
||||
struct _GstVaapiDisplayGLXClass {
|
||||
/*< private >*/
|
||||
GstVaapiDisplayX11Class parent_class;
|
||||
};
|
||||
|
||||
GType
|
||||
gst_vaapi_display_glx_get_type(void);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_glx_new(const gchar *display_name);
|
||||
|
||||
GstVaapiDisplay *
|
||||
gst_vaapi_display_glx_new_with_display(Display *x11_display);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_DISPLAY_GLX_H */
|
183
gst-libs/gst/vaapi/gstvaapiutils_glx.c
Normal file
183
gst-libs/gst/vaapi/gstvaapiutils_glx.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* gstvaapiutils_glx.c - GLX utilties
|
||||
*
|
||||
* gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gstvaapiutils_glx.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
/**
|
||||
* gl_get_error_string:
|
||||
* @error: an OpenGL error enumeration
|
||||
*
|
||||
* Retrieves the string representation the OpenGL @error.
|
||||
*
|
||||
* Return error: the static string representing the OpenGL @error
|
||||
*/
|
||||
const char *
|
||||
gl_get_error_string(GLenum error)
|
||||
{
|
||||
static const struct {
|
||||
GLenum val;
|
||||
const char *str;
|
||||
}
|
||||
gl_errors[] = {
|
||||
{ GL_NO_ERROR, "no error" },
|
||||
{ GL_INVALID_ENUM, "invalid enumerant" },
|
||||
{ GL_INVALID_VALUE, "invalid value" },
|
||||
{ GL_INVALID_OPERATION, "invalid operation" },
|
||||
{ GL_STACK_OVERFLOW, "stack overflow" },
|
||||
{ GL_STACK_UNDERFLOW, "stack underflow" },
|
||||
{ GL_OUT_OF_MEMORY, "out of memory" },
|
||||
#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
|
||||
{ GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "invalid framebuffer operation" },
|
||||
#endif
|
||||
{ ~0, NULL }
|
||||
};
|
||||
|
||||
guint i;
|
||||
for (i = 0; gl_errors[i].str; i++) {
|
||||
if (gl_errors[i].val == error)
|
||||
return gl_errors[i].str;
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_purge_errors:
|
||||
*
|
||||
* Purges all OpenGL errors. This function is generally useful to
|
||||
* clear up the pending errors prior to calling gl_check_error().
|
||||
*/
|
||||
void
|
||||
gl_purge_errors(void)
|
||||
{
|
||||
while (glGetError() != GL_NO_ERROR)
|
||||
; /* nothing */
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_check_error:
|
||||
*
|
||||
* Checks whether there is any OpenGL error pending.
|
||||
*
|
||||
* Return value: %TRUE if an error was encountered
|
||||
*/
|
||||
gboolean
|
||||
gl_check_error(void)
|
||||
{
|
||||
GLenum error;
|
||||
gboolean has_errors = FALSE;
|
||||
|
||||
while ((error = glGetError()) != GL_NO_ERROR) {
|
||||
GST_DEBUG("glError: %s caught", gl_get_error_string(error));
|
||||
has_errors = TRUE;
|
||||
}
|
||||
return has_errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_get_param:
|
||||
* @param: the parameter name
|
||||
* @pval: return location for the value
|
||||
*
|
||||
* This function is a wrapper around glGetIntegerv() that does extra
|
||||
* error checking.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
*/
|
||||
gboolean
|
||||
gl_get_param(GLenum param, guint *pval)
|
||||
{
|
||||
GLint val;
|
||||
|
||||
gl_purge_errors();
|
||||
glGetIntegerv(param, &val);
|
||||
if (gl_check_error())
|
||||
return FALSE;
|
||||
|
||||
if (pval)
|
||||
*pval = val;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_get_param:
|
||||
* @param: the parameter name
|
||||
* @pval: return location for the value
|
||||
*
|
||||
* This function is a wrapper around glGetTexLevelParameteriv() that
|
||||
* does extra error checking.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
*/
|
||||
gboolean
|
||||
gl_get_texture_param(GLenum param, guint *pval)
|
||||
{
|
||||
GLint val;
|
||||
|
||||
gl_purge_errors();
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, param, &val);
|
||||
if (gl_check_error())
|
||||
return FALSE;
|
||||
|
||||
if (pval)
|
||||
*pval = val;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_set_bgcolor:
|
||||
* @color: the requested RGB color
|
||||
*
|
||||
* Sets background color to the RGB @color. This basically is a
|
||||
* wrapper around glClearColor().
|
||||
*/
|
||||
void
|
||||
gl_set_bgcolor(guint32 color)
|
||||
{
|
||||
glClearColor(
|
||||
((color >> 16) & 0xff) / 255.0f,
|
||||
((color >> 8) & 0xff) / 255.0f,
|
||||
( color & 0xff) / 255.0f,
|
||||
1.0f
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* gl_resize:
|
||||
* @width: the requested width, in pixels
|
||||
* @height: the requested height, in pixels
|
||||
*
|
||||
* Resizes the OpenGL viewport to the specified dimensions, using an
|
||||
* orthogonal projection. (0,0) represents the top-left corner of the
|
||||
* window.
|
||||
*/
|
||||
void
|
||||
gl_resize(guint width, guint height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, width, height, 0, -1, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
57
gst-libs/gst/vaapi/gstvaapiutils_glx.h
Normal file
57
gst-libs/gst/vaapi/gstvaapiutils_glx.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* gstvaapiutils_glx.h - GLX utilties
|
||||
*
|
||||
* gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_UTILS_GLX_H
|
||||
#define GST_VAAPI_UTILS_GLX_H
|
||||
|
||||
#include "config.h"
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include <glib/gtypes.h>
|
||||
|
||||
const char *
|
||||
gl_get_error_string(GLenum error)
|
||||
attribute_hidden;
|
||||
|
||||
void
|
||||
gl_purge_errors(void)
|
||||
attribute_hidden;
|
||||
|
||||
gboolean
|
||||
gl_check_error(void)
|
||||
attribute_hidden;
|
||||
|
||||
gboolean
|
||||
gl_get_param(GLenum param, guint *pval)
|
||||
attribute_hidden;
|
||||
|
||||
gboolean
|
||||
gl_get_texture_param(GLenum param, guint *pval)
|
||||
attribute_hidden;
|
||||
|
||||
void
|
||||
gl_set_bgcolor(guint32 color)
|
||||
attribute_hidden;
|
||||
|
||||
void
|
||||
gl_resize(guint width, guint height)
|
||||
attribute_hidden;
|
||||
|
||||
#endif /* GST_VAAPI_UTILS_GLX_H */
|
488
gst-libs/gst/vaapi/gstvaapiwindow_glx.c
Normal file
488
gst-libs/gst/vaapi/gstvaapiwindow_glx.c
Normal file
|
@ -0,0 +1,488 @@
|
|||
/*
|
||||
* gstvaapiwindow_glx.c - VA/GLX window abstraction
|
||||
*
|
||||
* gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstvaapiwindow_glx
|
||||
* @short_description: VA/GLX window abstraction
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gstvaapiwindow_glx.h"
|
||||
#include "gstvaapidisplay_x11.h"
|
||||
#include "gstvaapiutils_x11.h"
|
||||
#include "gstvaapiutils_glx.h"
|
||||
#include "gstvaapiobject_priv.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "gstvaapidebug.h"
|
||||
|
||||
G_DEFINE_TYPE(GstVaapiWindowGLX,
|
||||
gst_vaapi_window_glx,
|
||||
GST_VAAPI_TYPE_WINDOW_X11);
|
||||
|
||||
#define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((obj), \
|
||||
GST_VAAPI_TYPE_WINDOW_GLX, \
|
||||
GstVaapiWindowGLXPrivate))
|
||||
|
||||
struct _GstVaapiWindowGLXPrivate {
|
||||
XVisualInfo *vi;
|
||||
XVisualInfo vi_static;
|
||||
Colormap cmap;
|
||||
GLXContext context;
|
||||
guint foreign_context : 1;
|
||||
guint foreign_window : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_GLX_CONTEXT
|
||||
};
|
||||
|
||||
static XVisualInfo *
|
||||
gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window);
|
||||
|
||||
static inline void
|
||||
_gst_vaapi_window_glx_set_context(
|
||||
GstVaapiWindowGLX *window,
|
||||
GLXContext context,
|
||||
gboolean is_foreign
|
||||
)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
|
||||
priv->context = context;
|
||||
priv->foreign_context = is_foreign;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_glx_destroy_context(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||
|
||||
if (priv->context) {
|
||||
if (!priv->foreign_context) {
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
if (glXGetCurrentContext() == priv->context)
|
||||
glXMakeCurrent(dpy, None, NULL);
|
||||
glXDestroyContext(dpy, priv->context);
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
}
|
||||
priv->context = NULL;
|
||||
priv->foreign_context = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vaapi_window_glx_create_context(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||
GLXContext ctx = NULL;
|
||||
guint width, height;
|
||||
gboolean has_errors = TRUE;
|
||||
|
||||
if (!gst_vaapi_window_glx_create_visual(window))
|
||||
return FALSE;
|
||||
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
ctx = glXCreateContext(dpy, priv->vi, NULL, True);
|
||||
if (ctx && glXIsDirect(dpy, ctx)) {
|
||||
_gst_vaapi_window_glx_set_context(window, ctx, FALSE);
|
||||
if (glXMakeCurrent(dpy, GST_VAAPI_OBJECT_ID(window), ctx)) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDrawBuffer(GL_BACK);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gst_vaapi_window_get_size(GST_VAAPI_WINDOW(window), &width, &height);
|
||||
gl_resize(width, height);
|
||||
|
||||
gl_set_bgcolor(0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
has_errors = FALSE;
|
||||
}
|
||||
}
|
||||
else if (ctx)
|
||||
glXDestroyContext(dpy, ctx);
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
|
||||
return !has_errors;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gst_vaapi_window_glx_destroy_visual(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
|
||||
if (priv->vi) {
|
||||
if (priv->vi != &priv->vi_static)
|
||||
XFree(priv->vi);
|
||||
priv->vi = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static XVisualInfo *
|
||||
gst_vaapi_window_glx_create_visual(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||
XWindowAttributes wattr;
|
||||
int screen;
|
||||
gboolean has_errors;
|
||||
|
||||
/* XXX: add and use a GstVaapiWindow:double-buffer property? */
|
||||
static GLint gl_visual_attr[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GL_NONE
|
||||
};
|
||||
|
||||
if (!priv->vi) {
|
||||
/* XXX: add and use a GstVaapiDisplayX11:x11-screen property? */
|
||||
screen = DefaultScreen(dpy);
|
||||
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
x11_trap_errors();
|
||||
if (!priv->foreign_window)
|
||||
priv->vi = glXChooseVisual(dpy, screen, gl_visual_attr);
|
||||
else {
|
||||
XGetWindowAttributes(dpy, GST_VAAPI_OBJECT_ID(window), &wattr);
|
||||
if (XMatchVisualInfo(dpy, screen, wattr.depth, wattr.visual->class,
|
||||
&priv->vi_static))
|
||||
priv->vi = &priv->vi_static;
|
||||
}
|
||||
has_errors = x11_untrap_errors() != 0;
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
|
||||
if (has_errors)
|
||||
return NULL;
|
||||
}
|
||||
return priv->vi;
|
||||
}
|
||||
|
||||
static Visual *
|
||||
gst_vaapi_window_glx_get_visual(GstVaapiWindow *window)
|
||||
{
|
||||
XVisualInfo *vi;
|
||||
|
||||
vi = gst_vaapi_window_glx_create_visual(GST_VAAPI_WINDOW_GLX(window));
|
||||
if (!vi)
|
||||
return NULL;
|
||||
return vi->visual;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_glx_destroy_colormap(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||
|
||||
if (priv->cmap) {
|
||||
if (!priv->foreign_window) {
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
XFreeColormap(dpy, priv->cmap);
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
}
|
||||
priv->cmap = None;
|
||||
}
|
||||
}
|
||||
|
||||
static Colormap
|
||||
gst_vaapi_window_glx_create_colormap(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = window->priv;
|
||||
Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
|
||||
int screen;
|
||||
XWindowAttributes wattr;
|
||||
XVisualInfo *vi;
|
||||
gboolean has_errors;
|
||||
|
||||
if (!priv->cmap) {
|
||||
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
|
||||
x11_trap_errors();
|
||||
if (!priv->foreign_window) {
|
||||
vi = gst_vaapi_window_glx_create_visual(window);
|
||||
if (vi) {
|
||||
/* XXX: add a GstVaapiDisplayX11:x11-screen property? */
|
||||
screen = DefaultScreen(dpy);
|
||||
priv->cmap = XCreateColormap(
|
||||
dpy,
|
||||
RootWindow(dpy, screen),
|
||||
vi->visual,
|
||||
AllocNone
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
XGetWindowAttributes(dpy, GST_VAAPI_OBJECT_ID(window), &wattr);
|
||||
priv->cmap = wattr.colormap;
|
||||
}
|
||||
has_errors = x11_untrap_errors() != 0;
|
||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
|
||||
|
||||
if (has_errors)
|
||||
return None;
|
||||
}
|
||||
return priv->cmap;
|
||||
}
|
||||
|
||||
static Colormap
|
||||
gst_vaapi_window_glx_get_colormap(GstVaapiWindow *window)
|
||||
{
|
||||
return gst_vaapi_window_glx_create_colormap(GST_VAAPI_WINDOW_GLX(window));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_glx_finalize(GObject *object)
|
||||
{
|
||||
GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object);
|
||||
|
||||
gst_vaapi_window_glx_destroy_context(window);
|
||||
gst_vaapi_window_glx_destroy_visual(window);
|
||||
gst_vaapi_window_glx_destroy_colormap(window);
|
||||
|
||||
G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_glx_set_property(
|
||||
GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec
|
||||
)
|
||||
{
|
||||
GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_GLX_CONTEXT:
|
||||
gst_vaapi_window_glx_set_context(window, g_value_get_pointer(value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_glx_get_property(
|
||||
GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec
|
||||
)
|
||||
{
|
||||
GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_GLX_CONTEXT:
|
||||
g_value_set_pointer(value, gst_vaapi_window_glx_get_context(window));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_glx_constructed(GObject *object)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate * const priv = GST_VAAPI_WINDOW_GLX(object)->priv;
|
||||
GObjectClass *parent_class;
|
||||
|
||||
priv->foreign_context = priv->context != NULL;
|
||||
|
||||
parent_class = G_OBJECT_CLASS(gst_vaapi_window_glx_parent_class);
|
||||
if (parent_class->constructed)
|
||||
parent_class->constructed(object);
|
||||
|
||||
priv->foreign_window =
|
||||
gst_vaapi_window_x11_is_foreign_xid(GST_VAAPI_WINDOW_X11(object));
|
||||
|
||||
if (!priv->foreign_context)
|
||||
gst_vaapi_window_glx_create_context(GST_VAAPI_WINDOW_GLX(object));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_glx_class_init(GstVaapiWindowGLXClass *klass)
|
||||
{
|
||||
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
|
||||
GstVaapiWindowX11Class * const xwin_class = GST_VAAPI_WINDOW_X11_CLASS(klass);
|
||||
|
||||
g_type_class_add_private(klass, sizeof(GstVaapiWindowGLXPrivate));
|
||||
|
||||
object_class->finalize = gst_vaapi_window_glx_finalize;
|
||||
object_class->set_property = gst_vaapi_window_glx_set_property;
|
||||
object_class->get_property = gst_vaapi_window_glx_get_property;
|
||||
object_class->constructed = gst_vaapi_window_glx_constructed;
|
||||
|
||||
xwin_class->get_visual = gst_vaapi_window_glx_get_visual;
|
||||
xwin_class->get_colormap = gst_vaapi_window_glx_get_colormap;
|
||||
|
||||
/**
|
||||
* GstVaapiDisplayGLX:glx-context:
|
||||
*
|
||||
* The GLX context that was created by gst_vaapi_window_glx_new()
|
||||
* or that was bound from gst_vaapi_window_glx_set_context().
|
||||
*/
|
||||
g_object_class_install_property
|
||||
(object_class,
|
||||
PROP_GLX_CONTEXT,
|
||||
g_param_spec_pointer("glx-context",
|
||||
"GLX context",
|
||||
"GLX context",
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_window_glx_init(GstVaapiWindowGLX *window)
|
||||
{
|
||||
GstVaapiWindowGLXPrivate *priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window);
|
||||
|
||||
window->priv = priv;
|
||||
priv->vi = NULL;
|
||||
priv->cmap = None;
|
||||
priv->context = NULL;
|
||||
priv->foreign_context = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_window_glx_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
* @width: the requested window width, in pixels
|
||||
* @height: the requested windo height, in pixels
|
||||
*
|
||||
* Creates a window with the specified @width and @height. The window
|
||||
* will be attached to the @display and remains invisible to the user
|
||||
* until gst_vaapi_window_show() is called.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiWindow object
|
||||
*/
|
||||
GstVaapiWindow *
|
||||
gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height)
|
||||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
|
||||
g_return_val_if_fail(width > 0, NULL);
|
||||
g_return_val_if_fail(height > 0, NULL);
|
||||
|
||||
return g_object_new(GST_VAAPI_TYPE_WINDOW_GLX,
|
||||
"display", display,
|
||||
"id", GST_VAAPI_ID(None),
|
||||
"width", width,
|
||||
"height", height,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_window_glx_new_with_xid:
|
||||
* @display: a #GstVaapiDisplay
|
||||
* @xid: an X11 #Window id
|
||||
*
|
||||
* Creates a #GstVaapiWindow using the X11 #Window @xid. The caller
|
||||
* still owns the window and must call XDestroyWindow() when all
|
||||
* #GstVaapiWindow references are released. Doing so too early can
|
||||
* yield undefined behaviour.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiWindow object
|
||||
*/
|
||||
GstVaapiWindow *
|
||||
gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid)
|
||||
{
|
||||
GST_DEBUG("new window from xid 0x%08x", xid);
|
||||
|
||||
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
|
||||
g_return_val_if_fail(xid != None, NULL);
|
||||
|
||||
return g_object_new(GST_VAAPI_TYPE_WINDOW_GLX,
|
||||
"display", display,
|
||||
"id", GST_VAAPI_ID(xid),
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_window_glx_get_context:
|
||||
* @window: a #GstVaapiWindow
|
||||
*
|
||||
* Returns the #GLXContext bound to the @window.
|
||||
*
|
||||
* Return value: the #GLXContext bound to the @window
|
||||
*/
|
||||
GLXContext
|
||||
gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window)
|
||||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), NULL);
|
||||
|
||||
return window->priv->context;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_window_glx_set_context:
|
||||
* @window: a #GstVaapiWindow
|
||||
* @ctx: a GLX context
|
||||
*
|
||||
* Binds GLX context @ctx to @window. If @ctx is non %NULL, the caller
|
||||
* is responsible to making sure it has compatible visual with that of
|
||||
* the underlying X window. If @ctx is %NULL, a new context is created
|
||||
* and the @window owns it.
|
||||
*
|
||||
* Return value: %TRUE on success
|
||||
*/
|
||||
gboolean
|
||||
gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx)
|
||||
{
|
||||
g_return_val_if_fail(GST_VAAPI_IS_WINDOW_GLX(window), FALSE);
|
||||
|
||||
gst_vaapi_window_glx_destroy_context(window);
|
||||
|
||||
if (ctx) {
|
||||
_gst_vaapi_window_glx_set_context(window, ctx, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
return gst_vaapi_window_glx_create_context(window);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_window_glx_swap_buffers:
|
||||
* @window: a #GstVaapiWindowGLX
|
||||
*
|
||||
* Promotes the contents of the back buffer of @window to become the
|
||||
* contents of the front buffer of @window. This simply is wrapper
|
||||
* around glXSwapBuffers().
|
||||
*/
|
||||
void
|
||||
gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window)
|
||||
{
|
||||
g_return_if_fail(GST_VAAPI_IS_WINDOW_GLX(window));
|
||||
|
||||
glXSwapBuffers(
|
||||
GST_VAAPI_OBJECT_XDISPLAY(window),
|
||||
GST_VAAPI_OBJECT_ID(window)
|
||||
);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
100
gst-libs/gst/vaapi/gstvaapiwindow_glx.h
Normal file
100
gst-libs/gst/vaapi/gstvaapiwindow_glx.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* gstvaapiwindow_glx.h - VA/GLX window abstraction
|
||||
*
|
||||
* gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_WINDOW_GLX_H
|
||||
#define GST_VAAPI_WINDOW_GLX_H
|
||||
|
||||
#include <GL/glx.h>
|
||||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
#include <gst/vaapi/gstvaapiwindow_x11.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_VAAPI_TYPE_WINDOW_GLX \
|
||||
(gst_vaapi_window_glx_get_type())
|
||||
|
||||
#define GST_VAAPI_WINDOW_GLX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
GST_VAAPI_TYPE_WINDOW_GLX, \
|
||||
GstVaapiWindowGLX))
|
||||
|
||||
#define GST_VAAPI_WINDOW_GLX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass), \
|
||||
GST_VAAPI_TYPE_WINDOW_GLX, \
|
||||
GstVaapiWindowGLXClass))
|
||||
|
||||
#define GST_VAAPI_IS_WINDOW_GLX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_WINDOW_GLX))
|
||||
|
||||
#define GST_VAAPI_IS_WINDOW_GLX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_WINDOW_GLX))
|
||||
|
||||
#define GST_VAAPI_WINDOW_GLX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS((obj), \
|
||||
GST_VAAPI_TYPE_WINDOW_GLX, \
|
||||
GstVaapiWindowGLXClass))
|
||||
|
||||
typedef struct _GstVaapiWindowGLX GstVaapiWindowGLX;
|
||||
typedef struct _GstVaapiWindowGLXPrivate GstVaapiWindowGLXPrivate;
|
||||
typedef struct _GstVaapiWindowGLXClass GstVaapiWindowGLXClass;
|
||||
|
||||
/**
|
||||
* GstVaapiWindowGLX:
|
||||
*
|
||||
* An X11 #Window suitable for GLX rendering.
|
||||
*/
|
||||
struct _GstVaapiWindowGLX {
|
||||
/*< private >*/
|
||||
GstVaapiWindowX11 parent_instance;
|
||||
|
||||
GstVaapiWindowGLXPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstVaapiWindowGLXClass:
|
||||
*
|
||||
* An X11 #Window suitable for GLX rendering.
|
||||
*/
|
||||
struct _GstVaapiWindowGLXClass {
|
||||
/*< private >*/
|
||||
GstVaapiWindowX11Class parent_class;
|
||||
};
|
||||
|
||||
GType
|
||||
gst_vaapi_window_glx_get_type(void);
|
||||
|
||||
GstVaapiWindow *
|
||||
gst_vaapi_window_glx_new(GstVaapiDisplay *display, guint width, guint height);
|
||||
|
||||
GstVaapiWindow *
|
||||
gst_vaapi_window_glx_new_with_xid(GstVaapiDisplay *display, Window xid);
|
||||
|
||||
GLXContext
|
||||
gst_vaapi_window_glx_get_context(GstVaapiWindowGLX *window);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_window_glx_set_context(GstVaapiWindowGLX *window, GLXContext ctx);
|
||||
|
||||
void
|
||||
gst_vaapi_window_glx_swap_buffers(GstVaapiWindowGLX *window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_WINDOW_GLX_H */
|
|
@ -1,21 +1,21 @@
|
|||
AUTOMAKE_OPTIONS = -Wno-portability
|
||||
pcfiles_in = gstreamer-vaapi.pc.in
|
||||
pcfiles_in += gstreamer-vaapi-x11.pc.in
|
||||
if USE_GLX
|
||||
pcfiles_in += gstreamer-vaapi-glx.pc.in
|
||||
endif
|
||||
|
||||
pcfiles = gstreamer-vaapi-@GST_MAJORMINOR@.pc
|
||||
pcfiles += gstreamer-vaapi-x11-@GST_MAJORMINOR@.pc
|
||||
pcfiles = $(pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc)
|
||||
|
||||
pkgconfigdir = @pkgconfigdir@
|
||||
pkgconfig_DATA = $(pcfiles)
|
||||
|
||||
EXTRA_DIST = \
|
||||
gstreamer-vaapi.pc.in \
|
||||
gstreamer-vaapi-glx.pc.in \
|
||||
gstreamer-vaapi-x11.pc.in \
|
||||
$(NULL)
|
||||
|
||||
CLEANFILES = $(pcfiles)
|
||||
|
||||
# XXX: this is a GNU make extension
|
||||
%-@GST_MAJORMINOR@.pc: %.pc
|
||||
cp $< $@
|
||||
DISTCLEANFILES = $(pcfiles)
|
||||
|
||||
# Extra clean files so that maintainer-clean removes *everything*
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
12
pkgconfig/gstreamer-vaapi-glx.pc.in
Normal file
12
pkgconfig/gstreamer-vaapi-glx.pc.in
Normal file
|
@ -0,0 +1,12 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@/gstreamer-@GST_MAJORMINOR@
|
||||
pluginsdir=@libdir@/gstreamer-@GST_MAJORMINOR@
|
||||
|
||||
Name: GStreamer VA-API (glx) Plugins Libraries
|
||||
Description: Streaming media framework, VA-API (glx) plugins libraries
|
||||
Requires: gstreamer-vaapi-@GST_MAJORMINOR@ @LIBVA_GLX_PKGNAME@
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lgstvaapi-glx-@GST_MAJORMINOR@ @LIBVA_EXTRA_LIBS@
|
||||
Cflags: -I${includedir} @LIBVA_EXTRA_CFLAGS@
|
|
@ -4,26 +4,39 @@ noinst_PROGRAMS = \
|
|||
test-windows \
|
||||
$(NULL)
|
||||
|
||||
noinst_PROGRAMS += \
|
||||
test-textures \
|
||||
$(NULL)
|
||||
|
||||
TEST_CFLAGS = \
|
||||
$(GST_CFLAGS) \
|
||||
-I$(top_srcdir)/gst-libs \
|
||||
$(X11_CFLAGS)
|
||||
|
||||
TEST_LIBS = \
|
||||
$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la \
|
||||
$(X11_LIBS)
|
||||
|
||||
TEST_GLX_LIBS = \
|
||||
$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-@GST_MAJORMINOR@.la
|
||||
|
||||
TEST_X11_LIBS = \
|
||||
$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la
|
||||
|
||||
test_display_SOURCES = test-display.c
|
||||
test_display_CFLAGS = $(TEST_CFLAGS)
|
||||
test_display_LDADD = $(TEST_LIBS)
|
||||
test_display_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS)
|
||||
|
||||
test_surfaces_SOURCES = test-surfaces.c
|
||||
test_surfaces_CFLAGS = $(TEST_CFLAGS)
|
||||
test_surfaces_LDADD = $(TEST_LIBS)
|
||||
test_surfaces_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS)
|
||||
|
||||
test_windows_SOURCES = test-windows.c
|
||||
test_windows_CFLAGS = $(TEST_CFLAGS)
|
||||
test_windows_LDADD = $(TEST_LIBS)
|
||||
test_windows_LDADD = $(TEST_LIBS) $(TEST_X11_LIBS)
|
||||
|
||||
test_textures_SOURCES = test-textures.c
|
||||
test_textures_CFLAGS = $(TEST_CFLAGS)
|
||||
test_textures_LDADD = $(TEST_LIBS) $(TEST_GLX_LIBS)
|
||||
|
||||
# Extra clean files so that maintainer-clean removes *everything*
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
141
tests/test-textures.c
Normal file
141
tests/test-textures.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* test-textures.c - Test GstVaapiTexture
|
||||
*
|
||||
* gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <gst/vaapi/gstvaapidisplay_glx.h>
|
||||
#include <gst/vaapi/gstvaapiwindow_glx.h>
|
||||
|
||||
static inline void pause(void)
|
||||
{
|
||||
g_print("Press any key to continue...\n");
|
||||
getchar();
|
||||
}
|
||||
|
||||
static void
|
||||
print_caps(GstCaps *caps, const gchar *name)
|
||||
{
|
||||
guint i, n_caps = gst_caps_get_size(caps);
|
||||
|
||||
g_print("%u %s caps\n", n_caps, name);
|
||||
|
||||
for (i = 0; i < gst_caps_get_size(caps); i++) {
|
||||
GstStructure * const structure = gst_caps_get_structure(caps, i);
|
||||
if (!structure)
|
||||
g_error("could not get caps structure %d", i);
|
||||
|
||||
g_print(" %s:", gst_structure_get_name(structure));
|
||||
|
||||
if (gst_structure_has_name(structure, "video/x-raw-yuv")) {
|
||||
guint32 fourcc;
|
||||
|
||||
gst_structure_get_fourcc(structure, "format", &fourcc);
|
||||
|
||||
g_print(" fourcc '%c%c%c%c'",
|
||||
fourcc & 0xff,
|
||||
(fourcc >> 8) & 0xff,
|
||||
(fourcc >> 16) & 0xff,
|
||||
(fourcc >> 24) & 0xff);
|
||||
}
|
||||
else {
|
||||
gint bpp, endian, rmask, gmask, bmask, amask;
|
||||
gboolean has_alpha;
|
||||
|
||||
gst_structure_get_int(structure, "bpp", &bpp);
|
||||
gst_structure_get_int(structure, "endianness", &endian);
|
||||
gst_structure_get_int(structure, "red_mask", &rmask);
|
||||
gst_structure_get_int(structure, "blue_mask", &bmask);
|
||||
gst_structure_get_int(structure, "green_mask", &gmask);
|
||||
has_alpha = gst_structure_get_int(structure, "alpha_mask", &amask);
|
||||
|
||||
g_print(" %d bits per pixel, %s endian,",
|
||||
bpp, endian == G_BIG_ENDIAN ? "big" : "little");
|
||||
g_print(" %s masks", has_alpha ? "rgba" : "rgb");
|
||||
g_print(" 0x%08x 0x%08x 0x%08x", rmask, gmask, bmask);
|
||||
if (has_alpha)
|
||||
g_print(" 0x%08x", amask);
|
||||
}
|
||||
g_print("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_caps(GstVaapiDisplay *display)
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
caps = gst_vaapi_display_get_image_caps(display);
|
||||
if (!caps)
|
||||
g_error("could not get VA image caps");
|
||||
|
||||
print_caps(caps, "image");
|
||||
gst_caps_unref(caps);
|
||||
|
||||
caps = gst_vaapi_display_get_subpicture_caps(display);
|
||||
if (!caps)
|
||||
g_error("could not get VA subpicture caps");
|
||||
|
||||
print_caps(caps, "subpicture");
|
||||
gst_caps_unref(caps);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
GstVaapiDisplay *display;
|
||||
GstVaapiWindow *window;
|
||||
GstVaapiWindowGLX *glx_window;
|
||||
GLXContext glx_context;
|
||||
Display *x11_display;
|
||||
Window x11_window;
|
||||
|
||||
static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
|
||||
static const guint width = 320;
|
||||
static const guint height = 240;
|
||||
static const guint win_width = 640;
|
||||
static const guint win_height = 480;
|
||||
|
||||
gst_init(&argc, &argv);
|
||||
|
||||
display = gst_vaapi_display_glx_new(NULL);
|
||||
if (!display)
|
||||
g_error("could not create Gst/VA display");
|
||||
|
||||
dump_caps(display);
|
||||
|
||||
window = gst_vaapi_window_glx_new(display, win_width, win_height);
|
||||
if (!window)
|
||||
g_error("could not create window");
|
||||
|
||||
gst_vaapi_window_show(window);
|
||||
|
||||
glx_window = GST_VAAPI_WINDOW_GLX(window);
|
||||
glx_context = gst_vaapi_window_glx_get_context(glx_window);
|
||||
x11_display = gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display));
|
||||
x11_window = gst_vaapi_object_get_id(GST_VAAPI_OBJECT(window));
|
||||
|
||||
if (!glXMakeCurrent(x11_display, x11_window, glx_context))
|
||||
g_error("could not make VA/GLX window context current");
|
||||
|
||||
pause();
|
||||
|
||||
g_object_unref(window);
|
||||
g_object_unref(display);
|
||||
gst_deinit();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue