mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 00:31:13 +00:00
libs: texture: Make texture a standard GstMiniObject.
We store GstVaapiTextureGLX and GstVaapiTextureEGL's private data in the qdata of miniobject and avoid extending the base texture class. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/317>
This commit is contained in:
parent
808247a963
commit
f20bd8bfd1
9 changed files with 353 additions and 318 deletions
|
@ -38,51 +38,80 @@
|
||||||
(GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED | \
|
(GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED | \
|
||||||
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED)
|
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED)
|
||||||
|
|
||||||
|
#define GST_VAAPI_TEXTURE_PRIVATE_QUARK gst_vaapi_texture_private_quark ()
|
||||||
|
static GQuark
|
||||||
|
gst_vaapi_texture_private_quark (void)
|
||||||
|
{
|
||||||
|
static gsize g_quark;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&g_quark)) {
|
||||||
|
gsize quark = (gsize) g_quark_from_static_string ("GstVaapiTexturePrivate");
|
||||||
|
g_once_init_leave (&g_quark, quark);
|
||||||
|
}
|
||||||
|
return g_quark;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpointer
|
||||||
|
gst_vaapi_texture_get_private (GstVaapiTexture * texture)
|
||||||
|
{
|
||||||
|
return gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (texture),
|
||||||
|
GST_VAAPI_TEXTURE_PRIVATE_QUARK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_vaapi_texture_set_private (GstVaapiTexture * texture, gpointer priv,
|
||||||
|
GDestroyNotify destroy)
|
||||||
|
{
|
||||||
|
gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (texture),
|
||||||
|
GST_VAAPI_TEXTURE_PRIVATE_QUARK, (gpointer) priv, destroy);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_texture_init (GstVaapiTexture * texture, GstVaapiID id,
|
gst_vaapi_texture_init (GstVaapiTexture * texture, GstVaapiID id,
|
||||||
guint target, guint format, guint width, guint height)
|
guint target, guint format, guint width, guint height)
|
||||||
{
|
{
|
||||||
texture->is_wrapped = id != GST_VAAPI_ID_INVALID;
|
texture->is_wrapped = id != GST_VAAPI_ID_INVALID;
|
||||||
GST_VAAPI_OBJECT_ID (texture) = texture->is_wrapped ? id : 0;
|
GST_VAAPI_TEXTURE_ID (texture) = texture->is_wrapped ? id : 0;
|
||||||
texture->gl_target = target;
|
texture->gl_target = target;
|
||||||
texture->gl_format = format;
|
texture->gl_format = format;
|
||||||
texture->width = width;
|
texture->width = width;
|
||||||
texture->height = height;
|
texture->height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gboolean
|
static void
|
||||||
gst_vaapi_texture_allocate (GstVaapiTexture * texture)
|
gst_vaapi_texture_free (GstVaapiTexture * texture)
|
||||||
{
|
{
|
||||||
return GST_VAAPI_TEXTURE_GET_CLASS (texture)->allocate (texture);
|
gst_vaapi_display_replace (&GST_VAAPI_TEXTURE_DISPLAY (texture), NULL);
|
||||||
|
g_slice_free1 (sizeof (GstVaapiTexture), texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_DEFINE_MINI_OBJECT_TYPE (GstVaapiTexture, gst_vaapi_texture);
|
||||||
|
|
||||||
GstVaapiTexture *
|
GstVaapiTexture *
|
||||||
gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass,
|
gst_vaapi_texture_new_internal (GstVaapiDisplay * display, GstVaapiID id,
|
||||||
GstVaapiDisplay * display, GstVaapiID id, guint target, guint format,
|
guint target, guint format, guint width, guint height)
|
||||||
guint width, guint height)
|
|
||||||
{
|
{
|
||||||
GstVaapiTexture *texture;
|
GstVaapiTexture *texture;
|
||||||
|
|
||||||
|
g_return_val_if_fail (display, NULL);
|
||||||
g_return_val_if_fail (target != 0, NULL);
|
g_return_val_if_fail (target != 0, NULL);
|
||||||
g_return_val_if_fail (format != 0, NULL);
|
g_return_val_if_fail (format != 0, NULL);
|
||||||
g_return_val_if_fail (width > 0, NULL);
|
g_return_val_if_fail (width > 0, NULL);
|
||||||
g_return_val_if_fail (height > 0, NULL);
|
g_return_val_if_fail (height > 0, NULL);
|
||||||
|
|
||||||
texture = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (klass), display);
|
texture = g_slice_alloc (sizeof (GstVaapiTexture));
|
||||||
if (!texture)
|
if (!texture)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
gst_vaapi_texture_init (texture, id, target, format, width, height);
|
gst_mini_object_init (GST_MINI_OBJECT_CAST (texture), 0,
|
||||||
if (!gst_vaapi_texture_allocate (texture))
|
GST_TYPE_VAAPI_TEXTURE, NULL, NULL,
|
||||||
goto error;
|
(GstMiniObjectFreeFunction) gst_vaapi_texture_free);
|
||||||
return texture;
|
|
||||||
|
|
||||||
/* ERRORS */
|
GST_VAAPI_TEXTURE_DISPLAY (texture) = gst_object_ref (display);
|
||||||
error:
|
|
||||||
{
|
gst_vaapi_texture_init (texture, id, target, format, width, height);
|
||||||
gst_vaapi_object_unref (texture);
|
|
||||||
return NULL;
|
return texture;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,50 +184,6 @@ gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id,
|
||||||
return dpy_class->create_texture (display, id, target, format, width, height);
|
return dpy_class->create_texture (display, id, target, format, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_vaapi_texture_ref:
|
|
||||||
* @texture: a #GstVaapiTexture
|
|
||||||
*
|
|
||||||
* Atomically increases the reference count of the given @texture by one.
|
|
||||||
*
|
|
||||||
* Returns: The same @texture argument
|
|
||||||
*/
|
|
||||||
GstVaapiTexture *
|
|
||||||
gst_vaapi_texture_ref (GstVaapiTexture * texture)
|
|
||||||
{
|
|
||||||
return gst_vaapi_object_ref (GST_VAAPI_OBJECT (texture));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_vaapi_texture_unref:
|
|
||||||
* @texture: a #GstVaapiTexture
|
|
||||||
*
|
|
||||||
* Atomically decreases the reference count of the @texture by one. If
|
|
||||||
* the reference count reaches zero, the texture will be free'd.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gst_vaapi_texture_unref (GstVaapiTexture * texture)
|
|
||||||
{
|
|
||||||
gst_vaapi_object_unref (GST_VAAPI_OBJECT (texture));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_vaapi_texture_replace:
|
|
||||||
* @old_texture_ptr: a pointer to a #GstVaapiTexture
|
|
||||||
* @new_texture: a #GstVaapiTexture
|
|
||||||
*
|
|
||||||
* Atomically replaces the texture texture held in @old_texture_ptr
|
|
||||||
* with @new_texture. This means that @old_texture_ptr shall reference
|
|
||||||
* a valid texture. However, @new_texture can be NULL.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr,
|
|
||||||
GstVaapiTexture * new_texture)
|
|
||||||
{
|
|
||||||
gst_vaapi_object_replace ((GstVaapiObject **) (old_texture_ptr),
|
|
||||||
GST_VAAPI_OBJECT (new_texture));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_texture_get_id:
|
* gst_vaapi_texture_get_id:
|
||||||
* @texture: a #GstVaapiTexture
|
* @texture: a #GstVaapiTexture
|
||||||
|
@ -300,6 +285,21 @@ gst_vaapi_texture_get_size (GstVaapiTexture * texture,
|
||||||
*height_ptr = GST_VAAPI_TEXTURE_HEIGHT (texture);
|
*height_ptr = GST_VAAPI_TEXTURE_HEIGHT (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vaapi_texture_get_display:
|
||||||
|
* @texture: a #GstVaapiTexture
|
||||||
|
*
|
||||||
|
* Returns the #GstVaapiDisplay this @texture is bound to.
|
||||||
|
*
|
||||||
|
* Return value: the parent #GstVaapiDisplay object
|
||||||
|
*/
|
||||||
|
GstVaapiDisplay *
|
||||||
|
gst_vaapi_texture_get_display (GstVaapiTexture * texture)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (texture != NULL, NULL);
|
||||||
|
return GST_VAAPI_TEXTURE_DISPLAY (texture);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_texture_get_orientation_flags:
|
* gst_vaapi_texture_get_orientation_flags:
|
||||||
* @texture: a #GstVaapiTexture
|
* @texture: a #GstVaapiTexture
|
||||||
|
@ -313,8 +313,7 @@ gst_vaapi_texture_get_orientation_flags (GstVaapiTexture * texture)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (texture != NULL, 0);
|
g_return_val_if_fail (texture != NULL, 0);
|
||||||
|
|
||||||
return GST_VAAPI_TEXTURE_FLAGS (texture) &
|
return GST_MINI_OBJECT_FLAGS (texture) & GST_VAAPI_TEXTURE_ORIENTATION_FLAGS;
|
||||||
GST_VAAPI_TEXTURE_ORIENTATION_FLAGS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -333,8 +332,8 @@ gst_vaapi_texture_set_orientation_flags (GstVaapiTexture * texture, guint flags)
|
||||||
g_return_if_fail (texture != NULL);
|
g_return_if_fail (texture != NULL);
|
||||||
g_return_if_fail ((flags & ~GST_VAAPI_TEXTURE_ORIENTATION_FLAGS) == 0);
|
g_return_if_fail ((flags & ~GST_VAAPI_TEXTURE_ORIENTATION_FLAGS) == 0);
|
||||||
|
|
||||||
GST_VAAPI_TEXTURE_FLAG_UNSET (texture, GST_VAAPI_TEXTURE_ORIENTATION_FLAGS);
|
GST_MINI_OBJECT_FLAG_UNSET (texture, GST_VAAPI_TEXTURE_ORIENTATION_FLAGS);
|
||||||
GST_VAAPI_TEXTURE_FLAG_SET (texture, flags);
|
GST_MINI_OBJECT_FLAG_SET (texture, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -343,7 +342,7 @@ gst_vaapi_texture_set_orientation_flags (GstVaapiTexture * texture, guint flags)
|
||||||
* @surface: a #GstVaapiSurface
|
* @surface: a #GstVaapiSurface
|
||||||
* @flags: postprocessing flags. See #GstVaapiTextureRenderFlags
|
* @flags: postprocessing flags. See #GstVaapiTextureRenderFlags
|
||||||
*
|
*
|
||||||
* Renders the @surface into the àtexture. The @flags specify how
|
* Renders the @surface into the @texture. The @flags specify how
|
||||||
* de-interlacing (if needed), color space conversion, scaling and
|
* de-interlacing (if needed), color space conversion, scaling and
|
||||||
* other postprocessing transformations are performed.
|
* other postprocessing transformations are performed.
|
||||||
*
|
*
|
||||||
|
@ -353,14 +352,12 @@ gboolean
|
||||||
gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
|
gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
|
||||||
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
|
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
|
||||||
{
|
{
|
||||||
const GstVaapiTextureClass *klass;
|
|
||||||
GstVaapiRectangle rect;
|
GstVaapiRectangle rect;
|
||||||
|
|
||||||
g_return_val_if_fail (texture != NULL, FALSE);
|
g_return_val_if_fail (texture != NULL, FALSE);
|
||||||
g_return_val_if_fail (surface != NULL, FALSE);
|
g_return_val_if_fail (surface != NULL, FALSE);
|
||||||
|
|
||||||
klass = GST_VAAPI_TEXTURE_GET_CLASS (texture);
|
if (!texture->put_surface)
|
||||||
if (!klass)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!crop_rect) {
|
if (!crop_rect) {
|
||||||
|
@ -369,5 +366,5 @@ gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
|
||||||
gst_vaapi_surface_get_size (surface, &rect.width, &rect.height);
|
gst_vaapi_surface_get_size (surface, &rect.width, &rect.height);
|
||||||
crop_rect = ▭
|
crop_rect = ▭
|
||||||
}
|
}
|
||||||
return klass->put_surface (texture, surface, crop_rect, flags);
|
return texture->put_surface (texture, surface, crop_rect, flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,17 @@ G_BEGIN_DECLS
|
||||||
#define GST_VAAPI_TEXTURE(obj) \
|
#define GST_VAAPI_TEXTURE(obj) \
|
||||||
((GstVaapiTexture *)(obj))
|
((GstVaapiTexture *)(obj))
|
||||||
|
|
||||||
|
#define GST_TYPE_VAAPI_TEXTURE (gst_vaapi_texture_get_type ())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_VAAPI_TEXTURE_DISPLAY:
|
||||||
|
* @texture: a #GstVaapiTexture
|
||||||
|
*
|
||||||
|
* Macro that evaluates to the display associated with the @texture
|
||||||
|
*/
|
||||||
|
#define GST_VAAPI_TEXTURE_DISPLAY(texture) \
|
||||||
|
gst_vaapi_texture_get_display (GST_VAAPI_TEXTURE (texture))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GST_VAAPI_TEXTURE_ID:
|
* GST_VAAPI_TEXTURE_ID:
|
||||||
* @texture: a #GstVaapiTexture
|
* @texture: a #GstVaapiTexture
|
||||||
|
@ -94,10 +105,26 @@ typedef struct _GstVaapiTexture GstVaapiTexture;
|
||||||
* from the left to the right.
|
* from the left to the right.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED = 1 << 31,
|
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED = (GST_MINI_OBJECT_FLAG_LAST << 1),
|
||||||
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED = 1 << 30,
|
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED = (GST_MINI_OBJECT_FLAG_LAST << 2),
|
||||||
} GstVaapiTextureOrientationFlags;
|
} GstVaapiTextureOrientationFlags;
|
||||||
|
|
||||||
|
GType
|
||||||
|
gst_vaapi_texture_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vaapi_texture_unref: (skip)
|
||||||
|
* @texture: (transfer full): a #GstVaapiTexture.
|
||||||
|
*
|
||||||
|
* Decreases the refcount of the texture. If the refcount reaches 0, the
|
||||||
|
* texture will be freed.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
gst_vaapi_texture_unref (GstVaapiTexture * texture)
|
||||||
|
{
|
||||||
|
gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture));
|
||||||
|
}
|
||||||
|
|
||||||
GstVaapiTexture *
|
GstVaapiTexture *
|
||||||
gst_vaapi_texture_new (GstVaapiDisplay * display, guint target, guint format,
|
gst_vaapi_texture_new (GstVaapiDisplay * display, guint target, guint format,
|
||||||
guint width, guint height);
|
guint width, guint height);
|
||||||
|
@ -106,19 +133,12 @@ GstVaapiTexture *
|
||||||
gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id,
|
gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id,
|
||||||
guint target, guint format, guint width, guint height);
|
guint target, guint format, guint width, guint height);
|
||||||
|
|
||||||
GstVaapiTexture *
|
|
||||||
gst_vaapi_texture_ref (GstVaapiTexture * texture);
|
|
||||||
|
|
||||||
void
|
|
||||||
gst_vaapi_texture_unref (GstVaapiTexture * texture);
|
|
||||||
|
|
||||||
void
|
|
||||||
gst_vaapi_texture_replace (GstVaapiTexture ** old_texture_ptr,
|
|
||||||
GstVaapiTexture * new_texture);
|
|
||||||
|
|
||||||
guint
|
guint
|
||||||
gst_vaapi_texture_get_id (GstVaapiTexture * texture);
|
gst_vaapi_texture_get_id (GstVaapiTexture * texture);
|
||||||
|
|
||||||
|
GstVaapiDisplay *
|
||||||
|
gst_vaapi_texture_get_display (GstVaapiTexture * texture);
|
||||||
|
|
||||||
guint
|
guint
|
||||||
gst_vaapi_texture_get_target (GstVaapiTexture * texture);
|
gst_vaapi_texture_get_target (GstVaapiTexture * texture);
|
||||||
|
|
||||||
|
@ -147,6 +167,8 @@ gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
|
||||||
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
|
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
|
||||||
guint flags);
|
guint flags);
|
||||||
|
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiTexture, gst_vaapi_texture_unref)
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* GST_VAAPI_TEXTURE_H */
|
#endif /* GST_VAAPI_TEXTURE_H */
|
||||||
|
|
|
@ -40,48 +40,32 @@
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#include "gstvaapidebug.h"
|
#include "gstvaapidebug.h"
|
||||||
|
|
||||||
#define GST_VAAPI_TEXTURE_EGL(texture) \
|
typedef struct _GstVaapiTextureEGLPrivate GstVaapiTextureEGLPrivate;
|
||||||
((GstVaapiTextureEGL *) (texture))
|
|
||||||
|
|
||||||
typedef struct _GstVaapiTextureEGL GstVaapiTextureEGL;
|
|
||||||
typedef struct _GstVaapiTextureEGLClass GstVaapiTextureEGLClass;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVaapiTextureEGL:
|
* GstVaapiTextureEGLPrivate:
|
||||||
*
|
*
|
||||||
* Base object for EGL texture wrapper.
|
* EGL texture specific fields.
|
||||||
*/
|
*/
|
||||||
struct _GstVaapiTextureEGL
|
struct _GstVaapiTextureEGLPrivate
|
||||||
{
|
{
|
||||||
/*< private > */
|
/*< private > */
|
||||||
GstVaapiTexture parent_instance;
|
GstVaapiTexture *texture;
|
||||||
|
|
||||||
EglContext *egl_context;
|
EglContext *egl_context;
|
||||||
EGLImageKHR egl_image;
|
EGLImageKHR egl_image;
|
||||||
GstVaapiSurface *surface;
|
GstVaapiSurface *surface;
|
||||||
GstVaapiFilter *filter;
|
GstVaapiFilter *filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiTextureEGLClass:
|
|
||||||
*
|
|
||||||
* Base class for EGL texture wrapper.
|
|
||||||
*/
|
|
||||||
struct _GstVaapiTextureEGLClass
|
|
||||||
{
|
|
||||||
/*< private > */
|
|
||||||
GstVaapiTextureClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GstVaapiTextureEGL *texture;
|
GstVaapiTexture *texture;
|
||||||
gboolean success; /* result */
|
gboolean success; /* result */
|
||||||
} CreateTextureArgs;
|
} CreateTextureArgs;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GstVaapiTextureEGL *texture;
|
GstVaapiTexture *texture;
|
||||||
GstVaapiSurface *surface;
|
GstVaapiSurface *surface;
|
||||||
const GstVaapiRectangle *crop_rect;
|
const GstVaapiRectangle *crop_rect;
|
||||||
guint flags;
|
guint flags;
|
||||||
|
@ -89,32 +73,31 @@ typedef struct
|
||||||
} UploadSurfaceArgs;
|
} UploadSurfaceArgs;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
create_objects (GstVaapiTextureEGL * texture, GLuint texture_id)
|
create_objects (GstVaapiTexture * texture, GLuint texture_id)
|
||||||
{
|
{
|
||||||
GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture);
|
GstVaapiTextureEGLPrivate *const texture_egl =
|
||||||
EglContext *const ctx = texture->egl_context;
|
gst_vaapi_texture_get_private (texture);
|
||||||
|
EglContext *const ctx = texture_egl->egl_context;
|
||||||
EglVTable *const vtable = egl_context_get_vtable (ctx, FALSE);
|
EglVTable *const vtable = egl_context_get_vtable (ctx, FALSE);
|
||||||
GLint attribs[3], *attrib;
|
GLint attribs[3] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
|
||||||
|
|
||||||
attrib = attribs;
|
texture_egl->egl_image =
|
||||||
*attrib++ = EGL_IMAGE_PRESERVED_KHR;
|
vtable->eglCreateImageKHR (ctx->display->base.handle.p,
|
||||||
*attrib++ = EGL_TRUE;
|
|
||||||
*attrib++ = EGL_NONE;
|
|
||||||
texture->egl_image = vtable->eglCreateImageKHR (ctx->display->base.handle.p,
|
|
||||||
ctx->base.handle.p, EGL_GL_TEXTURE_2D_KHR,
|
ctx->base.handle.p, EGL_GL_TEXTURE_2D_KHR,
|
||||||
(EGLClientBuffer) GSIZE_TO_POINTER (texture_id), attribs);
|
(EGLClientBuffer) GSIZE_TO_POINTER (texture_id), attribs);
|
||||||
if (!texture->egl_image)
|
if (!texture_egl->egl_image)
|
||||||
goto error_create_image;
|
goto error_create_image;
|
||||||
|
|
||||||
texture->surface =
|
texture_egl->surface =
|
||||||
gst_vaapi_surface_new_with_egl_image (GST_VAAPI_OBJECT_DISPLAY (texture),
|
gst_vaapi_surface_new_with_egl_image (GST_VAAPI_TEXTURE_DISPLAY (texture),
|
||||||
texture->egl_image, GST_VIDEO_FORMAT_RGBA, base_texture->width,
|
texture_egl->egl_image, GST_VIDEO_FORMAT_RGBA, texture->width,
|
||||||
base_texture->height);
|
texture->height);
|
||||||
if (!texture->surface)
|
if (!texture_egl->surface)
|
||||||
goto error_create_surface;
|
goto error_create_surface;
|
||||||
|
|
||||||
texture->filter = gst_vaapi_filter_new (GST_VAAPI_OBJECT_DISPLAY (texture));
|
texture_egl->filter =
|
||||||
if (!texture->filter)
|
gst_vaapi_filter_new (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
|
if (!texture_egl->filter)
|
||||||
goto error_create_filter;
|
goto error_create_filter;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -137,17 +120,18 @@ error_create_filter:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
do_create_texture_unlocked (GstVaapiTextureEGL * texture)
|
do_create_texture_unlocked (GstVaapiTexture * texture)
|
||||||
{
|
{
|
||||||
GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture);
|
|
||||||
GLuint texture_id;
|
GLuint texture_id;
|
||||||
|
GstVaapiTextureEGLPrivate *texture_egl =
|
||||||
|
gst_vaapi_texture_get_private (texture);
|
||||||
|
|
||||||
if (base_texture->is_wrapped)
|
if (texture->is_wrapped)
|
||||||
texture_id = GST_VAAPI_TEXTURE_ID (texture);
|
texture_id = GST_VAAPI_TEXTURE_ID (texture);
|
||||||
else {
|
else {
|
||||||
texture_id = egl_create_texture (texture->egl_context,
|
texture_id = egl_create_texture (texture_egl->egl_context,
|
||||||
base_texture->gl_target, base_texture->gl_format,
|
texture->gl_target, texture->gl_format,
|
||||||
base_texture->width, base_texture->height);
|
texture->width, texture->height);
|
||||||
if (!texture_id)
|
if (!texture_id)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
GST_VAAPI_TEXTURE_ID (texture) = texture_id;
|
GST_VAAPI_TEXTURE_ID (texture) = texture_id;
|
||||||
|
@ -158,74 +142,78 @@ do_create_texture_unlocked (GstVaapiTextureEGL * texture)
|
||||||
static void
|
static void
|
||||||
do_create_texture (CreateTextureArgs * args)
|
do_create_texture (CreateTextureArgs * args)
|
||||||
{
|
{
|
||||||
GstVaapiTextureEGL *const texture = args->texture;
|
GstVaapiTexture *const texture = args->texture;
|
||||||
|
GstVaapiTextureEGLPrivate *texture_egl =
|
||||||
|
gst_vaapi_texture_get_private (texture);
|
||||||
EglContextState old_cs;
|
EglContextState old_cs;
|
||||||
|
|
||||||
args->success = FALSE;
|
args->success = FALSE;
|
||||||
|
|
||||||
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) {
|
if (egl_context_set_current (texture_egl->egl_context, TRUE, &old_cs)) {
|
||||||
args->success = do_create_texture_unlocked (texture);
|
args->success = do_create_texture_unlocked (texture);
|
||||||
egl_context_set_current (texture->egl_context, FALSE, &old_cs);
|
egl_context_set_current (texture_egl->egl_context, FALSE, &old_cs);
|
||||||
}
|
}
|
||||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_objects (GstVaapiTextureEGL * texture)
|
destroy_objects (GstVaapiTextureEGLPrivate * texture_egl)
|
||||||
{
|
{
|
||||||
EglContext *const ctx = texture->egl_context;
|
EglContext *const ctx = texture_egl->egl_context;
|
||||||
EglVTable *const vtable = egl_context_get_vtable (ctx, FALSE);
|
EglVTable *const vtable = egl_context_get_vtable (ctx, FALSE);
|
||||||
|
|
||||||
if (texture->egl_image != EGL_NO_IMAGE_KHR) {
|
if (texture_egl->egl_image != EGL_NO_IMAGE_KHR) {
|
||||||
vtable->eglDestroyImageKHR (ctx->display->base.handle.p,
|
vtable->eglDestroyImageKHR (ctx->display->base.handle.p,
|
||||||
texture->egl_image);
|
texture_egl->egl_image);
|
||||||
texture->egl_image = EGL_NO_IMAGE_KHR;
|
texture_egl->egl_image = EGL_NO_IMAGE_KHR;
|
||||||
}
|
}
|
||||||
gst_mini_object_replace ((GstMiniObject **) & texture->surface, NULL);
|
gst_mini_object_replace ((GstMiniObject **) & texture_egl->surface, NULL);
|
||||||
gst_vaapi_filter_replace (&texture->filter, NULL);
|
gst_vaapi_filter_replace (&texture_egl->filter, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_destroy_texture_unlocked (GstVaapiTextureEGL * texture)
|
do_destroy_texture_unlocked (GstVaapiTextureEGLPrivate * texture_egl)
|
||||||
{
|
{
|
||||||
GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture);
|
GstVaapiTexture *const base_texture = texture_egl->texture;
|
||||||
const GLuint texture_id = GST_VAAPI_TEXTURE_ID (texture);
|
const GLuint texture_id = GST_VAAPI_TEXTURE_ID (base_texture);
|
||||||
|
|
||||||
destroy_objects (texture);
|
destroy_objects (texture_egl);
|
||||||
|
|
||||||
if (texture_id) {
|
if (texture_id) {
|
||||||
if (!base_texture->is_wrapped)
|
if (!base_texture->is_wrapped)
|
||||||
egl_destroy_texture (texture->egl_context, texture_id);
|
egl_destroy_texture (texture_egl->egl_context, texture_id);
|
||||||
GST_VAAPI_TEXTURE_ID (texture) = 0;
|
GST_VAAPI_TEXTURE_ID (base_texture) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_destroy_texture (GstVaapiTextureEGL * texture)
|
do_destroy_texture (GstVaapiTextureEGLPrivate * texture_egl)
|
||||||
{
|
{
|
||||||
EglContextState old_cs;
|
EglContextState old_cs;
|
||||||
|
GstVaapiTexture *texture = texture_egl->texture;
|
||||||
|
|
||||||
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) {
|
if (egl_context_set_current (texture_egl->egl_context, TRUE, &old_cs)) {
|
||||||
do_destroy_texture_unlocked (texture);
|
do_destroy_texture_unlocked (texture_egl);
|
||||||
egl_context_set_current (texture->egl_context, FALSE, &old_cs);
|
egl_context_set_current (texture_egl->egl_context, FALSE, &old_cs);
|
||||||
}
|
}
|
||||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
egl_object_replace (&texture->egl_context, NULL);
|
egl_object_replace (&texture_egl->egl_context, NULL);
|
||||||
|
g_free (texture_egl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
do_upload_surface_unlocked (GstVaapiTextureEGL * texture,
|
do_upload_surface_unlocked (GstVaapiTextureEGLPrivate * texture_egl,
|
||||||
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
|
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
|
||||||
{
|
{
|
||||||
GstVaapiFilterStatus status;
|
GstVaapiFilterStatus status;
|
||||||
|
|
||||||
if (!gst_vaapi_filter_set_cropping_rectangle (texture->filter, crop_rect))
|
if (!gst_vaapi_filter_set_cropping_rectangle (texture_egl->filter, crop_rect))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
status = gst_vaapi_filter_process (texture->filter, surface, texture->surface,
|
status = gst_vaapi_filter_process (texture_egl->filter, surface,
|
||||||
flags);
|
texture_egl->surface, flags);
|
||||||
if (status != GST_VAAPI_FILTER_STATUS_SUCCESS)
|
if (status != GST_VAAPI_FILTER_STATUS_SUCCESS)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -234,74 +222,86 @@ do_upload_surface_unlocked (GstVaapiTextureEGL * texture,
|
||||||
static void
|
static void
|
||||||
do_upload_surface (UploadSurfaceArgs * args)
|
do_upload_surface (UploadSurfaceArgs * args)
|
||||||
{
|
{
|
||||||
GstVaapiTextureEGL *const texture = args->texture;
|
GstVaapiTexture *const texture = args->texture;
|
||||||
|
GstVaapiTextureEGLPrivate *texture_egl =
|
||||||
|
gst_vaapi_texture_get_private (texture);
|
||||||
EglContextState old_cs;
|
EglContextState old_cs;
|
||||||
|
|
||||||
args->success = FALSE;
|
args->success = FALSE;
|
||||||
|
|
||||||
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) {
|
if (egl_context_set_current (texture_egl->egl_context, TRUE, &old_cs)) {
|
||||||
args->success = do_upload_surface_unlocked (texture, args->surface,
|
args->success = do_upload_surface_unlocked (texture_egl, args->surface,
|
||||||
args->crop_rect, args->flags);
|
args->crop_rect, args->flags);
|
||||||
egl_context_set_current (texture->egl_context, FALSE, &old_cs);
|
egl_context_set_current (texture_egl->egl_context, FALSE, &old_cs);
|
||||||
}
|
}
|
||||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_texture_egl_create (GstVaapiTextureEGL * texture)
|
gst_vaapi_texture_egl_create (GstVaapiTexture * texture)
|
||||||
{
|
{
|
||||||
CreateTextureArgs args = { texture };
|
CreateTextureArgs args = { texture };
|
||||||
GstVaapiDisplayEGL *display =
|
GstVaapiDisplayEGL *display =
|
||||||
GST_VAAPI_DISPLAY_EGL (GST_VAAPI_OBJECT_DISPLAY (texture));
|
GST_VAAPI_DISPLAY_EGL (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
|
GstVaapiTextureEGLPrivate *texture_egl =
|
||||||
|
gst_vaapi_texture_get_private (texture);
|
||||||
|
|
||||||
if (GST_VAAPI_TEXTURE (texture)->is_wrapped) {
|
if (GST_VAAPI_TEXTURE (texture)->is_wrapped) {
|
||||||
if (!gst_vaapi_display_egl_set_current_display (display))
|
if (!gst_vaapi_display_egl_set_current_display (display))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_object_replace (&texture->egl_context,
|
egl_object_replace (&texture_egl->egl_context,
|
||||||
GST_VAAPI_DISPLAY_EGL_CONTEXT (display));
|
GST_VAAPI_DISPLAY_EGL_CONTEXT (display));
|
||||||
|
|
||||||
return egl_context_run (texture->egl_context,
|
return egl_context_run (texture_egl->egl_context,
|
||||||
(EglContextRunFunc) do_create_texture, &args) && args.success;
|
(EglContextRunFunc) do_create_texture, &args) && args.success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_texture_egl_destroy (GstVaapiTextureEGL * texture)
|
gst_vaapi_texture_egl_destroy (GstVaapiTextureEGLPrivate * texture_egl)
|
||||||
{
|
{
|
||||||
egl_context_run (texture->egl_context,
|
egl_context_run (texture_egl->egl_context,
|
||||||
(EglContextRunFunc) do_destroy_texture, texture);
|
(EglContextRunFunc) do_destroy_texture, texture_egl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_texture_egl_put_surface (GstVaapiTextureEGL * texture,
|
gst_vaapi_texture_egl_put_surface (GstVaapiTexture * texture,
|
||||||
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
|
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
|
||||||
{
|
{
|
||||||
UploadSurfaceArgs args = { texture, surface, crop_rect, flags };
|
UploadSurfaceArgs args = { texture, surface, crop_rect, flags };
|
||||||
|
GstVaapiTextureEGLPrivate *texture_egl =
|
||||||
|
gst_vaapi_texture_get_private (texture);
|
||||||
|
|
||||||
return egl_context_run (texture->egl_context,
|
return egl_context_run (texture_egl->egl_context,
|
||||||
(EglContextRunFunc) do_upload_surface, &args) && args.success;
|
(EglContextRunFunc) do_upload_surface, &args) && args.success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static GstVaapiTexture *
|
||||||
gst_vaapi_texture_egl_class_init (GstVaapiTextureEGLClass * klass)
|
gst_vaapi_texture_egl_new_internal (GstVaapiTexture * texture)
|
||||||
{
|
{
|
||||||
GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass);
|
GstVaapiTextureEGLPrivate *texture_egl;
|
||||||
GstVaapiTextureClass *const texture_class = GST_VAAPI_TEXTURE_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->finalize = (GstVaapiObjectFinalizeFunc)
|
texture->put_surface = gst_vaapi_texture_egl_put_surface;
|
||||||
gst_vaapi_texture_egl_destroy;
|
|
||||||
texture_class->allocate = (GstVaapiTextureAllocateFunc)
|
texture_egl = g_malloc0 (sizeof (GstVaapiTextureEGLPrivate));
|
||||||
gst_vaapi_texture_egl_create;
|
if (!texture_egl) {
|
||||||
texture_class->put_surface = (GstVaapiTexturePutSurfaceFunc)
|
gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture));
|
||||||
gst_vaapi_texture_egl_put_surface;
|
return NULL;
|
||||||
|
}
|
||||||
|
texture_egl->texture = texture;
|
||||||
|
gst_vaapi_texture_set_private (texture, texture_egl,
|
||||||
|
(GDestroyNotify) gst_vaapi_texture_egl_destroy);
|
||||||
|
|
||||||
|
if (!gst_vaapi_texture_egl_create (texture)) {
|
||||||
|
gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define gst_vaapi_texture_egl_finalize gst_vaapi_texture_egl_destroy
|
|
||||||
GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiTextureEGL,
|
|
||||||
gst_vaapi_texture_egl, gst_vaapi_texture_egl_class_init (&g_class));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_texture_egl_new:
|
* gst_vaapi_texture_egl_new:
|
||||||
* @display: a #GstVaapiDisplay
|
* @display: a #GstVaapiDisplay
|
||||||
|
@ -325,11 +325,16 @@ GstVaapiTexture *
|
||||||
gst_vaapi_texture_egl_new (GstVaapiDisplay * display, guint target,
|
gst_vaapi_texture_egl_new (GstVaapiDisplay * display, guint target,
|
||||||
guint format, guint width, guint height)
|
guint format, guint width, guint height)
|
||||||
{
|
{
|
||||||
|
GstVaapiTexture *texture;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL);
|
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL);
|
||||||
|
|
||||||
return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS
|
texture = gst_vaapi_texture_new_internal (display, GST_VAAPI_ID_INVALID,
|
||||||
(gst_vaapi_texture_egl_class ()), display, GST_VAAPI_ID_INVALID, target,
|
target, format, width, height);
|
||||||
format, width, height);
|
if (!texture)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return gst_vaapi_texture_egl_new_internal (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -356,10 +361,15 @@ GstVaapiTexture *
|
||||||
gst_vaapi_texture_egl_new_wrapped (GstVaapiDisplay * display,
|
gst_vaapi_texture_egl_new_wrapped (GstVaapiDisplay * display,
|
||||||
guint texture_id, guint target, GLenum format, guint width, guint height)
|
guint texture_id, guint target, GLenum format, guint width, guint height)
|
||||||
{
|
{
|
||||||
|
GstVaapiTexture *texture;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL);
|
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL);
|
||||||
g_return_val_if_fail (texture_id != GL_NONE, NULL);
|
g_return_val_if_fail (texture_id != GL_NONE, NULL);
|
||||||
|
|
||||||
return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS
|
texture = gst_vaapi_texture_new_internal (display, texture_id,
|
||||||
(gst_vaapi_texture_egl_class ()), display, texture_id, target, format,
|
target, format, width, height);
|
||||||
width, height);
|
if (!texture)
|
||||||
|
return texture;
|
||||||
|
|
||||||
|
return gst_vaapi_texture_egl_new_internal (texture);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,42 +45,29 @@
|
||||||
#define GST_VAAPI_TEXTURE_GLX(texture) \
|
#define GST_VAAPI_TEXTURE_GLX(texture) \
|
||||||
((GstVaapiTextureGLX *)(texture))
|
((GstVaapiTextureGLX *)(texture))
|
||||||
|
|
||||||
typedef struct _GstVaapiTextureGLX GstVaapiTextureGLX;
|
typedef struct _GstVaapiTextureGLXPrivate GstVaapiTextureGLXPrivate;
|
||||||
typedef struct _GstVaapiTextureGLXClass GstVaapiTextureGLXClass;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVaapiTextureGLX:
|
* GstVaapiTextureGLXPrivate:
|
||||||
*
|
*
|
||||||
* Base object for GLX texture wrapper.
|
* GLX texture specific fields.
|
||||||
*/
|
*/
|
||||||
struct _GstVaapiTextureGLX
|
struct _GstVaapiTextureGLXPrivate
|
||||||
{
|
{
|
||||||
/*< private > */
|
/*< private > */
|
||||||
GstVaapiTexture parent_instance;
|
GstVaapiTexture *texture;
|
||||||
|
|
||||||
GLContextState *gl_context;
|
GLContextState *gl_context;
|
||||||
GLPixmapObject *pixo;
|
GLPixmapObject *pixo;
|
||||||
GLFramebufferObject *fbo;
|
GLFramebufferObject *fbo;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* GstVaapiTextureGLXClass:
|
|
||||||
*
|
|
||||||
* Base class for GLX texture wrapper.
|
|
||||||
*/
|
|
||||||
struct _GstVaapiTextureGLXClass
|
|
||||||
{
|
|
||||||
/*< private > */
|
|
||||||
GstVaapiTextureClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture,
|
gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture,
|
||||||
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
|
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
|
||||||
guint flags);
|
guint flags);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_objects (GstVaapiTextureGLX * texture)
|
destroy_objects (GstVaapiTextureGLXPrivate * texture)
|
||||||
{
|
{
|
||||||
GLContextState old_cs;
|
GLContextState old_cs;
|
||||||
|
|
||||||
|
@ -105,11 +92,12 @@ destroy_objects (GstVaapiTextureGLX * texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_texture_unlocked (GstVaapiTexture * texture)
|
destroy_texture_unlocked (GstVaapiTextureGLXPrivate * texture_glx)
|
||||||
{
|
{
|
||||||
|
GstVaapiTexture *texture = texture_glx->texture;
|
||||||
const guint texture_id = GST_VAAPI_TEXTURE_ID (texture);
|
const guint texture_id = GST_VAAPI_TEXTURE_ID (texture);
|
||||||
|
|
||||||
destroy_objects (GST_VAAPI_TEXTURE_GLX (texture));
|
destroy_objects (texture_glx);
|
||||||
|
|
||||||
if (texture_id) {
|
if (texture_id) {
|
||||||
if (!texture->is_wrapped)
|
if (!texture->is_wrapped)
|
||||||
|
@ -119,38 +107,45 @@ destroy_texture_unlocked (GstVaapiTexture * texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_texture_glx_destroy (GstVaapiTexture * texture)
|
gst_vaapi_texture_glx_destroy (GstVaapiTextureGLXPrivate * texture_glx)
|
||||||
{
|
{
|
||||||
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
|
GstVaapiTexture *texture = texture_glx->texture;
|
||||||
destroy_texture_unlocked (texture);
|
|
||||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
|
destroy_texture_unlocked (texture_glx);
|
||||||
|
GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
|
|
||||||
|
g_free (texture_glx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
create_objects (GstVaapiTextureGLX * texture, guint texture_id)
|
create_objects (GstVaapiTexture * texture, guint texture_id)
|
||||||
{
|
{
|
||||||
GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture);
|
GstVaapiTextureGLXPrivate *texture_glx =
|
||||||
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (texture);
|
gst_vaapi_texture_get_private (texture);
|
||||||
|
Display *const dpy =
|
||||||
|
GST_VAAPI_DISPLAY_NATIVE (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
GLContextState old_cs;
|
GLContextState old_cs;
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
|
|
||||||
gl_get_current_context (&old_cs);
|
gl_get_current_context (&old_cs);
|
||||||
|
|
||||||
texture->gl_context = gl_create_context (dpy, DefaultScreen (dpy), &old_cs);
|
texture_glx->gl_context =
|
||||||
if (!texture->gl_context ||
|
gl_create_context (dpy, DefaultScreen (dpy), &old_cs);
|
||||||
!gl_set_current_context (texture->gl_context, NULL))
|
if (!texture_glx->gl_context
|
||||||
|
|| !gl_set_current_context (texture_glx->gl_context, NULL))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
texture->pixo = gl_create_pixmap_object (dpy,
|
texture_glx->pixo = gl_create_pixmap_object (dpy,
|
||||||
base_texture->width, base_texture->height);
|
texture->width, texture->height);
|
||||||
if (!texture->pixo) {
|
if (!texture_glx->pixo) {
|
||||||
GST_ERROR ("failed to create GLX pixmap");
|
GST_ERROR ("failed to create GLX pixmap");
|
||||||
goto out_reset_context;
|
goto out_reset_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture->fbo = gl_create_framebuffer_object (base_texture->gl_target,
|
texture_glx->fbo = gl_create_framebuffer_object (texture->gl_target,
|
||||||
texture_id, base_texture->width, base_texture->height);
|
texture_id, texture->width, texture->height);
|
||||||
if (!texture->fbo) {
|
if (!texture_glx->fbo) {
|
||||||
GST_ERROR ("failed to create FBO");
|
GST_ERROR ("failed to create FBO");
|
||||||
goto out_reset_context;
|
goto out_reset_context;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +170,7 @@ create_texture_unlocked (GstVaapiTexture * texture)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
GST_VAAPI_TEXTURE_ID (texture) = texture_id;
|
GST_VAAPI_TEXTURE_ID (texture) = texture_id;
|
||||||
}
|
}
|
||||||
return create_objects (GST_VAAPI_TEXTURE_GLX (texture), texture_id);
|
return create_objects (texture, texture_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -183,29 +178,37 @@ gst_vaapi_texture_glx_create (GstVaapiTexture * texture)
|
||||||
{
|
{
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
success = create_texture_unlocked (texture);
|
success = create_texture_unlocked (texture);
|
||||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_vaapi_texture_glx_class_init (GstVaapiTextureGLXClass * klass)
|
static GstVaapiTexture *
|
||||||
|
gst_vaapi_texture_glx_new_internal (GstVaapiTexture * texture)
|
||||||
{
|
{
|
||||||
GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass);
|
GstVaapiTextureGLXPrivate *texture_glx;
|
||||||
GstVaapiTextureClass *const texture_class = GST_VAAPI_TEXTURE_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->finalize = (GstVaapiObjectFinalizeFunc)
|
texture->put_surface = gst_vaapi_texture_glx_put_surface;
|
||||||
gst_vaapi_texture_glx_destroy;
|
|
||||||
|
|
||||||
texture_class->allocate = gst_vaapi_texture_glx_create;
|
texture_glx = g_malloc0 (sizeof (GstVaapiTextureGLXPrivate));
|
||||||
texture_class->put_surface = gst_vaapi_texture_glx_put_surface;
|
if (!texture_glx) {
|
||||||
|
gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
texture_glx->texture = texture;
|
||||||
|
gst_vaapi_texture_set_private (texture, texture_glx,
|
||||||
|
(GDestroyNotify) gst_vaapi_texture_glx_destroy);
|
||||||
|
|
||||||
|
if (!gst_vaapi_texture_glx_create (texture)) {
|
||||||
|
gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
#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:
|
* gst_vaapi_texture_glx_new:
|
||||||
* @display: a #GstVaapiDisplay
|
* @display: a #GstVaapiDisplay
|
||||||
|
@ -229,11 +232,16 @@ GstVaapiTexture *
|
||||||
gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target,
|
gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target,
|
||||||
guint format, guint width, guint height)
|
guint format, guint width, guint height)
|
||||||
{
|
{
|
||||||
|
GstVaapiTexture *texture;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
|
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
|
||||||
|
|
||||||
return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS
|
texture = gst_vaapi_texture_new_internal (display, GST_VAAPI_ID_INVALID,
|
||||||
(gst_vaapi_texture_glx_class ()), display, GST_VAAPI_ID_INVALID, target,
|
target, format, width, height);
|
||||||
format, width, height);
|
if (!texture)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return gst_vaapi_texture_glx_new_internal (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can we assume that the vsink/app context API won't change ever? */
|
/* Can we assume that the vsink/app context API won't change ever? */
|
||||||
|
@ -278,6 +286,7 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display,
|
||||||
GLTextureState ts = { 0, };
|
GLTextureState ts = { 0, };
|
||||||
gboolean success;
|
gboolean success;
|
||||||
GstVaapiGLApi gl_api;
|
GstVaapiGLApi gl_api;
|
||||||
|
GstVaapiTexture *texture;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
|
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
|
||||||
g_return_val_if_fail (texture_id != GL_NONE, NULL);
|
g_return_val_if_fail (texture_id != GL_NONE, NULL);
|
||||||
|
@ -312,9 +321,12 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display,
|
||||||
g_return_val_if_fail (width > 0, NULL);
|
g_return_val_if_fail (width > 0, NULL);
|
||||||
g_return_val_if_fail (height > 0, NULL);
|
g_return_val_if_fail (height > 0, NULL);
|
||||||
|
|
||||||
return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS
|
texture = gst_vaapi_texture_new_internal (display, texture_id, target,
|
||||||
(gst_vaapi_texture_glx_class ()), display, texture_id, target, format,
|
format, width, height);
|
||||||
width, height);
|
if (!texture)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return gst_vaapi_texture_glx_new_internal (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -330,10 +342,11 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display,
|
||||||
* Return value: %TRUE on success
|
* Return value: %TRUE on success
|
||||||
*/
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture,
|
gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * texture,
|
||||||
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
|
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
|
||||||
{
|
{
|
||||||
GstVaapiTextureGLX *const texture = GST_VAAPI_TEXTURE_GLX (base_texture);
|
GstVaapiTextureGLXPrivate *texture_glx =
|
||||||
|
gst_vaapi_texture_get_private (texture);
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
GLContextState old_cs;
|
GLContextState old_cs;
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
|
@ -344,19 +357,19 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture,
|
||||||
{1.0f, 0.0f},
|
{1.0f, 0.0f},
|
||||||
};
|
};
|
||||||
|
|
||||||
status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture),
|
status = vaPutSurface (GST_VAAPI_DISPLAY_VADISPLAY (GST_VAAPI_TEXTURE_DISPLAY
|
||||||
GST_VAAPI_SURFACE_ID (surface), texture->pixo->pixmap,
|
(texture)), GST_VAAPI_SURFACE_ID (surface), texture_glx->pixo->pixmap,
|
||||||
crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height,
|
crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height, 0, 0,
|
||||||
0, 0, base_texture->width, base_texture->height,
|
texture->width, texture->height, NULL, 0,
|
||||||
NULL, 0, from_GstVaapiSurfaceRenderFlags (flags));
|
from_GstVaapiSurfaceRenderFlags (flags));
|
||||||
if (!vaapi_check_status (status, "vaPutSurface() [TFP]"))
|
if (!vaapi_check_status (status, "vaPutSurface() [TFP]"))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (texture->gl_context &&
|
if (texture_glx->gl_context &&
|
||||||
!gl_set_current_context (texture->gl_context, &old_cs))
|
!gl_set_current_context (texture_glx->gl_context, &old_cs))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!gl_bind_framebuffer_object (texture->fbo)) {
|
if (!gl_bind_framebuffer_object (texture_glx->fbo)) {
|
||||||
GST_ERROR ("failed to bind FBO");
|
GST_ERROR ("failed to bind FBO");
|
||||||
goto out_reset_context;
|
goto out_reset_context;
|
||||||
}
|
}
|
||||||
|
@ -366,12 +379,12 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture,
|
||||||
goto out_unbind_fbo;
|
goto out_unbind_fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gl_bind_pixmap_object (texture->pixo)) {
|
if (!gl_bind_pixmap_object (texture_glx->pixo)) {
|
||||||
GST_ERROR ("could not bind GLX pixmap");
|
GST_ERROR ("could not bind GLX pixmap");
|
||||||
goto out_unbind_fbo;
|
goto out_unbind_fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = GST_VAAPI_TEXTURE_FLAGS (texture);
|
flags = GST_MINI_OBJECT_FLAGS (texture);
|
||||||
txc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED)];
|
txc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED)];
|
||||||
tyc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED)];
|
tyc = g_texcoords[! !(flags & GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED)];
|
||||||
|
|
||||||
|
@ -381,25 +394,25 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture,
|
||||||
glTexCoord2f (txc[0], tyc[0]);
|
glTexCoord2f (txc[0], tyc[0]);
|
||||||
glVertex2i (0, 0);
|
glVertex2i (0, 0);
|
||||||
glTexCoord2f (txc[0], tyc[1]);
|
glTexCoord2f (txc[0], tyc[1]);
|
||||||
glVertex2i (0, base_texture->height);
|
glVertex2i (0, texture->height);
|
||||||
glTexCoord2f (txc[1], tyc[1]);
|
glTexCoord2f (txc[1], tyc[1]);
|
||||||
glVertex2i (base_texture->width, base_texture->height);
|
glVertex2i (texture->width, texture->height);
|
||||||
glTexCoord2f (txc[1], tyc[0]);
|
glTexCoord2f (txc[1], tyc[0]);
|
||||||
glVertex2i (base_texture->width, 0);
|
glVertex2i (texture->width, 0);
|
||||||
}
|
}
|
||||||
glEnd ();
|
glEnd ();
|
||||||
|
|
||||||
if (!gl_unbind_pixmap_object (texture->pixo)) {
|
if (!gl_unbind_pixmap_object (texture_glx->pixo)) {
|
||||||
GST_ERROR ("failed to release GLX pixmap");
|
GST_ERROR ("failed to release GLX pixmap");
|
||||||
goto out_unbind_fbo;
|
goto out_unbind_fbo;
|
||||||
}
|
}
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
|
|
||||||
out_unbind_fbo:
|
out_unbind_fbo:
|
||||||
if (!gl_unbind_framebuffer_object (texture->fbo))
|
if (!gl_unbind_framebuffer_object (texture_glx->fbo))
|
||||||
success = FALSE;
|
success = FALSE;
|
||||||
out_reset_context:
|
out_reset_context:
|
||||||
if (texture->gl_context && !gl_set_current_context (&old_cs, NULL))
|
if (texture_glx->gl_context && !gl_set_current_context (&old_cs, NULL))
|
||||||
success = FALSE;
|
success = FALSE;
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -410,9 +423,9 @@ gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture,
|
||||||
{
|
{
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
success = gst_vaapi_texture_glx_put_surface_unlocked (texture, surface,
|
success = gst_vaapi_texture_glx_put_surface_unlocked (texture, surface,
|
||||||
crop_rect, flags);
|
crop_rect, flags);
|
||||||
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
|
GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,19 @@
|
||||||
#define GST_VAAPI_TEXTURE_PRIV_H
|
#define GST_VAAPI_TEXTURE_PRIV_H
|
||||||
|
|
||||||
#include "gstvaapiobject_priv.h"
|
#include "gstvaapiobject_priv.h"
|
||||||
|
#include <gst/gstminiobject.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define GST_VAAPI_TEXTURE_CLASS(klass) \
|
/**
|
||||||
((GstVaapiTextureClass *)(klass))
|
* GST_VAAPI_TEXTURE_DISPLAY:
|
||||||
|
* @texture: a #GstVaapiTexture
|
||||||
#define GST_VAAPI_TEXTURE_GET_CLASS(obj) \
|
*
|
||||||
GST_VAAPI_TEXTURE_CLASS (GST_VAAPI_OBJECT_GET_CLASS (obj))
|
* Macro that evaluates to the @texture's display.
|
||||||
|
*/
|
||||||
|
#undef GST_VAAPI_TEXTURE_DISPLAY
|
||||||
|
#define GST_VAAPI_TEXTURE_DISPLAY(texture) \
|
||||||
|
(GST_VAAPI_TEXTURE (texture)->display)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GST_VAAPI_TEXTURE_ID:
|
* GST_VAAPI_TEXTURE_ID:
|
||||||
|
@ -43,7 +48,7 @@ G_BEGIN_DECLS
|
||||||
*/
|
*/
|
||||||
#undef GST_VAAPI_TEXTURE_ID
|
#undef GST_VAAPI_TEXTURE_ID
|
||||||
#define GST_VAAPI_TEXTURE_ID(texture) \
|
#define GST_VAAPI_TEXTURE_ID(texture) \
|
||||||
(GST_VAAPI_OBJECT_ID (texture))
|
(GST_VAAPI_TEXTURE (texture)->object_id)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GST_VAAPI_TEXTURE_TARGET:
|
* GST_VAAPI_TEXTURE_TARGET:
|
||||||
|
@ -85,18 +90,9 @@ G_BEGIN_DECLS
|
||||||
#define GST_VAAPI_TEXTURE_HEIGHT(texture) \
|
#define GST_VAAPI_TEXTURE_HEIGHT(texture) \
|
||||||
(GST_VAAPI_TEXTURE (texture)->height)
|
(GST_VAAPI_TEXTURE (texture)->height)
|
||||||
|
|
||||||
#define GST_VAAPI_TEXTURE_FLAGS GST_VAAPI_MINI_OBJECT_FLAGS
|
|
||||||
#define GST_VAAPI_TEXTURE_FLAG_IS_SET GST_VAAPI_MINI_OBJECT_FLAG_IS_SET
|
|
||||||
#define GST_VAAPI_TEXTURE_FLAG_SET GST_VAAPI_MINI_OBJECT_FLAG_SET
|
|
||||||
#define GST_VAAPI_TEXTURE_FLAG_UNSET GST_VAAPI_MINI_OBJECT_FLAG_UNSET
|
|
||||||
|
|
||||||
/* GstVaapiTextureClass hooks */
|
/* GstVaapiTextureClass hooks */
|
||||||
typedef gboolean (*GstVaapiTextureAllocateFunc) (GstVaapiTexture * texture);
|
|
||||||
typedef gboolean (*GstVaapiTexturePutSurfaceFunc) (GstVaapiTexture * texture,
|
typedef gboolean (*GstVaapiTexturePutSurfaceFunc) (GstVaapiTexture * texture,
|
||||||
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
|
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags);
|
||||||
guint flags);
|
|
||||||
|
|
||||||
typedef struct _GstVaapiTextureClass GstVaapiTextureClass;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstVaapiTexture:
|
* GstVaapiTexture:
|
||||||
|
@ -105,9 +101,12 @@ typedef struct _GstVaapiTextureClass GstVaapiTextureClass;
|
||||||
*/
|
*/
|
||||||
struct _GstVaapiTexture {
|
struct _GstVaapiTexture {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GstVaapiObject parent_instance;
|
GstMiniObject mini_object;
|
||||||
|
GstVaapiDisplay *display;
|
||||||
|
GstVaapiID object_id;
|
||||||
|
|
||||||
/*< protected >*/
|
/*< protected >*/
|
||||||
|
GstVaapiTexturePutSurfaceFunc put_surface;
|
||||||
guint gl_target;
|
guint gl_target;
|
||||||
guint gl_format;
|
guint gl_format;
|
||||||
guint width;
|
guint width;
|
||||||
|
@ -115,25 +114,16 @@ struct _GstVaapiTexture {
|
||||||
guint is_wrapped:1;
|
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 *
|
GstVaapiTexture *
|
||||||
gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass,
|
gst_vaapi_texture_new_internal (GstVaapiDisplay * display, GstVaapiID id,
|
||||||
GstVaapiDisplay * display, GstVaapiID id, guint target, guint format,
|
guint target, guint format, guint width, guint height);
|
||||||
guint width, guint height);
|
|
||||||
|
gpointer
|
||||||
|
gst_vaapi_texture_get_private (GstVaapiTexture * texture);
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_vaapi_texture_set_private (GstVaapiTexture * texture, gpointer priv,
|
||||||
|
GDestroyNotify destroy);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ gst_vaapi_texture_map_init (GstVaapiTextureMap * map)
|
||||||
{
|
{
|
||||||
map->texture_map =
|
map->texture_map =
|
||||||
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
|
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
|
||||||
(GDestroyNotify) gst_vaapi_texture_unref);
|
(GDestroyNotify) gst_mini_object_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -139,8 +139,9 @@ ensure_texture (GstVaapiWindowEGL * window, guint width, guint height)
|
||||||
|
|
||||||
texture = gst_vaapi_texture_egl_new (GST_VAAPI_WINDOW_DISPLAY (window),
|
texture = gst_vaapi_texture_egl_new (GST_VAAPI_WINDOW_DISPLAY (window),
|
||||||
GL_TEXTURE_2D, GL_RGBA, width, height);
|
GL_TEXTURE_2D, GL_RGBA, width, height);
|
||||||
gst_vaapi_texture_replace (&window->texture, texture);
|
gst_mini_object_replace ((GstMiniObject **) & window->texture,
|
||||||
gst_vaapi_texture_replace (&texture, NULL);
|
(GstMiniObject *) texture);
|
||||||
|
gst_mini_object_replace ((GstMiniObject **) & texture, NULL);
|
||||||
return window->texture != NULL;
|
return window->texture != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +288,7 @@ gst_vaapi_window_egl_finalize (GObject * object)
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_vaapi_window_replace (&window->window, NULL);
|
gst_vaapi_window_replace (&window->window, NULL);
|
||||||
gst_vaapi_texture_replace (&window->texture, NULL);
|
gst_mini_object_replace ((GstMiniObject **) & window->texture, NULL);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gst_vaapi_window_egl_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gst_vaapi_window_egl_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -385,7 +386,7 @@ gst_vaapi_window_egl_resize (GstVaapiWindow * window, guint width, guint height)
|
||||||
static gboolean
|
static gboolean
|
||||||
do_render_texture (GstVaapiWindowEGL * window, const GstVaapiRectangle * rect)
|
do_render_texture (GstVaapiWindowEGL * window, const GstVaapiRectangle * rect)
|
||||||
{
|
{
|
||||||
const GLuint tex_id = GST_VAAPI_OBJECT_ID (window->texture);
|
const GLuint tex_id = GST_VAAPI_TEXTURE_ID (window->texture);
|
||||||
EglVTable *const vtable = window->egl_vtable;
|
EglVTable *const vtable = window->egl_vtable;
|
||||||
GLfloat x0, y0, x1, y1;
|
GLfloat x0, y0, x1, y1;
|
||||||
GLfloat texcoords[4][2];
|
GLfloat texcoords[4][2];
|
||||||
|
|
|
@ -125,7 +125,7 @@ meta_texture_free (GstVaapiVideoMetaTexture * meta)
|
||||||
if (G_UNLIKELY (!meta))
|
if (G_UNLIKELY (!meta))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gst_vaapi_texture_replace (&meta->texture, NULL);
|
gst_mini_object_replace ((GstMiniObject **) & meta->texture, NULL);
|
||||||
g_slice_free (GstVaapiVideoMetaTexture, meta);
|
g_slice_free (GstVaapiVideoMetaTexture, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +164,9 @@ meta_texture_copy (GstVaapiVideoMetaTexture * meta)
|
||||||
copy->gl_format = meta->gl_format;
|
copy->gl_format = meta->gl_format;
|
||||||
copy->width = meta->width;
|
copy->width = meta->width;
|
||||||
copy->height = meta->height;
|
copy->height = meta->height;
|
||||||
gst_vaapi_texture_replace (©->texture, meta->texture);
|
|
||||||
|
gst_mini_object_replace ((GstMiniObject **) & copy->texture,
|
||||||
|
(GstMiniObject *) meta->texture);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,8 +188,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta,
|
||||||
|
|
||||||
if (meta_texture->texture
|
if (meta_texture->texture
|
||||||
/* Check whether VA display changed */
|
/* Check whether VA display changed */
|
||||||
&& gst_vaapi_object_get_display
|
&& GST_VAAPI_TEXTURE_DISPLAY (meta_texture->texture) == dpy
|
||||||
(GST_VAAPI_OBJECT (meta_texture->texture)) == dpy
|
|
||||||
/* Check whether texture id changed */
|
/* Check whether texture id changed */
|
||||||
&& (gst_vaapi_texture_get_id (meta_texture->texture) == texture_id[0])) {
|
&& (gst_vaapi_texture_get_id (meta_texture->texture) == texture_id[0])) {
|
||||||
texture = meta_texture->texture;
|
texture = meta_texture->texture;
|
||||||
|
@ -202,7 +203,8 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta_texture->texture != texture) {
|
if (meta_texture->texture != texture) {
|
||||||
gst_vaapi_texture_replace (&meta_texture->texture, texture);
|
gst_mini_object_replace ((GstMiniObject **) & meta_texture->texture,
|
||||||
|
(GstMiniObject *) texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!texture)
|
if (!texture)
|
||||||
|
|
|
@ -168,8 +168,8 @@ main (int argc, char *argv[])
|
||||||
gst_vaapi_window_glx_swap_buffers (glx_window);
|
gst_vaapi_window_glx_swap_buffers (glx_window);
|
||||||
pause ();
|
pause ();
|
||||||
|
|
||||||
gst_vaapi_texture_unref (textures[0]);
|
gst_mini_object_unref (GST_MINI_OBJECT_CAST (textures[0]));
|
||||||
gst_vaapi_texture_unref (textures[1]);
|
gst_mini_object_unref (GST_MINI_OBJECT_CAST (textures[1]));
|
||||||
glDeleteTextures (1, &texture_id);
|
glDeleteTextures (1, &texture_id);
|
||||||
|
|
||||||
gst_object_unref (window);
|
gst_object_unref (window);
|
||||||
|
|
Loading…
Reference in a new issue