API change: gst_vaapi_display_x11_new() now takes an X11 display name.
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Thu, 11 Mar 2010 15:01:00 +0000 (15:01 +0000)
committergb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Thu, 11 Mar 2010 15:01:00 +0000 (15:01 +0000)
gst-libs/gst/vaapi/gstvaapidisplay.c
gst-libs/gst/vaapi/gstvaapidisplay.h
gst-libs/gst/vaapi/gstvaapidisplay_x11.c
gst-libs/gst/vaapi/gstvaapidisplay_x11.h
tests/examples/generic/test-display.c

index 8f3f1d6..f98ba56 100644 (file)
@@ -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)
 {
index a895aaf..72488ba 100644 (file)
@@ -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
index 305fadc..1f22408 100644 (file)
@@ -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;
 }
index bd7b223..1881b34 100644 (file)
@@ -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);
index bfe4055..dbbf1f9 100644 (file)
@@ -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;
 }