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))
struct _GstVaapiDisplayPrivate {
GStaticMutex mutex;
VADisplay display;
gboolean create_display;
VAProfile *profiles;
@ -292,6 +293,18 @@ gst_vaapi_display_create(GstVaapiDisplay *display)
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
gst_vaapi_display_finalize(GObject *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)
{

View 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);

View 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;

View 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;

View 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;

View 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);
dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
GST_VAAPI_DISPLAY_LOCK(priv->display);
priv->xid = x11_create_window(dpy, width, height);
if (!priv->xid)
return FALSE;
XRaiseWindow(dpy, priv->xid);
return TRUE;
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;