From: gb Date: Wed, 17 Mar 2010 07:59:31 +0000 (+0000) Subject: Add VA display locking utilities. X-Git-Tag: accepted/trunk/20120822.173359~699 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bcb5d3f13877e497974e5fa7432f9b4a55a12216;p=profile%2Fivi%2Fgstreamer-vaapi.git Add VA display locking utilities. --- diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index d9feb7c..ad3f2a6 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -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) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index cccb095..de142c9 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -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); diff --git a/gst-libs/gst/vaapi/gstvaapiimage.c b/gst-libs/gst/vaapi/gstvaapiimage.c index d18271d..7d9027b 100644 --- a/gst-libs/gst/vaapi/gstvaapiimage.c +++ b/gst-libs/gst/vaapi/gstvaapiimage.c @@ -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; diff --git a/gst-libs/gst/vaapi/gstvaapisubpicture.c b/gst-libs/gst/vaapi/gstvaapisubpicture.c index df82ed3..e74bfdd 100644 --- a/gst-libs/gst/vaapi/gstvaapisubpicture.c +++ b/gst-libs/gst/vaapi/gstvaapisubpicture.c @@ -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; diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c index db3dd20..40b5cde 100644 --- a/gst-libs/gst/vaapi/gstvaapisurface.c +++ b/gst-libs/gst/vaapi/gstvaapisurface.c @@ -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; diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c index 2b85b70..63526d3 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_x11.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_x11.c @@ -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;