GstVaapiDisplayPrivate))
struct _GstVaapiDisplayPrivate {
+ GStaticMutex mutex;
VADisplay display;
gboolean create_display;
VAProfile *profiles;
}
static void
+gst_vaapi_display_lock_default(GstVaapiDisplay *display)
+{
+ g_static_mutex_lock(&display->priv->mutex);
+}
+
+static void
+gst_vaapi_display_unlock_default(GstVaapiDisplay *display)
+{
+ g_static_mutex_unlock(&display->priv->mutex);
+}
+
+static void
gst_vaapi_display_finalize(GObject *object)
{
GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object);
gst_vaapi_display_class_init(GstVaapiDisplayClass *klass)
{
GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass);
GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi, "vaapi", 0, "VA-API helper");
g_type_class_add_private(klass, sizeof(GstVaapiDisplayPrivate));
- object_class->finalize = gst_vaapi_display_finalize;
- object_class->set_property = gst_vaapi_display_set_property;
- object_class->get_property = gst_vaapi_display_get_property;
- object_class->constructed = gst_vaapi_display_constructed;
+ object_class->finalize = gst_vaapi_display_finalize;
+ object_class->set_property = gst_vaapi_display_set_property;
+ object_class->get_property = gst_vaapi_display_get_property;
+ object_class->constructed = gst_vaapi_display_constructed;
+
+ dpy_class->lock_display = gst_vaapi_display_lock_default;
+ dpy_class->unlock_display = gst_vaapi_display_unlock_default;
g_object_class_install_property
(object_class,
priv->subpicture_formats = NULL;
priv->subpicture_flags = NULL;
priv->num_subpicture_formats = 0;
+
+ g_static_mutex_init(&priv->mutex);
}
GstVaapiDisplay *
NULL);
}
+void
+gst_vaapi_display_lock(GstVaapiDisplay *display)
+{
+ GstVaapiDisplayClass *klass;
+
+ g_return_if_fail(GST_VAAPI_IS_DISPLAY(display));
+
+ klass = GST_VAAPI_DISPLAY_GET_CLASS(display);
+ if (klass->lock_display)
+ klass->lock_display(display);
+}
+
+void
+gst_vaapi_display_unlock(GstVaapiDisplay *display)
+{
+ GstVaapiDisplayClass *klass;
+
+ g_return_if_fail(GST_VAAPI_IS_DISPLAY(display));
+
+ klass = GST_VAAPI_DISPLAY_GET_CLASS(display);
+ if (klass->unlock_display)
+ klass->unlock_display(display);
+}
+
VADisplay
gst_vaapi_display_get_display(GstVaapiDisplay *display)
{
#define GST_VAAPI_DISPLAY_VADISPLAY(display) \
gst_vaapi_display_get_display(display)
+#define GST_VAAPI_DISPLAY_LOCK(display) \
+ gst_vaapi_display_lock(display)
+
+#define GST_VAAPI_DISPLAY_UNLOCK(display) \
+ gst_vaapi_display_unlock(display)
+
typedef struct _GstVaapiDisplay GstVaapiDisplay;
typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate;
typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass;
/*< private >*/
GObjectClass parent_class;
- gboolean (*open_display) (GstVaapiDisplay *display);
- void (*close_display)(GstVaapiDisplay *display);
- VADisplay (*get_display) (GstVaapiDisplay *display);
+ gboolean (*open_display) (GstVaapiDisplay *display);
+ void (*close_display) (GstVaapiDisplay *display);
+ void (*lock_display) (GstVaapiDisplay *display);
+ void (*unlock_display)(GstVaapiDisplay *display);
+ VADisplay (*get_display) (GstVaapiDisplay *display);
};
GType
GstVaapiDisplay *
gst_vaapi_display_new_with_display(VADisplay va_display);
+void
+gst_vaapi_display_lock(GstVaapiDisplay *display);
+
+void
+gst_vaapi_display_unlock(GstVaapiDisplay *display);
+
VADisplay
gst_vaapi_display_get_display(GstVaapiDisplay *display);
gst_vaapi_image_destroy(GstVaapiImage *image)
{
GstVaapiImagePrivate * const priv = image->priv;
- VADisplay dpy = gst_vaapi_display_get_display(priv->display);
VAStatus status;
gst_vaapi_image_unmap(image);
if (priv->image.image_id != VA_INVALID_ID) {
- status = vaDestroyImage(dpy, priv->image.image_id);
+ GST_VAAPI_DISPLAY_LOCK(priv->display);
+ status = vaDestroyImage(
+ GST_VAAPI_DISPLAY_VADISPLAY(priv->display),
+ priv->image.image_id
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(priv->display);
if (!vaapi_check_status(status, "vaDestroyImage()"))
g_warning("failed to destroy image 0x%08x\n", priv->image.image_id);
priv->image.image_id = VA_INVALID_ID;
if (!va_format)
return FALSE;
+ GST_VAAPI_DISPLAY_LOCK(priv->display);
status = vaCreateImage(
- gst_vaapi_display_get_display(priv->display),
+ GST_VAAPI_DISPLAY_VADISPLAY(priv->display),
(VAImageFormat *)va_format,
priv->width,
priv->height,
&priv->image
);
+ GST_VAAPI_DISPLAY_UNLOCK(priv->display);
return (status == VA_STATUS_SUCCESS &&
priv->image.format.fourcc == va_format->fourcc);
}
if (_gst_vaapi_image_is_mapped(image))
return TRUE;
+ GST_VAAPI_DISPLAY_LOCK(image->priv->display);
status = vaMapBuffer(
- gst_vaapi_display_get_display(image->priv->display),
+ GST_VAAPI_DISPLAY_VADISPLAY(image->priv->display),
image->priv->image.buf,
&image_data
);
+ GST_VAAPI_DISPLAY_UNLOCK(image->priv->display);
if (!vaapi_check_status(status, "vaMapBuffer()"))
return FALSE;
if (!_gst_vaapi_image_is_mapped(image))
return FALSE;
+ GST_VAAPI_DISPLAY_LOCK(image->priv->display);
status = vaUnmapBuffer(
- gst_vaapi_display_get_display(image->priv->display),
+ GST_VAAPI_DISPLAY_VADISPLAY(image->priv->display),
image->priv->image.buf
);
+ GST_VAAPI_DISPLAY_UNLOCK(image->priv->display);
if (!vaapi_check_status(status, "vaUnmapBuffer()"))
return FALSE;
if (priv->subpicture_id != VA_INVALID_ID) {
display = gst_vaapi_image_get_display(priv->image);
if (display) {
+ GST_VAAPI_DISPLAY_LOCK(display);
status = vaDestroySubpicture(
- gst_vaapi_display_get_display(display),
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
priv->subpicture_id
);
+ GST_VAAPI_DISPLAY_UNLOCK(display);
if (!vaapi_check_status(status, "vaDestroySubpicture()"))
g_warning("failed to destroy subpicture 0x%08x\n",
priv->subpicture_id);
if (!display)
return FALSE;
+ GST_VAAPI_DISPLAY_LOCK(display);
status = vaCreateSubpicture(
- gst_vaapi_display_get_display(display),
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
gst_vaapi_image_get_id(priv->image),
&subpicture_id
);
+ GST_VAAPI_DISPLAY_UNLOCK(display);
if (!vaapi_check_status(status, "vaCreateSubpicture()"))
return FALSE;
gst_vaapi_surface_destroy(GstVaapiSurface *surface)
{
GstVaapiSurfacePrivate * const priv = surface->priv;
- VADisplay dpy = GST_VAAPI_DISPLAY_VADISPLAY(priv->display);
VAStatus status;
if (priv->surface_id != VA_INVALID_SURFACE) {
- status = vaDestroySurfaces(dpy, &priv->surface_id, 1);
+ GST_VAAPI_DISPLAY_LOCK(priv->display);
+ status = vaDestroySurfaces(
+ GST_VAAPI_DISPLAY_VADISPLAY(priv->display),
+ &priv->surface_id, 1
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(priv->display);
if (!vaapi_check_status(status, "vaDestroySurfaces()"))
g_warning("failed to destroy surface 0x%08x\n", priv->surface_id);
priv->surface_id = VA_INVALID_SURFACE;
return FALSE;
}
+ GST_VAAPI_DISPLAY_LOCK(priv->display);
status = vaCreateSurfaces(
GST_VAAPI_DISPLAY_VADISPLAY(priv->display),
priv->width,
format,
1, &surface_id
);
+ GST_VAAPI_DISPLAY_UNLOCK(priv->display);
if (!vaapi_check_status(status, "vaCreateSurfaces()"))
return FALSE;
priv->surface_id = VA_INVALID_SURFACE;
priv->width = 0;
priv->height = 0;
- priv->chroma_type = 0;
+ priv->chroma_type = 0;
}
GstVaapiSurface *
if (image_id == VA_INVALID_ID)
return FALSE;
+ GST_VAAPI_DISPLAY_LOCK(surface->priv->display);
status = vaGetImage(
GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display),
surface->priv->surface_id,
0, 0, width, height,
image_id
);
+ GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display);
if (!vaapi_check_status(status, "vaGetImage()"))
return FALSE;
if (image_id == VA_INVALID_ID)
return FALSE;
+ GST_VAAPI_DISPLAY_LOCK(surface->priv->display);
status = vaPutImage(
GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display),
surface->priv->surface_id,
0, 0, width, height,
0, 0, width, height
);
+ GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display);
if (!vaapi_check_status(status, "vaPutImage()"))
return FALSE;
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
+ GST_VAAPI_DISPLAY_LOCK(surface->priv->display);
status = vaSyncSurface(
GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display),
surface->priv->surface_id
);
+ GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display);
if (!vaapi_check_status(status, "vaSyncSurface()"))
return FALSE;
{
GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
+ gboolean has_errors;
if (priv->is_visible)
return TRUE;
+ GST_VAAPI_DISPLAY_LOCK(priv->display);
x11_trap_errors();
XMapWindow(dpy, priv->xid);
if (priv->create_window)
x11_wait_event(dpy, priv->xid, MapNotify);
- if (x11_untrap_errors() != 0)
+ has_errors = x11_untrap_errors() != 0;
+ GST_VAAPI_DISPLAY_UNLOCK(priv->display);
+ if (has_errors)
return FALSE;
priv->is_visible = TRUE;
{
GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
+ gboolean has_errors;
if (!priv->is_visible)
return TRUE;
+ GST_VAAPI_DISPLAY_LOCK(priv->display);
x11_trap_errors();
XUnmapWindow(dpy, priv->xid);
if (priv->create_window)
x11_wait_event(dpy, priv->xid, UnmapNotify);
- if (x11_untrap_errors() != 0)
+ has_errors = x11_untrap_errors() != 0;
+ GST_VAAPI_DISPLAY_UNLOCK(priv->display);
+ if (has_errors)
return FALSE;
priv->is_visible = FALSE;
if (!priv->create_window && priv->xid)
return TRUE;
- dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
- priv->xid = x11_create_window(dpy, width, height);
+ dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
- if (!priv->xid)
- return FALSE;
-
- XRaiseWindow(dpy, priv->xid);
- return TRUE;
+ GST_VAAPI_DISPLAY_LOCK(priv->display);
+ priv->xid = x11_create_window(dpy, width, height);
+ if (priv->xid)
+ XRaiseWindow(dpy, priv->xid);
+ GST_VAAPI_DISPLAY_UNLOCK(priv->display);
+ return priv->xid != None;
}
static void
Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
if (priv->xid) {
- if (priv->create_window)
+ if (priv->create_window) {
+ GST_VAAPI_DISPLAY_LOCK(priv->display);
XDestroyWindow(dpy, priv->xid);
+ GST_VAAPI_DISPLAY_UNLOCK(priv->display);
+ }
priv->xid = None;
}
gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height)
{
GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
+ gboolean has_errors;
if (!priv->xid)
return FALSE;
+ GST_VAAPI_DISPLAY_LOCK(priv->display);
x11_trap_errors();
XResizeWindow(
GST_VAAPI_DISPLAY_XDISPLAY(priv->display),
width,
height
);
- if (x11_untrap_errors() != 0)
- return FALSE;
- return TRUE;
+ has_errors = x11_untrap_errors() != 0;
+ GST_VAAPI_DISPLAY_UNLOCK(priv->display);
+ return !has_errors;
}
static gboolean
guint flags
)
{
+ GstVaapiDisplay *display;
VASurfaceID surface_id;
VAStatus status;
unsigned int va_flags = 0;
+ display = gst_vaapi_surface_get_display(surface);
+ if (!display)
+ return FALSE;
+
surface_id = gst_vaapi_surface_get_id(surface);
if (surface_id == VA_INVALID_ID)
return FALSE;
else if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601)
va_flags |= VA_SRC_BT601;
+ GST_VAAPI_DISPLAY_LOCK(display);
status = vaPutSurface(
- GST_VAAPI_DISPLAY_VADISPLAY(gst_vaapi_surface_get_display(surface)),
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
surface_id,
GST_VAAPI_WINDOW_X11(window)->priv->xid,
src_rect->x,
NULL, 0,
va_flags
);
+ GST_VAAPI_DISPLAY_UNLOCK(display);
if (!vaapi_check_status(status, "vaPutSurface()"))
return FALSE;