gstvaapisurface.c \
gstvaapisurfacepool.c \
gstvaapisurfaceproxy.c \
+ gstvaapitexture.c \
gstvaapiutils.c \
gstvaapiutils_core.c \
gstvaapiutils_h264.c \
gstvaapisurface.h \
gstvaapisurfacepool.h \
gstvaapisurfaceproxy.h \
+ gstvaapitexture.h \
gstvaapitypes.h \
gstvaapiutils_h264.h \
gstvaapiutils_mpeg2.h \
gstvaapipixmap_priv.h \
gstvaapisurface_priv.h \
gstvaapisurfaceproxy_priv.h \
+ gstvaapitexture_priv.h \
gstvaapiutils.h \
gstvaapiutils_core.h \
gstvaapiutils_h264_priv.h \
libgstvaapi_glx_source_c = \
gstvaapidisplay_glx.c \
- gstvaapitexture.c \
+ gstvaapitexture_glx.c \
gstvaapiutils.c \
gstvaapiutils_glx.c \
gstvaapiutils_x11.c \
#include "sysdeps.h"
#include "gstvaapitexture.h"
-#include "gstvaapicompat.h"
-#include "gstvaapiutils.h"
-#include "gstvaapiutils_glx.h"
-#include "gstvaapidisplay_glx.h"
-#include "gstvaapidisplay_x11_priv.h"
-#include "gstvaapidisplay_glx_priv.h"
-#include "gstvaapiobject_priv.h"
+#include "gstvaapitexture_priv.h"
#define DEBUG 1
#include "gstvaapidebug.h"
-typedef struct _GstVaapiTextureClass GstVaapiTextureClass;
-
-/**
- * GstVaapiTexture:
- *
- * Base object for system-dependent textures.
- */
-struct _GstVaapiTexture
-{
- /*< private >*/
- GstVaapiObject parent_instance;
-
- GLenum target;
- GLenum format;
- guint width;
- guint height;
- GLContextState *gl_context;
- void *gl_surface;
- GLPixmapObject *pixo;
- GLFramebufferObject *fbo;
- guint foreign_texture:1;
-};
-
-/**
- * GstVaapiTextureClass:
- *
- * Base class for system-dependent textures.
- */
-struct _GstVaapiTextureClass
-{
- GstVaapiObjectClass parent_class;
-};
-
-static void
-_gst_vaapi_texture_destroy_objects (GstVaapiTexture * texture)
-{
- GLContextState old_cs;
-
- GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
- if (texture->gl_context)
- gl_set_current_context (texture->gl_context, &old_cs);
-
- if (texture->fbo) {
- gl_destroy_framebuffer_object (texture->fbo);
- texture->fbo = NULL;
- }
-
- if (texture->pixo) {
- gl_destroy_pixmap_object (texture->pixo);
- texture->pixo = NULL;
- }
-
- if (texture->gl_context) {
- gl_set_current_context (&old_cs, NULL);
- gl_destroy_context (texture->gl_context);
- texture->gl_context = NULL;
- }
- GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
-}
-
-static void
-gst_vaapi_texture_destroy (GstVaapiTexture * texture)
-{
- const GLuint texture_id = GST_VAAPI_OBJECT_ID (texture);
-
- _gst_vaapi_texture_destroy_objects (texture);
-
- if (texture_id) {
- if (!texture->foreign_texture)
- glDeleteTextures (1, &texture_id);
- GST_VAAPI_OBJECT_ID (texture) = 0;
- }
-}
-
-static gboolean
-_gst_vaapi_texture_create_objects (GstVaapiTexture * texture, GLuint texture_id)
-{
- gboolean success = FALSE;
- GLContextState old_cs;
-
- GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
- gl_get_current_context (&old_cs);
- texture->gl_context = gl_create_context (GST_VAAPI_OBJECT_XDISPLAY (texture),
- GST_VAAPI_OBJECT_XSCREEN (texture), &old_cs);
- if (!texture->gl_context ||
- !gl_set_current_context (texture->gl_context, NULL))
- goto end;
-
- texture->pixo = gl_create_pixmap_object (GST_VAAPI_OBJECT_XDISPLAY (texture),
- texture->width, texture->height);
- if (!texture->pixo)
- goto end;
-
- texture->fbo = gl_create_framebuffer_object (texture->target,
- texture_id, texture->width, texture->height);
- if (texture->fbo)
- success = TRUE;
-end:
- gl_set_current_context (&old_cs, NULL);
- GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
- return success;
-}
-
-static gboolean
-gst_vaapi_texture_create (GstVaapiTexture * texture)
-{
- GLuint texture_id;
-
- if (texture->foreign_texture)
- texture_id = GST_VAAPI_OBJECT_ID (texture);
- else {
- GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
- texture_id = gl_create_texture (texture->target,
- texture->format, texture->width, texture->height);
- GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
- if (!texture_id)
- return FALSE;
- GST_VAAPI_OBJECT_ID (texture) = texture_id;
- }
-
- return _gst_vaapi_texture_create_objects (texture, texture_id);
-}
+/* Ensure those symbols are actually defined in the resulting libraries */
+#undef gst_vaapi_texture_ref
+#undef gst_vaapi_texture_unref
+#undef gst_vaapi_texture_replace
static void
-gst_vaapi_texture_init (GstVaapiTexture * texture, GLuint texture_id,
- GLenum target, GLenum format, guint width, guint height)
+gst_vaapi_texture_init (GstVaapiTexture * texture, guint texture_id,
+ guint target, guint format, guint width, guint height)
{
GST_VAAPI_OBJECT_ID (texture) = texture_id;
- texture->foreign_texture = texture_id != GL_NONE;
-
- texture->target = target;
- texture->format = format;
+ texture->is_wrapped = texture_id != 0;
+ texture->gl_target = target;
+ texture->gl_format = format;
texture->width = width;
texture->height = height;
}
-#define gst_vaapi_texture_finalize gst_vaapi_texture_destroy
-GST_VAAPI_OBJECT_DEFINE_CLASS (GstVaapiTexture, gst_vaapi_texture);
-
-/**
- * gst_vaapi_texture_new:
- * @display: a #GstVaapiDisplay
- * @target: the target to which the texture is bound
- * @format: the format of the pixel data
- * @width: the requested width, in pixels
- * @height: the requested height, in pixels
- *
- * Creates a texture with the specified dimensions, @target and
- * @format. Note that only GL_TEXTURE_2D @target and GL_RGBA or
- * GL_BGRA formats are supported at this time.
- *
- * The application shall maintain the live GL context itself. That is,
- * gst_vaapi_window_glx_make_current() must be called beforehand, or
- * any other function like glXMakeCurrent() if the context is managed
- * outside of this library.
- *
- * Return value: the newly created #GstVaapiTexture object
- */
-GstVaapiTexture *
-gst_vaapi_texture_new (GstVaapiDisplay * display, GLenum target, GLenum format,
- guint width, guint height)
+static inline gboolean
+gst_vaapi_texture_allocate (GstVaapiTexture * texture)
{
- GstVaapiTexture *texture;
-
- g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
- g_return_val_if_fail (target != GL_NONE, NULL);
- g_return_val_if_fail (format != GL_NONE, NULL);
- g_return_val_if_fail (width > 0, NULL);
- g_return_val_if_fail (height > 0, NULL);
-
- texture = gst_vaapi_object_new (gst_vaapi_texture_class (), display);
- if (!texture)
- return NULL;
-
- gst_vaapi_texture_init (texture, GL_NONE, target, format, width, height);
- if (!gst_vaapi_texture_create (texture))
- goto error;
- return texture;
-
-error:
- gst_vaapi_object_unref (texture);
- return NULL;
+ return GST_VAAPI_TEXTURE_GET_CLASS (texture)->allocate (texture);
}
-/**
- * gst_vaapi_texture_new_with_texture:
- * @display: a #GstVaapiDisplay
- * @texture_id: the foreign GL texture name to use
- * @target: the target to which the texture is bound
- * @format: the format of the pixel data
- *
- * Creates a texture from an existing GL texture, with the specified
- * @target and @format. Note that only GL_TEXTURE_2D @target and
- * GL_RGBA or GL_BGRA formats are supported at this time. The
- * dimensions will be retrieved from the @texture_id.
- *
- * The application shall maintain the live GL context itself. That is,
- * gst_vaapi_window_glx_make_current() must be called beforehand, or
- * any other function like glXMakeCurrent() if the context is managed
- * outside of this library.
- *
- * Return value: the newly created #GstVaapiTexture object
- */
GstVaapiTexture *
-gst_vaapi_texture_new_with_texture (GstVaapiDisplay * display,
- GLuint texture_id, GLenum target, GLenum format)
+gst_vaapi_texture_new (const GstVaapiTextureClass * klass,
+ GstVaapiDisplay * display, guint texture_id, guint target, guint format,
+ guint width, guint height)
{
GstVaapiTexture *texture;
- guint width, height, border_width;
- GLTextureState ts;
- gboolean success;
- g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
- g_return_val_if_fail (target != GL_NONE, NULL);
- g_return_val_if_fail (format != GL_NONE, NULL);
-
- /* Check texture dimensions */
- GST_VAAPI_DISPLAY_LOCK (display);
- success = gl_bind_texture (&ts, target, texture_id);
- if (success) {
- if (!gl_get_texture_param (target, GL_TEXTURE_WIDTH, &width) ||
- !gl_get_texture_param (target, GL_TEXTURE_HEIGHT, &height) ||
- !gl_get_texture_param (target, GL_TEXTURE_BORDER, &border_width))
- success = FALSE;
- gl_unbind_texture (&ts);
- }
- GST_VAAPI_DISPLAY_UNLOCK (display);
- if (!success)
- return NULL;
-
- width -= 2 * border_width;
- height -= 2 * border_width;
+ g_return_val_if_fail (target != 0, NULL);
+ g_return_val_if_fail (format != 0, NULL);
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
- texture = gst_vaapi_object_new (gst_vaapi_texture_class (), display);
+ texture = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (klass), display);
if (!texture)
return NULL;
gst_vaapi_texture_init (texture, texture_id, target, format, width, height);
- if (!gst_vaapi_texture_create (texture))
+ if (!gst_vaapi_texture_allocate (texture))
goto error;
return texture;
GstVaapiTexture *
gst_vaapi_texture_ref (GstVaapiTexture * texture)
{
- return gst_vaapi_object_ref (texture);
+ return gst_vaapi_texture_ref_internal (texture);
}
/**
void
gst_vaapi_texture_unref (GstVaapiTexture * texture)
{
- gst_vaapi_object_unref (texture);
+ gst_vaapi_texture_unref_internal (texture);
}
/**
gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr,
GstVaapiTexture * new_texture)
{
- gst_vaapi_object_replace (old_texture_ptr, new_texture);
+ gst_vaapi_texture_replace_internal (old_texture_ptr, new_texture);
}
/**
*
* Return value: the underlying texture id of the @texture
*/
-GLuint
+guint
gst_vaapi_texture_get_id (GstVaapiTexture * texture)
{
g_return_val_if_fail (texture != NULL, 0);
- return GST_VAAPI_OBJECT_ID (texture);
+ return GST_VAAPI_TEXTURE_ID (texture);
}
/**
*
* Return value: the texture target
*/
-GLenum
+guint
gst_vaapi_texture_get_target (GstVaapiTexture * texture)
{
- g_return_val_if_fail (texture != NULL, GL_NONE);
+ g_return_val_if_fail (texture != NULL, 0);
- return texture->target;
+ return GST_VAAPI_TEXTURE_TARGET (texture);
}
/**
*
* Return value: the texture format
*/
-GLenum
+guint
gst_vaapi_texture_get_format (GstVaapiTexture * texture)
{
- g_return_val_if_fail (texture != NULL, GL_NONE);
+ g_return_val_if_fail (texture != NULL, 0);
- return texture->format;
+ return GST_VAAPI_TEXTURE_FORMAT (texture);
}
/**
{
g_return_val_if_fail (texture != NULL, 0);
- return texture->width;
+ return GST_VAAPI_TEXTURE_WIDTH (texture);
}
/**
{
g_return_val_if_fail (texture != NULL, 0);
- return texture->height;
+ return GST_VAAPI_TEXTURE_HEIGHT (texture);
}
/**
g_return_if_fail (texture != NULL);
if (width_ptr)
- *width_ptr = texture->width;
+ *width_ptr = GST_VAAPI_TEXTURE_WIDTH (texture);
if (height_ptr)
- *height_ptr = texture->height;
+ *height_ptr = GST_VAAPI_TEXTURE_HEIGHT (texture);
}
/**
*
* Return value: %TRUE on success
*/
-static gboolean
-_gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
+gboolean
+gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
{
- VAStatus status;
+ const GstVaapiTextureClass *klass;
GstVaapiRectangle rect;
- GLContextState old_cs;
- gboolean success = FALSE;
+
+ g_return_val_if_fail (texture != NULL, FALSE);
+ g_return_val_if_fail (surface != NULL, FALSE);
+
+ klass = GST_VAAPI_TEXTURE_GET_CLASS (texture);
+ if (!klass)
+ return FALSE;
if (!crop_rect) {
rect.x = 0;
gst_vaapi_surface_get_size (surface, &rect.width, &rect.height);
crop_rect = ▭
}
-
- GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
- status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture),
- GST_VAAPI_OBJECT_ID (surface),
- texture->pixo->pixmap,
- crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height,
- 0, 0, texture->width, texture->height,
- NULL, 0, from_GstVaapiSurfaceRenderFlags (flags)
- );
- GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
- if (!vaapi_check_status (status, "vaPutSurface() [TFP]"))
- return FALSE;
-
- GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
- if (texture->gl_context) {
- success = gl_set_current_context (texture->gl_context, &old_cs);
- if (!success)
- goto end;
- }
-
- success = gl_bind_framebuffer_object (texture->fbo);
- if (!success) {
- GST_DEBUG ("could not bind FBO");
- goto out_reset_context;
- }
-
- GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
- success = gst_vaapi_surface_sync (surface);
- GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
- if (!success) {
- GST_DEBUG ("could not render surface to pixmap");
- goto out_unbind_fbo;
- }
-
- success = gl_bind_pixmap_object (texture->pixo);
- 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, texture->height);
- glTexCoord2f (1.0f, 1.0f);
- glVertex2i (texture->width, texture->height);
- glTexCoord2f (1.0f, 0.0f);
- glVertex2i (texture->width, 0);
- }
- glEnd ();
-
- success = gl_unbind_pixmap_object (texture->pixo);
- if (!success) {
- GST_DEBUG ("could not release GLX pixmap");
- goto out_unbind_fbo;
- }
-
-out_unbind_fbo:
- if (!gl_unbind_framebuffer_object (texture->fbo))
- success = FALSE;
-out_reset_context:
- if (texture->gl_context && !gl_set_current_context (&old_cs, NULL))
- success = FALSE;
-end:
- GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
- return success;
-}
-
-gboolean
-gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
- GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
-{
- g_return_val_if_fail (texture != NULL, FALSE);
- g_return_val_if_fail (surface != NULL, FALSE);
-
- return _gst_vaapi_texture_put_surface (texture, surface, crop_rect, flags);
+ return klass->put_surface (texture, surface, crop_rect, flags);
}
#ifndef GST_VAAPI_TEXTURE_H
#define GST_VAAPI_TEXTURE_H
-#include <GL/gl.h>
#include <gst/vaapi/gstvaapitypes.h>
-#include <gst/vaapi/gstvaapiobject.h>
-#include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapisurface.h>
G_BEGIN_DECLS
-typedef struct _GstVaapiTexture GstVaapiTexture;
+#define GST_VAAPI_TEXTURE(obj) \
+ ((GstVaapiTexture *)(obj))
-GstVaapiTexture *
-gst_vaapi_texture_new (GstVaapiDisplay * display, GLenum target, GLenum format,
- guint width, guint height);
+/**
+ * GST_VAAPI_TEXTURE_ID:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture id associated with the @texture
+ */
+#define GST_VAAPI_TEXTURE_ID(texture) \
+ gst_vaapi_texture_get_id (GST_VAAPI_TEXTURE (texture))
-GstVaapiTexture *
-gst_vaapi_texture_new_with_texture (GstVaapiDisplay * display, GLuint texture_id,
- GLenum target, GLenum format);
+/**
+ * GST_VAAPI_TEXTURE_TARGET:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture target associated with the @texture
+ */
+#define GST_VAAPI_TEXTURE_TARGET(texture) \
+ gst_vaapi_texture_get_target (GST_VAAPI_TEXTURE (texture))
+
+/**
+ * GST_VAAPI_TEXTURE_FORMAT:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture format associated with the @texture
+ */
+#define GST_VAAPI_TEXTURE_FORMAT(texture) \
+ gst_vaapi_texture_get_format (GST_VAAPI_TEXTURE (texture))
+
+/**
+ * GST_VAAPI_TEXTURE_WIDTH:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture width associated with the @texture
+ */
+#define GST_VAAPI_TEXTURE_WIDTH(texture) \
+ gst_vaapi_texture_get_width (GST_VAAPI_TEXTURE (texture))
+
+/**
+ * GST_VAAPI_TEXTURE_HEIGHT:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture height associated with the @texture
+ */
+#define GST_VAAPI_TEXTURE_HEIGHT(texture) \
+ gst_vaapi_texture_get_height (GST_VAAPI_TEXTURE (texture))
+
+typedef struct _GstVaapiTexture GstVaapiTexture;
GstVaapiTexture *
gst_vaapi_texture_ref (GstVaapiTexture * texture);
gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr,
GstVaapiTexture * new_texture);
-GLuint
+guint
gst_vaapi_texture_get_id (GstVaapiTexture * texture);
-GLenum
+guint
gst_vaapi_texture_get_target (GstVaapiTexture * texture);
-GLenum
+guint
gst_vaapi_texture_get_format (GstVaapiTexture * texture);
guint
--- /dev/null
+/*
+ * gstvaapitexture_glx.c - VA/GLX texture abstraction
+ *
+ * Copyright (C) 2010-2011 Splitted-Desktop Systems
+ * Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
+ * Copyright (C) 2012-2014 Intel Corporation
+ * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+/**
+ * SECTION:gstvaapitexture_glx
+ * @short_description: VA/GLX texture abstraction
+ */
+
+#include "sysdeps.h"
+#include "gstvaapitexture.h"
+#include "gstvaapitexture_glx.h"
+#include "gstvaapitexture_priv.h"
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+#include "gstvaapiutils_glx.h"
+#include "gstvaapidisplay_glx.h"
+#include "gstvaapidisplay_x11_priv.h"
+#include "gstvaapidisplay_glx_priv.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+#define GST_VAAPI_TEXTURE_GLX(texture) \
+ ((GstVaapiTextureGLX *)(texture))
+
+typedef struct _GstVaapiTextureGLX GstVaapiTextureGLX;
+typedef struct _GstVaapiTextureGLXClass GstVaapiTextureGLXClass;
+
+/**
+ * GstVaapiTextureGLX:
+ *
+ * Base object for GLX texture wrapper.
+ */
+struct _GstVaapiTextureGLX
+{
+ /*< private >*/
+ GstVaapiTexture parent_instance;
+
+ GLContextState *gl_context;
+ GLPixmapObject *pixo;
+ GLFramebufferObject *fbo;
+};
+
+/**
+ * GstVaapiTextureGLXClass:
+ *
+ * Base class for GLX texture wrapper.
+ */
+struct _GstVaapiTextureGLXClass
+{
+ /*< private >*/
+ GstVaapiTextureClass parent_class;
+};
+
+static gboolean
+gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture,
+ GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
+ guint flags);
+
+static void
+destroy_objects (GstVaapiTextureGLX * texture)
+{
+ GLContextState old_cs;
+
+ if (texture->gl_context)
+ gl_set_current_context (texture->gl_context, &old_cs);
+
+ if (texture->fbo) {
+ gl_destroy_framebuffer_object (texture->fbo);
+ texture->fbo = NULL;
+ }
+
+ if (texture->pixo) {
+ gl_destroy_pixmap_object (texture->pixo);
+ texture->pixo = NULL;
+ }
+
+ if (texture->gl_context) {
+ gl_set_current_context (&old_cs, NULL);
+ gl_destroy_context (texture->gl_context);
+ texture->gl_context = NULL;
+ }
+}
+
+static void
+destroy_texture_unlocked (GstVaapiTexture * texture)
+{
+ const guint texture_id = GST_VAAPI_TEXTURE_ID (texture);
+
+ destroy_objects (GST_VAAPI_TEXTURE_GLX (texture));
+
+ if (texture_id) {
+ if (!texture->is_wrapped)
+ glDeleteTextures (1, &texture_id);
+ GST_VAAPI_TEXTURE_ID (texture) = 0;
+ }
+}
+
+static void
+gst_vaapi_texture_glx_destroy (GstVaapiTexture * texture)
+{
+ GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
+ destroy_texture_unlocked (texture);
+ GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
+}
+
+static gboolean
+create_objects (GstVaapiTextureGLX * texture, guint texture_id)
+{
+ GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture);
+ GLContextState old_cs;
+ gboolean success = FALSE;
+
+ gl_get_current_context (&old_cs);
+
+ texture->gl_context = gl_create_context (GST_VAAPI_OBJECT_XDISPLAY (texture),
+ GST_VAAPI_OBJECT_XSCREEN (texture), &old_cs);
+ if (!texture->gl_context ||
+ !gl_set_current_context (texture->gl_context, NULL))
+ return FALSE;
+
+ texture->pixo = gl_create_pixmap_object (GST_VAAPI_OBJECT_XDISPLAY (texture),
+ base_texture->width, base_texture->height);
+ if (!texture->pixo) {
+ GST_ERROR ("failed to create GLX pixmap");
+ goto out_reset_context;
+ }
+
+ texture->fbo = gl_create_framebuffer_object (base_texture->gl_target,
+ texture_id, base_texture->width, base_texture->height);
+ if (!texture->fbo) {
+ GST_ERROR ("failed to create FBO");
+ goto out_reset_context;
+ }
+ success = TRUE;
+
+out_reset_context:
+ gl_set_current_context (&old_cs, NULL);
+ return success;
+}
+
+static gboolean
+create_texture_unlocked (GstVaapiTexture * texture)
+{
+ guint texture_id;
+
+ if (texture->is_wrapped)
+ texture_id = GST_VAAPI_TEXTURE_ID (texture);
+ else {
+ texture_id = gl_create_texture (texture->gl_target, texture->gl_format,
+ texture->width, texture->height);
+ if (!texture_id)
+ return FALSE;
+ GST_VAAPI_TEXTURE_ID (texture) = texture_id;
+ }
+ return create_objects (GST_VAAPI_TEXTURE_GLX (texture), texture_id);
+}
+
+static gboolean
+gst_vaapi_texture_glx_create (GstVaapiTexture * texture)
+{
+ gboolean success;
+
+ GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
+ success = create_texture_unlocked (texture);
+ GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
+ return success;
+}
+
+static void
+gst_vaapi_texture_glx_class_init (GstVaapiTextureGLXClass * klass)
+{
+ GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass);
+ GstVaapiTextureClass *const texture_class = GST_VAAPI_TEXTURE_CLASS (klass);
+
+ object_class->finalize = (GstVaapiObjectFinalizeFunc)
+ gst_vaapi_texture_glx_destroy;
+
+ texture_class->allocate = gst_vaapi_texture_glx_create;
+ texture_class->put_surface = gst_vaapi_texture_glx_put_surface;
+}
+
+#define gst_vaapi_texture_glx_finalize gst_vaapi_texture_glx_destroy
+GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiTextureGLX,
+ gst_vaapi_texture_glx, gst_vaapi_texture_glx_class_init (&g_class));
+
+/**
+ * gst_vaapi_texture_glx_new:
+ * @display: a #GstVaapiDisplay
+ * @target: the target to which the texture is bound
+ * @format: the format of the pixel data
+ * @width: the requested width, in pixels
+ * @height: the requested height, in pixels
+ *
+ * Creates a texture with the specified dimensions, @target and
+ * @format. Note that only GL_TEXTURE_2D @target and GL_RGBA or
+ * GL_BGRA formats are supported at this time.
+ *
+ * The application shall maintain the live GL context itself. That is,
+ * gst_vaapi_window_glx_make_current() must be called beforehand, or
+ * any other function like glXMakeCurrent() if the context is managed
+ * outside of this library.
+ *
+ * Return value: the newly created #GstVaapiTexture object
+ */
+GstVaapiTexture *
+gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target,
+ guint format, guint width, guint height)
+{
+ g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
+
+ return
+ gst_vaapi_texture_new (GST_VAAPI_TEXTURE_CLASS
+ (gst_vaapi_texture_glx_class ()), display, GL_NONE, target, format, width,
+ height);
+}
+
+/**
+ * gst_vaapi_texture_glx_new_wrapped:
+ * @display: a #GstVaapiDisplay
+ * @texture_id: the foreign GL texture name to use
+ * @target: the target to which the texture is bound
+ * @format: the format of the pixel data
+ *
+ * Creates a texture from an existing GL texture, with the specified
+ * @target and @format. Note that only GL_TEXTURE_2D @target and
+ * GL_RGBA or GL_BGRA formats are supported at this time. The
+ * dimensions will be retrieved from the @texture_id.
+ *
+ * The application shall maintain the live GL context itself. That is,
+ * gst_vaapi_window_glx_make_current() must be called beforehand, or
+ * any other function like glXMakeCurrent() if the context is managed
+ * outside of this library.
+ *
+ * Return value: the newly created #GstVaapiTexture object
+ */
+GstVaapiTexture *
+gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display,
+ guint texture_id, guint target, guint format)
+{
+ guint width, height, border_width;
+ GLTextureState ts;
+ gboolean success;
+
+ g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
+ g_return_val_if_fail (target != GL_NONE, NULL);
+ g_return_val_if_fail (format != GL_NONE, NULL);
+
+ /* Check texture dimensions */
+ GST_VAAPI_DISPLAY_LOCK (display);
+ success = gl_bind_texture (&ts, target, texture_id);
+ if (success) {
+ if (!gl_get_texture_param (target, GL_TEXTURE_WIDTH, &width) ||
+ !gl_get_texture_param (target, GL_TEXTURE_HEIGHT, &height) ||
+ !gl_get_texture_param (target, GL_TEXTURE_BORDER, &border_width))
+ success = FALSE;
+ gl_unbind_texture (&ts);
+ }
+ GST_VAAPI_DISPLAY_UNLOCK (display);
+ if (!success)
+ return NULL;
+
+ width -= 2 * border_width;
+ height -= 2 * border_width;
+ g_return_val_if_fail (width > 0, NULL);
+ g_return_val_if_fail (height > 0, NULL);
+
+ return
+ gst_vaapi_texture_new (GST_VAAPI_TEXTURE_CLASS
+ (gst_vaapi_texture_glx_class ()), display, texture_id, target, format,
+ width, height);
+}
+
+/**
+ * gst_vaapi_texture_put_surface:
+ * @texture: a #GstVaapiTexture
+ * @surface: a #GstVaapiSurface
+ * @flags: postprocessing flags. See #GstVaapiTextureRenderFlags
+ *
+ * Renders the @surface into the àtexture. The @flags specify how
+ * de-interlacing (if needed), color space conversion, scaling and
+ * other postprocessing transformations are performed.
+ *
+ * Return value: %TRUE on success
+ */
+static gboolean
+gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture,
+ GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
+{
+ GstVaapiTextureGLX *const texture = GST_VAAPI_TEXTURE_GLX (base_texture);
+ VAStatus status;
+ GLContextState old_cs;
+ gboolean success = FALSE;
+
+ status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture),
+ GST_VAAPI_OBJECT_ID (surface), texture->pixo->pixmap,
+ crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height,
+ 0, 0, base_texture->width, base_texture->height,
+ NULL, 0, from_GstVaapiSurfaceRenderFlags (flags));
+ if (!vaapi_check_status (status, "vaPutSurface() [TFP]"))
+ return FALSE;
+
+ if (texture->gl_context &&
+ !gl_set_current_context (texture->gl_context, &old_cs))
+ return FALSE;
+
+ if (!gl_bind_framebuffer_object (texture->fbo)) {
+ GST_ERROR ("failed to bind FBO");
+ goto out_reset_context;
+ }
+
+ if (!gst_vaapi_surface_sync (surface)) {
+ GST_ERROR ("failed to render surface to pixmap");
+ goto out_unbind_fbo;
+ }
+
+ if (!gl_bind_pixmap_object (texture->pixo)) {
+ GST_ERROR ("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, base_texture->height);
+ glTexCoord2f (1.0f, 1.0f);
+ glVertex2i (base_texture->width, base_texture->height);
+ glTexCoord2f (1.0f, 0.0f);
+ glVertex2i (base_texture->width, 0);
+ }
+ glEnd ();
+
+ if (!gl_unbind_pixmap_object (texture->pixo)) {
+ GST_ERROR ("failed to release GLX pixmap");
+ goto out_unbind_fbo;
+ }
+ success = TRUE;
+
+out_unbind_fbo:
+ if (!gl_unbind_framebuffer_object (texture->fbo))
+ success = FALSE;
+out_reset_context:
+ if (texture->gl_context && !gl_set_current_context (&old_cs, NULL))
+ success = FALSE;
+ return success;
+}
+
+static gboolean
+gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture,
+ GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
+{
+ gboolean success;
+
+ GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
+ success = gst_vaapi_texture_glx_put_surface_unlocked (texture, surface,
+ crop_rect, flags);
+ GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
+ return success;
+}
--- /dev/null
+/*
+ * gstvaapitexture_glx.h - VA/GLX texture abstraction
+ *
+ * Copyright (C) 2010-2011 Splitted-Desktop Systems
+ * Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
+ * Copyright (C) 2012-2014 Intel Corporation
+ * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef GST_VAAPI_TEXTURE_GLX_H
+#define GST_VAAPI_TEXTURE_GLX_H
+
+#include <gst/vaapi/gstvaapitexture.h>
+
+G_BEGIN_DECLS
+
+GstVaapiTexture *
+gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target,
+ guint format, guint width, guint height);
+
+GstVaapiTexture *
+gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display, guint id,
+ guint target, guint format);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_TEXTURE_GLX_H */
--- /dev/null
+/*
+ * gstvaapitexture_priv.h - VA texture abstraction (private definitions)
+ *
+ * Copyright (C) 2010-2011 Splitted-Desktop Systems
+ * Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
+ * Copyright (C) 2012-2014 Intel Corporation
+ * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef GST_VAAPI_TEXTURE_PRIV_H
+#define GST_VAAPI_TEXTURE_PRIV_H
+
+#include "gstvaapiobject_priv.h"
+
+G_BEGIN_DECLS
+
+#define GST_VAAPI_TEXTURE_CLASS(klass) \
+ ((GstVaapiTextureClass *)(klass))
+
+#define GST_VAAPI_TEXTURE_GET_CLASS(obj) \
+ GST_VAAPI_TEXTURE_CLASS (GST_VAAPI_OBJECT_GET_CLASS (obj))
+
+/**
+ * GST_VAAPI_TEXTURE_ID:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture id associated with the @texture
+ */
+#undef GST_VAAPI_TEXTURE_ID
+#define GST_VAAPI_TEXTURE_ID(texture) \
+ (GST_VAAPI_OBJECT_ID (texture))
+
+/**
+ * GST_VAAPI_TEXTURE_TARGET:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture target associated with the @texture
+ */
+#undef GST_VAAPI_TEXTURE_TARGET
+#define GST_VAAPI_TEXTURE_TARGET(texture) \
+ (GST_VAAPI_TEXTURE (texture)->gl_target)
+
+/**
+ * GST_VAAPI_TEXTURE_FORMAT:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture format associated with the @texture
+ */
+#undef GST_VAAPI_TEXTURE_FORMAT
+#define GST_VAAPI_TEXTURE_FORMAT(texture) \
+ (GST_VAAPI_TEXTURE (texture)->gl_format)
+
+/**
+ * GST_VAAPI_TEXTURE_WIDTH:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture width associated with the @texture
+ */
+#undef GST_VAAPI_TEXTURE_WIDTH
+#define GST_VAAPI_TEXTURE_WIDTH(texture) \
+ (GST_VAAPI_TEXTURE (texture)->width)
+
+/**
+ * GST_VAAPI_TEXTURE_HEIGHT:
+ * @texture: a #GstVaapiTexture
+ *
+ * Macro that evaluates to the GL texture height associated with the @texture
+ */
+#undef GST_VAAPI_TEXTURE_HEIGHT
+#define GST_VAAPI_TEXTURE_HEIGHT(texture) \
+ (GST_VAAPI_TEXTURE (texture)->height)
+
+/* GstVaapiTextureClass hooks */
+typedef gboolean (*GstVaapiTextureAllocateFunc) (GstVaapiTexture * texture);
+typedef gboolean (*GstVaapiTexturePutSurfaceFunc) (GstVaapiTexture * texture,
+ GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
+ guint flags);
+
+typedef struct _GstVaapiTextureClass GstVaapiTextureClass;
+
+/**
+ * GstVaapiTexture:
+ *
+ * Base class for API-dependent textures.
+ */
+struct _GstVaapiTexture {
+ /*< private >*/
+ GstVaapiObject parent_instance;
+
+ /*< protected >*/
+ guint gl_target;
+ guint gl_format;
+ guint width;
+ guint height;
+ guint is_wrapped:1;
+};
+
+/**
+ * GstVaapiTextureClass:
+ * @put_surface: virtual function to render a #GstVaapiSurface into a texture
+ *
+ * Base class for API-dependent textures.
+ */
+struct _GstVaapiTextureClass {
+ /*< private >*/
+ GstVaapiObjectClass parent_class;
+
+ /*< protected >*/
+ GstVaapiTextureAllocateFunc allocate;
+ GstVaapiTexturePutSurfaceFunc put_surface;
+};
+
+GstVaapiTexture *
+gst_vaapi_texture_new (const GstVaapiTextureClass * klass,
+ GstVaapiDisplay * display, guint texture_id, guint target, guint format,
+ guint width, guint height);
+
+/* Inline reference counting for core libgstvaapi library */
+#ifdef IN_LIBGSTVAAPI_CORE
+#define gst_vaapi_texture_ref_internal(texture) \
+ ((gpointer)gst_vaapi_mini_object_ref (GST_VAAPI_MINI_OBJECT (texture)))
+
+#define gst_vaapi_texture_unref_internal(texture) \
+ gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (texture))
+
+#define gst_vaapi_texture_replace_internal(old_texture_ptr, new_texture) \
+ gst_vaapi_mini_object_replace ((GstVaapiMiniObject **)(old_texture_ptr), \
+ GST_VAAPI_MINI_OBJECT (new_texture))
+
+#undef gst_vaapi_texture_ref
+#define gst_vaapi_texture_ref(texture) \
+ gst_vaapi_texture_ref_internal ((texture))
+
+#undef gst_vaapi_texture_unref
+#define gst_vaapi_texture_unref(texture) \
+ gst_vaapi_texture_unref_internal ((texture))
+
+#undef gst_vaapi_texture_replace
+#define gst_vaapi_texture_replace(old_texture_ptr, new_texture) \
+ gst_vaapi_texture_replace_internal ((old_texture_ptr), (new_texture))
+#endif
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_TEXTURE_PRIV_H */
*/
#include "gst/vaapi/sysdeps.h"
-#include <gst/vaapi/gstvaapitexture.h>
+#include <gst/vaapi/gstvaapitexture_glx.h>
#include "gstvaapivideoconverter_glx.h"
#include "gstvaapivideoconverter_x11.h"
#include "gstvaapipluginutil.h"
/* FIXME Should we assume target and format ? */
texture =
- gst_vaapi_texture_new_with_texture (gst_vaapi_video_meta_get_display
+ gst_vaapi_texture_glx_new_wrapped (gst_vaapi_video_meta_get_display
(meta), g_value_get_uint (dest), GL_TEXTURE_2D, GL_BGRA);
if (!texture)
return NULL;
const guint texture = gst_vaapi_texture_get_id (priv->texture);
gst_vaapi_texture_replace (&priv->texture, NULL);
- priv->texture = gst_vaapi_texture_new_with_texture (new_dpy,
+ priv->texture = gst_vaapi_texture_glx_new_wrapped (new_dpy,
texture, GL_TEXTURE_2D, GL_BGRA);
}
*/
#include "gst/vaapi/sysdeps.h"
+#include <GL/gl.h>
#include "gstvaapivideometa.h"
#include "gstvaapipluginutil.h"
+#if USE_GLX
+#include <gst/vaapi/gstvaapitexture_glx.h>
+#endif
+
#if GST_CHECK_VERSION(1,1,0) && USE_GLX
#include "gstvaapivideometa_texture.h"
gst_vaapi_texture_get_id (meta_texture->texture) != texture_id[0]) {
/* FIXME: should we assume target? */
GstVaapiTexture *const texture =
- gst_vaapi_texture_new_with_texture (dpy, texture_id[0],
+ gst_vaapi_texture_glx_new_wrapped (dpy, texture_id[0],
GL_TEXTURE_2D, GL_RGBA);
gst_vaapi_texture_replace (&meta_texture->texture, texture);
if (!texture)
#include "gst/vaapi/sysdeps.h"
#include <gst/vaapi/gstvaapidisplay_glx.h>
#include <gst/vaapi/gstvaapiwindow_glx.h>
+#include <gst/vaapi/gstvaapitexture_glx.h>
#include <gst/vaapi/gstvaapisurface.h>
#include <gst/vaapi/gstvaapiimage.h>
-#include <gst/vaapi/gstvaapitexture.h>
#include "image.h"
static inline void pause(void)
g_error("coult not bind GL context");
g_print("#\n");
- g_print("# Create texture with gst_vaapi_texture_new()\n");
+ g_print("# Create texture with gst_vaapi_texture_glx_new()\n");
g_print("#\n");
{
- texture = gst_vaapi_texture_new(
+ texture = gst_vaapi_texture_glx_new(
display,
GL_TEXTURE_2D,
GL_RGBA,
}
g_print("#\n");
- g_print("# Create texture with gst_vaapi_texture_new_with_texture()\n");
+ g_print("# Create texture with gst_vaapi_texture_glx_new_wrapped()\n");
g_print("#\n");
{
const GLenum target = GL_TEXTURE_2D;
);
glDisable(target);
- texture = gst_vaapi_texture_new_with_texture(
+ texture = gst_vaapi_texture_glx_new_wrapped(
display,
texture_id,
target,
g_error("invalid texture id");
if (gl_get_current_texture_2d() != texture_id)
- g_error("gst_vaapi_texture_new_with_texture() altered texture bindings");
+ g_error("gst_vaapi_texture_glx_new_wrapped() altered texture bindings");
textures[1] = texture;