Fix build without X11.
[profile/ivi/gstreamer-vaapi.git] / gst / vaapi / gstvaapipluginutil.c
1 /*
2  *  gstvaapipluginutil.h - VA-API plugin helpers
3  *
4  *  Copyright (C) 2011-2012 Intel Corporation
5  *  Copyright (C) 2011 Collabora
6  *    Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public License
10  *  as published by the Free Software Foundation; either version 2.1
11  *  of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free
20  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  *  Boston, MA 02110-1301 USA
22  */
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27 #include <string.h>
28 #include <gst/video/videocontext.h>
29 #if USE_X11
30 # include <gst/vaapi/gstvaapidisplay_x11.h>
31 #endif
32 #if USE_GLX
33 # include <gst/vaapi/gstvaapidisplay_glx.h>
34 #endif
35 #if USE_WAYLAND
36 # include <gst/vaapi/gstvaapidisplay_wayland.h>
37 #endif
38 #include "gstvaapipluginutil.h"
39
40 /* Preferred first */
41 static const char *display_types[] = {
42     "gst-vaapi-display",
43     "vaapi-display",
44 #if USE_WAYLAND
45     "wl-display",
46     "wl-display-name",
47 #endif
48 #if USE_X11
49     "x11-display",
50     "x11-display-name",
51 #endif
52     NULL
53 };
54
55 typedef struct {
56     const gchar        *type_str;
57     GstVaapiDisplayType type;
58     GstVaapiDisplay * (*create_display)(const gchar *);
59 } DisplayMap;
60
61 static const DisplayMap g_display_map[] = {
62 #if USE_WAYLAND
63     { "wayland",
64       GST_VAAPI_DISPLAY_TYPE_WAYLAND,
65       gst_vaapi_display_wayland_new },
66 #endif
67 #if USE_GLX
68     { "glx",
69       GST_VAAPI_DISPLAY_TYPE_GLX,
70       gst_vaapi_display_glx_new },
71 #endif
72 #if USE_X11
73     { "x11",
74       GST_VAAPI_DISPLAY_TYPE_X11,
75       gst_vaapi_display_x11_new },
76 #endif
77     { NULL, }
78 };
79
80 gboolean
81 gst_vaapi_ensure_display(
82     gpointer             element,
83     GstVaapiDisplayType  display_type,
84     GstVaapiDisplay    **display_ptr
85 )
86 {
87     GstVaapiDisplay *display;
88     GstVideoContext *context;
89     const DisplayMap *m;
90
91     g_return_val_if_fail(GST_IS_VIDEO_CONTEXT(element), FALSE);
92     g_return_val_if_fail(display_ptr != NULL, FALSE);
93
94     /* Already exist ? */
95     display = *display_ptr;
96     if (display)
97         return TRUE;
98
99     context = GST_VIDEO_CONTEXT(element);
100     g_return_val_if_fail(context != NULL, FALSE);
101
102     gst_video_context_prepare(context, display_types);
103
104     /* Neighbour found and it updated the display */
105     if (*display_ptr)
106         return TRUE;
107
108     /* If no neighboor, or application not interested, use system default */
109     for (m = g_display_map; m->type_str != NULL; m++) {
110         if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY &&
111             display_type != m->type)
112             continue;
113
114         display = m->create_display(NULL);
115         if (display) {
116             /* FIXME: allocator should return NULL if an error occurred */
117             if (gst_vaapi_display_get_display(display)) {
118                 display_type = m->type;
119                 break;
120             }
121             g_object_unref(display);
122             display = NULL;
123         }
124
125         if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY)
126             break;
127     }
128
129     if (display_ptr)
130         *display_ptr = display;
131     return display != NULL;
132 }
133
134 void
135 gst_vaapi_set_display(
136     const gchar      *type,
137     const GValue     *value,
138     GstVaapiDisplay **display
139 )
140 {
141     GstVaapiDisplay *dpy = NULL;
142
143     if (!strcmp(type, "vaapi-display")) {
144         g_return_if_fail(G_VALUE_HOLDS_POINTER(value));
145         dpy = gst_vaapi_display_new_with_display(g_value_get_pointer(value));
146     }
147     else if (!strcmp(type, "gst-vaapi-display")) {
148         g_return_if_fail(G_VALUE_HOLDS_OBJECT(value));
149         dpy = g_value_dup_object(value);
150     }
151 #if USE_X11
152     else if (!strcmp(type, "x11-display-name")) {
153         g_return_if_fail(G_VALUE_HOLDS_STRING(value));
154 #if USE_GLX
155         dpy = gst_vaapi_display_glx_new(g_value_get_string(value));
156 #endif
157         if (!dpy)
158             dpy = gst_vaapi_display_x11_new(g_value_get_string(value));
159     }
160     else if (!strcmp(type, "x11-display")) {
161         g_return_if_fail(G_VALUE_HOLDS_POINTER(value));
162 #if USE_GLX
163         dpy = gst_vaapi_display_glx_new_with_display(g_value_get_pointer(value));
164 #endif
165         if (!dpy)
166             dpy = gst_vaapi_display_x11_new_with_display(g_value_get_pointer(value));
167     }
168 #endif
169 #if USE_WAYLAND
170     else if (!strcmp(type, "wl-display")) {
171         struct wl_display *wl_display;
172         g_return_if_fail(G_VALUE_HOLDS_POINTER(value));
173         wl_display = g_value_get_pointer(value);
174         dpy = gst_vaapi_display_wayland_new_with_display(wl_display);
175     }
176     else if (!strcmp(type, "wl-display-name")) {
177         const gchar *display_name;
178         g_return_if_fail(G_VALUE_HOLDS_STRING(value));
179         display_name = g_value_get_string(value);
180         dpy = gst_vaapi_display_wayland_new(display_name);
181     }
182 #endif
183
184     if (dpy) {
185         if (*display)
186             g_object_unref(*display);
187         *display = dpy;
188     }
189 }
190
191 gboolean
192 gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display)
193 {
194     GstVaapiDisplayType display_type;
195     const gchar **types;
196     const gchar *type;
197     gint i;
198     gboolean res = FALSE;
199
200     if (!display)
201         return FALSE;
202
203     types = gst_video_context_query_get_supported_types(query);
204
205     if (!types)
206         return FALSE;
207
208     display_type = gst_vaapi_display_get_display_type(display);
209     for (i = 0; types[i] && !res; i++) {
210         type = types[i];
211
212         res = TRUE;
213         if (!strcmp(type, "gst-vaapi-display")) {
214             gst_video_context_query_set_object(query, type, G_OBJECT(display));
215         }
216         else if (!strcmp(type, "vaapi-display")) {
217             VADisplay vadpy = gst_vaapi_display_get_display(display);
218             gst_video_context_query_set_pointer(query, type, vadpy);
219         }
220         else {
221             switch (display_type) {
222 #if USE_X11
223 #if USE_GLX
224             case GST_VAAPI_DISPLAY_TYPE_GLX:
225 #endif
226             case GST_VAAPI_DISPLAY_TYPE_X11: {
227                 GstVaapiDisplayX11 * const xvadpy =
228                     GST_VAAPI_DISPLAY_X11(display);
229                 Display * const x11dpy =
230                     gst_vaapi_display_x11_get_display(xvadpy);
231                 if (!strcmp(type, "x11-display"))
232                     gst_video_context_query_set_pointer(query, type, x11dpy);
233                 else if (!strcmp(type, "x11-display-name"))
234                     gst_video_context_query_set_string(query, type,
235                         DisplayString(x11dpy));
236                 else
237                     res = FALSE;
238                 break;
239             }
240 #endif
241 #if USE_WAYLAND
242             case GST_VAAPI_DISPLAY_TYPE_WAYLAND: {
243                 GstVaapiDisplayWayland * const wlvadpy =
244                     GST_VAAPI_DISPLAY_WAYLAND(display);
245                 struct wl_display * const wldpy =
246                     gst_vaapi_display_wayland_get_display(wlvadpy);
247                 if (!strcmp(type, "wl-display"))
248                     gst_video_context_query_set_pointer(query, type, wldpy);
249                 else
250                     res = FALSE;
251                 break;
252             }
253 #endif
254             default:
255                 res = FALSE;
256                 break;
257             }
258         }
259     }
260     return res;
261 }
262
263 gboolean
264 gst_vaapi_append_surface_caps(GstCaps *out_caps, GstCaps *in_caps)
265 {
266     GstStructure *structure;
267     const GValue *v_width, *v_height, *v_framerate, *v_par;
268     guint i, n_structures;
269
270     structure   = gst_caps_get_structure(in_caps, 0);
271     v_width     = gst_structure_get_value(structure, "width");
272     v_height    = gst_structure_get_value(structure, "height");
273     v_framerate = gst_structure_get_value(structure, "framerate");
274     v_par       = gst_structure_get_value(structure, "pixel-aspect-ratio");
275     if (!v_width || !v_height)
276         return FALSE;
277
278     n_structures = gst_caps_get_size(out_caps);
279     for (i = 0; i < n_structures; i++) {
280         structure = gst_caps_get_structure(out_caps, i);
281         gst_structure_set_value(structure, "width", v_width);
282         gst_structure_set_value(structure, "height", v_height);
283         if (v_framerate)
284             gst_structure_set_value(structure, "framerate", v_framerate);
285         if (v_par)
286             gst_structure_set_value(structure, "pixel-aspect-ratio", v_par);
287     }
288     return TRUE;
289 }