~ubuntu-branches/ubuntu/vivid/gstreamer-vaapi/vivid

« back to all changes in this revision

Viewing changes to gst-libs/gst/vaapi/gstvaapidisplay_x11.c

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng
  • Date: 2014-08-06 23:56:00 UTC
  • mfrom: (0.1.4 sid) (1.1.3)
  • Revision ID: package-import@ubuntu.com-20140806235600-fg1kcmiu67k315q5
Tags: 0.5.9-2
* Remove spurious build-deps: libva-drm1, libavcodec-dev. (Closes: #757283)
* Drop Build-Depends-Indep and build docs unconditionally on all archs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
#include "gstvaapidebug.h"
47
47
 
48
48
static const guint g_display_types =
49
 
    (1U << GST_VAAPI_DISPLAY_TYPE_X11) |
50
 
    (1U << GST_VAAPI_DISPLAY_TYPE_GLX);
 
49
    (1U << GST_VAAPI_DISPLAY_TYPE_X11) | (1U << GST_VAAPI_DISPLAY_TYPE_GLX);
 
50
 
 
51
static gboolean
 
52
parse_display_name (const gchar * name, guint * len_ptr, guint * id_ptr,
 
53
    guint * screen_ptr)
 
54
{
 
55
  gulong len, id = 0, screen = 0;
 
56
  gchar *end;
 
57
 
 
58
  end = strchr (name, ':');
 
59
  len = end ? end - name : strlen (name);
 
60
 
 
61
  if (end) {
 
62
    id = strtoul (&end[1], &end, 10);
 
63
    if (*end == '.')
 
64
      screen = strtoul (&end[1], &end, 10);
 
65
    if (*end != '\0')
 
66
      return FALSE;
 
67
  }
 
68
 
 
69
  if (len_ptr)
 
70
    *len_ptr = len;
 
71
  if (id_ptr)
 
72
    *id_ptr = id;
 
73
  if (screen_ptr)
 
74
    *screen_ptr = screen;
 
75
  return TRUE;
 
76
}
 
77
 
 
78
static gint
 
79
compare_display_name (gconstpointer a, gconstpointer b)
 
80
{
 
81
  const GstVaapiDisplayInfo *const info = a;
 
82
  const gchar *const cached_name = info->display_name;
 
83
  const gchar *const tested_name = b;
 
84
  guint cached_name_length, cached_id;
 
85
  guint tested_name_length, tested_id;
 
86
 
 
87
  g_return_val_if_fail (cached_name, FALSE);
 
88
  g_return_val_if_fail (tested_name, FALSE);
 
89
 
 
90
  if (!parse_display_name (cached_name, &cached_name_length, &cached_id, NULL))
 
91
    return FALSE;
 
92
  if (!parse_display_name (tested_name, &tested_name_length, &tested_id, NULL))
 
93
    return FALSE;
 
94
  if (cached_name_length != tested_name_length)
 
95
    return FALSE;
 
96
  if (strncmp (cached_name, tested_name, cached_name_length) != 0)
 
97
    return FALSE;
 
98
  if (cached_id != tested_id)
 
99
    return FALSE;
 
100
  return TRUE;
 
101
}
51
102
 
52
103
static inline const gchar *
53
 
get_default_display_name(void)
54
 
{
55
 
    static const gchar *g_display_name;
56
 
 
57
 
    if (!g_display_name)
58
 
        g_display_name = getenv("DISPLAY");
59
 
    return g_display_name;
60
 
}
61
 
 
62
 
static gint
63
 
compare_display_name(gconstpointer a, gconstpointer b)
64
 
{
65
 
    const GstVaapiDisplayInfo * const info = a;
66
 
    const gchar *cached_name = info->display_name, *cached_name_end;
67
 
    const gchar *tested_name = b, *tested_name_end;
68
 
    guint cached_name_length, tested_name_length;
69
 
 
70
 
    g_return_val_if_fail(cached_name, FALSE);
71
 
    g_return_val_if_fail(tested_name, FALSE);
72
 
 
73
 
    cached_name_end = strchr(cached_name, ':');
74
 
    if (cached_name_end)
75
 
        cached_name_length = cached_name_end - cached_name;
76
 
    else
77
 
        cached_name_length = strlen(cached_name);
78
 
 
79
 
    tested_name_end = strchr(tested_name, ':');
80
 
    if (tested_name_end)
81
 
        tested_name_length = tested_name_end - tested_name;
82
 
    else
83
 
        tested_name_length = strlen(tested_name);
84
 
 
85
 
    if (cached_name_length != tested_name_length)
86
 
        return FALSE;
87
 
    if (strncmp(cached_name, tested_name, cached_name_length) != 0)
88
 
        return FALSE;
89
 
 
90
 
    /* XXX: handle screen number? */
91
 
    return TRUE;
 
104
get_default_display_name (void)
 
105
{
 
106
  static const gchar *g_display_name;
 
107
 
 
108
  if (!g_display_name)
 
109
    g_display_name = getenv ("DISPLAY");
 
110
  return g_display_name;
92
111
}
93
112
 
94
113
/* Reconstruct a display name without our prefix */
95
114
static const gchar *
96
 
get_display_name(GstVaapiDisplayX11 *display)
 
115
get_display_name (GstVaapiDisplayX11 * display)
97
116
{
98
 
    GstVaapiDisplayX11Private * const priv = &display->priv;
99
 
    const gchar *display_name = priv->display_name;
 
117
  GstVaapiDisplayX11Private *const priv = &display->priv;
 
118
  const gchar *display_name = priv->display_name;
100
119
 
101
 
    if (!display_name || *display_name == '\0')
102
 
        return NULL;
103
 
    return display_name;
 
120
  if (!display_name || *display_name == '\0')
 
121
    return NULL;
 
122
  return display_name;
104
123
}
105
124
 
106
125
/* Mangle display name with our prefix */
107
126
static gboolean
108
 
set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name)
 
127
set_display_name (GstVaapiDisplayX11 * display, const gchar * display_name)
109
128
{
110
 
    GstVaapiDisplayX11Private * const priv = &display->priv;
111
 
 
112
 
    g_free(priv->display_name);
113
 
 
114
 
    if (!display_name) {
115
 
        display_name = get_default_display_name();
116
 
        if (!display_name)
117
 
            display_name = "";
118
 
    }
119
 
    priv->display_name = g_strdup(display_name);
120
 
    return priv->display_name != NULL;
 
129
  GstVaapiDisplayX11Private *const priv = &display->priv;
 
130
 
 
131
  g_free (priv->display_name);
 
132
 
 
133
  if (!display_name) {
 
134
    display_name = get_default_display_name ();
 
135
    if (!display_name)
 
136
      display_name = "";
 
137
  }
 
138
  priv->display_name = g_strdup (display_name);
 
139
  return priv->display_name != NULL;
121
140
}
122
141
 
123
142
/* Set synchronous behavious on the underlying X11 display */
124
143
static void
125
 
set_synchronous(GstVaapiDisplayX11 *display, gboolean synchronous)
 
144
set_synchronous (GstVaapiDisplayX11 * display, gboolean synchronous)
126
145
{
127
 
    GstVaapiDisplayX11Private * const priv = &display->priv;
 
146
  GstVaapiDisplayX11Private *const priv = &display->priv;
128
147
 
129
 
    if (priv->synchronous != synchronous) {
130
 
        priv->synchronous = synchronous;
131
 
        if (priv->x11_display) {
132
 
            GST_VAAPI_DISPLAY_LOCK(display);
133
 
            XSynchronize(priv->x11_display, synchronous);
134
 
            GST_VAAPI_DISPLAY_UNLOCK(display);
135
 
        }
 
148
  if (priv->synchronous != synchronous) {
 
149
    priv->synchronous = synchronous;
 
150
    if (priv->x11_display) {
 
151
      GST_VAAPI_DISPLAY_LOCK (display);
 
152
      XSynchronize (priv->x11_display, synchronous);
 
153
      GST_VAAPI_DISPLAY_UNLOCK (display);
136
154
    }
 
155
  }
137
156
}
138
157
 
139
158
/* Check for display server extensions */
140
159
static void
141
 
check_extensions(GstVaapiDisplayX11 *display)
 
160
check_extensions (GstVaapiDisplayX11 * display)
142
161
{
143
 
    GstVaapiDisplayX11Private * const priv =
144
 
        GST_VAAPI_DISPLAY_X11_PRIVATE(display);
145
 
    int evt_base, err_base;
 
162
  GstVaapiDisplayX11Private *const priv =
 
163
      GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
164
  int evt_base, err_base;
146
165
 
147
166
#ifdef HAVE_XRANDR
148
 
    priv->use_xrandr = XRRQueryExtension(priv->x11_display,
149
 
        &evt_base, &err_base);
 
167
  priv->use_xrandr = XRRQueryExtension (priv->x11_display,
 
168
      &evt_base, &err_base);
150
169
#endif
151
170
#ifdef HAVE_XRENDER
152
 
    priv->has_xrender = XRenderQueryExtension(priv->x11_display,
153
 
        &evt_base, &err_base);
 
171
  priv->has_xrender = XRenderQueryExtension (priv->x11_display,
 
172
      &evt_base, &err_base);
154
173
#endif
155
174
}
156
175
 
157
176
static gboolean
158
 
gst_vaapi_display_x11_bind_display(GstVaapiDisplay *base_display,
 
177
gst_vaapi_display_x11_bind_display (GstVaapiDisplay * base_display,
159
178
    gpointer native_display)
160
179
{
161
 
    GstVaapiDisplayX11 * const display =
162
 
        GST_VAAPI_DISPLAY_X11_CAST(base_display);
163
 
    GstVaapiDisplayX11Private * const priv = &display->priv;
164
 
 
165
 
    priv->x11_display = native_display;
166
 
    priv->x11_screen = DefaultScreen(native_display);
 
180
  GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11_CAST (base_display);
 
181
  GstVaapiDisplayX11Private *const priv = &display->priv;
 
182
 
 
183
  priv->x11_display = native_display;
 
184
  priv->x11_screen = DefaultScreen (native_display);
 
185
  priv->use_foreign_display = TRUE;
 
186
 
 
187
  check_extensions (display);
 
188
 
 
189
  if (!set_display_name (display, XDisplayString (priv->x11_display)))
 
190
    return FALSE;
 
191
  return TRUE;
 
192
}
 
193
 
 
194
static gboolean
 
195
gst_vaapi_display_x11_open_display (GstVaapiDisplay * base_display,
 
196
    const gchar * name)
 
197
{
 
198
  GstVaapiDisplayX11 *const display = GST_VAAPI_DISPLAY_X11_CAST (base_display);
 
199
  GstVaapiDisplayX11Private *const priv = &display->priv;
 
200
  GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display);
 
201
  const GstVaapiDisplayInfo *info;
 
202
 
 
203
  if (!set_display_name (display, name))
 
204
    return FALSE;
 
205
 
 
206
  info = gst_vaapi_display_cache_lookup_custom (cache, compare_display_name,
 
207
      priv->display_name, GST_VAAPI_DISPLAY_TYPES (display));
 
208
  if (info) {
 
209
    priv->x11_display = info->native_display;
167
210
    priv->use_foreign_display = TRUE;
168
 
 
169
 
    check_extensions(display);
170
 
 
171
 
    if (!set_display_name(display, XDisplayString(priv->x11_display)))
172
 
        return FALSE;
173
 
    return TRUE;
174
 
}
175
 
 
176
 
static gboolean
177
 
gst_vaapi_display_x11_open_display(GstVaapiDisplay *base_display,
178
 
    const gchar *name)
179
 
{
180
 
    GstVaapiDisplayX11 * const display =
181
 
        GST_VAAPI_DISPLAY_X11_CAST(base_display);
182
 
    GstVaapiDisplayX11Private * const priv = &display->priv;
183
 
    GstVaapiDisplayCache *cache;
184
 
    const GstVaapiDisplayInfo *info;
185
 
 
186
 
    cache = gst_vaapi_display_get_cache();
187
 
    g_return_val_if_fail(cache != NULL, FALSE);
188
 
 
189
 
    if (!set_display_name(display, name))
190
 
        return FALSE;
191
 
 
192
 
    info = gst_vaapi_display_cache_lookup_custom(cache, compare_display_name,
193
 
        priv->display_name, GST_VAAPI_DISPLAY_TYPES(display));
194
 
    if (info) {
195
 
        priv->x11_display = info->native_display;
196
 
        priv->use_foreign_display = TRUE;
197
 
    }
198
 
    else {
199
 
        priv->x11_display = XOpenDisplay(get_display_name(display));
200
 
        if (!priv->x11_display)
201
 
            return FALSE;
202
 
        priv->use_foreign_display = FALSE;
203
 
    }
204
 
    priv->x11_screen = DefaultScreen(priv->x11_display);
205
 
 
206
 
    check_extensions(display);
207
 
    return TRUE;
208
 
}
209
 
 
210
 
static void
211
 
gst_vaapi_display_x11_close_display(GstVaapiDisplay *display)
212
 
{
213
 
    GstVaapiDisplayX11Private * const priv =
214
 
        GST_VAAPI_DISPLAY_X11_PRIVATE(display);
215
 
 
216
 
    if (priv->pixmap_formats) {
217
 
        g_array_free(priv->pixmap_formats, TRUE);
218
 
        priv->pixmap_formats = NULL;
219
 
    }
220
 
 
221
 
    if (priv->x11_display) {
222
 
        if (!priv->use_foreign_display)
223
 
            XCloseDisplay(priv->x11_display);
224
 
        priv->x11_display = NULL;
225
 
    }
226
 
 
227
 
    if (priv->display_name) {
228
 
        g_free(priv->display_name);
229
 
        priv->display_name = NULL;
230
 
    }
231
 
}
232
 
 
233
 
static void
234
 
gst_vaapi_display_x11_sync(GstVaapiDisplay *display)
235
 
{
236
 
    GstVaapiDisplayX11Private * const priv =
237
 
        GST_VAAPI_DISPLAY_X11_PRIVATE(display);
238
 
 
239
 
    if (priv->x11_display) {
240
 
        GST_VAAPI_DISPLAY_LOCK(display);
241
 
        XSync(priv->x11_display, False);
242
 
        GST_VAAPI_DISPLAY_UNLOCK(display);
243
 
    }
244
 
}
245
 
 
246
 
static void
247
 
gst_vaapi_display_x11_flush(GstVaapiDisplay *display)
248
 
{
249
 
    GstVaapiDisplayX11Private * const priv =
250
 
        GST_VAAPI_DISPLAY_X11_PRIVATE(display);
251
 
 
252
 
    if (priv->x11_display) {
253
 
        GST_VAAPI_DISPLAY_LOCK(display);
254
 
        XFlush(priv->x11_display);
255
 
        GST_VAAPI_DISPLAY_UNLOCK(display);
256
 
    }
257
 
}
258
 
 
259
 
static gboolean
260
 
gst_vaapi_display_x11_get_display_info(
261
 
    GstVaapiDisplay     *display,
262
 
    GstVaapiDisplayInfo *info
263
 
)
264
 
{
265
 
    GstVaapiDisplayX11Private * const priv =
266
 
        GST_VAAPI_DISPLAY_X11_PRIVATE(display);
267
 
    GstVaapiDisplayCache *cache;
268
 
    const GstVaapiDisplayInfo *cached_info;
269
 
 
270
 
    /* Return any cached info even if child has its own VA display */
271
 
    cache = gst_vaapi_display_get_cache();
272
 
    if (!cache)
273
 
        return FALSE;
274
 
    cached_info = gst_vaapi_display_cache_lookup_by_native_display(
275
 
        cache, priv->x11_display, GST_VAAPI_DISPLAY_TYPES(display));
276
 
    if (cached_info) {
277
 
        *info = *cached_info;
278
 
        return TRUE;
279
 
    }
280
 
 
281
 
    /* Otherwise, create VA display if there is none already */
282
 
    info->native_display = priv->x11_display;
283
 
    info->display_name   = priv->display_name;
284
 
    if (!info->va_display) {
285
 
        info->va_display = vaGetDisplay(priv->x11_display);
286
 
        if (!info->va_display)
287
 
            return FALSE;
288
 
        info->display_type = GST_VAAPI_DISPLAY_TYPE_X11;
289
 
    }
290
 
    return TRUE;
291
 
}
292
 
 
293
 
static void
294
 
gst_vaapi_display_x11_get_size(
295
 
    GstVaapiDisplay *display,
296
 
    guint           *pwidth,
297
 
    guint           *pheight
298
 
)
299
 
{
300
 
    GstVaapiDisplayX11Private * const priv =
301
 
        GST_VAAPI_DISPLAY_X11_PRIVATE(display);
302
 
 
303
 
    if (!priv->x11_display)
304
 
        return;
305
 
 
306
 
    if (pwidth)
307
 
        *pwidth = DisplayWidth(priv->x11_display, priv->x11_screen);
308
 
 
309
 
    if (pheight)
310
 
        *pheight = DisplayHeight(priv->x11_display, priv->x11_screen);
311
 
}
312
 
 
313
 
static void
314
 
gst_vaapi_display_x11_get_size_mm(
315
 
    GstVaapiDisplay *display,
316
 
    guint           *pwidth,
317
 
    guint           *pheight
318
 
)
319
 
{
320
 
    GstVaapiDisplayX11Private * const priv =
321
 
        GST_VAAPI_DISPLAY_X11_PRIVATE(display);
322
 
    guint width_mm, height_mm;
323
 
 
324
 
    if (!priv->x11_display)
325
 
        return;
326
 
 
327
 
    width_mm  = DisplayWidthMM(priv->x11_display, priv->x11_screen);
328
 
    height_mm = DisplayHeightMM(priv->x11_display, priv->x11_screen);
 
211
  } else {
 
212
    priv->x11_display = XOpenDisplay (get_display_name (display));
 
213
    if (!priv->x11_display)
 
214
      return FALSE;
 
215
    priv->use_foreign_display = FALSE;
 
216
  }
 
217
  priv->x11_screen = DefaultScreen (priv->x11_display);
 
218
 
 
219
  check_extensions (display);
 
220
  return TRUE;
 
221
}
 
222
 
 
223
static void
 
224
gst_vaapi_display_x11_close_display (GstVaapiDisplay * display)
 
225
{
 
226
  GstVaapiDisplayX11Private *const priv =
 
227
      GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
228
 
 
229
  if (priv->pixmap_formats) {
 
230
    g_array_free (priv->pixmap_formats, TRUE);
 
231
    priv->pixmap_formats = NULL;
 
232
  }
 
233
 
 
234
  if (priv->x11_display) {
 
235
    if (!priv->use_foreign_display)
 
236
      XCloseDisplay (priv->x11_display);
 
237
    priv->x11_display = NULL;
 
238
  }
 
239
 
 
240
  if (priv->display_name) {
 
241
    g_free (priv->display_name);
 
242
    priv->display_name = NULL;
 
243
  }
 
244
}
 
245
 
 
246
static void
 
247
gst_vaapi_display_x11_sync (GstVaapiDisplay * display)
 
248
{
 
249
  GstVaapiDisplayX11Private *const priv =
 
250
      GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
251
 
 
252
  if (priv->x11_display) {
 
253
    GST_VAAPI_DISPLAY_LOCK (display);
 
254
    XSync (priv->x11_display, False);
 
255
    GST_VAAPI_DISPLAY_UNLOCK (display);
 
256
  }
 
257
}
 
258
 
 
259
static void
 
260
gst_vaapi_display_x11_flush (GstVaapiDisplay * display)
 
261
{
 
262
  GstVaapiDisplayX11Private *const priv =
 
263
      GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
264
 
 
265
  if (priv->x11_display) {
 
266
    GST_VAAPI_DISPLAY_LOCK (display);
 
267
    XFlush (priv->x11_display);
 
268
    GST_VAAPI_DISPLAY_UNLOCK (display);
 
269
  }
 
270
}
 
271
 
 
272
static gboolean
 
273
gst_vaapi_display_x11_get_display_info (GstVaapiDisplay * display,
 
274
    GstVaapiDisplayInfo * info)
 
275
{
 
276
  GstVaapiDisplayX11Private *const priv =
 
277
      GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
278
  GstVaapiDisplayCache *const cache = GST_VAAPI_DISPLAY_GET_CACHE (display);
 
279
  const GstVaapiDisplayInfo *cached_info;
 
280
 
 
281
  /* Return any cached info even if child has its own VA display */
 
282
  cached_info = gst_vaapi_display_cache_lookup_by_native_display (cache,
 
283
      priv->x11_display, GST_VAAPI_DISPLAY_TYPES (display));
 
284
  if (cached_info) {
 
285
    *info = *cached_info;
 
286
    return TRUE;
 
287
  }
 
288
 
 
289
  /* Otherwise, create VA display if there is none already */
 
290
  info->native_display = priv->x11_display;
 
291
  info->display_name = priv->display_name;
 
292
  if (!info->va_display) {
 
293
    info->va_display = vaGetDisplay (priv->x11_display);
 
294
    if (!info->va_display)
 
295
      return FALSE;
 
296
    info->display_type = GST_VAAPI_DISPLAY_TYPE_X11;
 
297
  }
 
298
  return TRUE;
 
299
}
 
300
 
 
301
static void
 
302
gst_vaapi_display_x11_get_size (GstVaapiDisplay * display,
 
303
    guint * pwidth, guint * pheight)
 
304
{
 
305
  GstVaapiDisplayX11Private *const priv =
 
306
      GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
307
 
 
308
  if (!priv->x11_display)
 
309
    return;
 
310
 
 
311
  if (pwidth)
 
312
    *pwidth = DisplayWidth (priv->x11_display, priv->x11_screen);
 
313
 
 
314
  if (pheight)
 
315
    *pheight = DisplayHeight (priv->x11_display, priv->x11_screen);
 
316
}
 
317
 
 
318
static void
 
319
gst_vaapi_display_x11_get_size_mm (GstVaapiDisplay * display,
 
320
    guint * pwidth, guint * pheight)
 
321
{
 
322
  GstVaapiDisplayX11Private *const priv =
 
323
      GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
324
  guint width_mm, height_mm;
 
325
 
 
326
  if (!priv->x11_display)
 
327
    return;
 
328
 
 
329
  width_mm = DisplayWidthMM (priv->x11_display, priv->x11_screen);
 
330
  height_mm = DisplayHeightMM (priv->x11_display, priv->x11_screen);
329
331
 
330
332
#ifdef HAVE_XRANDR
331
 
    /* XXX: fix up physical size if the display is rotated */
332
 
    if (priv->use_xrandr) {
333
 
        XRRScreenConfiguration *xrr_config = NULL;
334
 
        XRRScreenSize *xrr_sizes;
335
 
        Window win;
336
 
        int num_xrr_sizes, size_id, screen;
337
 
        Rotation rotation;
338
 
 
339
 
        do {
340
 
            win    = DefaultRootWindow(priv->x11_display);
341
 
            screen = XRRRootToScreen(priv->x11_display, win);
342
 
 
343
 
            xrr_config = XRRGetScreenInfo(priv->x11_display, win);
344
 
            if (!xrr_config)
345
 
                break;
346
 
 
347
 
            size_id = XRRConfigCurrentConfiguration(xrr_config, &rotation);
348
 
            if (rotation == RR_Rotate_0 || rotation == RR_Rotate_180)
349
 
                break;
350
 
 
351
 
            xrr_sizes = XRRSizes(priv->x11_display, screen, &num_xrr_sizes);
352
 
            if (!xrr_sizes || size_id >= num_xrr_sizes)
353
 
                break;
354
 
 
355
 
            width_mm  = xrr_sizes[size_id].mheight;
356
 
            height_mm = xrr_sizes[size_id].mwidth;
357
 
        } while (0);
358
 
        if (xrr_config)
359
 
            XRRFreeScreenConfigInfo(xrr_config);
360
 
    }
 
333
  /* XXX: fix up physical size if the display is rotated */
 
334
  if (priv->use_xrandr) {
 
335
    XRRScreenConfiguration *xrr_config = NULL;
 
336
    XRRScreenSize *xrr_sizes;
 
337
    Window win;
 
338
    int num_xrr_sizes, size_id, screen;
 
339
    Rotation rotation;
 
340
 
 
341
    do {
 
342
      win = DefaultRootWindow (priv->x11_display);
 
343
      screen = XRRRootToScreen (priv->x11_display, win);
 
344
 
 
345
      xrr_config = XRRGetScreenInfo (priv->x11_display, win);
 
346
      if (!xrr_config)
 
347
        break;
 
348
 
 
349
      size_id = XRRConfigCurrentConfiguration (xrr_config, &rotation);
 
350
      if (rotation == RR_Rotate_0 || rotation == RR_Rotate_180)
 
351
        break;
 
352
 
 
353
      xrr_sizes = XRRSizes (priv->x11_display, screen, &num_xrr_sizes);
 
354
      if (!xrr_sizes || size_id >= num_xrr_sizes)
 
355
        break;
 
356
 
 
357
      width_mm = xrr_sizes[size_id].mheight;
 
358
      height_mm = xrr_sizes[size_id].mwidth;
 
359
    } while (0);
 
360
    if (xrr_config)
 
361
      XRRFreeScreenConfigInfo (xrr_config);
 
362
  }
361
363
#endif
362
364
 
363
 
    if (pwidth)
364
 
        *pwidth = width_mm;
 
365
  if (pwidth)
 
366
    *pwidth = width_mm;
365
367
 
366
 
    if (pheight)
367
 
        *pheight = height_mm;
 
368
  if (pheight)
 
369
    *pheight = height_mm;
368
370
}
369
371
 
370
372
void
371
 
gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass)
 
373
gst_vaapi_display_x11_class_init (GstVaapiDisplayX11Class * klass)
372
374
{
373
 
    GstVaapiMiniObjectClass * const object_class =
374
 
        GST_VAAPI_MINI_OBJECT_CLASS(klass);
375
 
    GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass);
376
 
 
377
 
    gst_vaapi_display_class_init(&klass->parent_class);
378
 
 
379
 
    object_class->size          = sizeof(GstVaapiDisplayX11);
380
 
    dpy_class->display_types    = g_display_types;
381
 
    dpy_class->bind_display     = gst_vaapi_display_x11_bind_display;
382
 
    dpy_class->open_display     = gst_vaapi_display_x11_open_display;
383
 
    dpy_class->close_display    = gst_vaapi_display_x11_close_display;
384
 
    dpy_class->sync             = gst_vaapi_display_x11_sync;
385
 
    dpy_class->flush            = gst_vaapi_display_x11_flush;
386
 
    dpy_class->get_display      = gst_vaapi_display_x11_get_display_info;
387
 
    dpy_class->get_size         = gst_vaapi_display_x11_get_size;
388
 
    dpy_class->get_size_mm      = gst_vaapi_display_x11_get_size_mm;
 
375
  GstVaapiMiniObjectClass *const object_class =
 
376
      GST_VAAPI_MINI_OBJECT_CLASS (klass);
 
377
  GstVaapiDisplayClass *const dpy_class = GST_VAAPI_DISPLAY_CLASS (klass);
 
378
 
 
379
  gst_vaapi_display_class_init (&klass->parent_class);
 
380
 
 
381
  object_class->size = sizeof (GstVaapiDisplayX11);
 
382
  dpy_class->display_types = g_display_types;
 
383
  dpy_class->bind_display = gst_vaapi_display_x11_bind_display;
 
384
  dpy_class->open_display = gst_vaapi_display_x11_open_display;
 
385
  dpy_class->close_display = gst_vaapi_display_x11_close_display;
 
386
  dpy_class->sync = gst_vaapi_display_x11_sync;
 
387
  dpy_class->flush = gst_vaapi_display_x11_flush;
 
388
  dpy_class->get_display = gst_vaapi_display_x11_get_display_info;
 
389
  dpy_class->get_size = gst_vaapi_display_x11_get_size;
 
390
  dpy_class->get_size_mm = gst_vaapi_display_x11_get_size_mm;
389
391
}
390
392
 
