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:
He Junyan 2020-04-18 19:32:24 +08:00 committed by Víctor Manuel Jáquez Leal
parent 808247a963
commit f20bd8bfd1
9 changed files with 353 additions and 318 deletions

View file

@ -38,51 +38,80 @@
(GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_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
gst_vaapi_texture_init (GstVaapiTexture * texture, GstVaapiID id,
guint target, guint format, guint width, guint height)
{
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_format = format;
texture->width = width;
texture->height = height;
}
static inline gboolean
gst_vaapi_texture_allocate (GstVaapiTexture * texture)
static void
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 *
gst_vaapi_texture_new_internal (const GstVaapiTextureClass * klass,
GstVaapiDisplay * display, GstVaapiID id, guint target, guint format,
guint width, guint height)
gst_vaapi_texture_new_internal (GstVaapiDisplay * display, GstVaapiID id,
guint target, guint format, guint width, guint height)
{
GstVaapiTexture *texture;
g_return_val_if_fail (display, NULL);
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_OBJECT_CLASS (klass), display);
texture = g_slice_alloc (sizeof (GstVaapiTexture));
if (!texture)
return NULL;
gst_vaapi_texture_init (texture, id, target, format, width, height);
if (!gst_vaapi_texture_allocate (texture))
goto error;
return texture;
gst_mini_object_init (GST_MINI_OBJECT_CAST (texture), 0,
GST_TYPE_VAAPI_TEXTURE, NULL, NULL,
(GstMiniObjectFreeFunction) gst_vaapi_texture_free);
/* ERRORS */
error:
{
gst_vaapi_object_unref (texture);
return NULL;
}
GST_VAAPI_TEXTURE_DISPLAY (texture) = gst_object_ref (display);
gst_vaapi_texture_init (texture, id, target, format, width, height);
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);
}
/**
* 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:
* @texture: a #GstVaapiTexture
@ -300,6 +285,21 @@ gst_vaapi_texture_get_size (GstVaapiTexture * 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:
* @texture: a #GstVaapiTexture
@ -313,8 +313,7 @@ gst_vaapi_texture_get_orientation_flags (GstVaapiTexture * texture)
{
g_return_val_if_fail (texture != NULL, 0);
return GST_VAAPI_TEXTURE_FLAGS (texture) &
GST_VAAPI_TEXTURE_ORIENTATION_FLAGS;
return GST_MINI_OBJECT_FLAGS (texture) & 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 ((flags & ~GST_VAAPI_TEXTURE_ORIENTATION_FLAGS) == 0);
GST_VAAPI_TEXTURE_FLAG_UNSET (texture, GST_VAAPI_TEXTURE_ORIENTATION_FLAGS);
GST_VAAPI_TEXTURE_FLAG_SET (texture, flags);
GST_MINI_OBJECT_FLAG_UNSET (texture, GST_VAAPI_TEXTURE_ORIENTATION_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
* @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
* other postprocessing transformations are performed.
*
@ -353,14 +352,12 @@ gboolean
gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
{
const GstVaapiTextureClass *klass;
GstVaapiRectangle rect;
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)
if (!texture->put_surface)
return FALSE;
if (!crop_rect) {
@ -369,5 +366,5 @@ gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
gst_vaapi_surface_get_size (surface, &rect.width, &rect.height);
crop_rect = &rect;
}
return klass->put_surface (texture, surface, crop_rect, flags);
return texture->put_surface (texture, surface, crop_rect, flags);
}

View file

@ -33,6 +33,17 @@ G_BEGIN_DECLS
#define GST_VAAPI_TEXTURE(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:
* @texture: a #GstVaapiTexture
@ -94,10 +105,26 @@ typedef struct _GstVaapiTexture GstVaapiTexture;
* from the left to the right.
*/
typedef enum {
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED = 1 << 31,
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED = 1 << 30,
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_X_INVERTED = (GST_MINI_OBJECT_FLAG_LAST << 1),
GST_VAAPI_TEXTURE_ORIENTATION_FLAG_Y_INVERTED = (GST_MINI_OBJECT_FLAG_LAST << 2),
} 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 *
gst_vaapi_texture_new (GstVaapiDisplay * display, guint target, guint format,
guint width, guint height);
@ -106,19 +133,12 @@ GstVaapiTexture *
gst_vaapi_texture_new_wrapped (GstVaapiDisplay * display, guint id,
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
gst_vaapi_texture_get_id (GstVaapiTexture * texture);
GstVaapiDisplay *
gst_vaapi_texture_get_display (GstVaapiTexture * texture);
guint
gst_vaapi_texture_get_target (GstVaapiTexture * texture);
@ -147,6 +167,8 @@ gst_vaapi_texture_put_surface (GstVaapiTexture * texture,
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
guint flags);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiTexture, gst_vaapi_texture_unref)
G_END_DECLS
#endif /* GST_VAAPI_TEXTURE_H */

