mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-10 03:19:40 +00:00
Add VA display locking utilities.
This commit is contained in:
parent
65cc4aa494
commit
bcb5d3f138
6 changed files with 134 additions and 31 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue