Add VA display locking utilities.

This commit is contained in:
gb 2010-03-17 07:59:31 +00:00
parent 65cc4aa494
commit bcb5d3f138
6 changed files with 134 additions and 31 deletions

View file

@ -36,6 +36,7 @@ G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT);
GstVaapiDisplayPrivate)) GstVaapiDisplayPrivate))
struct _GstVaapiDisplayPrivate { struct _GstVaapiDisplayPrivate {
GStaticMutex mutex;
VADisplay display; VADisplay display;
gboolean create_display; gboolean create_display;
VAProfile *profiles; VAProfile *profiles;
@ -292,6 +293,18 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
return TRUE; return TRUE;
} }
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 static void
gst_vaapi_display_finalize(GObject *object) gst_vaapi_display_finalize(GObject *object)
{ {
@ -360,6 +373,7 @@ static void
gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) gst_vaapi_display_class_init(GstVaapiDisplayClass *klass)
{ {
GObjectClass * const object_class = G_OBJECT_CLASS(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"); GST_DEBUG_CATEGORY_INIT(gst_debug_vaapi, "vaapi", 0, "VA-API helper");
@ -370,6 +384,9 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass)
object_class->get_property = gst_vaapi_display_get_property; object_class->get_property = gst_vaapi_display_get_property;
object_class->constructed = gst_vaapi_display_constructed; 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 g_object_class_install_property
(object_class, (object_class,
PROP_DISPLAY, PROP_DISPLAY,
@ -394,6 +411,8 @@ gst_vaapi_display_init(GstVaapiDisplay *display)
priv->subpicture_formats = NULL; priv->subpicture_formats = NULL;
priv->subpicture_flags = NULL; priv->subpicture_flags = NULL;
priv->num_subpicture_formats = 0; priv->num_subpicture_formats = 0;
g_static_mutex_init(&priv->mutex);
} }
GstVaapiDisplay * GstVaapiDisplay *
@ -404,6 +423,30 @@ gst_vaapi_display_new_with_display(VADisplay va_display)
NULL); 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 VADisplay
gst_vaapi_display_get_display(GstVaapiDisplay *display) gst_vaapi_display_get_display(GstVaapiDisplay *display)
{ {

View file

@ -54,6 +54,12 @@ G_BEGIN_DECLS
#define GST_VAAPI_DISPLAY_VADISPLAY(display) \ #define GST_VAAPI_DISPLAY_VADISPLAY(display) \
gst_vaapi_display_get_display(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 _GstVaapiDisplay GstVaapiDisplay;
typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate;
typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass; typedef struct _GstVaapiDisplayClass GstVaapiDisplayClass;
@ -71,6 +77,8 @@ struct _GstVaapiDisplayClass {
gboolean (*open_display) (GstVaapiDisplay *display); gboolean (*open_display) (GstVaapiDisplay *display);
void (*close_display) (GstVaapiDisplay *display); void (*close_display) (GstVaapiDisplay *display);
void (*lock_display) (GstVaapiDisplay *display);
void (*unlock_display)(GstVaapiDisplay *display);
VADisplay (*get_display) (GstVaapiDisplay *display); VADisplay (*get_display) (GstVaapiDisplay *display);
}; };
@ -80,6 +88,12 @@ gst_vaapi_display_get_type(void);
GstVaapiDisplay * GstVaapiDisplay *
gst_vaapi_display_new_with_display(VADisplay va_display); gst_vaapi_display_new_with_display(VADisplay va_display);
void
gst_vaapi_display_lock(GstVaapiDisplay *display);
void
gst_vaapi_display_unlock(GstVaapiDisplay *display);
VADisplay VADisplay
gst_vaapi_display_get_display(GstVaapiDisplay *display); gst_vaapi_display_get_display(GstVaapiDisplay *display);

View file

@ -65,13 +65,17 @@ static void
gst_vaapi_image_destroy(GstVaapiImage *image) gst_vaapi_image_destroy(GstVaapiImage *image)
{ {
GstVaapiImagePrivate * const priv = image->priv; GstVaapiImagePrivate * const priv = image->priv;
VADisplay dpy = gst_vaapi_display_get_display(priv->display);
VAStatus status; VAStatus status;
gst_vaapi_image_unmap(image); gst_vaapi_image_unmap(image);
if (priv->image.image_id != VA_INVALID_ID) { 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()")) if (!vaapi_check_status(status, "vaDestroyImage()"))
g_warning("failed to destroy image 0x%08x\n", priv->image.image_id); g_warning("failed to destroy image 0x%08x\n", priv->image.image_id);
priv->image.image_id = VA_INVALID_ID; priv->image.image_id = VA_INVALID_ID;
@ -97,13 +101,15 @@ _gst_vaapi_image_create(GstVaapiImage *image, GstVaapiImageFormat format)
if (!va_format) if (!va_format)
return FALSE; return FALSE;
GST_VAAPI_DISPLAY_LOCK(priv->display);
status = vaCreateImage( status = vaCreateImage(
gst_vaapi_display_get_display(priv->display), GST_VAAPI_DISPLAY_VADISPLAY(priv->display),
(VAImageFormat *)va_format, (VAImageFormat *)va_format,
priv->width, priv->width,
priv->height, priv->height,
&priv->image &priv->image
); );
GST_VAAPI_DISPLAY_UNLOCK(priv->display);
return (status == VA_STATUS_SUCCESS && return (status == VA_STATUS_SUCCESS &&
priv->image.format.fourcc == va_format->fourcc); priv->image.format.fourcc == va_format->fourcc);
} }
@ -467,11 +473,13 @@ gst_vaapi_image_map(GstVaapiImage *image)
if (_gst_vaapi_image_is_mapped(image)) if (_gst_vaapi_image_is_mapped(image))
return TRUE; return TRUE;
GST_VAAPI_DISPLAY_LOCK(image->priv->display);
status = vaMapBuffer( status = vaMapBuffer(
gst_vaapi_display_get_display(image->priv->display), GST_VAAPI_DISPLAY_VADISPLAY(image->priv->display),
image->priv->image.buf, image->priv->image.buf,
&image_data &image_data
); );
GST_VAAPI_DISPLAY_UNLOCK(image->priv->display);
if (!vaapi_check_status(status, "vaMapBuffer()")) if (!vaapi_check_status(status, "vaMapBuffer()"))
return FALSE; return FALSE;
@ -490,10 +498,12 @@ gst_vaapi_image_unmap(GstVaapiImage *image)
if (!_gst_vaapi_image_is_mapped(image)) if (!_gst_vaapi_image_is_mapped(image))
return FALSE; return FALSE;
GST_VAAPI_DISPLAY_LOCK(image->priv->display);
status = vaUnmapBuffer( status = vaUnmapBuffer(
gst_vaapi_display_get_display(image->priv->display), GST_VAAPI_DISPLAY_VADISPLAY(image->priv->display),
image->priv->image.buf image->priv->image.buf
); );
GST_VAAPI_DISPLAY_UNLOCK(image->priv->display);
if (!vaapi_check_status(status, "vaUnmapBuffer()")) if (!vaapi_check_status(status, "vaUnmapBuffer()"))
return FALSE; return FALSE;

View file

@ -56,10 +56,12 @@ gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture)
if (priv->subpicture_id != VA_INVALID_ID) { if (priv->subpicture_id != VA_INVALID_ID) {
display = gst_vaapi_image_get_display(priv->image); display = gst_vaapi_image_get_display(priv->image);
if (display) { if (display) {
GST_VAAPI_DISPLAY_LOCK(display);
status = vaDestroySubpicture( status = vaDestroySubpicture(
gst_vaapi_display_get_display(display), GST_VAAPI_DISPLAY_VADISPLAY(display),
priv->subpicture_id priv->subpicture_id
); );
GST_VAAPI_DISPLAY_UNLOCK(display);
if (!vaapi_check_status(status, "vaDestroySubpicture()")) if (!vaapi_check_status(status, "vaDestroySubpicture()"))
g_warning("failed to destroy subpicture 0x%08x\n", g_warning("failed to destroy subpicture 0x%08x\n",
priv->subpicture_id); priv->subpicture_id);
@ -88,11 +90,13 @@ gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture)
if (!display) if (!display)
return FALSE; return FALSE;
GST_VAAPI_DISPLAY_LOCK(display);
status = vaCreateSubpicture( status = vaCreateSubpicture(
gst_vaapi_display_get_display(display), GST_VAAPI_DISPLAY_VADISPLAY(display),
gst_vaapi_image_get_id(priv->image), gst_vaapi_image_get_id(priv->image),
&subpicture_id &subpicture_id
); );
GST_VAAPI_DISPLAY_UNLOCK(display);
if (!vaapi_check_status(status, "vaCreateSubpicture()")) if (!vaapi_check_status(status, "vaCreateSubpicture()"))
return FALSE; return FALSE;

View file

@ -55,11 +55,15 @@ static void
gst_vaapi_surface_destroy(GstVaapiSurface *surface) gst_vaapi_surface_destroy(GstVaapiSurface *surface)
{ {
GstVaapiSurfacePrivate * const priv = surface->priv; GstVaapiSurfacePrivate * const priv = surface->priv;
VADisplay dpy = GST_VAAPI_DISPLAY_VADISPLAY(priv->display);
VAStatus status; VAStatus status;
if (priv->surface_id != VA_INVALID_SURFACE) { 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()")) if (!vaapi_check_status(status, "vaDestroySurfaces()"))
g_warning("failed to destroy surface 0x%08x\n", priv->surface_id); g_warning("failed to destroy surface 0x%08x\n", priv->surface_id);
priv->surface_id = VA_INVALID_SURFACE; priv->surface_id = VA_INVALID_SURFACE;
@ -94,6 +98,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface)
return FALSE; return FALSE;
} }
GST_VAAPI_DISPLAY_LOCK(priv->display);
status = vaCreateSurfaces( status = vaCreateSurfaces(
GST_VAAPI_DISPLAY_VADISPLAY(priv->display), GST_VAAPI_DISPLAY_VADISPLAY(priv->display),
priv->width, priv->width,
@ -101,6 +106,7 @@ gst_vaapi_surface_create(GstVaapiSurface *surface)
format, format,
1, &surface_id 1, &surface_id
); );
GST_VAAPI_DISPLAY_UNLOCK(priv->display);
if (!vaapi_check_status(status, "vaCreateSurfaces()")) if (!vaapi_check_status(status, "vaCreateSurfaces()"))
return FALSE; return FALSE;
@ -354,12 +360,14 @@ gst_vaapi_surface_get_image(GstVaapiSurface *surface, GstVaapiImage *image)
if (image_id == VA_INVALID_ID) if (image_id == VA_INVALID_ID)
return FALSE; return FALSE;
GST_VAAPI_DISPLAY_LOCK(surface->priv->display);
status = vaGetImage( status = vaGetImage(
GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display),
surface->priv->surface_id, surface->priv->surface_id,
0, 0, width, height, 0, 0, width, height,
image_id image_id
); );
GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display);
if (!vaapi_check_status(status, "vaGetImage()")) if (!vaapi_check_status(status, "vaGetImage()"))
return FALSE; return FALSE;
@ -384,6 +392,7 @@ gst_vaapi_surface_put_image(GstVaapiSurface *surface, GstVaapiImage *image)
if (image_id == VA_INVALID_ID) if (image_id == VA_INVALID_ID)
return FALSE; return FALSE;
GST_VAAPI_DISPLAY_LOCK(surface->priv->display);
status = vaPutImage( status = vaPutImage(
GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display),
surface->priv->surface_id, 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,
0, 0, width, height 0, 0, width, height
); );
GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display);
if (!vaapi_check_status(status, "vaPutImage()")) if (!vaapi_check_status(status, "vaPutImage()"))
return FALSE; return FALSE;
@ -404,10 +414,12 @@ gst_vaapi_surface_sync(GstVaapiSurface *surface)
g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE); g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
GST_VAAPI_DISPLAY_LOCK(surface->priv->display);
status = vaSyncSurface( status = vaSyncSurface(
GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display), GST_VAAPI_DISPLAY_VADISPLAY(surface->priv->display),
surface->priv->surface_id surface->priv->surface_id
); );
GST_VAAPI_DISPLAY_UNLOCK(surface->priv->display);
if (!vaapi_check_status(status, "vaSyncSurface()")) if (!vaapi_check_status(status, "vaSyncSurface()"))
return FALSE; return FALSE;

View file

@ -52,15 +52,19 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window)
{ {
GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
gboolean has_errors;
if (priv->is_visible) if (priv->is_visible)
return TRUE; return TRUE;
GST_VAAPI_DISPLAY_LOCK(priv->display);
x11_trap_errors(); x11_trap_errors();
XMapWindow(dpy, priv->xid); XMapWindow(dpy, priv->xid);
if (priv->create_window) if (priv->create_window)
x11_wait_event(dpy, priv->xid, MapNotify); 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; return FALSE;
priv->is_visible = TRUE; priv->is_visible = TRUE;
@ -72,15 +76,19 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window)
{ {
GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
gboolean has_errors;
if (!priv->is_visible) if (!priv->is_visible)
return TRUE; return TRUE;
GST_VAAPI_DISPLAY_LOCK(priv->display);
x11_trap_errors(); x11_trap_errors();
XUnmapWindow(dpy, priv->xid); XUnmapWindow(dpy, priv->xid);
if (priv->create_window) if (priv->create_window)
x11_wait_event(dpy, priv->xid, UnmapNotify); 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; return FALSE;
priv->is_visible = FALSE; priv->is_visible = FALSE;
@ -97,13 +105,13 @@ gst_vaapi_window_x11_create(GstVaapiWindow *window, guint width, guint height)
return TRUE; return TRUE;
dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
GST_VAAPI_DISPLAY_LOCK(priv->display);
priv->xid = x11_create_window(dpy, width, height); priv->xid = x11_create_window(dpy, width, height);
if (priv->xid)
if (!priv->xid)
return FALSE;
XRaiseWindow(dpy, priv->xid); XRaiseWindow(dpy, priv->xid);
return TRUE; GST_VAAPI_DISPLAY_UNLOCK(priv->display);
return priv->xid != None;
} }
static void static void
@ -113,8 +121,11 @@ gst_vaapi_window_x11_destroy(GstVaapiWindow *window)
Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display); Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
if (priv->xid) { if (priv->xid) {
if (priv->create_window) if (priv->create_window) {
GST_VAAPI_DISPLAY_LOCK(priv->display);
XDestroyWindow(dpy, priv->xid); XDestroyWindow(dpy, priv->xid);
GST_VAAPI_DISPLAY_UNLOCK(priv->display);
}
priv->xid = None; priv->xid = None;
} }
@ -128,10 +139,12 @@ static gboolean
gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height) gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height)
{ {
GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv; GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
gboolean has_errors;
if (!priv->xid) if (!priv->xid)
return FALSE; return FALSE;
GST_VAAPI_DISPLAY_LOCK(priv->display);
x11_trap_errors(); x11_trap_errors();
XResizeWindow( XResizeWindow(
GST_VAAPI_DISPLAY_XDISPLAY(priv->display), GST_VAAPI_DISPLAY_XDISPLAY(priv->display),
@ -139,9 +152,9 @@ gst_vaapi_window_x11_resize(GstVaapiWindow *window, guint width, guint height)
width, width,
height height
); );
if (x11_untrap_errors() != 0) has_errors = x11_untrap_errors() != 0;
return FALSE; GST_VAAPI_DISPLAY_UNLOCK(priv->display);
return TRUE; return !has_errors;
} }
static gboolean static gboolean
@ -153,10 +166,15 @@ gst_vaapi_window_x11_render(
guint flags guint flags
) )
{ {
GstVaapiDisplay *display;
VASurfaceID surface_id; VASurfaceID surface_id;
VAStatus status; VAStatus status;
unsigned int va_flags = 0; unsigned int va_flags = 0;
display = gst_vaapi_surface_get_display(surface);
if (!display)
return FALSE;
surface_id = gst_vaapi_surface_get_id(surface); surface_id = gst_vaapi_surface_get_id(surface);
if (surface_id == VA_INVALID_ID) if (surface_id == VA_INVALID_ID)
return FALSE; return FALSE;
@ -173,8 +191,9 @@ gst_vaapi_window_x11_render(
else if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601) else if (flags & GST_VAAPI_COLOR_STANDARD_ITUR_BT_601)
va_flags |= VA_SRC_BT601; va_flags |= VA_SRC_BT601;
GST_VAAPI_DISPLAY_LOCK(display);
status = vaPutSurface( status = vaPutSurface(
GST_VAAPI_DISPLAY_VADISPLAY(gst_vaapi_surface_get_display(surface)), GST_VAAPI_DISPLAY_VADISPLAY(display),
surface_id, surface_id,
GST_VAAPI_WINDOW_X11(window)->priv->xid, GST_VAAPI_WINDOW_X11(window)->priv->xid,
src_rect->x, src_rect->x,
@ -188,6 +207,7 @@ gst_vaapi_window_x11_render(
NULL, 0, NULL, 0,
va_flags va_flags
); );
GST_VAAPI_DISPLAY_UNLOCK(display);
if (!vaapi_check_status(status, "vaPutSurface()")) if (!vaapi_check_status(status, "vaPutSurface()"))
return FALSE; return FALSE;