tests: use gst_vaapi_image_format_from_structure() in test-display.
[vaapi:gstreamer-vaapi.git] / tests / test-display.c
1 /*
2  *  test-display.c - Test GstVaapiDisplayX11
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *  Copyright (C) 2012 Intel Corporation
6  *
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.
11  *
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.
16  *
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
21 */
22
23 #include "gst/vaapi/sysdeps.h"
24 #include <gst/video/video.h>
25 #if USE_DRM
26 # include <gst/vaapi/gstvaapidisplay_drm.h>
27 # include <va/va_drm.h>
28 # include <fcntl.h>
29 # include <unistd.h>
30 # ifndef DRM_DEVICE_PATH
31 # define DRM_DEVICE_PATH "/dev/dri/card0"
32 # endif
33 #endif
34 #if USE_X11
35 # include <gst/vaapi/gstvaapidisplay_x11.h>
36 #endif
37 #if USE_GLX
38 # include <gst/vaapi/gstvaapidisplay_glx.h>
39 #endif
40 #if USE_WAYLAND
41 # include <gst/vaapi/gstvaapidisplay_wayland.h>
42 #endif
43
44 #ifdef HAVE_VA_VA_GLX_H
45 # include <va/va_glx.h>
46 #endif
47
48 static void
49 print_value(const GValue *value, const gchar *name)
50 {
51     gchar *value_string;
52
53     value_string = g_strdup_value_contents(value);
54     if (!value_string)
55         return;
56     g_print("  %s: %s\n", name, value_string);
57     g_free(value_string);
58 }
59
60 static void
61 print_profile_caps(GstCaps *caps, const gchar *name)
62 {
63     guint i, n_caps = gst_caps_get_size(caps);
64     gint version;
65     const gchar *profile;
66     gboolean has_version;
67
68     g_print("%u %s caps\n", n_caps, name);
69
70     for (i = 0; i < gst_caps_get_size(caps); i++) {
71         GstStructure * const structure = gst_caps_get_structure(caps, i);
72         if (!structure)
73             g_error("could not get caps structure %d", i);
74
75         has_version = (
76             gst_structure_get_int(structure, "version", &version) ||
77             gst_structure_get_int(structure, "mpegversion", &version)
78         );
79
80         g_print("  %s", gst_structure_get_name(structure));
81         if (has_version)
82             g_print("%d", version);
83
84         profile = gst_structure_get_string(structure, "profile");
85         if (!profile)
86             g_error("could not get structure profile");
87         g_print(": %s profile\n", profile);
88     }
89 }
90
91 static void
92 print_format_caps_yuv(const VAImageFormat *va_format)
93 {
94     const guint32 fourcc = va_format->fourcc;
95
96     g_print(" fourcc '%c%c%c%c'",
97             fourcc & 0xff,
98             (fourcc >> 8) & 0xff,
99             (fourcc >> 16) & 0xff,
100             (fourcc >> 24) & 0xff);
101 }
102
103 static void
104 print_format_caps_rgb(const VAImageFormat *va_format)
105 {
106     g_print(" %d bits per pixel, %s endian,",
107             va_format->bits_per_pixel,
108             va_format->byte_order == VA_MSB_FIRST ? "big" : "little");
109     g_print(" %s masks", va_format->alpha_mask ? "rgba" : "rgb");
110     g_print(" 0x%08x 0x%08x 0x%08x",
111             va_format->red_mask, va_format->green_mask, va_format->blue_mask);
112     if (va_format->alpha_mask)
113         g_print(" 0x%08x", va_format->alpha_mask);
114 }
115
116 static void
117 print_format_caps(GstCaps *caps, const gchar *name)
118 {
119     guint i, n_caps = gst_caps_get_size(caps);
120
121     g_print("%u %s caps\n", n_caps, name);
122
123     for (i = 0; i < gst_caps_get_size(caps); i++) {
124         GstStructure * const structure = gst_caps_get_structure(caps, i);
125         const VAImageFormat *va_format;
126         GstVaapiImageFormat format;
127
128         if (!structure)
129             g_error("could not get caps structure %d", i);
130
131         g_print("  %s:", gst_structure_get_name(structure));
132
133         format = gst_vaapi_image_format_from_structure(structure);
134         if (!format)
135             g_error("could not determine format");
136
137         va_format = gst_vaapi_image_format_get_va_format(format);
138         if (!va_format)
139             g_error("could not determine VA format");
140
141         if (gst_vaapi_image_format_is_yuv(format))
142             print_format_caps_yuv(va_format);
143         else
144             print_format_caps_rgb(va_format);
145         g_print("\n");
146     }
147 }
148
149 typedef struct _GstVaapiDisplayProperty GstVaapiDisplayProperty;
150 struct _GstVaapiDisplayProperty {
151     const gchar *name;
152     GValue       value;
153 };
154
155 static void
156 gst_vaapi_display_property_free(GstVaapiDisplayProperty *prop)
157 {
158     if (!prop)
159         return;
160     g_value_unset(&prop->value);
161     g_slice_free(GstVaapiDisplayProperty, prop);
162 }
163
164 static GstVaapiDisplayProperty *
165 gst_vaapi_display_property_new(const gchar *name)
166 {
167     GstVaapiDisplayProperty *prop;
168
169     prop = g_slice_new0(GstVaapiDisplayProperty);
170     if (!prop)
171         return NULL;
172     prop->name = name;
173     return prop;
174 }
175
176 static void
177 free_property_cb(gpointer data, gpointer user_data)
178 {
179     gst_vaapi_display_property_free(data);
180 }
181
182 static inline GParamSpec *
183 get_display_property(GstVaapiDisplay *display, const gchar *name)
184 {
185     GObjectClass *klass;
186
187     klass = G_OBJECT_CLASS(GST_VAAPI_DISPLAY_GET_CLASS(display));
188     if (!klass)
189         return NULL;
190     return g_object_class_find_property(klass, name);
191 }
192
193 static void
194 dump_properties(GstVaapiDisplay *display)
195 {
196     GstVaapiDisplayProperty *prop;
197     GPtrArray *properties;
198     guint i;
199
200     static const gchar *g_properties[] = {
201         GST_VAAPI_DISPLAY_PROP_RENDER_MODE,
202         GST_VAAPI_DISPLAY_PROP_ROTATION,
203         GST_VAAPI_DISPLAY_PROP_HUE,
204         GST_VAAPI_DISPLAY_PROP_SATURATION,
205         GST_VAAPI_DISPLAY_PROP_BRIGHTNESS,
206         GST_VAAPI_DISPLAY_PROP_CONTRAST,
207         NULL
208     };
209
210     properties = g_ptr_array_new();
211     if (!properties)
212         return;
213
214     for (i = 0; g_properties[i] != NULL; i++) {
215         GParamSpec *pspec = get_display_property(display, g_properties[i]);
216
217         if (!pspec) {
218             GST_ERROR("failed to find GstVaapiDisplay property '%s'",
219                       g_properties[i]);
220             goto end;
221         }
222
223         if (!gst_vaapi_display_has_property(display, pspec->name))
224             continue;
225             
226         prop = gst_vaapi_display_property_new(pspec->name);
227         if (!prop) {
228             GST_ERROR("failed to allocate GstVaapiDisplayProperty");
229             goto end;
230         }
231
232         g_value_init(&prop->value, pspec->value_type);
233         g_object_get_property(G_OBJECT(display), pspec->name, &prop->value);
234         g_ptr_array_add(properties, prop);
235     }
236
237     g_print("%u properties\n", properties->len);
238     for (i = 0; i < properties->len; i++) {
239         prop = g_ptr_array_index(properties, i);
240         print_value(&prop->value, prop->name);
241     }
242
243 end:
244     if (properties) {
245         g_ptr_array_foreach(properties, free_property_cb, NULL);
246         g_ptr_array_free(properties, TRUE);
247     }
248 }
249
250 static void
251 dump_info(GstVaapiDisplay *display)
252 {
253     GstCaps *caps;
254
255     caps = gst_vaapi_display_get_decode_caps(display);
256     if (!caps)
257         g_error("could not get VA decode caps");
258
259     print_profile_caps(caps, "decoders");
260     gst_caps_unref(caps);
261
262     caps = gst_vaapi_display_get_encode_caps(display);
263     if (!caps)
264         g_error("could not get VA encode caps");
265
266     print_profile_caps(caps, "encoders");
267     gst_caps_unref(caps);
268
269     caps = gst_vaapi_display_get_image_caps(display);
270     if (!caps)
271         g_error("could not get VA image caps");
272
273     print_format_caps(caps, "image");
274     gst_caps_unref(caps);
275
276     caps = gst_vaapi_display_get_subpicture_caps(display);
277     if (!caps)
278         g_error("could not get VA subpicture caps");
279
280     print_format_caps(caps, "subpicture");
281     gst_caps_unref(caps);
282
283     dump_properties(display);
284 }
285
286 int
287 main(int argc, char *argv[])
288 {
289     GstVaapiDisplay *display;
290     guint width, height, par_n, par_d;
291
292     gst_init(&argc, &argv);
293
294 #if USE_DRM
295     g_print("#\n");
296     g_print("# Create display with gst_vaapi_display_drm_new()\n");
297     g_print("#\n");
298     {
299         display = gst_vaapi_display_drm_new(NULL);
300         if (!display)
301             g_error("could not create Gst/VA display");
302
303         dump_info(display);
304         g_object_unref(display);
305     }
306     g_print("\n");
307
308     g_print("#\n");
309     g_print("# Create display with gst_vaapi_display_drm_new_with_device()\n");
310     g_print("#\n");
311     {
312         int drm_device;
313
314         drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC);
315         if (drm_device < 0)
316             g_error("could not open DRM device");
317
318         display = gst_vaapi_display_drm_new_with_device(drm_device);
319         if (!display)
320             g_error("could not create Gst/VA display");
321
322         dump_info(display);
323         g_object_unref(display);
324         close(drm_device);
325     }
326     g_print("\n");
327
328     g_print("#\n");
329     g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayDRM()]\n");
330     g_print("#\n");
331     {
332         int drm_device;
333         VADisplay va_display;
334
335         drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC);
336         if (drm_device < 0)
337             g_error("could not open DRM device");
338
339         va_display = vaGetDisplayDRM(drm_device);
340         if (!va_display)
341             g_error("could not create VA display");
342
343         display = gst_vaapi_display_new_with_display(va_display);
344         if (!display)
345             g_error("could not create Gst/VA display");
346
347         dump_info(display);
348         g_object_unref(display);
349         close(drm_device);
350     }
351     g_print("\n");
352 #endif
353
354 #if USE_X11
355     g_print("#\n");
356     g_print("# Create display with gst_vaapi_display_x11_new()\n");
357     g_print("#\n");
358     {
359         display = gst_vaapi_display_x11_new(NULL);
360         if (!display)
361             g_error("could not create Gst/VA display");
362
363         gst_vaapi_display_get_size(display, &width, &height);
364         g_print("Display size: %ux%u\n", width, height);
365
366         gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d);
367         g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d);
368
369         dump_info(display);
370         g_object_unref(display);
371     }
372     g_print("\n");
373
374     g_print("#\n");
375     g_print("# Create display with gst_vaapi_display_x11_new_with_display()\n");
376     g_print("#\n");
377     {
378         Display *x11_display;
379
380         x11_display = XOpenDisplay(NULL);
381         if (!x11_display)
382             g_error("could not create X11 display");
383
384         display = gst_vaapi_display_x11_new_with_display(x11_display);
385         if (!display)
386             g_error("could not create Gst/VA display");
387
388         dump_info(display);
389         g_object_unref(display);
390         XCloseDisplay(x11_display);
391     }
392     g_print("\n");
393
394     g_print("#\n");
395     g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplay()]\n");
396     g_print("#\n");
397     {
398         Display *x11_display;
399         VADisplay va_display;
400
401         x11_display = XOpenDisplay(NULL);
402         if (!x11_display)
403             g_error("could not create X11 display");
404
405         va_display = vaGetDisplay(x11_display);
406         if (!va_display)
407             g_error("could not create VA display");
408
409         display = gst_vaapi_display_new_with_display(va_display);
410         if (!display)
411             g_error("could not create Gst/VA display");
412
413         dump_info(display);
414         g_object_unref(display);
415         XCloseDisplay(x11_display);
416     }
417     g_print("\n");
418 #endif
419
420 #if USE_GLX
421     g_print("#\n");
422     g_print("# Create display with gst_vaapi_display_glx_new()\n");
423     g_print("#\n");
424     {
425         display = gst_vaapi_display_glx_new(NULL);
426         if (!display)
427             g_error("could not create Gst/VA display");
428
429         gst_vaapi_display_get_size(display, &width, &height);
430         g_print("Display size: %ux%u\n", width, height);
431
432         gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d);
433         g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d);
434
435         dump_info(display);
436         g_object_unref(display);
437     }
438     g_print("\n");
439
440     g_print("#\n");
441     g_print("# Create display with gst_vaapi_display_glx_new_with_display()\n");
442     g_print("#\n");
443     {
444         Display *x11_display;
445
446         x11_display = XOpenDisplay(NULL);
447         if (!x11_display)
448             g_error("could not create X11 display");
449
450         display = gst_vaapi_display_glx_new_with_display(x11_display);
451         if (!display)
452             g_error("could not create Gst/VA display");
453
454         dump_info(display);
455         g_object_unref(display);
456         XCloseDisplay(x11_display);
457     }
458     g_print("\n");
459
460 #ifdef HAVE_VA_VA_GLX_H
461     g_print("#\n");
462     g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n");
463     g_print("#\n");
464     {
465         Display *x11_display;
466         VADisplay va_display;
467
468         x11_display = XOpenDisplay(NULL);
469         if (!x11_display)
470             g_error("could not create X11 display");
471
472         va_display = vaGetDisplayGLX(x11_display);
473         if (!va_display)
474             g_error("could not create VA display");
475
476         display = gst_vaapi_display_new_with_display(va_display);
477         if (!display)
478             g_error("could not create Gst/VA display");
479
480         dump_info(display);
481         g_object_unref(display);
482         XCloseDisplay(x11_display);
483     }
484     g_print("\n");
485 #endif
486 #endif
487
488 #if USE_WAYLAND
489     g_print("#\n");
490     g_print("# Create display with gst_vaapi_display_wayland_new()\n");
491     g_print("#\n");
492     {
493         display = gst_vaapi_display_wayland_new(NULL);
494         if (!display)
495             g_error("could not create Gst/VA display");
496
497         gst_vaapi_display_get_size(display, &width, &height);
498         g_print("Display size: %ux%u\n", width, height);
499
500         gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d);
501         g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d);
502
503         dump_info(display);
504         g_object_unref(display);
505     }
506     g_print("\n");
507 #endif
508
509     gst_deinit();
510     return 0;
511 }