libs: window: refactor as gobject

This is another step in the gobjectification of the internal library
of gstreamer-vaapi. Now it is the turn of GstVaapiWindow and its
derivates.

The idea is to minimize the changeset keeping the same design as
much as possible.

GstVaapiWindow is defined as an abstract class with two properties:
the GstVaapiDisplay and the native ID. Thus, many of the
GstVaapiObject macros were copied as GstVaapiWindow macros.

The function gst_vaapi_window_new_internal() is kept as a decorator
of for calling gst_vaapi_window_create() and the possibility of
failure.

The descendant classes, such as glx, still use the private
structures, but through the gobject mechanism.
This commit is contained in:
Víctor Manuel Jáquez Leal 2018-12-22 18:02:38 +01:00
parent 7b782be5dd
commit 6c364cb9a7
14 changed files with 529 additions and 407 deletions

View file

@ -36,6 +36,17 @@
#define DEBUG 1 #define DEBUG 1
#include "gstvaapidebug.h" #include "gstvaapidebug.h"
G_DEFINE_ABSTRACT_TYPE (GstVaapiWindow, gst_vaapi_window, GST_TYPE_OBJECT);
enum
{
PROP_DISPLAY = 1,
PROP_NATIVE_ID,
N_PROPERTIES
};
static GParamSpec *g_properties[N_PROPERTIES] = { NULL, };
static void static void
gst_vaapi_window_ensure_size (GstVaapiWindow * window) gst_vaapi_window_ensure_size (GstVaapiWindow * window)
{ {
@ -55,7 +66,7 @@ gst_vaapi_window_ensure_size (GstVaapiWindow * window)
static gboolean static gboolean
ensure_filter (GstVaapiWindow * window) ensure_filter (GstVaapiWindow * window)
{ {
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window);
/* Ensure VPP pipeline is built */ /* Ensure VPP pipeline is built */
if (window->filter) if (window->filter)
@ -87,7 +98,7 @@ error_unsupported_format:
static gboolean static gboolean
ensure_filter_surface_pool (GstVaapiWindow * window) ensure_filter_surface_pool (GstVaapiWindow * window)
{ {
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window);
if (window->surface_pool) if (window->surface_pool)
goto ensure_filter; goto ensure_filter;
@ -109,7 +120,7 @@ ensure_filter:
static gboolean static gboolean
gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height) gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height)
{ {
gst_vaapi_display_get_size (GST_VAAPI_OBJECT_DISPLAY (window), gst_vaapi_display_get_size (GST_VAAPI_WINDOW_DISPLAY (window),
&window->display_width, &window->display_height); &window->display_width, &window->display_height);
if (!GST_VAAPI_WINDOW_GET_CLASS (window)->create (window, &width, &height)) if (!GST_VAAPI_WINDOW_GET_CLASS (window)->create (window, &width, &height))
@ -124,24 +135,101 @@ gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height)
} }
static void static void
gst_vaapi_window_finalize (GstVaapiWindow * window) gst_vaapi_window_finalize (GObject * object)
{ {
GstVaapiWindow *const window = GST_VAAPI_WINDOW (object);
gst_vaapi_video_pool_replace (&window->surface_pool, NULL); gst_vaapi_video_pool_replace (&window->surface_pool, NULL);
gst_vaapi_filter_replace (&window->filter, NULL); gst_vaapi_filter_replace (&window->filter, NULL);
gst_vaapi_display_replace (&window->display, NULL);
G_OBJECT_CLASS (gst_vaapi_window_parent_class)->finalize (object);
} }
void static void
gst_vaapi_window_set_property (GObject * object, guint property_id,
const GValue * value, GParamSpec * pspec)
{
GstVaapiWindow *const window = GST_VAAPI_WINDOW (object);
switch (property_id) {
case PROP_DISPLAY:
g_assert (window->display == NULL);
window->display = g_value_dup_object (value);
g_assert (window->display != NULL);
window->has_vpp = GST_VAAPI_DISPLAY_HAS_VPP (window->display);
break;
case PROP_NATIVE_ID:{
gulong id = g_value_get_ulong (value);
window->use_foreign_window = (id != GST_VAAPI_ID_INVALID);
GST_VAAPI_WINDOW_ID (window) = window->use_foreign_window ? id : 0;
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gst_vaapi_window_get_property (GObject * object, guint property_id,
GValue * value, GParamSpec * pspec)
{
GstVaapiWindow *const window = GST_VAAPI_WINDOW (object);
switch (property_id) {
case PROP_DISPLAY:
g_value_set_object (value, window->display);
break;
case PROP_NATIVE_ID:
g_value_set_ulong (value, window->native_id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gst_vaapi_window_class_init (GstVaapiWindowClass * klass) gst_vaapi_window_class_init (GstVaapiWindowClass * klass)
{ {
GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); GObjectClass *const object_class = G_OBJECT_CLASS (klass);
object_class->finalize = (GstVaapiObjectFinalizeFunc) object_class->set_property = gst_vaapi_window_set_property;
gst_vaapi_window_finalize; object_class->get_property = gst_vaapi_window_get_property;
object_class->finalize = gst_vaapi_window_finalize;
/**
* GstVaapiWindow:display:
*
* #GstVaapiDisplay to be used.
*/
g_properties[PROP_DISPLAY] =
g_param_spec_object ("display", "Gst VA-API Display",
"The VA-API display object to use", GST_TYPE_VAAPI_DISPLAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME);
/**
* GstVaapiWindow:native-id:
*
* Native window ID: either XDisplay, EGLDisplay, or drm-fd.
*/
g_properties[PROP_NATIVE_ID] =
g_param_spec_ulong ("native-id", "Native window id",
"Native window ID", 0, G_MAXULONG, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME);
g_object_class_install_properties (object_class, N_PROPERTIES, g_properties);
}
static void
gst_vaapi_window_init (GstVaapiWindow * window)
{
} }
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, gst_vaapi_window_new_internal (GType type, GstVaapiDisplay * display,
GstVaapiDisplay * display, GstVaapiID id, guint width, guint height) GstVaapiID id, guint width, guint height)
{ {
GstVaapiWindow *window; GstVaapiWindow *window;
@ -153,18 +241,14 @@ gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class,
g_return_val_if_fail (height > 0, NULL); g_return_val_if_fail (height > 0, NULL);
} }
window = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (window_class), window = g_object_new (type, "display", display, "native-id", id, NULL);
display);
if (!window)
return NULL;
window->use_foreign_window = id != GST_VAAPI_ID_INVALID; GST_DEBUG_OBJECT (window, "new window with id = 0x%08lx and size %ux%u", id,
GST_VAAPI_OBJECT_ID (window) = window->use_foreign_window ? id : 0; width, height);
window->has_vpp =
GST_VAAPI_DISPLAY_HAS_VPP (GST_VAAPI_OBJECT_DISPLAY (window));
if (!gst_vaapi_window_create (window, width, height)) if (!gst_vaapi_window_create (window, width, height))
goto error; goto error;
return window; return window;
/* ERRORS */ /* ERRORS */
@ -234,7 +318,7 @@ gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height)
{ {
GstVaapiDisplayClass *dpy_class; GstVaapiDisplayClass *dpy_class;
g_return_val_if_fail (display != NULL, NULL); g_return_val_if_fail (GST_VAAPI_IS_DISPLAY (display), NULL);
dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display); dpy_class = GST_VAAPI_DISPLAY_GET_CLASS (display);
if (G_UNLIKELY (!dpy_class->create_window)) if (G_UNLIKELY (!dpy_class->create_window))
@ -254,7 +338,7 @@ gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height)
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_ref (GstVaapiWindow * window) gst_vaapi_window_ref (GstVaapiWindow * window)
{ {
return (GstVaapiWindow *) gst_vaapi_object_ref (GST_VAAPI_OBJECT (window)); return (GstVaapiWindow *) gst_object_ref (window);
} }
/** /**
@ -267,7 +351,7 @@ gst_vaapi_window_ref (GstVaapiWindow * window)
void void
gst_vaapi_window_unref (GstVaapiWindow * window) gst_vaapi_window_unref (GstVaapiWindow * window)
{ {
gst_vaapi_object_unref (GST_VAAPI_OBJECT (window)); gst_object_unref (window);
} }
/** /**
@ -283,8 +367,7 @@ void
gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr, gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr,
GstVaapiWindow * new_window) GstVaapiWindow * new_window)
{ {
gst_vaapi_object_replace ((GstVaapiObject **) (old_window_ptr), gst_object_replace ((GstObject **) old_window_ptr, GST_OBJECT (new_window));
GST_VAAPI_OBJECT (new_window));
} }
/** /**
@ -298,9 +381,9 @@ gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr,
GstVaapiDisplay * GstVaapiDisplay *
gst_vaapi_window_get_display (GstVaapiWindow * window) gst_vaapi_window_get_display (GstVaapiWindow * window)
{ {
g_return_val_if_fail (window != NULL, NULL); g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), NULL);
return GST_VAAPI_OBJECT_DISPLAY (window); return GST_VAAPI_WINDOW_DISPLAY (window);
} }
/** /**
@ -313,7 +396,7 @@ gst_vaapi_window_get_display (GstVaapiWindow * window)
void void
gst_vaapi_window_show (GstVaapiWindow * window) gst_vaapi_window_show (GstVaapiWindow * window)
{ {
g_return_if_fail (window != NULL); g_return_if_fail (GST_VAAPI_IS_WINDOW (window));
GST_VAAPI_WINDOW_GET_CLASS (window)->show (window); GST_VAAPI_WINDOW_GET_CLASS (window)->show (window);
window->check_geometry = TRUE; window->check_geometry = TRUE;
@ -329,7 +412,7 @@ gst_vaapi_window_show (GstVaapiWindow * window)
void void
gst_vaapi_window_hide (GstVaapiWindow * window) gst_vaapi_window_hide (GstVaapiWindow * window)
{ {
g_return_if_fail (window != NULL); g_return_if_fail (GST_VAAPI_IS_WINDOW (window));
GST_VAAPI_WINDOW_GET_CLASS (window)->hide (window); GST_VAAPI_WINDOW_GET_CLASS (window)->hide (window);
} }
@ -345,7 +428,7 @@ gst_vaapi_window_hide (GstVaapiWindow * window)
gboolean gboolean
gst_vaapi_window_get_fullscreen (GstVaapiWindow * window) gst_vaapi_window_get_fullscreen (GstVaapiWindow * window)
{ {
g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE);
gst_vaapi_window_ensure_size (window); gst_vaapi_window_ensure_size (window);
@ -364,7 +447,7 @@ gst_vaapi_window_set_fullscreen (GstVaapiWindow * window, gboolean fullscreen)
{ {
const GstVaapiWindowClass *klass; const GstVaapiWindowClass *klass;
g_return_if_fail (window != NULL); g_return_if_fail (GST_VAAPI_IS_WINDOW (window));
klass = GST_VAAPI_WINDOW_GET_CLASS (window); klass = GST_VAAPI_WINDOW_GET_CLASS (window);
@ -386,7 +469,7 @@ gst_vaapi_window_set_fullscreen (GstVaapiWindow * window, gboolean fullscreen)
guint guint
gst_vaapi_window_get_width (GstVaapiWindow * window) gst_vaapi_window_get_width (GstVaapiWindow * window)
{ {
g_return_val_if_fail (window != NULL, 0); g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), 0);
gst_vaapi_window_ensure_size (window); gst_vaapi_window_ensure_size (window);
@ -404,7 +487,7 @@ gst_vaapi_window_get_width (GstVaapiWindow * window)
guint guint
gst_vaapi_window_get_height (GstVaapiWindow * window) gst_vaapi_window_get_height (GstVaapiWindow * window)
{ {
g_return_val_if_fail (window != NULL, 0); g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), 0);
gst_vaapi_window_ensure_size (window); gst_vaapi_window_ensure_size (window);
@ -423,7 +506,7 @@ void
gst_vaapi_window_get_size (GstVaapiWindow * window, guint * width_ptr, gst_vaapi_window_get_size (GstVaapiWindow * window, guint * width_ptr,
guint * height_ptr) guint * height_ptr)
{ {
g_return_if_fail (window != NULL); g_return_if_fail (GST_VAAPI_IS_WINDOW (window));
gst_vaapi_window_ensure_size (window); gst_vaapi_window_ensure_size (window);
@ -444,7 +527,7 @@ gst_vaapi_window_get_size (GstVaapiWindow * window, guint * width_ptr,
void void
gst_vaapi_window_set_width (GstVaapiWindow * window, guint width) gst_vaapi_window_set_width (GstVaapiWindow * window, guint width)
{ {
g_return_if_fail (window != NULL); g_return_if_fail (GST_VAAPI_IS_WINDOW (window));
gst_vaapi_window_set_size (window, width, window->height); gst_vaapi_window_set_size (window, width, window->height);
} }
@ -459,7 +542,7 @@ gst_vaapi_window_set_width (GstVaapiWindow * window, guint width)
void void
gst_vaapi_window_set_height (GstVaapiWindow * window, guint height) gst_vaapi_window_set_height (GstVaapiWindow * window, guint height)
{ {
g_return_if_fail (window != NULL); g_return_if_fail (GST_VAAPI_IS_WINDOW (window));
gst_vaapi_window_set_size (window, window->width, height); gst_vaapi_window_set_size (window, window->width, height);
} }
@ -475,7 +558,7 @@ gst_vaapi_window_set_height (GstVaapiWindow * window, guint height)
void void
gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height) gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height)
{ {
g_return_if_fail (window != NULL); g_return_if_fail (GST_VAAPI_IS_WINDOW (window));
if (width == window->width && height == window->height) if (width == window->width && height == window->height)
return; return;
@ -537,7 +620,7 @@ gst_vaapi_window_put_surface (GstVaapiWindow * window,
const GstVaapiWindowClass *klass; const GstVaapiWindowClass *klass;
GstVaapiRectangle src_rect_default, dst_rect_default; GstVaapiRectangle src_rect_default, dst_rect_default;
g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE);
g_return_val_if_fail (surface != NULL, FALSE); g_return_val_if_fail (surface != NULL, FALSE);
klass = GST_VAAPI_WINDOW_GET_CLASS (window); klass = GST_VAAPI_WINDOW_GET_CLASS (window);
@ -592,7 +675,7 @@ gst_vaapi_window_put_pixmap (GstVaapiWindow * window,
const GstVaapiWindowClass *klass; const GstVaapiWindowClass *klass;
GstVaapiRectangle src_rect_default, dst_rect_default; GstVaapiRectangle src_rect_default, dst_rect_default;
g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE);
g_return_val_if_fail (pixmap != NULL, FALSE); g_return_val_if_fail (pixmap != NULL, FALSE);
klass = GST_VAAPI_WINDOW_GET_CLASS (window); klass = GST_VAAPI_WINDOW_GET_CLASS (window);
@ -621,7 +704,7 @@ gst_vaapi_window_put_pixmap (GstVaapiWindow * window,
void void
gst_vaapi_window_reconfigure (GstVaapiWindow * window) gst_vaapi_window_reconfigure (GstVaapiWindow * window)
{ {
g_return_if_fail (window != NULL); g_return_if_fail (GST_VAAPI_IS_WINDOW (window));
window->check_geometry = TRUE; window->check_geometry = TRUE;
gst_vaapi_window_ensure_size (window); gst_vaapi_window_ensure_size (window);
@ -638,7 +721,7 @@ gst_vaapi_window_unblock (GstVaapiWindow * window)
{ {
const GstVaapiWindowClass *klass; const GstVaapiWindowClass *klass;
g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE);
klass = GST_VAAPI_WINDOW_GET_CLASS (window); klass = GST_VAAPI_WINDOW_GET_CLASS (window);
@ -659,7 +742,7 @@ gst_vaapi_window_unblock_cancel (GstVaapiWindow * window)
{ {
const GstVaapiWindowClass *klass; const GstVaapiWindowClass *klass;
g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_IS_WINDOW (window), FALSE);
klass = GST_VAAPI_WINDOW_GET_CLASS (window); klass = GST_VAAPI_WINDOW_GET_CLASS (window);

View file

@ -25,21 +25,26 @@
#ifndef GST_VAAPI_WINDOW_H #ifndef GST_VAAPI_WINDOW_H
#define GST_VAAPI_WINDOW_H #define GST_VAAPI_WINDOW_H
#include <gst/video/gstvideosink.h> #include <gst/gst.h>
#include <gst/vaapi/gstvaapitypes.h> #include <gst/vaapi/gstvaapitypes.h>
#include <gst/vaapi/gstvaapiobject.h>
#include <gst/vaapi/gstvaapidisplay.h> #include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapisurface.h> #include <gst/vaapi/gstvaapisurface.h>
#include <gst/vaapi/gstvaapipixmap.h> #include <gst/vaapi/gstvaapipixmap.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_VAAPI_WINDOW (gst_vaapi_window_get_type ())
#define GST_VAAPI_WINDOW(obj) \ #define GST_VAAPI_WINDOW(obj) \
((GstVaapiWindow *)(obj)) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW, GstVaapiWindow))
#define GST_VAAPI_IS_WINDOW(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW))
typedef struct _GstVaapiWindow GstVaapiWindow; typedef struct _GstVaapiWindow GstVaapiWindow;
typedef struct _GstVaapiWindowClass GstVaapiWindowClass; typedef struct _GstVaapiWindowClass GstVaapiWindowClass;
GType
gst_vaapi_window_get_type (void) G_GNUC_CONST;
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height); gst_vaapi_window_new (GstVaapiDisplay * display, guint width, guint height);
@ -105,6 +110,10 @@ gst_vaapi_window_unblock (GstVaapiWindow * window);
gboolean gboolean
gst_vaapi_window_unblock_cancel (GstVaapiWindow * window); gst_vaapi_window_unblock_cancel (GstVaapiWindow * window);
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindow, gst_object_unref)
#endif
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_WINDOW_H */ #endif /* GST_VAAPI_WINDOW_H */

View file

@ -57,6 +57,8 @@ struct _GstVaapiWindowDRMClass
GstVaapiWindowClass parent_instance; GstVaapiWindowClass parent_instance;
}; };
G_DEFINE_TYPE (GstVaapiWindowDRM, gst_vaapi_window_drm, GST_TYPE_VAAPI_WINDOW);
static gboolean static gboolean
gst_vaapi_window_drm_show (GstVaapiWindow * window) gst_vaapi_window_drm_show (GstVaapiWindow * window)
{ {
@ -91,7 +93,7 @@ gst_vaapi_window_drm_render (GstVaapiWindow * window,
return TRUE; return TRUE;
} }
void static void
gst_vaapi_window_drm_class_init (GstVaapiWindowDRMClass * klass) gst_vaapi_window_drm_class_init (GstVaapiWindowDRMClass * klass)
{ {
GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass);
@ -104,13 +106,10 @@ gst_vaapi_window_drm_class_init (GstVaapiWindowDRMClass * klass)
} }
static void static void
gst_vaapi_window_drm_finalize (GstVaapiWindowDRM * window) gst_vaapi_window_drm_init (GstVaapiWindowDRM * window)
{ {
} }
GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowDRM,
gst_vaapi_window_drm, gst_vaapi_window_drm_class_init (&g_class));
/** /**
* gst_vaapi_window_drm_new: * gst_vaapi_window_drm_new:
* @display: a #GstVaapiDisplay * @display: a #GstVaapiDisplay
@ -132,12 +131,8 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowDRM,
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height) gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height)
{ {
GST_DEBUG ("new window, size %ux%u", width, height);
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_DRM (display), NULL); g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_DRM (display), NULL);
return return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_DRM, display,
gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS GST_VAAPI_ID_INVALID, width, height);
(gst_vaapi_window_drm_class ()), display, GST_VAAPI_ID_INVALID, width,
height);
} }

View file

@ -23,19 +23,30 @@
#ifndef GST_VAAPI_WINDOW_DRM_H #ifndef GST_VAAPI_WINDOW_DRM_H
#define GST_VAAPI_WINDOW_DRM_H #define GST_VAAPI_WINDOW_DRM_H
#include <gst/gst.h>
#include <gst/vaapi/gstvaapidisplay.h> #include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapiwindow.h> #include <gst/vaapi/gstvaapiwindow.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_VAAPI_WINDOW_DRM (gst_vaapi_window_drm_get_type ())
#define GST_VAAPI_WINDOW_DRM(obj) \ #define GST_VAAPI_WINDOW_DRM(obj) \
((GstVaapiWindowDRM *)(obj)) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_DRM, GstVaapiWindowDRM))
#define GST_VAAPI_IS_WINDOW_DRM(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_DRM))
typedef struct _GstVaapiWindowDRM GstVaapiWindowDRM; typedef struct _GstVaapiWindowDRM GstVaapiWindowDRM;
GType
gst_vaapi_window_drm_get_type (void) G_GNUC_CONST;
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height); gst_vaapi_window_drm_new (GstVaapiDisplay * display, guint width, guint height);
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowDRM, gst_object_unref)
#endif
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_WINDOW_DRM_H */ #endif /* GST_VAAPI_WINDOW_DRM_H */

View file

@ -32,16 +32,16 @@
#include "gstvaapitexture_priv.h" #include "gstvaapitexture_priv.h"
#include "gstvaapidisplay_egl_priv.h" #include "gstvaapidisplay_egl_priv.h"
#define GST_VAAPI_WINDOW_EGL(obj) \
#define GST_VAAPI_WINDOW_EGL_CAST(obj) \
((GstVaapiWindowEGL *)(obj)) ((GstVaapiWindowEGL *)(obj))
#define GST_VAAPI_WINDOW_EGL_CLASS(klass) \ #define GST_VAAPI_WINDOW_EGL_GET_PROXY(obj) \
((GstVaapiWindowEGLClass *)(klass)) (GST_VAAPI_WINDOW_EGL_CAST(obj)->window)
#define GST_VAAPI_WINDOW_EGL_GET_CLASS(obj) \ #define GST_VAAPI_WINDOW_EGL_GET_CLASS(obj) \
GST_VAAPI_WINDOW_EGL_CLASS (GST_VAAPI_WINDOW_GET_CLASS (obj)) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_EGL, GstVaapiWindowEGLClass))
typedef struct _GstVaapiWindowEGL GstVaapiWindowEGL;
typedef struct _GstVaapiWindowEGLClass GstVaapiWindowEGLClass; typedef struct _GstVaapiWindowEGLClass GstVaapiWindowEGLClass;
enum enum
@ -123,6 +123,8 @@ static const gchar *frag_shader_text_rgba =
"} \n"; "} \n";
/* *IDENT-ON* */ /* *IDENT-ON* */
G_DEFINE_TYPE (GstVaapiWindowEGL, gst_vaapi_window_egl, GST_TYPE_VAAPI_WINDOW);
static gboolean static gboolean
ensure_texture (GstVaapiWindowEGL * window, guint width, guint height) ensure_texture (GstVaapiWindowEGL * window, guint width, guint height)
{ {
@ -133,7 +135,7 @@ ensure_texture (GstVaapiWindowEGL * window, guint width, guint height)
GST_VAAPI_TEXTURE_HEIGHT (window->texture) == height) GST_VAAPI_TEXTURE_HEIGHT (window->texture) == height)
return TRUE; return TRUE;
texture = gst_vaapi_texture_egl_new (GST_VAAPI_OBJECT_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_vaapi_texture_replace (&window->texture, texture);
gst_vaapi_texture_replace (&texture, NULL); gst_vaapi_texture_replace (&texture, NULL);
@ -187,7 +189,8 @@ do_create_objects_unlocked (GstVaapiWindowEGL * window, guint width,
EglVTable *egl_vtable; EglVTable *egl_vtable;
egl_window = egl_window_new (egl_context, egl_window = egl_window_new (egl_context,
GSIZE_TO_POINTER (GST_VAAPI_OBJECT_ID (window->window))); GSIZE_TO_POINTER (GST_VAAPI_WINDOW_ID (GST_VAAPI_WINDOW_EGL_GET_PROXY
(window))));
if (!egl_window) if (!egl_window)
return FALSE; return FALSE;
window->egl_window = egl_window; window->egl_window = egl_window;
@ -207,36 +210,37 @@ do_create_objects (CreateObjectsArgs * args)
args->success = FALSE; args->success = FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
if (egl_context_set_current (args->egl_context, TRUE, &old_cs)) { if (egl_context_set_current (args->egl_context, TRUE, &old_cs)) {
args->success = do_create_objects_unlocked (window, args->width, args->success = do_create_objects_unlocked (window, args->width,
args->height, args->egl_context); args->height, args->egl_context);
egl_context_set_current (args->egl_context, FALSE, &old_cs); egl_context_set_current (args->egl_context, FALSE, &old_cs);
} }
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
static gboolean static gboolean
gst_vaapi_window_egl_create (GstVaapiWindowEGL * window, gst_vaapi_window_egl_create (GstVaapiWindow * window, guint * width,
guint * width, guint * height) guint * height)
{ {
GstVaapiDisplayEGL *const display = GstVaapiDisplayEGL *const display =
GST_VAAPI_DISPLAY_EGL (GST_VAAPI_OBJECT_DISPLAY (window)); GST_VAAPI_DISPLAY_EGL (GST_VAAPI_WINDOW_DISPLAY (window));
const GstVaapiDisplayClass *const native_dpy_class = const GstVaapiDisplayClass *const native_dpy_class =
GST_VAAPI_DISPLAY_GET_CLASS (display->display); GST_VAAPI_DISPLAY_GET_CLASS (display->display);
CreateObjectsArgs args; CreateObjectsArgs args;
g_return_val_if_fail (native_dpy_class != NULL, FALSE); g_return_val_if_fail (native_dpy_class != NULL, FALSE);
window->window = GST_VAAPI_WINDOW_EGL_GET_PROXY (window) =
native_dpy_class->create_window (GST_VAAPI_DISPLAY (display->display), native_dpy_class->create_window (GST_VAAPI_DISPLAY (display->display),
GST_VAAPI_ID_INVALID, *width, *height); GST_VAAPI_ID_INVALID, *width, *height);
if (!window->window) if (!GST_VAAPI_WINDOW_EGL_GET_PROXY (window))
return FALSE; return FALSE;
gst_vaapi_window_get_size (window->window, width, height); gst_vaapi_window_get_size (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), width,
height);
args.window = window; args.window = GST_VAAPI_WINDOW_EGL_CAST (window);
args.width = *width; args.width = *width;
args.height = *height; args.height = *height;
args.egl_context = GST_VAAPI_DISPLAY_EGL_CONTEXT (display); args.egl_context = GST_VAAPI_DISPLAY_EGL_CONTEXT (display);
@ -256,70 +260,76 @@ static void
do_destroy_objects (GstVaapiWindowEGL * window) do_destroy_objects (GstVaapiWindowEGL * window)
{ {
EglContext *const egl_context = EglContext *const egl_context =
GST_VAAPI_DISPLAY_EGL_CONTEXT (GST_VAAPI_OBJECT_DISPLAY (window)); GST_VAAPI_DISPLAY_EGL_CONTEXT (GST_VAAPI_WINDOW_DISPLAY (window));
EglContextState old_cs; EglContextState old_cs;
if (!window->egl_window) if (!window->egl_window)
return; return;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
if (egl_context_set_current (egl_context, TRUE, &old_cs)) { if (egl_context_set_current (egl_context, TRUE, &old_cs)) {
do_destroy_objects_unlocked (window); do_destroy_objects_unlocked (window);
egl_context_set_current (egl_context, FALSE, &old_cs); egl_context_set_current (egl_context, FALSE, &old_cs);
} }
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
static void static void
gst_vaapi_window_egl_destroy (GstVaapiWindowEGL * window) gst_vaapi_window_egl_finalize (GObject * object)
{ {
GstVaapiWindowEGL *const window = GST_VAAPI_WINDOW_EGL (object);
egl_context_run (window->egl_window->context, egl_context_run (window->egl_window->context,
(EglContextRunFunc) do_destroy_objects, window); (EglContextRunFunc) do_destroy_objects, window);
gst_vaapi_window_replace (&window->window, NULL); gst_vaapi_window_replace (&window->window, NULL);
gst_vaapi_texture_replace (&window->texture, NULL); gst_vaapi_texture_replace (&window->texture, NULL);
G_OBJECT_CLASS (gst_vaapi_window_egl_parent_class)->finalize (object);
} }
static gboolean static gboolean
gst_vaapi_window_egl_show (GstVaapiWindowEGL * window) gst_vaapi_window_egl_show (GstVaapiWindow * window)
{ {
const GstVaapiWindowClass *const klass = const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window); GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window));
g_return_val_if_fail (klass->show, FALSE); g_return_val_if_fail (klass->show, FALSE);
return klass->show (window->window); return klass->show (GST_VAAPI_WINDOW_EGL_GET_PROXY (window));
} }
static gboolean static gboolean
gst_vaapi_window_egl_hide (GstVaapiWindowEGL * window) gst_vaapi_window_egl_hide (GstVaapiWindow * window)
{ {
const GstVaapiWindowClass *const klass = const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window); GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window));
g_return_val_if_fail (klass->hide, FALSE); g_return_val_if_fail (klass->hide, FALSE);
return klass->hide (window->window); return klass->hide (GST_VAAPI_WINDOW_EGL_GET_PROXY (window));
} }
static gboolean static gboolean
gst_vaapi_window_egl_get_geometry (GstVaapiWindowEGL * window, gst_vaapi_window_egl_get_geometry (GstVaapiWindow * window, gint * x_ptr,
gint * x_ptr, gint * y_ptr, guint * width_ptr, guint * height_ptr) gint * y_ptr, guint * width_ptr, guint * height_ptr)
{ {
const GstVaapiWindowClass *const klass = const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window); GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window));
return klass->get_geometry ? klass->get_geometry (window->window, return klass->get_geometry ?
x_ptr, y_ptr, width_ptr, height_ptr) : FALSE; klass->get_geometry (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), x_ptr,
y_ptr, width_ptr, height_ptr) : FALSE;
} }
static gboolean static gboolean
gst_vaapi_window_egl_set_fullscreen (GstVaapiWindowEGL * window, gst_vaapi_window_egl_set_fullscreen (GstVaapiWindow * window,
gboolean fullscreen) gboolean fullscreen)
{ {
const GstVaapiWindowClass *const klass = const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window); GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window));
return klass->set_fullscreen ? klass->set_fullscreen (window->window, return klass->set_fullscreen ?
klass->set_fullscreen (GST_VAAPI_WINDOW_EGL_GET_PROXY (window),
fullscreen) : FALSE; fullscreen) : FALSE;
} }
@ -341,29 +351,29 @@ do_resize_window (ResizeWindowArgs * args)
GstVaapiWindowEGL *const window = args->window; GstVaapiWindowEGL *const window = args->window;
EglContextState old_cs; EglContextState old_cs;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) { if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) {
args->success = do_resize_window_unlocked (window, args->width, args->success = do_resize_window_unlocked (window, args->width,
args->height); args->height);
egl_context_set_current (window->egl_window->context, FALSE, &old_cs); egl_context_set_current (window->egl_window->context, FALSE, &old_cs);
} }
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
static gboolean static gboolean
gst_vaapi_window_egl_resize (GstVaapiWindowEGL * window, guint width, gst_vaapi_window_egl_resize (GstVaapiWindow * window, guint width, guint height)
guint height)
{ {
GstVaapiWindowEGL *const win = GST_VAAPI_WINDOW_EGL_CAST (window);
const GstVaapiWindowClass *const klass = const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window); GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window));
ResizeWindowArgs args = { window, width, height }; ResizeWindowArgs args = { win, width, height };
g_return_val_if_fail (klass->resize, FALSE); g_return_val_if_fail (klass->resize, FALSE);
if (!klass->resize (window->window, width, height)) if (!klass->resize (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), width, height))
return FALSE; return FALSE;
return egl_context_run (window->egl_window->context, return egl_context_run (win->egl_window->context,
(EglContextRunFunc) do_resize_window, &args) && args.success; (EglContextRunFunc) do_resize_window, &args) && args.success;
} }
@ -472,71 +482,63 @@ do_upload_surface (UploadSurfaceArgs * args)
args->success = FALSE; args->success = FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) { if (egl_context_set_current (window->egl_window->context, TRUE, &old_cs)) {
args->success = do_upload_surface_unlocked (window, args->surface, args->success = do_upload_surface_unlocked (window, args->surface,
args->src_rect, args->dst_rect, args->flags); args->src_rect, args->dst_rect, args->flags);
egl_context_set_current (window->egl_window->context, FALSE, &old_cs); egl_context_set_current (window->egl_window->context, FALSE, &old_cs);
} }
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
static gboolean static gboolean
gst_vaapi_window_egl_render (GstVaapiWindowEGL * window, gst_vaapi_window_egl_render (GstVaapiWindow * window, GstVaapiSurface * surface,
GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect,
const GstVaapiRectangle * dst_rect, guint flags) guint flags)
{ {
UploadSurfaceArgs args = { window, surface, src_rect, dst_rect, flags }; GstVaapiWindowEGL *const win = GST_VAAPI_WINDOW_EGL_CAST (window);
UploadSurfaceArgs args = { win, surface, src_rect, dst_rect, flags };
return egl_context_run (window->egl_window->context, return egl_context_run (win->egl_window->context,
(EglContextRunFunc) do_upload_surface, &args) && args.success; (EglContextRunFunc) do_upload_surface, &args) && args.success;
} }
static gboolean static gboolean
gst_vaapi_window_egl_render_pixmap (GstVaapiWindowEGL * window, gst_vaapi_window_egl_render_pixmap (GstVaapiWindow * window,
GstVaapiPixmap * pixmap, GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect,
const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect) const GstVaapiRectangle * dst_rect)
{ {
const GstVaapiWindowClass *const klass = const GstVaapiWindowClass *const klass =
GST_VAAPI_WINDOW_GET_CLASS (window->window); GST_VAAPI_WINDOW_GET_CLASS (GST_VAAPI_WINDOW_EGL_GET_PROXY (window));
if (!klass->render_pixmap) if (!klass->render_pixmap)
return FALSE; return FALSE;
return klass->render_pixmap (window->window, pixmap, src_rect, dst_rect); return klass->render_pixmap (GST_VAAPI_WINDOW_EGL_GET_PROXY (window), pixmap,
src_rect, dst_rect);
} }
void static void
gst_vaapi_window_egl_class_init (GstVaapiWindowEGLClass * klass) gst_vaapi_window_egl_class_init (GstVaapiWindowEGLClass * klass)
{ {
GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); GObjectClass *const object_class = G_OBJECT_CLASS (klass);
GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass);
object_class->finalize = (GstVaapiObjectFinalizeFunc) object_class->finalize = gst_vaapi_window_egl_finalize;
gst_vaapi_window_egl_destroy;
window_class->create = (GstVaapiWindowCreateFunc) window_class->create = gst_vaapi_window_egl_create;
gst_vaapi_window_egl_create; window_class->show = gst_vaapi_window_egl_show;
window_class->show = (GstVaapiWindowShowFunc) window_class->hide = gst_vaapi_window_egl_hide;
gst_vaapi_window_egl_show; window_class->get_geometry = gst_vaapi_window_egl_get_geometry;
window_class->hide = (GstVaapiWindowHideFunc) window_class->set_fullscreen = gst_vaapi_window_egl_set_fullscreen;
gst_vaapi_window_egl_hide; window_class->resize = gst_vaapi_window_egl_resize;
window_class->get_geometry = (GstVaapiWindowGetGeometryFunc) window_class->render = gst_vaapi_window_egl_render;
gst_vaapi_window_egl_get_geometry; window_class->render_pixmap = gst_vaapi_window_egl_render_pixmap;
window_class->set_fullscreen = (GstVaapiWindowSetFullscreenFunc)
gst_vaapi_window_egl_set_fullscreen;
window_class->resize = (GstVaapiWindowResizeFunc)
gst_vaapi_window_egl_resize;
window_class->render = (GstVaapiWindowRenderFunc)
gst_vaapi_window_egl_render;
window_class->render_pixmap = (GstVaapiWindowRenderPixmapFunc)
gst_vaapi_window_egl_render_pixmap;
} }
#define gst_vaapi_window_egl_finalize \ static void
gst_vaapi_window_egl_destroy gst_vaapi_window_egl_init (GstVaapiWindowEGL * window)
{
GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowEGL, }
gst_vaapi_window_egl, gst_vaapi_window_egl_class_init (&g_class));
/** /**
* gst_vaapi_window_egl_new: * gst_vaapi_window_egl_new:
@ -553,12 +555,8 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowEGL,
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height) gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height)
{ {
GST_DEBUG ("new window, size %ux%u", width, height);
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 return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_EGL, display,
gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS GST_VAAPI_ID_INVALID, width, height);
(gst_vaapi_window_egl_class ()), display, GST_VAAPI_ID_INVALID, width,
height);
} }

View file

@ -23,17 +23,30 @@
#ifndef GST_VAAPI_WINDOW_EGL_H #ifndef GST_VAAPI_WINDOW_EGL_H
#define GST_VAAPI_WINDOW_EGL_H #define GST_VAAPI_WINDOW_EGL_H
#include <gst/gst.h>
#include <gst/vaapi/gstvaapidisplay.h> #include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapiwindow.h> #include <gst/vaapi/gstvaapiwindow.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_VAAPI_WINDOW_EGL (gst_vaapi_window_egl_get_type ())
#define GST_VAAPI_WINDOW_EGL(obj) \ #define GST_VAAPI_WINDOW_EGL(obj) \
((GstVaapiWindowEGL *)(obj)) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_EGL, GstVaapiWindowEGL))
#define GST_VAAPI_IS_WINDOW_EGL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_EGL))
typedef struct _GstVaapiWindowEGL GstVaapiWindowEGL;
GType
gst_vaapi_window_egl_get_type (void) G_GNUC_CONST;
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height); gst_vaapi_window_egl_new (GstVaapiDisplay * display, guint width, guint height);
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowEGL, gst_object_unref)
#endif
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_WINDOW_EGL_H */ #endif /* GST_VAAPI_WINDOW_EGL_H */

View file

@ -39,14 +39,12 @@
#define DEBUG 1 #define DEBUG 1
#include "gstvaapidebug.h" #include "gstvaapidebug.h"
#define GST_VAAPI_WINDOW_GLX_CAST(obj) ((GstVaapiWindowGLX *)(obj))
#define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window) \ #define GST_VAAPI_WINDOW_GLX_GET_PRIVATE(window) \
(&GST_VAAPI_WINDOW_GLX(window)->priv) gst_vaapi_window_glx_get_instance_private (GST_VAAPI_WINDOW_GLX_CAST (window))
#define GST_VAAPI_WINDOW_GLX_CLASS(klass) \
((GstVaapiWindowGLXClass *)(klass))
#define GST_VAAPI_WINDOW_GLX_GET_CLASS(obj) \ #define GST_VAAPI_WINDOW_GLX_GET_CLASS(obj) \
GST_VAAPI_WINDOW_GLX_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_GLX, GstVaapiWindowGLXClass))
typedef struct _GstVaapiWindowGLXPrivate GstVaapiWindowGLXPrivate; typedef struct _GstVaapiWindowGLXPrivate GstVaapiWindowGLXPrivate;
typedef struct _GstVaapiWindowGLXClass GstVaapiWindowGLXClass; typedef struct _GstVaapiWindowGLXClass GstVaapiWindowGLXClass;
@ -66,8 +64,6 @@ struct _GstVaapiWindowGLX
{ {
/*< private > */ /*< private > */
GstVaapiWindowX11 parent_instance; GstVaapiWindowX11 parent_instance;
GstVaapiWindowGLXPrivate priv;
}; };
/** /**
@ -79,11 +75,11 @@ struct _GstVaapiWindowGLXClass
{ {
/*< private > */ /*< private > */
GstVaapiWindowX11Class parent_class; GstVaapiWindowX11Class parent_class;
GstVaapiObjectFinalizeFunc parent_finalize;
GstVaapiWindowResizeFunc parent_resize;
}; };
G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiWindowGLX, gst_vaapi_window_glx,
GST_TYPE_VAAPI_WINDOW_X11);
/* Fill rectangle coords with capped bounds */ /* Fill rectangle coords with capped bounds */
static inline void static inline void
fill_rect (GstVaapiRectangle * dst_rect, fill_rect (GstVaapiRectangle * dst_rect,
@ -114,12 +110,12 @@ _gst_vaapi_window_glx_destroy_context (GstVaapiWindow * window)
GstVaapiWindowGLXPrivate *const priv = GstVaapiWindowGLXPrivate *const priv =
GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window);
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
if (priv->gl_context) { if (priv->gl_context) {
gl_destroy_context (priv->gl_context); gl_destroy_context (priv->gl_context);
priv->gl_context = NULL; priv->gl_context = NULL;
} }
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
static gboolean static gboolean
@ -128,14 +124,14 @@ _gst_vaapi_window_glx_create_context (GstVaapiWindow * window,
{ {
GstVaapiWindowGLXPrivate *const priv = GstVaapiWindowGLXPrivate *const priv =
GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
GLContextState parent_cs; GLContextState parent_cs;
parent_cs.display = dpy; parent_cs.display = dpy;
parent_cs.window = None; parent_cs.window = None;
parent_cs.context = foreign_context; parent_cs.context = foreign_context;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
priv->gl_context = gl_create_context (dpy, DefaultScreen (dpy), &parent_cs); priv->gl_context = gl_create_context (dpy, DefaultScreen (dpy), &parent_cs);
if (!priv->gl_context) { if (!priv->gl_context) {
GST_DEBUG ("could not create GLX context"); GST_DEBUG ("could not create GLX context");
@ -152,7 +148,7 @@ out_destroy_context:
gl_destroy_context (priv->gl_context); gl_destroy_context (priv->gl_context);
priv->gl_context = NULL; priv->gl_context = NULL;
end: end:
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
return priv->gl_context != NULL; return priv->gl_context != NULL;
} }
@ -183,7 +179,7 @@ gst_vaapi_window_glx_ensure_context (GstVaapiWindow * window,
if (!_gst_vaapi_window_glx_ensure_context (window, foreign_context)) if (!_gst_vaapi_window_glx_ensure_context (window, foreign_context))
return FALSE; return FALSE;
priv->gl_context->window = GST_VAAPI_OBJECT_ID (window); priv->gl_context->window = GST_VAAPI_WINDOW_ID (window);
if (!gl_set_current_context (priv->gl_context, &old_cs)) { if (!gl_set_current_context (priv->gl_context, &old_cs)) {
GST_DEBUG ("could not make newly created GLX context current"); GST_DEBUG ("could not make newly created GLX context current");
return FALSE; return FALSE;
@ -222,13 +218,13 @@ gst_vaapi_window_glx_destroy_colormap (GstVaapiWindow * window)
{ {
GstVaapiWindowGLXPrivate *const priv = GstVaapiWindowGLXPrivate *const priv =
GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
if (priv->cmap) { if (priv->cmap) {
if (!window->use_foreign_window) { if (!window->use_foreign_window) {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
XFreeColormap (dpy, priv->cmap); XFreeColormap (dpy, priv->cmap);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
priv->cmap = None; priv->cmap = None;
} }
@ -239,7 +235,7 @@ gst_vaapi_window_glx_create_colormap (GstVaapiWindow * window)
{ {
GstVaapiWindowGLXPrivate *const priv = GstVaapiWindowGLXPrivate *const priv =
GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
XWindowAttributes wattr; XWindowAttributes wattr;
gboolean success = FALSE; gboolean success = FALSE;
@ -247,20 +243,20 @@ gst_vaapi_window_glx_create_colormap (GstVaapiWindow * window)
if (!window->use_foreign_window) { if (!window->use_foreign_window) {
if (!_gst_vaapi_window_glx_ensure_context (window, NULL)) if (!_gst_vaapi_window_glx_ensure_context (window, NULL))
return None; return None;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
x11_trap_errors (); x11_trap_errors ();
/* XXX: add a GstVaapiDisplayX11:x11-screen property? */ /* XXX: add a GstVaapiDisplayX11:x11-screen property? */
priv->cmap = XCreateColormap (dpy, RootWindow (dpy, DefaultScreen (dpy)), priv->cmap = XCreateColormap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
priv->gl_context->visual->visual, AllocNone); priv->gl_context->visual->visual, AllocNone);
success = x11_untrap_errors () == 0; success = x11_untrap_errors () == 0;
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} else { } else {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
x11_trap_errors (); x11_trap_errors ();
XGetWindowAttributes (dpy, GST_VAAPI_OBJECT_ID (window), &wattr); XGetWindowAttributes (dpy, GST_VAAPI_WINDOW_ID (window), &wattr);
priv->cmap = wattr.colormap; priv->cmap = wattr.colormap;
success = x11_untrap_errors () == 0; success = x11_untrap_errors () == 0;
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
if (!success) if (!success)
return None; return None;
@ -279,53 +275,52 @@ gst_vaapi_window_glx_resize (GstVaapiWindow * window, guint width, guint height)
{ {
GstVaapiWindowGLXPrivate *const priv = GstVaapiWindowGLXPrivate *const priv =
GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window); GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window);
const GstVaapiWindowGLXClass *const klass = const GstVaapiWindowClass *const parent_klass =
GST_VAAPI_WINDOW_GLX_GET_CLASS (window); GST_VAAPI_WINDOW_CLASS (gst_vaapi_window_glx_parent_class);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
GLContextState old_cs; GLContextState old_cs;
if (!klass->parent_resize (window, width, height)) if (!parent_klass->resize (window, width, height))
return FALSE; return FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
XSync (dpy, False); /* make sure resize completed */ XSync (dpy, False); /* make sure resize completed */
if (gl_set_current_context (priv->gl_context, &old_cs)) { if (gl_set_current_context (priv->gl_context, &old_cs)) {
gl_resize (width, height); gl_resize (width, height);
gl_set_current_context (&old_cs, NULL); gl_set_current_context (&old_cs, NULL);
} }
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
return TRUE; return TRUE;
} }
static void static void
gst_vaapi_window_glx_finalize (GstVaapiWindowGLX * window) gst_vaapi_window_glx_finalize (GObject * object)
{ {
GstVaapiWindow *const base_window = GST_VAAPI_WINDOW (window); GstVaapiWindow *const window = GST_VAAPI_WINDOW (object);
_gst_vaapi_window_glx_destroy_context (base_window); _gst_vaapi_window_glx_destroy_context (window);
gst_vaapi_window_glx_destroy_colormap (base_window); gst_vaapi_window_glx_destroy_colormap (window);
GST_VAAPI_WINDOW_GLX_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT G_OBJECT_CLASS (gst_vaapi_window_glx_parent_class)->finalize (object);
(window));
} }
static void static void
gst_vaapi_window_glx_class_init (GstVaapiWindowGLXClass * klass) gst_vaapi_window_glx_class_init (GstVaapiWindowGLXClass * klass)
{ {
GObjectClass *const object_class = G_OBJECT_CLASS (klass);
GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass);
GstVaapiWindowX11Class *const xwindow_class =
GST_VAAPI_WINDOW_X11_CLASS (klass);
gst_vaapi_window_x11_class_init (xwindow_class); object_class->finalize = gst_vaapi_window_glx_finalize;
klass->parent_resize = window_class->resize;
klass->parent_finalize = GST_VAAPI_OBJECT_CLASS (klass)->finalize;
window_class->resize = gst_vaapi_window_glx_resize; window_class->resize = gst_vaapi_window_glx_resize;
window_class->get_visual_id = gst_vaapi_window_glx_get_visual_id; window_class->get_visual_id = gst_vaapi_window_glx_get_visual_id;
window_class->get_colormap = gst_vaapi_window_glx_get_colormap; window_class->get_colormap = gst_vaapi_window_glx_get_colormap;
} }
GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowGLX, static void
gst_vaapi_window_glx, gst_vaapi_window_glx_class_init (&g_class)); gst_vaapi_window_glx_init (GstVaapiWindowGLX * window)
{
}
/** /**
* gst_vaapi_window_glx_new: * gst_vaapi_window_glx_new:
@ -346,10 +341,8 @@ gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height)
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL); g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_GLX (display), NULL);
window = window = gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_GLX, display,
gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS GST_VAAPI_ID_INVALID, width, height);
(gst_vaapi_window_glx_class ()), display, GST_VAAPI_ID_INVALID, width,
height);
if (!window) if (!window)
return NULL; return NULL;
@ -382,14 +375,11 @@ gst_vaapi_window_glx_new_with_xid (GstVaapiDisplay * display, Window xid)
{ {
GstVaapiWindow *window; GstVaapiWindow *window;
GST_DEBUG ("new window from xid 0x%08x", (guint) xid);
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 (xid != None, NULL); g_return_val_if_fail (xid != None, NULL);
window = window = gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_GLX, display,
gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS xid, 0, 0);
(gst_vaapi_window_glx_class ()), display, xid, 0, 0);
if (!window) if (!window)
return NULL; return NULL;
@ -416,9 +406,12 @@ error:
GLXContext GLXContext
gst_vaapi_window_glx_get_context (GstVaapiWindowGLX * window) gst_vaapi_window_glx_get_context (GstVaapiWindowGLX * window)
{ {
g_return_val_if_fail (window != NULL, NULL); GstVaapiWindowGLXPrivate *priv;
return GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window)->gl_context->context; g_return_val_if_fail (GST_VAAPI_IS_WINDOW_GLX (window), NULL);
priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window);
return priv->gl_context->context;
} }
/** /**
@ -436,7 +429,7 @@ gst_vaapi_window_glx_get_context (GstVaapiWindowGLX * window)
gboolean gboolean
gst_vaapi_window_glx_set_context (GstVaapiWindowGLX * window, GLXContext ctx) gst_vaapi_window_glx_set_context (GstVaapiWindowGLX * window, GLXContext ctx)
{ {
g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_IS_WINDOW_GLX (window), FALSE);
return gst_vaapi_window_glx_ensure_context (GST_VAAPI_WINDOW (window), ctx); return gst_vaapi_window_glx_ensure_context (GST_VAAPI_WINDOW (window), ctx);
} }
@ -455,12 +448,14 @@ gboolean
gst_vaapi_window_glx_make_current (GstVaapiWindowGLX * window) gst_vaapi_window_glx_make_current (GstVaapiWindowGLX * window)
{ {
gboolean success; gboolean success;
GstVaapiWindowGLXPrivate *priv;
g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_IS_WINDOW_GLX (window), FALSE);
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
success = gl_set_current_context (window->priv.gl_context, NULL); priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); success = gl_set_current_context (priv->gl_context, NULL);
GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
return success; return success;
} }
@ -475,11 +470,14 @@ gst_vaapi_window_glx_make_current (GstVaapiWindowGLX * window)
void void
gst_vaapi_window_glx_swap_buffers (GstVaapiWindowGLX * window) gst_vaapi_window_glx_swap_buffers (GstVaapiWindowGLX * window)
{ {
g_return_if_fail (window != NULL); GstVaapiWindowGLXPrivate *priv;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); g_return_if_fail (GST_VAAPI_IS_WINDOW_GLX (window));
gl_swap_buffers (window->priv.gl_context);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
priv = GST_VAAPI_WINDOW_GLX_GET_PRIVATE (window);
gl_swap_buffers (priv->gl_context);
GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
/** /**
@ -511,7 +509,7 @@ gst_vaapi_window_glx_put_texture (GstVaapiWindowGLX * window,
guint tex_width, tex_height; guint tex_width, tex_height;
guint win_width, win_height; guint win_width, win_height;
g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_IS_WINDOW_GLX (window), FALSE);
g_return_val_if_fail (texture != NULL, FALSE); g_return_val_if_fail (texture != NULL, FALSE);
gst_vaapi_texture_get_size (texture, &tex_width, &tex_height); gst_vaapi_texture_get_size (texture, &tex_width, &tex_height);

View file

@ -26,17 +26,25 @@
#define GST_VAAPI_WINDOW_GLX_H #define GST_VAAPI_WINDOW_GLX_H
#include <GL/glx.h> #include <GL/glx.h>
#include <gst/gst.h>
#include <gst/vaapi/gstvaapidisplay.h> #include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapiwindow_x11.h> #include <gst/vaapi/gstvaapiwindow_x11.h>
#include <gst/vaapi/gstvaapitexture.h> #include <gst/vaapi/gstvaapitexture.h>
#include <gst/vaapi/gstvaapitypes.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_VAAPI_WINDOW_GLX (gst_vaapi_window_glx_get_type ())
#define GST_VAAPI_WINDOW_GLX(obj) \ #define GST_VAAPI_WINDOW_GLX(obj) \
((GstVaapiWindowGLX *)(obj)) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_GLX, GstVaapiWindowGLX))
#define GST_VAAPI_IS_WINDOW_GLX(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_GLX))
typedef struct _GstVaapiWindowGLX GstVaapiWindowGLX; typedef struct _GstVaapiWindowGLX GstVaapiWindowGLX;
GType
gst_vaapi_window_glx_get_type (void) G_GNUC_CONST;
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height); gst_vaapi_window_glx_new (GstVaapiDisplay * display, guint width, guint height);
@ -60,6 +68,10 @@ gst_vaapi_window_glx_put_texture (GstVaapiWindowGLX * window,
GstVaapiTexture * texture, const GstVaapiRectangle * src_rect, GstVaapiTexture * texture, const GstVaapiRectangle * src_rect,
const GstVaapiRectangle * dst_rect); const GstVaapiRectangle * dst_rect);
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowGLX, gst_object_unref)
#endif
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_WINDOW_GLX_H */ #endif /* GST_VAAPI_WINDOW_GLX_H */

View file

@ -25,39 +25,41 @@
#ifndef GST_VAAPI_WINDOW_PRIV_H #ifndef GST_VAAPI_WINDOW_PRIV_H
#define GST_VAAPI_WINDOW_PRIV_H #define GST_VAAPI_WINDOW_PRIV_H
#include "gstvaapiobject_priv.h" #include "gstvaapidisplay.h"
#include "gstvaapifilter.h" #include "gstvaapifilter.h"
#include "gstvaapisurfacepool.h" #include "gstvaapisurfacepool.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_WINDOW_CAST(window) \
((GstVaapiWindow *)(window))
#define GST_VAAPI_WINDOW_CLASS(klass) \ #define GST_VAAPI_WINDOW_CLASS(klass) \
((GstVaapiWindowClass *)(klass)) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_VAAPI_WINDOW, GstVaapiWindowClass))
#define GST_VAAPI_IS_WINDOW_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_WINDOW))
#define GST_VAAPI_WINDOW_GET_CLASS(obj) \ #define GST_VAAPI_WINDOW_GET_CLASS(obj) \
GST_VAAPI_WINDOW_CLASS(GST_VAAPI_OBJECT_GET_CLASS(obj)) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW, GstVaapiWindowClass))
/* GstVaapiWindowClass hooks */ #define GST_VAAPI_WINDOW_DISPLAY(window) \
typedef gboolean (*GstVaapiWindowCreateFunc) (GstVaapiWindow * window, (GST_VAAPI_WINDOW_CAST (window)->display)
guint * width, guint * height);
typedef gboolean (*GstVaapiWindowShowFunc) (GstVaapiWindow * window); #define GST_VAAPI_WINDOW_LOCK_DISPLAY(window) \
typedef gboolean (*GstVaapiWindowHideFunc) (GstVaapiWindow * window); GST_VAAPI_DISPLAY_LOCK (GST_VAAPI_WINDOW_DISPLAY (window))
typedef gboolean (*GstVaapiWindowGetGeometryFunc) (GstVaapiWindow * window,
gint * px, gint * py, guint * pwidth, guint * pheight); #define GST_VAAPI_WINDOW_UNLOCK_DISPLAY(window) \
typedef gboolean (*GstVaapiWindowSetFullscreenFunc) (GstVaapiWindow * window, GST_VAAPI_DISPLAY_UNLOCK (GST_VAAPI_WINDOW_DISPLAY (window))
gboolean fullscreen);
typedef gboolean (*GstVaapiWindowResizeFunc) (GstVaapiWindow * window, #define GST_VAAPI_WINDOW_NATIVE_DISPLAY(window) \
guint width, guint height); GST_VAAPI_DISPLAY_NATIVE (GST_VAAPI_WINDOW_DISPLAY (window))
typedef gboolean (*GstVaapiWindowRenderFunc) (GstVaapiWindow * window,
GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, #define GST_VAAPI_WINDOW_ID(window) \
const GstVaapiRectangle * dst_rect, guint flags); (GST_VAAPI_WINDOW_CAST (window)->native_id)
typedef gboolean (*GstVaapiWindowRenderPixmapFunc) (GstVaapiWindow * window,
GstVaapiPixmap * pixmap, const GstVaapiRectangle * src_rect, #define GST_VAAPI_WINDOW_VADISPLAY(window) \
const GstVaapiRectangle * dst_rect); GST_VAAPI_DISPLAY_VADISPLAY (GST_VAAPI_WINDOW_DISPLAY (window))
typedef guintptr (*GstVaapiWindowGetVisualIdFunc) (GstVaapiWindow * window);
typedef guintptr (*GstVaapiWindowGetColormapFunc) (GstVaapiWindow * window);
typedef gboolean (*GstVaapiWindowSetUnblockFunc) (GstVaapiWindow * window);
typedef gboolean (*GstVaapiWindowSetUnblockCancelFunc) (GstVaapiWindow * window);
/** /**
* GstVaapiWindow: * GstVaapiWindow:
@ -67,7 +69,9 @@ typedef gboolean (*GstVaapiWindowSetUnblockCancelFunc) (GstVaapiWindow * window)
struct _GstVaapiWindow struct _GstVaapiWindow
{ {
/*< private >*/ /*< private >*/
GstVaapiObject parent_instance; GstObject parent_instance;
GstVaapiDisplay *display;
GstVaapiID native_id;
/*< protected >*/ /*< protected >*/
guint width; guint width;
@ -106,35 +110,36 @@ struct _GstVaapiWindow
struct _GstVaapiWindowClass struct _GstVaapiWindowClass
{ {
/*< private >*/ /*< private >*/
GstVaapiObjectClass parent_class; GstObjectClass parent_class;
/*< protected >*/ /*< protected >*/
GstVaapiWindowCreateFunc create; gboolean (*create) (GstVaapiWindow * window, guint * width, guint * height);
GstVaapiWindowShowFunc show; gboolean (*show) (GstVaapiWindow * window);
GstVaapiWindowHideFunc hide; gboolean (*hide) (GstVaapiWindow * window);
GstVaapiWindowGetGeometryFunc get_geometry; gboolean (*get_geometry) (GstVaapiWindow * window, gint * px, gint * py,
GstVaapiWindowSetFullscreenFunc set_fullscreen; guint * pwidth, guint * pheight);
GstVaapiWindowResizeFunc resize; gboolean (*set_fullscreen) (GstVaapiWindow * window, gboolean fullscreen);
GstVaapiWindowRenderFunc render; gboolean (*resize) (GstVaapiWindow * window, guint width, guint height);
GstVaapiWindowRenderPixmapFunc render_pixmap; gboolean (*render) (GstVaapiWindow * window, GstVaapiSurface * surface,
GstVaapiWindowGetVisualIdFunc get_visual_id; const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect,
GstVaapiWindowGetColormapFunc get_colormap; guint flags);
GstVaapiWindowSetUnblockFunc unblock; gboolean (*render_pixmap) (GstVaapiWindow * window, GstVaapiPixmap * pixmap,
GstVaapiWindowSetUnblockCancelFunc unblock_cancel; const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect);
guintptr (*get_visual_id) (GstVaapiWindow * window);
guintptr (*get_colormap) (GstVaapiWindow * window);
gboolean (*unblock) (GstVaapiWindow * window);
gboolean (*unblock_cancel) (GstVaapiWindow * window);
}; };
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_new_internal (const GstVaapiWindowClass * window_class, gst_vaapi_window_new_internal (GType type, GstVaapiDisplay * display,
GstVaapiDisplay * display, GstVaapiID handle, guint width, guint height); GstVaapiID handle, guint width, guint height);
GstVaapiSurface * GstVaapiSurface *
gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window, gst_vaapi_window_vpp_convert_internal (GstVaapiWindow * window,
GstVaapiSurface * surface, const GstVaapiRectangle * src_rect, GstVaapiSurface * surface, const GstVaapiRectangle * src_rect,
const GstVaapiRectangle * dst_rect, guint flags); const GstVaapiRectangle * dst_rect, guint flags);
void
gst_vaapi_window_class_init (GstVaapiWindowClass * klass);
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_WINDOW_PRIV_H */ #endif /* GST_VAAPI_WINDOW_PRIV_H */

View file

@ -28,6 +28,7 @@
#include "sysdeps.h" #include "sysdeps.h"
#include "gstvaapicompat.h" #include "gstvaapicompat.h"
#include "gstvaapiobject_priv.h"
#include "gstvaapiwindow_wayland.h" #include "gstvaapiwindow_wayland.h"
#include "gstvaapiwindow_priv.h" #include "gstvaapiwindow_priv.h"
#include "gstvaapidisplay_wayland.h" #include "gstvaapidisplay_wayland.h"
@ -43,13 +44,10 @@
((GstVaapiWindowWayland *)(obj)) ((GstVaapiWindowWayland *)(obj))
#define GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(obj) \ #define GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE(obj) \
(&GST_VAAPI_WINDOW_WAYLAND_CAST(obj)->priv) gst_vaapi_window_wayland_get_instance_private (GST_VAAPI_WINDOW_WAYLAND_CAST (obj))
#define GST_VAAPI_WINDOW_WAYLAND_CLASS(klass) \
((GstVaapiWindowWaylandClass *)(klass))
#define GST_VAAPI_WINDOW_WAYLAND_GET_CLASS(obj) \ #define GST_VAAPI_WINDOW_WAYLAND_GET_CLASS(obj) \
GST_VAAPI_WINDOW_WAYLAND_CLASS (GST_VAAPI_WINDOW_GET_CLASS (obj)) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_WAYLAND, GstVaapiWindowWaylandClass))
typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate; typedef struct _GstVaapiWindowWaylandPrivate GstVaapiWindowWaylandPrivate;
typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass; typedef struct _GstVaapiWindowWaylandClass GstVaapiWindowWaylandClass;
@ -123,8 +121,6 @@ struct _GstVaapiWindowWayland
{ {
/*< private > */ /*< private > */
GstVaapiWindow parent_instance; GstVaapiWindow parent_instance;
GstVaapiWindowWaylandPrivate priv;
}; };
/** /**
@ -136,9 +132,11 @@ struct _GstVaapiWindowWaylandClass
{ {
/*< private > */ /*< private > */
GstVaapiWindowClass parent_class; GstVaapiWindowClass parent_class;
GstVaapiObjectFinalizeFunc parent_finalize;
}; };
G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiWindowWayland, gst_vaapi_window_wayland,
GST_TYPE_VAAPI_WINDOW);
static gboolean static gboolean
gst_vaapi_window_wayland_show (GstVaapiWindow * window) gst_vaapi_window_wayland_show (GstVaapiWindow * window)
{ {
@ -161,7 +159,7 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window)
GstVaapiWindowWaylandPrivate *const priv = GstVaapiWindowWaylandPrivate *const priv =
GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
struct wl_display *const wl_display = struct wl_display *const wl_display =
GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
if (priv->sync_failed) if (priv->sync_failed)
return FALSE; return FALSE;
@ -267,30 +265,30 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window,
GstVaapiWindowWaylandPrivate *const priv = GstVaapiWindowWaylandPrivate *const priv =
GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
GstVaapiDisplayWaylandPrivate *const priv_display = GstVaapiDisplayWaylandPrivate *const priv_display =
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_OBJECT_DISPLAY (window)); GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_WINDOW_DISPLAY (window));
GST_DEBUG ("create window, size %ux%u", *width, *height); GST_DEBUG ("create window, size %ux%u", *width, *height);
g_return_val_if_fail (priv_display->compositor != NULL, FALSE); g_return_val_if_fail (priv_display->compositor != NULL, FALSE);
g_return_val_if_fail (priv_display->shell != NULL, FALSE); g_return_val_if_fail (priv_display->shell != NULL, FALSE);
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
priv->event_queue = wl_display_create_queue (priv_display->wl_display); priv->event_queue = wl_display_create_queue (priv_display->wl_display);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (!priv->event_queue) if (!priv->event_queue)
return FALSE; return FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
priv->surface = wl_compositor_create_surface (priv_display->compositor); priv->surface = wl_compositor_create_surface (priv_display->compositor);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (!priv->surface) if (!priv->surface)
return FALSE; return FALSE;
wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue); wl_proxy_set_queue ((struct wl_proxy *) priv->surface, priv->event_queue);
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
priv->shell_surface = priv->shell_surface =
wl_shell_get_shell_surface (priv_display->shell, priv->surface); wl_shell_get_shell_surface (priv_display->shell, priv->surface);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (!priv->shell_surface) if (!priv->shell_surface)
return FALSE; return FALSE;
wl_proxy_set_queue ((struct wl_proxy *) priv->shell_surface, wl_proxy_set_queue ((struct wl_proxy *) priv->shell_surface,
@ -312,21 +310,22 @@ gst_vaapi_window_wayland_create (GstVaapiWindow * window,
} }
static void static void
gst_vaapi_window_wayland_destroy (GstVaapiWindow * window) gst_vaapi_window_wayland_finalize (GObject * object)
{ {
GstVaapiWindow *window = GST_VAAPI_WINDOW (object);
GstVaapiWindowWaylandPrivate *const priv = GstVaapiWindowWaylandPrivate *const priv =
GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
struct wl_display *const wl_display = struct wl_display *const wl_display =
GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
/* Make sure that the last wl buffer's callback could be called */ /* Make sure that the last wl buffer's callback could be called */
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
if (priv->surface) { if (priv->surface) {
wl_surface_attach (priv->surface, NULL, 0, 0); wl_surface_attach (priv->surface, NULL, 0, 0);
wl_surface_commit (priv->surface); wl_surface_commit (priv->surface);
wl_display_flush (wl_display); wl_display_flush (wl_display);
} }
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
gst_poll_set_flushing (priv->poll, TRUE); gst_poll_set_flushing (priv->poll, TRUE);
@ -339,8 +338,7 @@ gst_vaapi_window_wayland_destroy (GstVaapiWindow * window)
gst_poll_free (priv->poll); gst_poll_free (priv->poll);
GST_VAAPI_WINDOW_WAYLAND_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT G_OBJECT_CLASS (gst_vaapi_window_wayland_parent_class)->finalize (object);
(window));
} }
static gboolean static gboolean
@ -350,15 +348,15 @@ gst_vaapi_window_wayland_resize (GstVaapiWindow * window,
GstVaapiWindowWaylandPrivate *const priv = GstVaapiWindowWaylandPrivate *const priv =
GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
GstVaapiDisplayWaylandPrivate *const priv_display = GstVaapiDisplayWaylandPrivate *const priv_display =
GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_OBJECT_DISPLAY (window)); GST_VAAPI_DISPLAY_WAYLAND_GET_PRIVATE (GST_VAAPI_WINDOW_DISPLAY (window));
GST_DEBUG ("resize window, new size %ux%u", width, height); GST_DEBUG ("resize window, new size %ux%u", width, height);
if (priv->opaque_region) if (priv->opaque_region)
wl_region_destroy (priv->opaque_region); wl_region_destroy (priv->opaque_region);
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
priv->opaque_region = wl_compositor_create_region (priv_display->compositor); priv->opaque_region = wl_compositor_create_region (priv_display->compositor);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
wl_region_add (priv->opaque_region, 0, 0, width, height); wl_region_add (priv->opaque_region, 0, 0, width, height);
return TRUE; return TRUE;
@ -411,9 +409,9 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window,
{ {
GstVaapiWindowWaylandPrivate *const priv = GstVaapiWindowWaylandPrivate *const priv =
GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window);
struct wl_display *const wl_display = struct wl_display *const wl_display =
GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
struct wl_buffer *buffer; struct wl_buffer *buffer;
FrameState *frame; FrameState *frame;
guint width, height, va_flags; guint width, height, va_flags;
@ -434,12 +432,12 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window,
/* Try to construct a Wayland buffer from VA surface as is (without VPP) */ /* Try to construct a Wayland buffer from VA surface as is (without VPP) */
if (!priv->need_vpp) { if (!priv->need_vpp) {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
va_flags = from_GstVaapiSurfaceRenderFlags (flags); va_flags = from_GstVaapiSurfaceRenderFlags (flags);
status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display),
GST_VAAPI_OBJECT_ID (surface), GST_VAAPI_OBJECT_ID (surface),
va_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD), &buffer); va_flags & (VA_TOP_FIELD | VA_BOTTOM_FIELD), &buffer);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED || if (status == VA_STATUS_ERROR_FLAG_NOT_SUPPORTED ||
status == VA_STATUS_ERROR_UNIMPLEMENTED || status == VA_STATUS_ERROR_UNIMPLEMENTED ||
status == VA_STATUS_ERROR_INVALID_IMAGE_FORMAT) status == VA_STATUS_ERROR_INVALID_IMAGE_FORMAT)
@ -463,10 +461,10 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window,
} }
} }
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display), status = vaGetSurfaceBufferWl (GST_VAAPI_DISPLAY_VADISPLAY (display),
GST_VAAPI_OBJECT_ID (surface), VA_FRAME_PICTURE, &buffer); GST_VAAPI_OBJECT_ID (surface), VA_FRAME_PICTURE, &buffer);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()")) if (!vaapi_check_status (status, "vaGetSurfaceBufferWl()"))
return FALSE; return FALSE;
} }
@ -492,7 +490,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window,
} }
/* XXX: attach to the specified target rectangle */ /* XXX: attach to the specified target rectangle */
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
wl_surface_attach (priv->surface, buffer, 0, 0); wl_surface_attach (priv->surface, buffer, 0, 0);
wl_surface_damage (priv->surface, 0, 0, width, height); wl_surface_damage (priv->surface, 0, 0, width, height);
@ -510,7 +508,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window,
wl_surface_commit (priv->surface); wl_surface_commit (priv->surface);
wl_display_flush (wl_display); wl_display_flush (wl_display);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
return TRUE; return TRUE;
} }
@ -539,14 +537,10 @@ gst_vaapi_window_wayland_unblock_cancel (GstVaapiWindow * window)
static void static void
gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass) gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass)
{ {
GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); GObjectClass *const object_class = G_OBJECT_CLASS (klass);
GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass);
gst_vaapi_window_class_init (&klass->parent_class); object_class->finalize = gst_vaapi_window_wayland_finalize;
klass->parent_finalize = object_class->finalize;
object_class->finalize = (GstVaapiObjectFinalizeFunc)
gst_vaapi_window_wayland_destroy;
window_class->create = gst_vaapi_window_wayland_create; window_class->create = gst_vaapi_window_wayland_create;
window_class->show = gst_vaapi_window_wayland_show; window_class->show = gst_vaapi_window_wayland_show;
@ -558,11 +552,10 @@ gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass)
window_class->unblock_cancel = gst_vaapi_window_wayland_unblock_cancel; window_class->unblock_cancel = gst_vaapi_window_wayland_unblock_cancel;
} }
#define gst_vaapi_window_wayland_finalize \ static void
gst_vaapi_window_wayland_destroy gst_vaapi_window_wayland_init (GstVaapiWindowWayland * window)
{
GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowWayland, }
gst_vaapi_window_wayland, gst_vaapi_window_wayland_class_init (&g_class));
/** /**
* gst_vaapi_window_wayland_new: * gst_vaapi_window_wayland_new:
@ -580,11 +573,8 @@ GstVaapiWindow *
gst_vaapi_window_wayland_new (GstVaapiDisplay * display, gst_vaapi_window_wayland_new (GstVaapiDisplay * display,
guint width, guint height) guint width, guint height)
{ {
GST_DEBUG ("new window, size %ux%u", width, height);
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_WAYLAND (display), NULL); g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_WAYLAND (display), NULL);
return gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_WAYLAND, display,
(gst_vaapi_window_wayland_class ()), display, GST_VAAPI_ID_INVALID, width, GST_VAAPI_ID_INVALID, width, height);
height);
} }

View file

@ -24,17 +24,31 @@
#ifndef GST_VAAPI_WINDOW_WAYLAND_H #ifndef GST_VAAPI_WINDOW_WAYLAND_H
#define GST_VAAPI_WINDOW_WAYLAND_H #define GST_VAAPI_WINDOW_WAYLAND_H
#include <gst/gst.h>
#include <gst/vaapi/gstvaapidisplay.h> #include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapiwindow.h> #include <gst/vaapi/gstvaapiwindow.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_VAAPI_WINDOW_WAYLAND (gst_vaapi_window_wayland_get_type ())
#define GST_VAAPI_WINDOW_WAYLAND(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_WAYLAND, GstVaapiWindowWayland))
#define GST_VAAPI_IS_WINDOW_WAYLAND(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_WAYLAND))
typedef struct _GstVaapiWindowWayland GstVaapiWindowWayland; typedef struct _GstVaapiWindowWayland GstVaapiWindowWayland;
GType
gst_vaapi_window_wayland_get_type (void) G_GNUC_CONST;
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_wayland_new (GstVaapiDisplay * display, guint width, gst_vaapi_window_wayland_new (GstVaapiDisplay * display, guint width,
guint height); guint height);
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstVaapiWindowWayland, gst_object_unref)
#endif
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_WINDOW_WAYLAND_H */ #endif /* GST_VAAPI_WINDOW_WAYLAND_H */

