From a42754e31eb5b4d0e9a35a8f9bd25f1025a34c9e Mon Sep 17 00:00:00 2001 From: gb Date: Thu, 11 Mar 2010 15:01:00 +0000 Subject: [PATCH] API change: gst_vaapi_display_x11_new() now takes an X11 display name. --- gst-libs/gst/vaapi/gstvaapidisplay.c | 74 ++++++++++------- gst-libs/gst/vaapi/gstvaapidisplay.h | 6 +- gst-libs/gst/vaapi/gstvaapidisplay_x11.c | 133 ++++++++++++++++++++++++------- gst-libs/gst/vaapi/gstvaapidisplay_x11.h | 2 +- tests/examples/generic/test-display.c | 10 +-- 5 files changed, 157 insertions(+), 68 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.c b/gst-libs/gst/vaapi/gstvaapidisplay.c index 8f3f1d6..f98ba56 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay.c @@ -37,6 +37,7 @@ G_DEFINE_TYPE(GstVaapiDisplay, gst_vaapi_display, G_TYPE_OBJECT); struct _GstVaapiDisplayPrivate { VADisplay display; + gboolean create_display; VAProfile *profiles; unsigned int num_profiles; VAImageFormat *image_formats; @@ -53,9 +54,6 @@ enum { }; static void -gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display); - -static void filter_formats(VAImageFormat *va_formats, unsigned int *pnum_va_formats) { unsigned int i = 0; @@ -146,6 +144,12 @@ gst_vaapi_display_destroy(GstVaapiDisplay *display) vaTerminate(priv->display); priv->display = NULL; } + + if (priv->create_display) { + GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); + if (klass->close_display) + klass->close_display(display); + } } static gboolean @@ -156,6 +160,16 @@ gst_vaapi_display_create(GstVaapiDisplay *display) int major_version, minor_version; unsigned int i; + if (!priv->display && priv->create_display) { + GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS(display); + if (klass->open_display && !klass->open_display(display)) + return FALSE; + if (klass->get_display) + priv->display = klass->get_display(display); + } + if (!priv->display) + return FALSE; + status = vaInitialize(priv->display, &major_version, &minor_version); if (!vaapi_check_status(status, "vaInitialize()")) return FALSE; @@ -244,16 +258,17 @@ gst_vaapi_display_finalize(GObject *object) } static void -gst_vaapi_display_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +gst_vaapi_display_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); switch (prop_id) { case PROP_DISPLAY: - gst_vaapi_display_set_display(display, g_value_get_pointer(value)); + display->priv->display = g_value_get_pointer(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -262,10 +277,12 @@ gst_vaapi_display_set_property(GObject *object, } static void -gst_vaapi_display_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +gst_vaapi_display_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) { GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); @@ -280,6 +297,20 @@ gst_vaapi_display_get_property(GObject *object, } static void +gst_vaapi_display_constructed(GObject *object) +{ + GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object); + GObjectClass *parent_class; + + display->priv->create_display = display->priv->display == NULL; + gst_vaapi_display_create(display); + + parent_class = G_OBJECT_CLASS(gst_vaapi_display_parent_class); + if (parent_class->constructed) + parent_class->constructed(object); +} + +static void gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); @@ -291,6 +322,7 @@ gst_vaapi_display_class_init(GstVaapiDisplayClass *klass) 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; g_object_class_install_property (object_class, @@ -308,6 +340,7 @@ gst_vaapi_display_init(GstVaapiDisplay *display) display->priv = priv; priv->display = NULL; + priv->create_display = TRUE; priv->profiles = 0; priv->num_profiles = 0; priv->image_formats = NULL; @@ -333,23 +366,6 @@ gst_vaapi_display_get_display(GstVaapiDisplay *display) return display->priv->display; } -void -gst_vaapi_display_set_display(GstVaapiDisplay *display, VADisplay va_display) -{ - GstVaapiDisplayPrivate * const priv = display->priv; - - if (priv->display) - gst_vaapi_display_destroy(display); - - if (va_display) { - priv->display = va_display; - if (!gst_vaapi_display_create(display)) { - gst_vaapi_display_destroy(display); - return; - } - } -} - gboolean gst_vaapi_display_has_profile(GstVaapiDisplay *display, VAProfile profile) { diff --git a/gst-libs/gst/vaapi/gstvaapidisplay.h b/gst-libs/gst/vaapi/gstvaapidisplay.h index a895aaf..72488ba 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay.h @@ -49,7 +49,7 @@ G_BEGIN_DECLS #define GST_VAAPI_DISPLAY_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS((obj), \ GST_VAAPI_TYPE_DISPLAY, \ - GstVaapiDisplay)) + GstVaapiDisplayClass)) typedef struct _GstVaapiDisplay GstVaapiDisplay; typedef struct _GstVaapiDisplayPrivate GstVaapiDisplayPrivate; @@ -65,6 +65,10 @@ struct _GstVaapiDisplay { struct _GstVaapiDisplayClass { /*< private >*/ GObjectClass parent_class; + + gboolean (*open_display) (GstVaapiDisplay *display); + void (*close_display)(GstVaapiDisplay *display); + VADisplay (*get_display) (GstVaapiDisplay *display); }; GType diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c index 305fadc..1f22408 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.c @@ -35,12 +35,15 @@ G_DEFINE_TYPE(GstVaapiDisplayX11, GstVaapiDisplayX11Private)) struct _GstVaapiDisplayX11Private { - Display *display; + gchar *display_name; + Display *x11_display; + VADisplay *va_display; }; enum { PROP_0, + PROP_DISPLAY_NAME, PROP_X11_DISPLAY }; @@ -51,16 +54,31 @@ gst_vaapi_display_x11_finalize(GObject *object) } static void -gst_vaapi_display_x11_set_property(GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name) +{ + GstVaapiDisplayX11Private * const priv = display->priv; + + g_free(priv->display_name); + + if (display_name) + priv->display_name = g_strdup(display_name); + else + priv->display_name = NULL; +} + +static void +gst_vaapi_display_x11_set_property( + GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec +) { GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); switch (prop_id) { - case PROP_X11_DISPLAY: - display->priv->display = g_value_get_pointer(value); + case PROP_DISPLAY_NAME: + set_display_name(display, g_value_get_string(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -69,14 +87,19 @@ gst_vaapi_display_x11_set_property(GObject *object, } static void -gst_vaapi_display_x11_get_property(GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +gst_vaapi_display_x11_get_property( + GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec +) { GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object); switch (prop_id) { + case PROP_DISPLAY_NAME: + g_value_set_string(value, display->priv->display_name); + break; case PROP_X11_DISPLAY: g_value_set_pointer(value, gst_vaapi_display_x11_get_display(display)); break; @@ -86,16 +109,61 @@ gst_vaapi_display_x11_get_property(GObject *object, } } +static gboolean +gst_vaapi_display_x11_open_display(GstVaapiDisplay *display) +{ + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11(display)->priv; + + /* XXX: maintain an X11 display cache */ + priv->x11_display = XOpenDisplay(priv->display_name); + if (!priv->x11_display) + return FALSE; + + priv->va_display = vaGetDisplay(priv->x11_display); + return priv->va_display != NULL; +} + +static void +gst_vaapi_display_x11_close_display(GstVaapiDisplay *display) +{ + GstVaapiDisplayX11Private * const priv = + GST_VAAPI_DISPLAY_X11(display)->priv; + + if (priv->x11_display) { + XCloseDisplay(priv->x11_display); + priv->x11_display = NULL; + } + + if (priv->display_name) { + g_free(priv->display_name); + priv->display_name = NULL; + } + + priv->va_display = NULL; +} + +static VADisplay +gst_vaapi_display_x11_get_va_display(GstVaapiDisplay *display) +{ + return GST_VAAPI_DISPLAY_X11(display)->priv->va_display; +} + static void gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) { GObjectClass * const object_class = G_OBJECT_CLASS(klass); + GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass); g_type_class_add_private(klass, sizeof(GstVaapiDisplayX11Private)); - object_class->finalize = gst_vaapi_display_x11_finalize; - object_class->set_property = gst_vaapi_display_x11_set_property; - object_class->get_property = gst_vaapi_display_x11_get_property; + object_class->finalize = gst_vaapi_display_x11_finalize; + object_class->set_property = gst_vaapi_display_x11_set_property; + object_class->get_property = gst_vaapi_display_x11_get_property; + + dpy_class->open_display = gst_vaapi_display_x11_open_display; + dpy_class->close_display = gst_vaapi_display_x11_close_display; + dpy_class->get_display = gst_vaapi_display_x11_get_va_display; g_object_class_install_property (object_class, @@ -103,7 +171,16 @@ gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass) g_param_spec_pointer("x11-display", "X11 display", "X11 display", - G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, + PROP_DISPLAY_NAME, + g_param_spec_string("display-name", + "X11 display name", + "X11 display name", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); } static void @@ -111,25 +188,23 @@ gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display) { GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display); - display->priv = priv; - priv->display = NULL; + display->priv = priv; + priv->x11_display = NULL; + priv->display_name = NULL; } -Display * -gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) +GstVaapiDisplay * +gst_vaapi_display_x11_new(const gchar *display_name) { - g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); - - return display->priv->display; + return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, + "display-name", display_name, + NULL); } -GstVaapiDisplay * -gst_vaapi_display_x11_new(Display *x11_display) +Display * +gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display) { - g_return_val_if_fail(x11_display, NULL); + g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL); - return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11, - "x11-display", x11_display, - "display", vaGetDisplay(x11_display), - NULL); + return display->priv->x11_display; } diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h index bd7b223..1881b34 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_x11.h +++ b/gst-libs/gst/vaapi/gstvaapidisplay_x11.h @@ -70,7 +70,7 @@ GType gst_vaapi_display_x11_get_type(void); GstVaapiDisplay * -gst_vaapi_display_x11_new(Display *x11_display); +gst_vaapi_display_x11_new(const gchar *display_name); Display * gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display); diff --git a/tests/examples/generic/test-display.c b/tests/examples/generic/test-display.c index bfe4055..dbbf1f9 100644 --- a/tests/examples/generic/test-display.c +++ b/tests/examples/generic/test-display.c @@ -71,17 +71,12 @@ print_caps(GstCaps *caps, const gchar *name) int main(int argc, char *argv[]) { - Display *x11_display; GstVaapiDisplay *display; GstCaps *caps; gst_init(&argc, &argv); - x11_display = XOpenDisplay(NULL); - if (!x11_display) - g_error("could not create X11 display"); - - display = gst_vaapi_display_x11_new(x11_display); + display = gst_vaapi_display_x11_new(NULL); if (!display) g_error("could not create VA-API display"); @@ -99,8 +94,7 @@ main(int argc, char *argv[]) print_caps(caps, "subpicture"); gst_caps_unref(caps); - g_object_unref(G_OBJECT(display)); - XCloseDisplay(x11_display); + g_object_unref(display); gst_deinit(); return 0; } -- 2.7.4