2 * gstvaapidisplay_x11.c - VA/X11 display abstraction
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Copyright (C) 2011 Intel Corporation
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
24 * SECTION:gstvaapidisplay_x11
25 * @short_description: VA/X11 display abstraction
30 #include "gstvaapiutils.h"
31 #include "gstvaapidisplay_priv.h"
32 #include "gstvaapidisplay_x11.h"
33 #include "gstvaapidisplay_x11_priv.h"
36 #include "gstvaapidebug.h"
38 G_DEFINE_TYPE(GstVaapiDisplayX11,
39 gst_vaapi_display_x11,
40 GST_VAAPI_TYPE_DISPLAY);
51 static inline const gchar *
52 get_default_display_name(void)
54 static const gchar *g_display_name;
57 g_display_name = getenv("DISPLAY");
58 return g_display_name;
62 compare_display_name(gconstpointer a, gconstpointer b, gpointer user_data)
64 const gchar *display_name;
66 /* XXX: handle screen number? */
68 return strcmp(a, b) == 0;
70 /* Match "" or default display name */
78 if (*display_name == '\0')
80 if (strcmp(display_name, get_default_display_name()) == 0)
86 gst_vaapi_display_x11_finalize(GObject *object)
88 G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class)->finalize(object);
92 set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name)
94 GstVaapiDisplayX11Private * const priv = display->priv;
96 g_free(priv->display_name);
99 priv->display_name = g_strdup(display_name);
101 priv->display_name = NULL;
105 set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous)
107 GstVaapiDisplayX11Private * const priv = display->priv;
109 if (priv->synchronous != synchronous) {
110 priv->synchronous = synchronous;
111 if (priv->x11_display)
112 XSynchronize(priv->x11_display, synchronous);
117 gst_vaapi_display_x11_set_property(
124 GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object);
127 case PROP_SYNCHRONOUS:
128 set_synchronous(display, g_value_get_boolean(value));
130 case PROP_DISPLAY_NAME:
131 set_display_name(display, g_value_get_string(value));
133 case PROP_X11_DISPLAY:
134 display->priv->x11_display = g_value_get_pointer(value);
136 case PROP_X11_SCREEN:
137 display->priv->x11_screen = g_value_get_int(value);
140 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
146 gst_vaapi_display_x11_get_property(
153 GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object);
156 case PROP_SYNCHRONOUS:
157 g_value_set_boolean(value, display->priv->synchronous);
159 case PROP_DISPLAY_NAME:
160 g_value_set_string(value, display->priv->display_name);
162 case PROP_X11_DISPLAY:
163 g_value_set_pointer(value, gst_vaapi_display_x11_get_display(display));
165 case PROP_X11_SCREEN:
166 g_value_set_int(value, gst_vaapi_display_x11_get_screen(display));
169 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
175 gst_vaapi_display_x11_constructed(GObject *object)
177 GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object);
178 GstVaapiDisplayX11Private * const priv = display->priv;
179 GstVaapiDisplayCache * const cache = gst_vaapi_display_get_cache();
180 const GstVaapiDisplayInfo *info;
181 GObjectClass *parent_class;
183 priv->create_display = priv->x11_display == NULL;
185 /* Don't create X11 display if there is one in the cache already */
186 if (priv->create_display) {
187 info = gst_vaapi_display_cache_lookup_by_name(
190 compare_display_name, NULL
193 priv->x11_display = info->native_display;
194 priv->create_display = FALSE;
198 /* Reset display-name if the user provided his own X11 display */
199 if (!priv->create_display)
200 set_display_name(display, XDisplayString(priv->x11_display));
202 parent_class = G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class);
203 if (parent_class->constructed)
204 parent_class->constructed(object);
208 gst_vaapi_display_x11_open_display(GstVaapiDisplay *display)
210 GstVaapiDisplayX11Private * const priv =
211 GST_VAAPI_DISPLAY_X11(display)->priv;
213 if (priv->create_display) {
214 priv->x11_display = XOpenDisplay(priv->display_name);
215 if (!priv->x11_display)
217 priv->x11_screen = DefaultScreen(priv->x11_display);
219 if (!priv->x11_display)
222 if (priv->synchronous)
223 XSynchronize(priv->x11_display, True);
228 gst_vaapi_display_x11_close_display(GstVaapiDisplay *display)
230 GstVaapiDisplayX11Private * const priv =
231 GST_VAAPI_DISPLAY_X11(display)->priv;
233 if (priv->x11_display) {
234 if (priv->create_display)
235 XCloseDisplay(priv->x11_display);
236 priv->x11_display = NULL;
239 if (priv->display_name) {
240 g_free(priv->display_name);
241 priv->display_name = NULL;
246 gst_vaapi_display_x11_sync(GstVaapiDisplay *display)
248 GstVaapiDisplayX11Private * const priv =
249 GST_VAAPI_DISPLAY_X11(display)->priv;
251 if (priv->x11_display) {
252 GST_VAAPI_DISPLAY_LOCK(display);
253 XSync(priv->x11_display, False);
254 GST_VAAPI_DISPLAY_UNLOCK(display);
259 gst_vaapi_display_x11_flush(GstVaapiDisplay *display)
261 GstVaapiDisplayX11Private * const priv =
262 GST_VAAPI_DISPLAY_X11(display)->priv;
264 if (priv->x11_display) {
265 GST_VAAPI_DISPLAY_LOCK(display);
266 XFlush(priv->x11_display);
267 GST_VAAPI_DISPLAY_UNLOCK(display);
272 gst_vaapi_display_x11_get_display_info(
273 GstVaapiDisplay *display,
274 GstVaapiDisplayInfo *info
277 GstVaapiDisplayX11Private * const priv =
278 GST_VAAPI_DISPLAY_X11(display)->priv;
279 GstVaapiDisplayCache *cache;
280 const GstVaapiDisplayInfo *cached_info;
282 /* Return any cached info even if child has its own VA display */
283 cache = gst_vaapi_display_get_cache();
286 cached_info = gst_vaapi_display_cache_lookup_by_native_display(cache, priv->x11_display);
288 *info = *cached_info;
292 /* Otherwise, create VA display if there is none already */
293 info->native_display = priv->x11_display;
294 info->display_name = priv->display_name;
295 if (!info->va_display) {
296 info->va_display = vaGetDisplay(priv->x11_display);
297 if (!info->va_display)
304 gst_vaapi_display_x11_get_size(
305 GstVaapiDisplay *display,
310 GstVaapiDisplayX11Private * const priv =
311 GST_VAAPI_DISPLAY_X11(display)->priv;
313 if (!priv->x11_display)
317 *pwidth = DisplayWidth(priv->x11_display, priv->x11_screen);
320 *pheight = DisplayHeight(priv->x11_display, priv->x11_screen);
324 gst_vaapi_display_x11_get_size_mm(
325 GstVaapiDisplay *display,
330 GstVaapiDisplayX11Private * const priv =
331 GST_VAAPI_DISPLAY_X11(display)->priv;
333 if (!priv->x11_display)
337 *pwidth = DisplayWidthMM(priv->x11_display, priv->x11_screen);
340 *pheight = DisplayHeightMM(priv->x11_display, priv->x11_screen);
344 gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass)
346 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
347 GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass);
349 g_type_class_add_private(klass, sizeof(GstVaapiDisplayX11Private));
351 object_class->finalize = gst_vaapi_display_x11_finalize;
352 object_class->set_property = gst_vaapi_display_x11_set_property;
353 object_class->get_property = gst_vaapi_display_x11_get_property;
354 object_class->constructed = gst_vaapi_display_x11_constructed;
356 dpy_class->open_display = gst_vaapi_display_x11_open_display;
357 dpy_class->close_display = gst_vaapi_display_x11_close_display;
358 dpy_class->sync = gst_vaapi_display_x11_sync;
359 dpy_class->flush = gst_vaapi_display_x11_flush;
360 dpy_class->get_display = gst_vaapi_display_x11_get_display_info;
361 dpy_class->get_size = gst_vaapi_display_x11_get_size;
362 dpy_class->get_size_mm = gst_vaapi_display_x11_get_size_mm;
365 * GstVaapiDisplayX11:synchronous:
367 * When enabled, runs the X display in synchronous mode. Note that
368 * this is used only for debugging.
370 g_object_class_install_property
373 g_param_spec_boolean("synchronous",
375 "Toggles X display synchronous mode",
380 * GstVaapiDisplayX11:x11-display:
382 * The X11 #Display that was created by gst_vaapi_display_x11_new()
383 * or that was bound from gst_vaapi_display_x11_new_with_display().
385 g_object_class_install_property
388 g_param_spec_pointer("x11-display",
391 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
394 * GstVaapiDisplayX11:x11-screen:
396 * The X11 screen that was created by gst_vaapi_display_x11_new()
397 * or that was bound from gst_vaapi_display_x11_new_with_display().
399 g_object_class_install_property
402 g_param_spec_int("x11-screen",
406 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
409 * GstVaapiDisplayX11:display-name:
411 * The X11 display name.
413 g_object_class_install_property
416 g_param_spec_string("display-name",
420 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
424 gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display)
426 GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display);
428 display->priv = priv;
429 priv->create_display = TRUE;
430 priv->x11_display = NULL;
431 priv->x11_screen = 0;
432 priv->display_name = NULL;
436 * gst_vaapi_display_x11_new:
437 * @display_name: the X11 display name
439 * Opens an X11 #Display using @display_name and returns a newly
440 * allocated #GstVaapiDisplay object. The X11 display will be cloed
441 * when the reference count of the object reaches zero.
443 * Return value: a newly allocated #GstVaapiDisplay object
446 gst_vaapi_display_x11_new(const gchar *display_name)
448 return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11,
449 "display-name", display_name,
454 * gst_vaapi_display_x11_new_with_display:
455 * @x11_display: an X11 #Display
457 * Creates a #GstVaapiDisplay based on the X11 @x11_display
458 * display. The caller still owns the display and must call
459 * XCloseDisplay() when all #GstVaapiDisplay references are
460 * released. Doing so too early can yield undefined behaviour.
462 * Return value: a newly allocated #GstVaapiDisplay object
465 gst_vaapi_display_x11_new_with_display(Display *x11_display)
467 g_return_val_if_fail(x11_display, NULL);
469 return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11,
470 "x11-display", x11_display,
471 "x11-screen", DefaultScreen(x11_display),
476 * gst_vaapi_display_x11_get_display:
477 * @display: a #GstVaapiDisplayX11
479 * Returns the underlying X11 #Display that was created by
480 * gst_vaapi_display_x11_new() or that was bound from
481 * gst_vaapi_display_x11_new_with_display().
483 * Return value: the X11 #Display attached to @display
486 gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display)
488 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL);
490 return display->priv->x11_display;
494 * gst_vaapi_display_x11_get_screen:
495 * @display: a #GstVaapiDisplayX11
497 * Returns the default X11 screen that was created by
498 * gst_vaapi_display_x11_new() or that was bound from
499 * gst_vaapi_display_x11_new_with_display().
501 * Return value: the X11 #Display attached to @display
504 gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display)
506 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), -1);
508 return display->priv->x11_screen;