View file

@ -43,6 +43,12 @@
#define DEBUG 1 #define DEBUG 1
#include "gstvaapidebug.h" #include "gstvaapidebug.h"
#define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_X11, GstVaapiWindowX11Class))
G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiWindowX11, gst_vaapi_window_x11,
GST_TYPE_VAAPI_WINDOW);
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */ #define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
@ -52,13 +58,13 @@ send_wmspec_change_state (GstVaapiWindow * window, Atom state, gboolean add)
{ {
GstVaapiWindowX11Private *const priv = GstVaapiWindowX11Private *const priv =
GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); GST_VAAPI_WINDOW_X11_GET_PRIVATE (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
XClientMessageEvent xclient; XClientMessageEvent xclient;
memset (&xclient, 0, sizeof (xclient)); memset (&xclient, 0, sizeof (xclient));
xclient.type = ClientMessage; xclient.type = ClientMessage;
xclient.window = GST_VAAPI_OBJECT_ID (window); xclient.window = GST_VAAPI_WINDOW_ID (window);
xclient.message_type = priv->atom_NET_WM_STATE; xclient.message_type = priv->atom_NET_WM_STATE;
xclient.format = 32; xclient.format = 32;
@ -77,15 +83,15 @@ send_wmspec_change_state (GstVaapiWindow * window, Atom state, gboolean add)
static void static void
wait_event (GstVaapiWindow * window, int type) wait_event (GstVaapiWindow * window, int type)
{ {
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
const Window xid = GST_VAAPI_OBJECT_ID (window); const Window xid = GST_VAAPI_WINDOW_ID (window);
XEvent e; XEvent e;
Bool got_event; Bool got_event;
for (;;) { for (;;) {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
got_event = XCheckTypedWindowEvent (dpy, xid, type, &e); got_event = XCheckTypedWindowEvent (dpy, xid, type, &e);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (got_event) if (got_event)
break; break;
g_usleep (10); g_usleep (10);
@ -96,8 +102,8 @@ static gboolean
timed_wait_event (GstVaapiWindow * window, int type, guint64 end_time, timed_wait_event (GstVaapiWindow * window, int type, guint64 end_time,
XEvent * e) XEvent * e)
{ {
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
const Window xid = GST_VAAPI_OBJECT_ID (window); const Window xid = GST_VAAPI_WINDOW_ID (window);
XEvent tmp_event; XEvent tmp_event;
GTimeVal now; GTimeVal now;
guint64 now_time; guint64 now_time;
@ -106,17 +112,17 @@ timed_wait_event (GstVaapiWindow * window, int type, guint64 end_time,
if (!e) if (!e)
e = &tmp_event; e = &tmp_event;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
got_event = XCheckTypedWindowEvent (dpy, xid, type, e); got_event = XCheckTypedWindowEvent (dpy, xid, type, e);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (got_event) if (got_event)
return TRUE; return TRUE;
do { do {
g_usleep (10); g_usleep (10);
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
got_event = XCheckTypedWindowEvent (dpy, xid, type, e); got_event = XCheckTypedWindowEvent (dpy, xid, type, e);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (got_event) if (got_event)
return TRUE; return TRUE;
g_get_current_time (&now); g_get_current_time (&now);
@ -130,15 +136,15 @@ gst_vaapi_window_x11_show (GstVaapiWindow * window)
{ {
GstVaapiWindowX11Private *const priv = GstVaapiWindowX11Private *const priv =
GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); GST_VAAPI_WINDOW_X11_GET_PRIVATE (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
const Window xid = GST_VAAPI_OBJECT_ID (window); const Window xid = GST_VAAPI_WINDOW_ID (window);
XWindowAttributes wattr; XWindowAttributes wattr;
gboolean has_errors; gboolean has_errors;
if (priv->is_mapped) if (priv->is_mapped)
return TRUE; return TRUE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
x11_trap_errors (); x11_trap_errors ();
if (window->use_foreign_window) { if (window->use_foreign_window) {
XGetWindowAttributes (dpy, xid, &wattr); XGetWindowAttributes (dpy, xid, &wattr);
@ -147,17 +153,17 @@ gst_vaapi_window_x11_show (GstVaapiWindow * window)
} }
XMapWindow (dpy, xid); XMapWindow (dpy, xid);
has_errors = x11_untrap_errors () != 0; has_errors = x11_untrap_errors () != 0;
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (!has_errors) { if (!has_errors) {
wait_event (window, MapNotify); wait_event (window, MapNotify);
if (window->use_foreign_window && if (window->use_foreign_window &&
!(wattr.your_event_mask & StructureNotifyMask)) { !(wattr.your_event_mask & StructureNotifyMask)) {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
x11_trap_errors (); x11_trap_errors ();
XSelectInput (dpy, xid, wattr.your_event_mask); XSelectInput (dpy, xid, wattr.your_event_mask);
has_errors = x11_untrap_errors () != 0; has_errors = x11_untrap_errors () != 0;
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
priv->is_mapped = TRUE; priv->is_mapped = TRUE;
@ -172,15 +178,15 @@ gst_vaapi_window_x11_hide (GstVaapiWindow * window)
{ {
GstVaapiWindowX11Private *const priv = GstVaapiWindowX11Private *const priv =
GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); GST_VAAPI_WINDOW_X11_GET_PRIVATE (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
const Window xid = GST_VAAPI_OBJECT_ID (window); const Window xid = GST_VAAPI_WINDOW_ID (window);
XWindowAttributes wattr; XWindowAttributes wattr;
gboolean has_errors; gboolean has_errors;
if (!priv->is_mapped) if (!priv->is_mapped)
return TRUE; return TRUE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
x11_trap_errors (); x11_trap_errors ();
if (window->use_foreign_window) { if (window->use_foreign_window) {
XGetWindowAttributes (dpy, xid, &wattr); XGetWindowAttributes (dpy, xid, &wattr);
@ -189,17 +195,17 @@ gst_vaapi_window_x11_hide (GstVaapiWindow * window)
} }
XUnmapWindow (dpy, xid); XUnmapWindow (dpy, xid);
has_errors = x11_untrap_errors () != 0; has_errors = x11_untrap_errors () != 0;
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (!has_errors) { if (!has_errors) {
wait_event (window, UnmapNotify); wait_event (window, UnmapNotify);
if (window->use_foreign_window && if (window->use_foreign_window &&
!(wattr.your_event_mask & StructureNotifyMask)) { !(wattr.your_event_mask & StructureNotifyMask)) {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
x11_trap_errors (); x11_trap_errors ();
XSelectInput (dpy, xid, wattr.your_event_mask); XSelectInput (dpy, xid, wattr.your_event_mask);
has_errors = x11_untrap_errors () != 0; has_errors = x11_untrap_errors () != 0;
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
priv->is_mapped = FALSE; priv->is_mapped = FALSE;
} }
@ -212,9 +218,9 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width,
{ {
GstVaapiWindowX11Private *const priv = GstVaapiWindowX11Private *const priv =
GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); GST_VAAPI_WINDOW_X11_GET_PRIVATE (window);
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (window); GstVaapiDisplay *const display = GST_VAAPI_WINDOW_DISPLAY (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
Window xid = GST_VAAPI_OBJECT_ID (window); Window xid = GST_VAAPI_WINDOW_ID (window);
guint vid = 0; guint vid = 0;
Colormap cmap = None; Colormap cmap = None;
const GstVaapiDisplayClass *display_class; const GstVaapiDisplayClass *display_class;
@ -229,14 +235,14 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width,
}; };
priv->has_xrender = priv->has_xrender =
GST_VAAPI_DISPLAY_HAS_XRENDER (GST_VAAPI_OBJECT_DISPLAY (window)); GST_VAAPI_DISPLAY_HAS_XRENDER (GST_VAAPI_WINDOW_DISPLAY (window));
if (window->use_foreign_window && xid) { if (window->use_foreign_window && xid) {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
XGetWindowAttributes (dpy, xid, &wattr); XGetWindowAttributes (dpy, xid, &wattr);
priv->is_mapped = wattr.map_state == IsViewable; priv->is_mapped = wattr.map_state == IsViewable;
ok = x11_get_geometry (dpy, xid, NULL, NULL, width, height, NULL); ok = x11_get_geometry (dpy, xid, NULL, NULL, width, height, NULL);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
return ok; return ok;
} }
@ -256,7 +262,7 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width,
cmap = window_class->get_colormap (window); cmap = window_class->get_colormap (window);
} }
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
XInternAtoms (dpy, XInternAtoms (dpy,
(char **) atom_names, G_N_ELEMENTS (atom_names), False, atoms); (char **) atom_names, G_N_ELEMENTS (atom_names), False, atoms);
priv->atom_NET_WM_STATE = atoms[0]; priv->atom_NET_WM_STATE = atoms[0];
@ -265,54 +271,54 @@ gst_vaapi_window_x11_create (GstVaapiWindow * window, guint * width,
xid = x11_create_window (dpy, *width, *height, vid, cmap); xid = x11_create_window (dpy, *width, *height, vid, cmap);
if (xid) if (xid)
XRaiseWindow (dpy, xid); XRaiseWindow (dpy, xid);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
GST_DEBUG ("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (xid)); GST_DEBUG ("xid %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (xid));
GST_VAAPI_OBJECT_ID (window) = xid; GST_VAAPI_WINDOW_ID (window) = xid;
return xid != None; return xid != None;
} }
static void static void
gst_vaapi_window_x11_destroy (GstVaapiWindow * window) gst_vaapi_window_x11_finalize (GObject * object)
{ {
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); GstVaapiWindow *window = GST_VAAPI_WINDOW (object);
const Window xid = GST_VAAPI_OBJECT_ID (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
const Window xid = GST_VAAPI_WINDOW_ID (window);
#if HAVE_XRENDER #if HAVE_XRENDER
GstVaapiWindowX11Private *const priv = GstVaapiWindowX11Private *const priv =
GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); GST_VAAPI_WINDOW_X11_GET_PRIVATE (window);
if (priv->picture) { if (priv->picture) {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
XRenderFreePicture (dpy, priv->picture); XRenderFreePicture (dpy, priv->picture);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
priv->picture = None; priv->picture = None;
} }
#endif #endif
if (xid) { if (xid) {
if (!window->use_foreign_window) { if (!window->use_foreign_window) {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
XDestroyWindow (dpy, xid); XDestroyWindow (dpy, xid);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
} }
GST_VAAPI_OBJECT_ID (window) = None; GST_VAAPI_WINDOW_ID (window) = None;
} }
GST_VAAPI_WINDOW_X11_GET_CLASS (window)->parent_finalize (GST_VAAPI_OBJECT G_OBJECT_CLASS (gst_vaapi_window_x11_parent_class)->finalize (object);
(window));
} }
static gboolean static gboolean
gst_vaapi_window_x11_get_geometry (GstVaapiWindow * window, gst_vaapi_window_x11_get_geometry (GstVaapiWindow * window,
gint * px, gint * py, guint * pwidth, guint * pheight) gint * px, gint * py, guint * pwidth, guint * pheight)
{ {
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
const Window xid = GST_VAAPI_OBJECT_ID (window); const Window xid = GST_VAAPI_WINDOW_ID (window);
gboolean success; gboolean success;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
success = x11_get_geometry (dpy, xid, px, py, pwidth, pheight, NULL); success = x11_get_geometry (dpy, xid, px, py, pwidth, pheight, NULL);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
return success; return success;
} }
@ -322,15 +328,15 @@ gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window,
{ {
GstVaapiWindowX11Private *const priv = GstVaapiWindowX11Private *const priv =
GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); GST_VAAPI_WINDOW_X11_GET_PRIVATE (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
const Window xid = GST_VAAPI_OBJECT_ID (window); const Window xid = GST_VAAPI_WINDOW_ID (window);
XEvent e; XEvent e;
guint width, height; guint width, height;
gboolean has_errors; gboolean has_errors;
GTimeVal now; GTimeVal now;
guint64 end_time; guint64 end_time;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
x11_trap_errors (); x11_trap_errors ();
if (fullscreen) { if (fullscreen) {
if (!priv->is_mapped) { if (!priv->is_mapped) {
@ -357,7 +363,7 @@ gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window,
} }
XSync (dpy, False); XSync (dpy, False);
has_errors = x11_untrap_errors () != 0; has_errors = x11_untrap_errors () != 0;
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (has_errors) if (has_errors)
return FALSE; return FALSE;
@ -368,7 +374,7 @@ gst_vaapi_window_x11_set_fullscreen (GstVaapiWindow * window,
end_time = DELAY + ((guint64) now.tv_sec * 1000000 + now.tv_usec); end_time = DELAY + ((guint64) now.tv_sec * 1000000 + now.tv_usec);
while (timed_wait_event (window, ConfigureNotify, end_time, &e)) { while (timed_wait_event (window, ConfigureNotify, end_time, &e)) {
if (fullscreen) { if (fullscreen) {
gst_vaapi_display_get_size (GST_VAAPI_OBJECT_DISPLAY (window), gst_vaapi_display_get_size (GST_VAAPI_WINDOW_DISPLAY (window),
&width, &height); &width, &height);
if (e.xconfigure.width == width && e.xconfigure.height == height) if (e.xconfigure.width == width && e.xconfigure.height == height)
return TRUE; return TRUE;
@ -387,15 +393,15 @@ gst_vaapi_window_x11_resize (GstVaapiWindow * window, guint width, guint height)
{ {
gboolean has_errors; gboolean has_errors;
if (!GST_VAAPI_OBJECT_ID (window)) if (!GST_VAAPI_WINDOW_ID (window))
return FALSE; return FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
x11_trap_errors (); x11_trap_errors ();
XResizeWindow (GST_VAAPI_OBJECT_NATIVE_DISPLAY (window), XResizeWindow (GST_VAAPI_WINDOW_NATIVE_DISPLAY (window),
GST_VAAPI_OBJECT_ID (window), width, height); GST_VAAPI_WINDOW_ID (window), width, height);
has_errors = x11_untrap_errors () != 0; has_errors = x11_untrap_errors () != 0;
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
return !has_errors; return !has_errors;
} }
@ -407,10 +413,10 @@ gst_vaapi_window_x11_put_surface (GstVaapiWindow * window,
{ {
VAStatus status; VAStatus status;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
status = vaPutSurface (GST_VAAPI_OBJECT_VADISPLAY (window), status = vaPutSurface (GST_VAAPI_WINDOW_VADISPLAY (window),
surface_id, surface_id,
GST_VAAPI_OBJECT_ID (window), GST_VAAPI_WINDOW_ID (window),
src_rect->x, src_rect->x,
src_rect->y, src_rect->y,
src_rect->width, src_rect->width,
@ -421,7 +427,7 @@ gst_vaapi_window_x11_put_surface (GstVaapiWindow * window,
dst_rect->height, NULL, 0, from_GstVaapiSurfaceRenderFlags (flags) dst_rect->height, NULL, 0, from_GstVaapiSurfaceRenderFlags (flags)
); );
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
return status; return status;
} }
@ -498,8 +504,8 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window,
#if HAVE_XRENDER #if HAVE_XRENDER
GstVaapiWindowX11Private *const priv = GstVaapiWindowX11Private *const priv =
GST_VAAPI_WINDOW_X11_GET_PRIVATE (window); GST_VAAPI_WINDOW_X11_GET_PRIVATE (window);
Display *const dpy = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); Display *const dpy = GST_VAAPI_WINDOW_NATIVE_DISPLAY (window);
const Window win = GST_VAAPI_OBJECT_ID (window); const Window win = GST_VAAPI_WINDOW_ID (window);
const Pixmap pix = GST_VAAPI_OBJECT_ID (pixmap); const Pixmap pix = GST_VAAPI_OBJECT_ID (pixmap);
Picture picture; Picture picture;
XRenderPictFormat *pic_fmt; XRenderPictFormat *pic_fmt;
@ -509,12 +515,12 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window,
/* Ensure Picture for window is created */ /* Ensure Picture for window is created */
if (!priv->picture) { if (!priv->picture) {
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
XGetWindowAttributes (dpy, win, &wattr); XGetWindowAttributes (dpy, win, &wattr);
pic_fmt = XRenderFindVisualFormat (dpy, wattr.visual); pic_fmt = XRenderFindVisualFormat (dpy, wattr.visual);
if (pic_fmt) if (pic_fmt)
priv->picture = XRenderCreatePicture (dpy, win, pic_fmt, 0, NULL); priv->picture = XRenderCreatePicture (dpy, win, pic_fmt, 0, NULL);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
if (!priv->picture) if (!priv->picture)
return FALSE; return FALSE;
} }
@ -529,9 +535,9 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window,
fmt = PictStandardARGB32; fmt = PictStandardARGB32;
op = PictOpOver; op = PictOpOver;
get_pic_fmt: get_pic_fmt:
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
pic_fmt = XRenderFindStandardFormat (dpy, fmt); pic_fmt = XRenderFindStandardFormat (dpy, fmt);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
break; break;
default: default:
pic_fmt = NULL; pic_fmt = NULL;
@ -540,7 +546,7 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window,
if (!pic_fmt) if (!pic_fmt)
return FALSE; return FALSE;
GST_VAAPI_OBJECT_LOCK_DISPLAY (window); GST_VAAPI_WINDOW_LOCK_DISPLAY (window);
do { do {
const double sx = (double) src_rect->width / dst_rect->width; const double sx = (double) src_rect->width / dst_rect->width;
const double sy = (double) src_rect->height / dst_rect->height; const double sy = (double) src_rect->height / dst_rect->height;
@ -569,7 +575,7 @@ gst_vaapi_window_x11_render_pixmap_xrender (GstVaapiWindow * window,
} while (0); } while (0);
if (picture) if (picture)
XRenderFreePicture (dpy, picture); XRenderFreePicture (dpy, picture);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY (window); GST_VAAPI_WINDOW_UNLOCK_DISPLAY (window);
return success; return success;
#endif #endif
return FALSE; return FALSE;
@ -591,17 +597,13 @@ gst_vaapi_window_x11_render_pixmap (GstVaapiWindow * window,
return FALSE; return FALSE;
} }
void static void
gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass) gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass)
{ {
GstVaapiObjectClass *const object_class = GST_VAAPI_OBJECT_CLASS (klass); GObjectClass *const object_class = G_OBJECT_CLASS (klass);
GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass); GstVaapiWindowClass *const window_class = GST_VAAPI_WINDOW_CLASS (klass);
gst_vaapi_window_class_init (&klass->parent_class); object_class->finalize = gst_vaapi_window_x11_finalize;
klass->parent_finalize = object_class->finalize;
object_class->finalize = (GstVaapiObjectFinalizeFunc)
gst_vaapi_window_x11_destroy;
window_class->create = gst_vaapi_window_x11_create; window_class->create = gst_vaapi_window_x11_create;
window_class->show = gst_vaapi_window_x11_show; window_class->show = gst_vaapi_window_x11_show;
@ -613,11 +615,10 @@ gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass)
window_class->render_pixmap = gst_vaapi_window_x11_render_pixmap; window_class->render_pixmap = gst_vaapi_window_x11_render_pixmap;
} }
#define gst_vaapi_window_x11_finalize \ static void
gst_vaapi_window_x11_destroy gst_vaapi_window_x11_init (GstVaapiWindowX11 * window)
{
GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowX11, }
gst_vaapi_window_x11, gst_vaapi_window_x11_class_init (&g_class));
/** /**
* gst_vaapi_window_x11_new: * gst_vaapi_window_x11_new:
@ -634,14 +635,10 @@ GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE (GstVaapiWindowX11,
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height) gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height)
{ {
GST_DEBUG ("new window, size %ux%u", width, height);
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL);
return return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_X11, display,
gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS GST_VAAPI_ID_INVALID, width, height);
(gst_vaapi_window_x11_class ()), display, GST_VAAPI_ID_INVALID, width,
height);
} }
/** /**
@ -659,13 +656,11 @@ gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height)
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_x11_new_with_xid (GstVaapiDisplay * display, Window xid) gst_vaapi_window_x11_new_with_xid (GstVaapiDisplay * display, Window xid)
{ {
GST_DEBUG ("new window from xid 0x%08x", (guint) xid);
g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL); g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL);
g_return_val_if_fail (xid != None, NULL); g_return_val_if_fail (xid != None, NULL);
return gst_vaapi_window_new_internal (GST_VAAPI_WINDOW_CLASS return gst_vaapi_window_new_internal (GST_TYPE_VAAPI_WINDOW_X11, display,
(gst_vaapi_window_x11_class ()), display, xid, 0, 0); xid, 0, 0);
} }
/** /**
@ -681,9 +676,9 @@ gst_vaapi_window_x11_new_with_xid (GstVaapiDisplay * display, Window xid)
Window Window
gst_vaapi_window_x11_get_xid (GstVaapiWindowX11 * window) gst_vaapi_window_x11_get_xid (GstVaapiWindowX11 * window)
{ {
g_return_val_if_fail (window != NULL, None); g_return_val_if_fail (GST_VAAPI_IS_WINDOW_X11 (window), None);
return GST_VAAPI_OBJECT_ID (window); return GST_VAAPI_WINDOW_ID (window);
} }
/** /**
@ -698,7 +693,7 @@ gst_vaapi_window_x11_get_xid (GstVaapiWindowX11 * window)
gboolean gboolean
gst_vaapi_window_x11_is_foreign_xid (GstVaapiWindowX11 * window) gst_vaapi_window_x11_is_foreign_xid (GstVaapiWindowX11 * window)
{ {
g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GST_VAAPI_IS_WINDOW_X11 (window), FALSE);
return GST_VAAPI_WINDOW (window)->use_foreign_window; return GST_VAAPI_WINDOW (window)->use_foreign_window;
} }

View file

@ -26,13 +26,17 @@
#define GST_VAAPI_WINDOW_X11_H #define GST_VAAPI_WINDOW_X11_H
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <gst/gst.h>
#include <gst/vaapi/gstvaapidisplay.h> #include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapiwindow.h> #include <gst/vaapi/gstvaapiwindow.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_VAAPI_WINDOW_X11 (gst_vaapi_window_x11_get_type ())
#define GST_VAAPI_WINDOW_X11(obj) \ #define GST_VAAPI_WINDOW_X11(obj) \
((GstVaapiWindowX11 *)(obj)) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VAAPI_WINDOW_X11, GstVaapiWindowX11))
#define GST_VAAPI_IS_WINDOW_X11(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_WINDOW_X11))
/** /**
* GST_VAAPI_WINDOW_XWINDOW: * GST_VAAPI_WINDOW_XWINDOW:
@ -41,10 +45,13 @@ G_BEGIN_DECLS
* Macro that evaluates to the underlying X11 #Window of @window * Macro that evaluates to the underlying X11 #Window of @window
*/ */
#define GST_VAAPI_WINDOW_XWINDOW(window) \ #define GST_VAAPI_WINDOW_XWINDOW(window) \
gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(window)) gst_vaapi_window_x11_get_xid (GST_VAAPI_WINDOW_X11 (window))
typedef struct _GstVaapiWindowX11 GstVaapiWindowX11; typedef struct _GstVaapiWindowX11 GstVaapiWindowX11;
GType
gst_vaapi_window_x11_get_type (void) G_GNUC_CONST;
GstVaapiWindow * GstVaapiWindow *
gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height); gst_vaapi_window_x11_new (GstVaapiDisplay * display, guint width, guint height);

View file

@ -33,14 +33,12 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_VAAPI_WINDOW_X11_CAST(obj) ((GstVaapiWindowX11 *)(obj))
#define GST_VAAPI_WINDOW_X11_GET_PRIVATE(obj) \ #define GST_VAAPI_WINDOW_X11_GET_PRIVATE(obj) \
(&GST_VAAPI_WINDOW_X11(obj)->priv) gst_vaapi_window_x11_get_instance_private (GST_VAAPI_WINDOW_X11_CAST (obj))
#define GST_VAAPI_WINDOW_X11_CLASS(klass) \
((GstVaapiWindowX11Class *)(klass))
#define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \ #define GST_VAAPI_WINDOW_X11_GET_CLASS(obj) \
GST_VAAPI_WINDOW_X11_CLASS(GST_VAAPI_WINDOW_GET_CLASS(obj)) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VAAPI_WINDOW_X11, GstVaapiWindowX11Class))
typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private; typedef struct _GstVaapiWindowX11Private GstVaapiWindowX11Private;
typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class; typedef struct _GstVaapiWindowX11Class GstVaapiWindowX11Class;
@ -67,8 +65,6 @@ struct _GstVaapiWindowX11
{ {
/*< private >*/ /*< private >*/
GstVaapiWindow parent_instance; GstVaapiWindow parent_instance;
GstVaapiWindowX11Private priv;
}; };
/** /**
@ -80,12 +76,8 @@ struct _GstVaapiWindowX11Class
{ {
/*< private >*/ /*< private >*/
GstVaapiWindowClass parent_class; GstVaapiWindowClass parent_class;
GstVaapiObjectFinalizeFunc parent_finalize;
}; };
void
gst_vaapi_window_x11_class_init (GstVaapiWindowX11Class * klass);
G_END_DECLS G_END_DECLS
#endif /* GST_VAAPI_WINDOW_X11_PRIV_H */ #endif /* GST_VAAPI_WINDOW_X11_PRIV_H */