391
393
static inline const GstVaapiDisplayClass *
392
 
gst_vaapi_display_x11_class(void)
 
394
gst_vaapi_display_x11_class (void)
393
395
{
394
 
    static GstVaapiDisplayX11Class g_class;
395
 
    static gsize g_class_init = FALSE;
 
396
  static GstVaapiDisplayX11Class g_class;
 
397
  static gsize g_class_init = FALSE;
396
398
 
397
 
    if (g_once_init_enter(&g_class_init)) {
398
 
        gst_vaapi_display_x11_class_init(&g_class);
399
 
        g_once_init_leave(&g_class_init, TRUE);
400
 
    }
401
 
    return GST_VAAPI_DISPLAY_CLASS(&g_class);
 
399
  if (g_once_init_enter (&g_class_init)) {
 
400
    gst_vaapi_display_x11_class_init (&g_class);
 
401
    g_once_init_leave (&g_class_init, TRUE);
 
402
  }
 
403
  return GST_VAAPI_DISPLAY_CLASS (&g_class);
402
404
}
403
405
 
404
406
/**
412
414
 * Return value: a newly allocated #GstVaapiDisplay object
413
415
 */
414
416
GstVaapiDisplay *
415
 
gst_vaapi_display_x11_new(const gchar *display_name)
 
417
gst_vaapi_display_x11_new (const gchar * display_name)
416
418
{
417
 
    return gst_vaapi_display_new(gst_vaapi_display_x11_class(),
418
 
        GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer)display_name);
 
419
  return gst_vaapi_display_new (gst_vaapi_display_x11_class (),
 
420
      GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME, (gpointer) display_name);
419
421
}
420
422
 
421
423
/**
430
432
 * Return value: a newly allocated #GstVaapiDisplay object
431
433
 */
432
434
GstVaapiDisplay *
433
 
gst_vaapi_display_x11_new_with_display(Display *x11_display)
 
435
gst_vaapi_display_x11_new_with_display (Display * x11_display)
434
436
{
435
 
    g_return_val_if_fail(x11_display, NULL);
 
437
  g_return_val_if_fail (x11_display, NULL);
436
438
 
437
 
    return gst_vaapi_display_new(gst_vaapi_display_x11_class(),
438
 
        GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display);
 
439
  return gst_vaapi_display_new (gst_vaapi_display_x11_class (),
 
440
      GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY, x11_display);
439
441
}
440
442
 
441
443
/**
449
451
 * Return value: the X11 #Display attached to @display
450
452
 */
451
453
Display *
452
 
gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display)
 
454
gst_vaapi_display_x11_get_display (GstVaapiDisplayX11 * display)
453
455
{
454
 
    g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL);
 
