1 /*
2  *  test-display.c - Test GstVaapiDisplayX11
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *    Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6  *  Copyright (C) 2012-2013 Intel Corporation
7  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public License
11  *  as published by the Free Software Foundation; either version 2.1
12  *  of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free
21  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA 02110-1301 USA
23  */
24 
25 #define _GNU_SOURCE
26 #include "gst/vaapi/sysdeps.h"
27 #include <gst/video/video.h>
28 #if USE_DRM
29 # include <gst/vaapi/gstvaapidisplay_drm.h>
30 # include <va/va_drm.h>
31 # include <fcntl.h>
32 # include <unistd.h>
33 # ifndef DRM_DEVICE_PATH
34 # define DRM_DEVICE_PATH "/dev/dri/card0"
35 # endif
36 #endif
37 #if USE_X11
38 # include <gst/vaapi/gstvaapidisplay_x11.h>
39 #endif
40 #if USE_GLX
41 # include <gst/vaapi/gstvaapidisplay_glx.h>
42 #endif
43 #if USE_WAYLAND
44 # include <gst/vaapi/gstvaapidisplay_wayland.h>
45 #endif
46 #if USE_EGL
47 # include <gst/vaapi/gstvaapidisplay_egl.h>
48 #endif
49 
50 #ifdef HAVE_VA_VA_GLX_H
51 # include <va/va_glx.h>
52 #endif
53 
54 static void
print_value(const GValue * value,const gchar * name)55 print_value (const GValue * value, const gchar * name)
56 {
57   gchar *value_string;
58 
59   value_string = g_strdup_value_contents (value);
60   if (!value_string)
61     return;
62   g_print ("  %s: %s\n", name, value_string);
63   g_free (value_string);
64 }
65 
66 static void
print_profiles(GArray * profiles,const gchar * name)67 print_profiles (GArray * profiles, const gchar * name)
68 {
69   GstVaapiCodec codec;
70   const gchar *codec_name, *profile_name;
71   guint i;
72 
73   g_print ("%u %s caps\n", profiles->len, name);
74 
75   for (i = 0; i < profiles->len; i++) {
76     const GstVaapiProfile profile =
77         g_array_index (profiles, GstVaapiProfile, i);
78 
79     codec = gst_vaapi_profile_get_codec (profile);
80     if (!codec)
81       continue;
82 
83     codec_name = gst_vaapi_codec_get_name (codec);
84     if (!codec_name)
85       continue;
86 
87     profile_name = gst_vaapi_profile_get_name (profile);
88     if (!profile_name)
89       continue;
90 
91     g_print ("  %s: %s profile\n", codec_name, profile_name);
92   }
93 }
94 
95 static void
print_format_yuv(const VAImageFormat * va_format)96 print_format_yuv (const VAImageFormat * va_format)
97 {
98   const guint32 fourcc = va_format->fourcc;
99 
100   g_print (" fourcc '%c%c%c%c'",
101       fourcc & 0xff,
102       (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff);
103 }
104 
105 static void
print_format_rgb(const VAImageFormat * va_format)106 print_format_rgb (const VAImageFormat * va_format)
107 {
108   g_print (" %d bits per pixel, %s endian,",
109       va_format->bits_per_pixel,
110       va_format->byte_order == VA_MSB_FIRST ? "big" : "little");
111   g_print (" %s masks", va_format->alpha_mask ? "rgba" : "rgb");
112   g_print (" 0x%08x 0x%08x 0x%08x",
113       va_format->red_mask, va_format->green_mask, va_format->blue_mask);
114   if (va_format->alpha_mask)
115     g_print (" 0x%08x", va_format->alpha_mask);
116 }
117 
118 static void
print_formats(GArray * formats,const gchar * name)119 print_formats (GArray * formats, const gchar * name)
120 {
121   guint i;
122 
123   g_print ("%u %s caps\n", formats->len, name);
124 
125   for (i = 0; i < formats->len; i++) {
126     const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
127     const VAImageFormat *va_format;
128 
129     g_print ("  %s:", gst_vaapi_video_format_to_string (format));
130 
131     va_format = gst_vaapi_video_format_to_va_format (format);
132     if (!va_format)
133       g_error ("could not determine VA format");
134 
135     if (gst_vaapi_video_format_is_yuv (format))
136       print_format_yuv (va_format);
137     else
138       print_format_rgb (va_format);
139     g_print ("\n");
140   }
141 }
142 
143 static void
dump_properties(GstVaapiDisplay * display)144 dump_properties (GstVaapiDisplay * display)
145 {
146   GParamSpec **properties;
147   guint i, n_properties;
148 
149   properties =
150       g_object_class_list_properties (G_OBJECT_GET_CLASS (display),
151       &n_properties);
152 
153   for (i = 0; i < n_properties; i++) {
154     const gchar *const name = g_param_spec_get_nick (properties[i]);
155     GValue value = G_VALUE_INIT;
156 
157     if (!gst_vaapi_display_has_property (display, name))
158       continue;
159 
160     g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (properties[i]));
161     g_object_get_property (G_OBJECT (display), name, &value);
162     print_value (&value, name);
163   }
164 
165   g_free (properties);
166 }
167 
168 static void
dump_info(GstVaapiDisplay * display)169 dump_info (GstVaapiDisplay * display)
170 {
171   GArray *profiles, *formats;
172 
173   profiles = gst_vaapi_display_get_decode_profiles (display);
174   if (!profiles)
175     g_error ("could not get VA decode profiles");
176 
177   print_profiles (profiles, "decoders");
178   g_array_unref (profiles);
179 
180   profiles = gst_vaapi_display_get_encode_profiles (display);
181   if (!profiles)
182     g_error ("could not get VA encode profiles");
183 
184   print_profiles (profiles, "encoders");
185   g_array_unref (profiles);
186 
187   formats = gst_vaapi_display_get_image_formats (display);
188   if (!formats)
189     g_error ("could not get VA image formats");
190 
191   print_formats (formats, "image");
192   g_array_unref (formats);
193 
194   formats = gst_vaapi_display_get_subpicture_formats (display);
195   if (!formats)
196     g_error ("could not get VA subpicture formats");
197 
198   print_formats (formats, "subpicture");
199   g_array_unref (formats);
200 
201   dump_properties (display);
202 }
203 
204 int
main(int argc,char * argv[])205 main (int argc, char *argv[])
206 {
207   GstVaapiDisplay *display;
208 #if USE_X11 || USE_WAYLAND
209   guint width, height;
210   guint par_n, par_d;
211 #endif
212 
213   gst_init (&argc, &argv);
214 
215 #if USE_DRM
216   g_print ("#\n");
217   g_print ("# Create display with gst_vaapi_display_drm_new()\n");
218   g_print ("#\n");
219   {
220     display = gst_vaapi_display_drm_new (NULL);
221     if (!display)
222       g_error ("could not create Gst/VA display");
223 
224     dump_info (display);
225     gst_object_unref (display);
226   }
227   g_print ("\n");
228 
229   g_print ("#\n");
230   g_print ("# Create display with gst_vaapi_display_drm_new_with_device()\n");
231   g_print ("#\n");
232   {
233     int drm_device;
234 
235     drm_device = open (DRM_DEVICE_PATH, O_RDWR | O_CLOEXEC);
236     if (drm_device < 0)
237       g_error ("could not open DRM device");
238 
239     display = gst_vaapi_display_drm_new_with_device (drm_device);
240     if (!display)
241       g_error ("could not create Gst/VA display");
242 
243     dump_info (display);
244     gst_object_unref (display);
245     close (drm_device);
246   }
247   g_print ("\n");
248 
249   g_print ("#\n");
250   g_print
251       ("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayDRM()]\n");
252   g_print ("#\n");
253   {
254     int drm_device;
255     VADisplay va_display;
256 
257     drm_device = open (DRM_DEVICE_PATH, O_RDWR | O_CLOEXEC);
258     if (drm_device < 0)
259       g_error ("could not open DRM device");
260 
261     va_display = vaGetDisplayDRM (drm_device);
262     if (!va_display)
263       g_error ("could not create VA display");
264 
265     display = gst_vaapi_display_new_with_display (va_display);
266     if (!display)
267       g_error ("could not create Gst/VA display");
268 
269     dump_info (display);
270     gst_object_unref (display);
271     close (drm_device);
272   }
273   g_print ("\n");
274 #endif
275 
276 #if USE_X11
277   g_print ("#\n");
278   g_print ("# Create display with gst_vaapi_display_x11_new()\n");
279   g_print ("#\n");
280   {
281     display = gst_vaapi_display_x11_new (NULL);
282     if (!display)
283       g_error ("could not create Gst/VA display");
284   }
285   g_print ("\n");
286 
287   g_print ("#\n");
288   g_print ("# Create display with gst_vaapi_display_x11_new_with_display()\n");
289   g_print ("#\n");
290   {
291     Display *x11_display;
292 
293     x11_display = XOpenDisplay (NULL);
294     if (!x11_display)
295       g_error ("could not create X11 display");
296 
297     display = gst_vaapi_display_x11_new_with_display (x11_display);
298     if (!display)
299       g_error ("could not create Gst/VA display");
300 
301     dump_info (display);
302     gst_object_unref (display);
303     XCloseDisplay (x11_display);
304   }
305   g_print ("\n");
306 
307   g_print ("#\n");
308   g_print
309       ("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplay()]\n");
310   g_print ("#\n");
311   {
312     Display *x11_display;
313     VADisplay va_display;
314 
315     x11_display = XOpenDisplay (NULL);
316     if (!x11_display)
317       g_error ("could not create X11 display");
318 
319     va_display = vaGetDisplay (x11_display);
320     if (!va_display)
321       g_error ("could not create VA display");
322 
323     display = gst_vaapi_display_new_with_display (va_display);
324     if (!display)
325       g_error ("could not create Gst/VA display");
326 
327     dump_info (display);
328     gst_object_unref (display);
329     XCloseDisplay (x11_display);
330   }
331   g_print ("\n");
332 #endif
333 
334 #if USE_GLX
335   g_print ("#\n");
336   g_print ("# Create display with gst_vaapi_display_glx_new()\n");
337   g_print ("#\n");
338   {
339     display = gst_vaapi_display_glx_new (NULL);
340     if (!display)
341       g_error ("could not create Gst/VA display");
342 
343     gst_vaapi_display_get_size (display, &width, &height);
344     g_print ("Display size: %ux%u\n", width, height);
345 
346     gst_vaapi_display_get_pixel_aspect_ratio (display, &par_n, &par_d);
347     g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d);
348 
349     dump_info (display);
350     gst_object_unref (display);
351   }
352   g_print ("\n");
353 
354   g_print ("#\n");
355   g_print ("# Create display with gst_vaapi_display_glx_new_with_display()\n");
356   g_print ("#\n");
357   {
358     Display *x11_display;
359 
360     x11_display = XOpenDisplay (NULL);
361     if (!x11_display)
362       g_error ("could not create X11 display");
363 
364     display = gst_vaapi_display_glx_new_with_display (x11_display);
365     if (!display)
366       g_error ("could not create Gst/VA display");
367 
368     dump_info (display);
369     gst_object_unref (display);
370     XCloseDisplay (x11_display);
371   }
372   g_print ("\n");
373 
374 #ifdef HAVE_VA_VA_GLX_H
375   g_print ("#\n");
376   g_print
377       ("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n");
378   g_print ("#\n");
379   {
380     Display *x11_display;
381     VADisplay va_display;
382 
383     x11_display = XOpenDisplay (NULL);
384     if (!x11_display)
385       g_error ("could not create X11 display");
386 
387     va_display = vaGetDisplayGLX (x11_display);
388     if (!va_display)
389       g_error ("could not create VA display");
390 
391     display = gst_vaapi_display_new_with_display (va_display);
392     if (!display)
393       g_error ("could not create Gst/VA display");
394 
395     dump_info (display);
396     gst_object_unref (display);
397     XCloseDisplay (x11_display);
398   }
399   g_print ("\n");
400 #endif
401 #endif
402 
403 #if USE_WAYLAND
404   g_print ("#\n");
405   g_print ("# Create display with gst_vaapi_display_wayland_new()\n");
406   g_print ("#\n");
407   {
408     display = gst_vaapi_display_wayland_new (NULL);
409     if (!display)
410       g_error ("could not create Gst/VA display");
411 
412     gst_vaapi_display_get_size (display, &width, &height);
413     g_print ("Display size: %ux%u\n", width, height);
414 
415     gst_vaapi_display_get_pixel_aspect_ratio (display, &par_n, &par_d);
416     g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d);
417 
418     dump_info (display);
419     gst_object_unref (display);
420   }
421   g_print ("\n");
422 #endif
423 
424   gst_deinit ();
425   return 0;
426 }
427