View file

@ -40,48 +40,32 @@
#define DEBUG 1
#include "gstvaapidebug.h"
#define GST_VAAPI_TEXTURE_EGL(texture) \
((GstVaapiTextureEGL *) (texture))
typedef struct _GstVaapiTextureEGL GstVaapiTextureEGL;
typedef struct _GstVaapiTextureEGLClass GstVaapiTextureEGLClass;
typedef struct _GstVaapiTextureEGLPrivate GstVaapiTextureEGLPrivate;
/**
* GstVaapiTextureEGL:
* GstVaapiTextureEGLPrivate:
*
* Base object for EGL texture wrapper.
* EGL texture specific fields.
*/
struct _GstVaapiTextureEGL
struct _GstVaapiTextureEGLPrivate
{
/*< private > */
GstVaapiTexture parent_instance;
GstVaapiTexture *texture;
EglContext *egl_context;
EGLImageKHR egl_image;
GstVaapiSurface *surface;
GstVaapiFilter *filter;
};
/**
* GstVaapiTextureEGLClass:
*
* Base class for EGL texture wrapper.
*/
struct _GstVaapiTextureEGLClass
{
/*< private > */
GstVaapiTextureClass parent_class;
};
typedef struct
{
GstVaapiTextureEGL *texture;
GstVaapiTexture *texture;
gboolean success; /* result */
} CreateTextureArgs;
typedef struct
{
GstVaapiTextureEGL *texture;
GstVaapiTexture *texture;
GstVaapiSurface *surface;
const GstVaapiRectangle *crop_rect;
guint flags;
@ -89,32 +73,31 @@ typedef struct
} UploadSurfaceArgs;
static gboolean
create_objects (GstVaapiTextureEGL * texture, GLuint texture_id)
create_objects (GstVaapiTexture * texture, GLuint texture_id)
{
GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture);
EglContext *const ctx = texture->egl_context;
GstVaapiTextureEGLPrivate *const texture_egl =
gst_vaapi_texture_get_private (texture);
EglContext *const ctx = texture_egl->egl_context;
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;
*attrib++ = EGL_IMAGE_PRESERVED_KHR;
*attrib++ = EGL_TRUE;
*attrib++ = EGL_NONE;
texture->egl_image = vtable->eglCreateImageKHR (ctx->display->base.handle.p,
texture_egl->egl_image =
vtable->eglCreateImageKHR (ctx->display->base.handle.p,
ctx->base.handle.p, EGL_GL_TEXTURE_2D_KHR,
(EGLClientBuffer) GSIZE_TO_POINTER (texture_id), attribs);
if (!texture->egl_image)
if (!texture_egl->egl_image)
goto error_create_image;
texture->surface =
gst_vaapi_surface_new_with_egl_image (GST_VAAPI_OBJECT_DISPLAY (texture),
texture->egl_image, GST_VIDEO_FORMAT_RGBA, base_texture->width,
base_texture->height);
if (!texture->surface)
texture_egl->surface =
gst_vaapi_surface_new_with_egl_image (GST_VAAPI_TEXTURE_DISPLAY (texture),
texture_egl->egl_image, GST_VIDEO_FORMAT_RGBA, texture->width,
texture->height);
if (!texture_egl->surface)
goto error_create_surface;
texture->filter = gst_vaapi_filter_new (GST_VAAPI_OBJECT_DISPLAY (texture));
if (!texture->filter)
texture_egl->filter =
gst_vaapi_filter_new (GST_VAAPI_TEXTURE_DISPLAY (texture));
if (!texture_egl->filter)
goto error_create_filter;
return TRUE;
@ -137,17 +120,18 @@ error_create_filter:
}
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;
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);
else {
texture_id = egl_create_texture (texture->egl_context,
base_texture->gl_target, base_texture->gl_format,
base_texture->width, base_texture->height);
texture_id = egl_create_texture (texture_egl->egl_context,
texture->gl_target, texture->gl_format,
texture->width, texture->height);
if (!texture_id)
return FALSE;
GST_VAAPI_TEXTURE_ID (texture) = texture_id;
@ -158,74 +142,78 @@ do_create_texture_unlocked (GstVaapiTextureEGL * texture)
static void
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;
args->success = FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) {
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
if (egl_context_set_current (texture_egl->egl_context, TRUE, &old_cs)) {
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
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);
if (texture->egl_image != EGL_NO_IMAGE_KHR) {
if (texture_egl->egl_image != EGL_NO_IMAGE_KHR) {
vtable->eglDestroyImageKHR (ctx->display->base.handle.p,
texture->egl_image);
texture->egl_image = EGL_NO_IMAGE_KHR;
texture_egl->egl_image);
texture_egl->egl_image = EGL_NO_IMAGE_KHR;
}
gst_mini_object_replace ((GstMiniObject **) & texture->surface, NULL);
gst_vaapi_filter_replace (&texture->filter, NULL);
gst_mini_object_replace ((GstMiniObject **) & texture_egl->surface, NULL);
gst_vaapi_filter_replace (&texture_egl->filter, NULL);
}
static void
do_destroy_texture_unlocked (GstVaapiTextureEGL * texture)
do_destroy_texture_unlocked (GstVaapiTextureEGLPrivate * texture_egl)
{
GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture);
const GLuint texture_id = GST_VAAPI_TEXTURE_ID (texture);
GstVaapiTexture *const base_texture = texture_egl->texture;
const GLuint texture_id = GST_VAAPI_TEXTURE_ID (base_texture);
destroy_objects (texture);
destroy_objects (texture_egl);
if (texture_id) {
if (!base_texture->is_wrapped)
egl_destroy_texture (texture->egl_context, texture_id);
GST_VAAPI_TEXTURE_ID (texture) = 0;
egl_destroy_texture (texture_egl->egl_context, texture_id);
GST_VAAPI_TEXTURE_ID (base_texture) = 0;
}
}
static void
do_destroy_texture (GstVaapiTextureEGL * texture)
do_destroy_texture (GstVaapiTextureEGLPrivate * texture_egl)
{
EglContextState old_cs;
GstVaapiTexture *texture = texture_egl->texture;
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) {
do_destroy_texture_unlocked (texture);
egl_context_set_current (texture->egl_context, FALSE, &old_cs);
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
if (egl_context_set_current (texture_egl->egl_context, TRUE, &old_cs)) {
do_destroy_texture_unlocked (texture_egl);
egl_context_set_current (texture_egl->egl_context, FALSE, &old_cs);
}
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
egl_object_replace (&texture->egl_context, NULL);
GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
egl_object_replace (&texture_egl->egl_context, NULL);
g_free (texture_egl);
}
static gboolean
do_upload_surface_unlocked (GstVaapiTextureEGL * texture,
do_upload_surface_unlocked (GstVaapiTextureEGLPrivate * texture_egl,
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags)
{
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;
status = gst_vaapi_filter_process (texture->filter, surface, texture->surface,
flags);
status = gst_vaapi_filter_process (texture_egl->filter, surface,
texture_egl->surface, flags);
if (status != GST_VAAPI_FILTER_STATUS_SUCCESS)
return FALSE;
return TRUE;
@ -234,74 +222,86 @@ do_upload_surface_unlocked (GstVaapiTextureEGL * texture,
static void
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;
args->success = FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
if (egl_context_set_current (texture->egl_context, TRUE, &old_cs)) {
args->success = do_upload_surface_unlocked (texture, args->surface,
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
if (egl_context_set_current (texture_egl->egl_context, TRUE, &old_cs)) {
args->success = do_upload_surface_unlocked (texture_egl, args->surface,
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
gst_vaapi_texture_egl_create (GstVaapiTextureEGL * texture)
gst_vaapi_texture_egl_create (GstVaapiTexture * texture)
{
CreateTextureArgs args = { texture };
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_display_egl_set_current_display (display))
return FALSE;
}
egl_object_replace (&texture->egl_context,
egl_object_replace (&texture_egl->egl_context,
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;
}
static void
gst_vaapi_texture_egl_destroy (GstVaapiTextureEGL * texture)
gst_vaapi_texture_egl_destroy (GstVaapiTextureEGLPrivate * texture_egl)
{
egl_context_run (texture->egl_context,
(EglContextRunFunc) do_destroy_texture, texture);
egl_context_run (texture_egl->egl_context,
(EglContextRunFunc) do_destroy_texture, texture_egl);
}
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)
{
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;
}
static void
gst_vaapi_texture_egl_class_init (GstVaapiTextureEGLClass * klass)
static GstVaapiTexture *
gst_vaapi_texture_egl_new_internal (GstVaapiTexture * texture)
{
GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass);
GstVaapiTextureClass *const texture_class = GST_VAAPI_TEXTURE_CLASS (klass);
GstVaapiTextureEGLPrivate *texture_egl;
object_class->finalize = (GstVaapiObjectFinalizeFunc)
gst_vaapi_texture_egl_destroy;
texture_class->allocate = (GstVaapiTextureAllocateFunc)
gst_vaapi_texture_egl_create;
texture_class->put_surface = (GstVaapiTexturePutSurfaceFunc)
gst_vaapi_texture_egl_put_surface;
texture->put_surface = gst_vaapi_texture_egl_put_surface;
texture_egl = g_malloc0 (sizeof (GstVaapiTextureEGLPrivate));
if (!texture_egl) {
gst_mini_object_unref (GST_MINI_OBJECT_CAST (texture));
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:
* @display: a #GstVaapiDisplay
@ -325,11 +325,16 @@ GstVaapiTexture *
gst_vaapi_texture_egl_new (GstVaapiDisplay * display, guint target,
guint format, guint width, guint height)
{
GstVaapiTexture *texture;
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_EGL (display), NULL);
return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS
(gst_vaapi_texture_egl_class ()), display, GST_VAAPI_ID_INVALID, target,
format, width, height);
texture = gst_vaapi_texture_new_internal (display, GST_VAAPI_ID_INVALID,
target, 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,
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 (texture_id != GL_NONE, NULL);
return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS
(gst_vaapi_texture_egl_class ()), display, texture_id, target, format,
width, height);
texture = gst_vaapi_texture_new_internal (display, texture_id,
target, format, width, height);
if (!texture)
return texture;
return gst_vaapi_texture_egl_new_internal (texture);
}

View file

@ -45,42 +45,29 @@
#define GST_VAAPI_TEXTURE_GLX(texture) \
((GstVaapiTextureGLX *)(texture))
typedef struct _GstVaapiTextureGLX GstVaapiTextureGLX;
typedef struct _GstVaapiTextureGLXClass GstVaapiTextureGLXClass;
typedef struct _GstVaapiTextureGLXPrivate GstVaapiTextureGLXPrivate;
/**
* GstVaapiTextureGLX:
* GstVaapiTextureGLXPrivate:
*
* Base object for GLX texture wrapper.
* GLX texture specific fields.
*/
struct _GstVaapiTextureGLX
struct _GstVaapiTextureGLXPrivate
{
/*< private > */
GstVaapiTexture parent_instance;
GstVaapiTexture *texture;
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)
destroy_objects (GstVaapiTextureGLXPrivate * texture)
{
GLContextState old_cs;
@ -105,11 +92,12 @@ destroy_objects (GstVaapiTextureGLX * texture)
}
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);
destroy_objects (GST_VAAPI_TEXTURE_GLX (texture));
destroy_objects (texture_glx);
if (texture_id) {
if (!texture->is_wrapped)
@ -119,38 +107,45 @@ destroy_texture_unlocked (GstVaapiTexture * texture)
}
static void
gst_vaapi_texture_glx_destroy (GstVaapiTexture * texture)
gst_vaapi_texture_glx_destroy (GstVaapiTextureGLXPrivate * texture_glx)
{
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
destroy_texture_unlocked (texture);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
GstVaapiTexture *texture = texture_glx->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
create_objects (GstVaapiTextureGLX * texture, guint texture_id)
create_objects (GstVaapiTexture * texture, guint texture_id)
{
GstVaapiTexture *const base_texture = GST_VAAPI_TEXTURE (texture);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (texture);
GstVaapiTextureGLXPrivate *texture_glx =
gst_vaapi_texture_get_private (texture);
Display *const dpy =
GST_VAAPI_DISPLAY_NATIVE (GST_VAAPI_TEXTURE_DISPLAY (texture));
GLContextState old_cs;
gboolean success = FALSE;
gl_get_current_context (&old_cs);
texture->gl_context = gl_create_context (dpy, DefaultScreen (dpy), &old_cs);
if (!texture->gl_context ||
!gl_set_current_context (texture->gl_context, NULL))
texture_glx->gl_context =
gl_create_context (dpy, DefaultScreen (dpy), &old_cs);
if (!texture_glx->gl_context
|| !gl_set_current_context (texture_glx->gl_context, NULL))
return FALSE;
texture->pixo = gl_create_pixmap_object (dpy,
base_texture->width, base_texture->height);
if (!texture->pixo) {
texture_glx->pixo = gl_create_pixmap_object (dpy,
texture->width, texture->height);
if (!texture_glx->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) {
texture_glx->fbo = gl_create_framebuffer_object (texture->gl_target,
texture_id, texture->width, texture->height);
if (!texture_glx->fbo) {
GST_ERROR ("failed to create FBO");
goto out_reset_context;
}
@ -175,7 +170,7 @@ create_texture_unlocked (GstVaapiTexture * texture)
return FALSE;
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
@ -183,29 +178,37 @@ gst_vaapi_texture_glx_create (GstVaapiTexture * texture)
{
gboolean success;
GST_VAAPI_OBJECT_LOCK_DISPLAY (texture);
GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
success = create_texture_unlocked (texture);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
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);
GstVaapiTextureClass *const texture_class = GST_VAAPI_TEXTURE_CLASS (klass);
GstVaapiTextureGLXPrivate *texture_glx;
object_class->finalize = (GstVaapiObjectFinalizeFunc)
gst_vaapi_texture_glx_destroy;
texture->put_surface = gst_vaapi_texture_glx_put_surface;
texture_class->allocate = gst_vaapi_texture_glx_create;
texture_class->put_surface = gst_vaapi_texture_glx_put_surface;
texture_glx = g_malloc0 (sizeof (GstVaapiTextureGLXPrivate));
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:
* @display: a #GstVaapiDisplay
@ -229,11 +232,16 @@ GstVaapiTexture *
gst_vaapi_texture_glx_new (GstVaapiDisplay * display, guint target,
guint format, guint width, guint height)
{
GstVaapiTexture *texture;
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS
(gst_vaapi_texture_glx_class ()), display, GST_VAAPI_ID_INVALID, target,
format, width, height);
texture = gst_vaapi_texture_new_internal (display, GST_VAAPI_ID_INVALID,
target, 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? */
@ -278,6 +286,7 @@ gst_vaapi_texture_glx_new_wrapped (GstVaapiDisplay * display,
GLTextureState ts = { 0, };
gboolean success;
GstVaapiGLApi gl_api;
GstVaapiTexture *texture;
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), 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 (height > 0, NULL);
return gst_vaapi_texture_new_internal (GST_VAAPI_TEXTURE_CLASS
(gst_vaapi_texture_glx_class ()), display, texture_id, target, format,
width, height);
texture = gst_vaapi_texture_new_internal (display, texture_id, target,
format, 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
*/
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)
{
GstVaapiTextureGLX *const texture = GST_VAAPI_TEXTURE_GLX (base_texture);
GstVaapiTextureGLXPrivate *texture_glx =
gst_vaapi_texture_get_private (texture);
VAStatus status;
GLContextState old_cs;
gboolean success = FALSE;
@ -344,19 +357,19 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture,
{1.0f, 0.0f},
};
status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (texture),
GST_VAAPI_SURFACE_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));
status = vaPutSurface (GST_VAAPI_DISPLAY_VADISPLAY (GST_VAAPI_TEXTURE_DISPLAY
(texture)), GST_VAAPI_SURFACE_ID (surface), texture_glx->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));
if (!vaapi_check_status (status, "vaPutSurface() [TFP]"))
return FALSE;
if (texture->gl_context &&
!gl_set_current_context (texture->gl_context, &old_cs))
if (texture_glx->gl_context &&
!gl_set_current_context (texture_glx->gl_context, &old_cs))
return FALSE;
if (!gl_bind_framebuffer_object (texture->fbo)) {
if (!gl_bind_framebuffer_object (texture_glx->fbo)) {
GST_ERROR ("failed to bind FBO");
goto out_reset_context;
}
@ -366,12 +379,12 @@ gst_vaapi_texture_glx_put_surface_unlocked (GstVaapiTexture * base_texture,
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");
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)];
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]);
glVertex2i (0, 0);
glTexCoord2f (txc[0], tyc[1]);
glVertex2i (0, base_texture->height);
glVertex2i (0, texture->height);
glTexCoord2f (txc[1], tyc[1]);
glVertex2i (base_texture->width, base_texture->height);
glVertex2i (texture->width, texture->height);
glTexCoord2f (txc[1], tyc[0]);
glVertex2i (base_texture->width, 0);
glVertex2i (texture->width, 0);
}
glEnd ();
if (!gl_unbind_pixmap_object (texture->pixo)) {
if (!gl_unbind_pixmap_object (texture_glx->pixo)) {
GST_ERROR ("failed to release GLX pixmap");
goto out_unbind_fbo;
}
success = TRUE;
out_unbind_fbo:
if (!gl_unbind_framebuffer_object (texture->fbo))
if (!gl_unbind_framebuffer_object (texture_glx->fbo))
success = FALSE;
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;
return success;
}
@ -410,9 +423,9 @@ gst_vaapi_texture_glx_put_surface (GstVaapiTexture * texture,
{
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,
crop_rect, flags);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (texture);
GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_TEXTURE_DISPLAY (texture));
return success;
}

View file

@ -26,14 +26,19 @@
#define GST_VAAPI_TEXTURE_PRIV_H
#include "gstvaapiobject_priv.h"
#include <gst/gstminiobject.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_DISPLAY:
* @texture: a #GstVaapiTexture
*
* 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:
@ -43,7 +48,7 @@ G_BEGIN_DECLS
*/
#undef GST_VAAPI_TEXTURE_ID
#define GST_VAAPI_TEXTURE_ID(texture) \
(GST_VAAPI_OBJECT_ID (texture))
(GST_VAAPI_TEXTURE (texture)->object_id)
/**
* GST_VAAPI_TEXTURE_TARGET:
@ -85,18 +90,9 @@ G_BEGIN_DECLS
#define GST_VAAPI_TEXTURE_HEIGHT(texture) \
(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 */
typedef gboolean (*GstVaapiTextureAllocateFunc) (GstVaapiTexture * texture);
typedef gboolean (*GstVaapiTexturePutSurfaceFunc) (GstVaapiTexture * texture,
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect,
guint flags);
typedef struct _GstVaapiTextureClass GstVaapiTextureClass;
GstVaapiSurface * surface, const GstVaapiRectangle * crop_rect, guint flags);
/**
* GstVaapiTexture:
@ -105,9 +101,12 @@ typedef struct _GstVaapiTextureClass GstVaapiTextureClass;
*/
struct _GstVaapiTexture {
/*< private >*/
GstVaapiObject parent_instance;
GstMiniObject mini_object;
GstVaapiDisplay *display;
GstVaapiID object_id;
/*< protected >*/
GstVaapiTexturePutSurfaceFunc put_surface;
guint gl_target;
guint gl_format;
guint width;
@ -115,25 +114,16 @@ struct _GstVaapiTexture {
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_internal (const GstVaapiTextureClass * klass,
GstVaapiDisplay * display, GstVaapiID id, guint target, guint format,
guint width, guint height);
gst_vaapi_texture_new_internal (GstVaapiDisplay * display, GstVaapiID id,
guint target, guint format, 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

View file

@ -62,7 +62,7 @@ gst_vaapi_texture_map_init (GstVaapiTextureMap * map)
{
map->texture_map =
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
(GDestroyNotify) gst_vaapi_texture_unref);
(GDestroyNotify) gst_mini_object_unref);
}
static void

View file

@ -139,8 +139,9 @@ ensure_texture (GstVaapiWindowEGL * window, guint width, guint height)
texture = gst_vaapi_texture_egl_new (GST_VAAPI_WINDOW_DISPLAY (window),
GL_TEXTURE_2D, GL_RGBA, width, height);
gst_vaapi_texture_replace (&window->texture, texture);
gst_vaapi_texture_replace (&texture, NULL);
gst_mini_object_replace ((GstMiniObject **) & window->texture,
(GstMiniObject *) texture);
gst_mini_object_replace ((GstMiniObject **) & 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_texture_replace (&window->texture, NULL);
gst_mini_object_replace ((GstMiniObject **) & window->texture, NULL);
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
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;
GLfloat x0, y0, x1, y1;
GLfloat texcoords[4][2];

View file

@ -125,7 +125,7 @@ meta_texture_free (GstVaapiVideoMetaTexture * meta)
if (G_UNLIKELY (!meta))
return;
gst_vaapi_texture_replace (&meta->texture, NULL);
gst_mini_object_replace ((GstMiniObject **) & meta->texture, NULL);
g_slice_free (GstVaapiVideoMetaTexture, meta);
}
@ -164,7 +164,9 @@ meta_texture_copy (GstVaapiVideoMetaTexture * meta)
copy->gl_format = meta->gl_format;
copy->width = meta->width;
copy->height = meta->height;
gst_vaapi_texture_replace (&copy->texture, meta->texture);
gst_mini_object_replace ((GstMiniObject **) & copy->texture,
(GstMiniObject *) meta->texture);
return copy;
}
@ -186,8 +188,7 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta,
if (meta_texture->texture
/* Check whether VA display changed */
&& gst_vaapi_object_get_display
(GST_VAAPI_OBJECT (meta_texture->texture)) == dpy
&& GST_VAAPI_TEXTURE_DISPLAY (meta_texture->texture) == dpy
/* Check whether texture id changed */
&& (gst_vaapi_texture_get_id (meta_texture->texture) == texture_id[0])) {
texture = meta_texture->texture;
@ -202,7 +203,8 @@ gst_vaapi_texture_upload (GstVideoGLTextureUploadMeta * meta,
}
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)

View file

@ -168,8 +168,8 @@ main (int argc, char *argv[])
gst_vaapi_window_glx_swap_buffers (glx_window);
pause ();
gst_vaapi_texture_unref (textures[0]);
gst_vaapi_texture_unref (textures[1]);
gst_mini_object_unref (GST_MINI_OBJECT_CAST (textures[0]));
gst_mini_object_unref (GST_MINI_OBJECT_CAST (textures[1]));
glDeleteTextures (1, &texture_id);
gst_object_unref (window);