456
  g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), NULL);
455
457
 
456
 
    return GST_VAAPI_DISPLAY_XDISPLAY(display);
 
458
  return GST_VAAPI_DISPLAY_XDISPLAY (display);
457
459
}
458
460
 
459
461
/**
467
469
 * Return value: the X11 #Display attached to @display
468
470
 */
469
471
int
470
 
gst_vaapi_display_x11_get_screen(GstVaapiDisplayX11 *display)
 
472
gst_vaapi_display_x11_get_screen (GstVaapiDisplayX11 * display)
471
473
{
472
 
    g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), -1);
 
474
  g_return_val_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display), -1);
473
475
 
474
 
    return GST_VAAPI_DISPLAY_XSCREEN(display);
 
476
  return GST_VAAPI_DISPLAY_XSCREEN (display);
475
477
}
476
478
 
477
479
/**
486
488
 * @synchronous is %FALSE.
487
489
 */
488
490
void
489
 
gst_vaapi_display_x11_set_synchronous(GstVaapiDisplayX11 *display,
 
491
gst_vaapi_display_x11_set_synchronous (GstVaapiDisplayX11 * display,
490
492
    gboolean synchronous)
491
493
{
492
 
    g_return_if_fail(GST_VAAPI_IS_DISPLAY_X11(display));
 
494
  g_return_if_fail (GST_VAAPI_IS_DISPLAY_X11 (display));
493
495
 
494
 
    set_synchronous(display, synchronous);
 
496
  set_synchronous (display, synchronous);
495
497
}
496
498
 
497
499
typedef struct _GstVaapiPixmapFormatX11 GstVaapiPixmapFormatX11;
498
 
struct _GstVaapiPixmapFormatX11 {
499
 
    GstVideoFormat      format;
500
 
    gint                depth;
501
 
    gint                bpp;
 
500
struct _GstVaapiPixmapFormatX11
 
501
{
 
502
  GstVideoFormat format;
 
503
  gint depth;
 
504
  gint bpp;
502
505
};
503
506
 
504
507
static GstVideoFormat
505
 
pix_fmt_to_video_format(gint depth, gint bpp)
 
508
pix_fmt_to_video_format (gint depth, gint bpp)
506
509
{
507
 
    GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
 
510
  GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
508
511
 
509
 
    switch (bpp) {
 
512
  switch (bpp) {
510
513
    case 16:
511
 
        if (depth == 15)
512
 
            format = GST_VIDEO_FORMAT_RGB15;
513
 
        else if (depth == 16)
514
 
            format = GST_VIDEO_FORMAT_RGB16;
515
 
        break;
 
514
      if (depth == 15)
 
515
        format = GST_VIDEO_FORMAT_RGB15;
 
516
      else if (depth == 16)
 
517
        format = GST_VIDEO_FORMAT_RGB16;
 
518
      break;
516
519
    case 24:
517
 
        if (depth == 24)
518
 
            format = GST_VIDEO_FORMAT_RGB;
519
 
        break;
 
520
      if (depth == 24)
 
521
        format = GST_VIDEO_FORMAT_RGB;
 
522
      break;
520
523
    case 32:
521
 
        if (depth == 24 || depth == 32)
522
 
            format = GST_VIDEO_FORMAT_xRGB;
523
 
        break;
524
 
    }
525
 
    return format;
 
524
      if (depth == 24 || depth == 32)
 
525
        format = GST_VIDEO_FORMAT_xRGB;
 
526
      break;
 
527
  }
 
528
  return format;
526
529
}
527
530
 
528
531
static gboolean
529
 
ensure_pix_fmts(GstVaapiDisplayX11 *display)
 
532
ensure_pix_fmts (GstVaapiDisplayX11 * display)
530
533
{
531
 
    GstVaapiDisplayX11Private * const priv =
532
 
        GST_VAAPI_DISPLAY_X11_PRIVATE(display);
533
 
    XPixmapFormatValues *pix_fmts;
534
 
    int i, n, num_pix_fmts;
535
 
 
536
 
    if (priv->pixmap_formats)
537
 
        return TRUE;
538
 
 
539
 
    GST_VAAPI_DISPLAY_LOCK(display);
540
 
    pix_fmts = XListPixmapFormats(GST_VAAPI_DISPLAY_XDISPLAY(display),
541
 
        &num_pix_fmts);
542
 
    GST_VAAPI_DISPLAY_UNLOCK(display);
543
 
    if (!pix_fmts)
544
 
        return FALSE;
545
 
 
546
 
    priv->pixmap_formats = g_array_sized_new(FALSE, FALSE,
547
 
        sizeof(GstVaapiPixmapFormatX11), num_pix_fmts);
548
 
    if (!priv->pixmap_formats) {
549
 
        XFree(pix_fmts);
550
 
        return FALSE;
551
 
    }
552
 
 
553
 
    for (i = 0, n = 0; i < num_pix_fmts; i++) {
554
 
        GstVaapiPixmapFormatX11 * const pix_fmt =
555
 
            &g_array_index(priv->pixmap_formats, GstVaapiPixmapFormatX11, n);
556
 
 
557
 
        pix_fmt->depth  = pix_fmts[i].depth;
558
 
        pix_fmt->bpp    = pix_fmts[i].bits_per_pixel;
559
 
        pix_fmt->format = pix_fmt_to_video_format(pix_fmt->depth, pix_fmt->bpp);
560
 
        if (pix_fmt->format != GST_VIDEO_FORMAT_UNKNOWN)
561
 
            n++;
562
 
    }
563
 
    priv->pixmap_formats->len = n;
 
534
  GstVaapiDisplayX11Private *const priv =
 
535
      GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
536
  XPixmapFormatValues *pix_fmts;
 
537
  int i, n, num_pix_fmts;
 
538
 
 
539
  if (priv->pixmap_formats)
564
540
    return TRUE;
 
541
 
 
542
  GST_VAAPI_DISPLAY_LOCK (display);
 
543
  pix_fmts = XListPixmapFormats (GST_VAAPI_DISPLAY_XDISPLAY (display),
 
544
      &num_pix_fmts);
 
545
  GST_VAAPI_DISPLAY_UNLOCK (display);
 
546
  if (!pix_fmts)
 
547
    return FALSE;
 
548
 
 
549
  priv->pixmap_formats = g_array_sized_new (FALSE, FALSE,
 
550
      sizeof (GstVaapiPixmapFormatX11), num_pix_fmts);
 
551
  if (!priv->pixmap_formats) {
 
552
    XFree (pix_fmts);
 
553
    return FALSE;
 
554
  }
 
555
 
 
556
  for (i = 0, n = 0; i < num_pix_fmts; i++) {
 
557
    GstVaapiPixmapFormatX11 *const pix_fmt =
 
558
        &g_array_index (priv->pixmap_formats, GstVaapiPixmapFormatX11, n);
 
559
 
 
560
    pix_fmt->depth = pix_fmts[i].depth;
 
561
    pix_fmt->bpp = pix_fmts[i].bits_per_pixel;
 
562
    pix_fmt->format = pix_fmt_to_video_format (pix_fmt->depth, pix_fmt->bpp);
 
563
    if (pix_fmt->format != GST_VIDEO_FORMAT_UNKNOWN)
 
564
      n++;
 
565
  }
 
566
  priv->pixmap_formats->len = n;
 
567
  return TRUE;
565
568
}
566
569
 
567
570
/* Determine the GstVideoFormat based on a supported Pixmap depth */
568
571
GstVideoFormat
569
 
gst_vaapi_display_x11_get_pixmap_format(GstVaapiDisplayX11 *display,
 
572
gst_vaapi_display_x11_get_pixmap_format (GstVaapiDisplayX11 * display,
570
573
    guint depth)
571
574
{
572
 
    if (ensure_pix_fmts(display)) {
573
 
        GstVaapiDisplayX11Private * const priv =
574
 
            GST_VAAPI_DISPLAY_X11_PRIVATE(display);
575
 
        guint i;
 
575
  if (ensure_pix_fmts (display)) {
 
576
    GstVaapiDisplayX11Private *const priv =
 
577
        GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
578
    guint i;
576
579
 
577
 
        for (i = 0; i < priv->pixmap_formats->len; i++) {
578
 
            GstVaapiPixmapFormatX11 * const pix_fmt = &g_array_index(
579
 
                priv->pixmap_formats, GstVaapiPixmapFormatX11, i);
580
 
            if (pix_fmt->depth == depth)
581
 
                return pix_fmt->format;
582
 
        }
 
580
    for (i = 0; i < priv->pixmap_formats->len; i++) {
 
581
      GstVaapiPixmapFormatX11 *const pix_fmt =
 
582
          &g_array_index (priv->pixmap_formats, GstVaapiPixmapFormatX11, i);
 
583
      if (pix_fmt->depth == depth)
 
584
        return pix_fmt->format;
583
585
    }
584
 
    return GST_VIDEO_FORMAT_UNKNOWN;
 
586
  }
 
587
  return GST_VIDEO_FORMAT_UNKNOWN;
585
588
}
586
589
 
587
590
/* Determine the Pixmap depth based on a GstVideoFormat */
588
591
guint
589
 
gst_vaapi_display_x11_get_pixmap_depth(GstVaapiDisplayX11 *display,
 
592
gst_vaapi_display_x11_get_pixmap_depth (GstVaapiDisplayX11 * display,
590
593
    GstVideoFormat format)
591
594
{
592
 
    if (ensure_pix_fmts(display)) {
593
 
        GstVaapiDisplayX11Private * const priv =
594
 
            GST_VAAPI_DISPLAY_X11_PRIVATE(display);
595
 
        guint i;
 
595
  if (ensure_pix_fmts (display)) {
 
596
    GstVaapiDisplayX11Private *const priv =
 
597
        GST_VAAPI_DISPLAY_X11_PRIVATE (display);
 
598
    guint i;
596
599
 
597
 
        for (i = 0; i < priv->pixmap_formats->len; i++) {
598
 
            GstVaapiPixmapFormatX11 * const pix_fmt = &g_array_index(
599
 
                priv->pixmap_formats, GstVaapiPixmapFormatX11, i);
600
 
            if (pix_fmt->format == format)
601
 
                return pix_fmt->depth;
602
 
        }
 
600
    for (i = 0; i < priv->pixmap_formats->len; i++) {
 
601
      GstVaapiPixmapFormatX11 *const pix_fmt =
 
602
          &g_array_index (priv->pixmap_formats, GstVaapiPixmapFormatX11, i);
 
603
      if (pix_fmt->format == format)
 
604
        return pix_fmt->depth;
603
605
    }
604
 
    return 0;
 
606
  }
 
607
  return 0;
605
608
}