Add VA display locking utilities.
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Wed, 17 Mar 2010 07:59:31 +0000 (07:59 +0000)
committergb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Wed, 17 Mar 2010 07:59:31 +0000 (07:59 +0000)
gst-libs/gst/vaapi/gstvaapidisplay.c
gst-libs/gst/vaapi/gstvaapidisplay.h
gst-libs/gst/vaapi/gstvaapiimage.c
gst-libs/gst/vaapi/gstvaapisubpicture.c
gst-libs/gst/vaapi/gstvaapisurface.c
gst-libs/gst/vaapi/gstvaapiwindow_x11.c

index d9feb7c..ad3f2a6 100644 (file)
@@ -36,6 +36,7 @@ G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT);
                                  GstVaapiDisplayPrivate))
 
 struct _GstVaapiDisplayPrivate {
+    GStaticMutex        mutex;
     VADisplay           display;
     gboolean            create_display;
     VAProfile          *profiles;
@@ -293,6 +294,18 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
 }
 
 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);
@@ -360,15 +373,19 @@ static void
 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,
@@ -394,6 +411,8 @@ gst_vaapi_display_init(GstVaapiDisplay *display)
     priv->subpicture_formats     = NULL;
     priv->subpicture_flags       = NULL;
     priv->num_subpicture_formats = 0;
+
+    g_static_mutex_init(&priv->mutex);
 }
 
 GstVaapiDisplay *
@@ -404,6 +423,30 @@ gst_vaapi_display_new_with_display(VADisplay va_display)
                         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)
 {
index cccb095..de142c9 100644 (file)
@@ -54,6 +54,12 @@ G_BEGIN_DECLS
 #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;
@@ -69,9 +75,11 @@ struct _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
@@ -80,6 +88,12 @@ gst_vaapi_display_get_type(void);
 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);
 
index d18271d..7d9027b 100644 (file)
@@ -65,13 +65,17 @@ static void
 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;
@@ -97,13 +101,15 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format)
     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);
 }
@@ -467,11 +473,13 @@ gst_vaapi_image_map(GstVaapiImage *image)
     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;
 
@@ -490,10 +498,12 @@ gst_vaapi_image_unmap(GstVaapiImage *image)
     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;
 
index df82ed3..e74bfdd 100644 (file)
@@ -56,10 +56,12 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture)
     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);
@@ -88,11 +90,13 @@ gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture)
     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;
 
index db3dd20..40b5cde 100644 (file)
@@ -55,11 +55,15 @@ static void
 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;
@@ -94,6 +98,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface)
         return FALSE;
     }
 
+    GST_VAAPI_DISPLAY_LOCK(priv->display);
     status = vaCreateSurfaces(
         GST_VAAPI_DISPLAY_VADISPLAY(priv->display),
         priv->width,
@@ -101,6 +106,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface)
         format,
         1, &surface_id
     );
+    GST_VAAPI_DISPLAY_UNLOCK(priv->display);
     if (!vaapi_check_status(status, "vaCreateSurfaces()"))
         return FALSE;
 
@@ -259,7 +265,7 @@ gst_vaapi_surface_init(GstVaapiSurface *surface)
     priv->surface_id    = VA_INVALID_SURFACE;
     priv->width         = 0;
     priv->height        = 0;
-    priv->chroma_type        = 0;
+    priv->chroma_type   = 0;
 }
 
 GstVaapiSurface *
@@ -354,12 +360,14 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image)
     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;
 
@@ -384,6 +392,7 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image)
     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,
@@ -391,6 +400,7 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image)
         0, 0, width, height,
         0, 0, width, height
     );
+    GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display);
     if (!vaapi_check_status(status, "vaPutImage()"))
         return FALSE;
 
@@ -404,10 +414,12 @@ gst_vaapi_surface_sync(GstVaapiSurface *surface)
 
     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;
 
index 2b85b70..63526d3 100644 (file)
@@ -52,15 +52,19 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window)
 {
     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;
@@ -72,15 +76,19 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window)
 {
     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;
@@ -96,14 +104,14 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint width, guint height)
     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
@@ -113,8 +121,11 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window)
     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;
     }
 
@@ -128,10 +139,12 @@ static gboolean
 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),
@@ -139,9 +152,9 @@ gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height)
         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
@@ -153,10 +166,15 @@ gst_vaapi_window_x11_render(
     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;
@@ -173,8 +191,9 @@ gst_vaapi_window_x11_render(
     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,
@@ -188,6 +207,7 @@ gst_vaapi_window_x11_render(
         NULL, 0,
         va_flags
     );
+    GST_VAAPI_DISPLAY_UNLOCK(display);
     if (!vaapi_check_status(status, "vaPutSurface()"))
         return FALSE;