ce16a43741d271e52839b91dd72ac1bc6742a517
[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 #include "gstvaapipluginutil.h"
36
37 /* Preferred first */
38 static const char *display_types[] = {
39     "gst-vaapi-display",
40     "vaapi-display",
41     "x11-display",
42     "x11-display-name",
43     NULL
44 };
45
46 gboolean
47 gst_vaapi_ensure_display(gpointer element, GstVaapiDisplay **display)
48 {
49     GstVideoContext *context;
50
51     g_return_val_if_fail(GST_IS_VIDEO_CONTEXT(element), FALSE);
52     g_return_val_if_fail(display != NULL, FALSE);
53
54     /* Already exist ? */
55     if (*display)
56         return TRUE;
57
58     context = GST_VIDEO_CONTEXT(element);
59     gst_video_context_prepare(context, display_types);
60
61     /* If no neighboor, or application not interested, use system default */
62 #if USE_GLX
63     if (!*display)
64         *display = gst_vaapi_display_glx_new(NULL);
65 #endif
66     if (!*display)
67         *display = gst_vaapi_display_x11_new(NULL);
68
69     /* FIXME allocator should return NULL in case of failure */
70     if (*display && !gst_vaapi_display_get_display(*display)) {
71         g_object_unref(*display);
72         *display = NULL;
73     }
74     return (*display != NULL);
75 }
76
77 void
78 gst_vaapi_set_display(
79     const gchar      *type,
80     const GValue     *value,
81     GstVaapiDisplay **display
82 )
83 {
84     GstVaapiDisplay *dpy = NULL;
85
86     if (!strcmp(type, "x11-display-name")) {
87         g_return_if_fail(G_VALUE_HOLDS_STRING(value));
88 #if USE_GLX
89         dpy = gst_vaapi_display_glx_new(g_value_get_string(value));
90 #endif
91         if (!dpy)
92             dpy = gst_vaapi_display_x11_new(g_value_get_string(value));
93     }
94     else if (!strcmp(type, "x11-display")) {
95         g_return_if_fail(G_VALUE_HOLDS_POINTER(value));
96 #if USE_GLX
97         dpy = gst_vaapi_display_glx_new_with_display(g_value_get_pointer(value));
98 #endif
99         if (!dpy)
100             dpy = gst_vaapi_display_x11_new_with_display(g_value_get_pointer(value));
101     }
102     else if (!strcmp(type, "vaapi-display")) {
103         g_return_if_fail(G_VALUE_HOLDS_POINTER(value));
104         dpy = gst_vaapi_display_new_with_display(g_value_get_pointer(value));
105     }
106     else if (!strcmp(type, "gst-vaapi-display")) {
107         g_return_if_fail(G_VALUE_HOLDS_OBJECT(value));
108         dpy = g_value_dup_object(value);
109     }
110
111     if (dpy) {
112         if (*display)
113             g_object_unref(*display);
114         *display = dpy;
115     }
116 }
117
118 gboolean
119 gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display)
120 {
121     const gchar **types;
122     const gchar *type;
123     gint i;
124     gboolean res = FALSE;
125
126     if (!display)
127         return FALSE;
128
129     types = gst_video_context_query_get_supported_types(query);
130
131     if (!types)
132         return FALSE;
133
134     for (i = 0; types[i]; i++) {
135         type = types[i];
136
137         if (!strcmp(type, "gst-vaapi-display")) {
138             gst_video_context_query_set_object(query, type, G_OBJECT(display));
139         }
140         else if (!strcmp(type, "vaapi-display")) {
141             VADisplay vadpy = gst_vaapi_display_get_display(display);
142             gst_video_context_query_set_pointer(query, type, vadpy);
143         }
144         else if (!strcmp(type, "x11-display") &&
145                  GST_VAAPI_IS_DISPLAY_X11(display)) {
146             GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11(display);
147             Display *x11dpy = gst_vaapi_display_x11_get_display(xvadpy);
148             gst_video_context_query_set_pointer(query, type, x11dpy);
149             
150         }
151         else if (!strcmp(type, "x11-display-name") &&
152                  GST_VAAPI_IS_DISPLAY_X11(display)) {
153             GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11(display);
154             Display *x11dpy = gst_vaapi_display_x11_get_display(xvadpy);
155             gst_video_context_query_set_string(query, type, DisplayString(x11dpy));
156         }
157         else {
158             continue;
159         }
160
161         res = TRUE;
162         break;
163     }
164     return res;
165 }
166
167 gboolean
168 gst_vaapi_append_surface_caps(GstCaps *out_caps, GstCaps *in_caps)
169 {
170     GstStructure *structure;
171     const GValue *v_width, *v_height, *v_framerate, *v_par;
172     guint i, n_structures;
173
174     structure   = gst_caps_get_structure(in_caps, 0);
175     v_width     = gst_structure_get_value(structure, "width");
176     v_height    = gst_structure_get_value(structure, "height");
177     v_framerate = gst_structure_get_value(structure, "framerate");
178     v_par       = gst_structure_get_value(structure, "pixel-aspect-ratio");
179     if (!v_width || !v_height)
180         return FALSE;
181
182     n_structures = gst_caps_get_size(out_caps);
183     for (i = 0; i < n_structures; i++) {
184         structure = gst_caps_get_structure(out_caps, i);
185         gst_structure_set_value(structure, "width", v_width);
186         gst_structure_set_value(structure, "height", v_height);
187         if (v_framerate)
188             gst_structure_set_value(structure, "framerate", v_framerate);
189         if (v_par)
190             gst_structure_set_value(structure, "pixel-aspect-ratio", v_par);
191     }
192     return TRUE;
193 }
194
195 GType
196 gst_vaapi_display_type_get_type(void)
197 {
198     static GType g_type = 0;
199
200     static const GEnumValue display_types[] = {
201         { GST_VAAPI_DISPLAY_TYPE_AUTO,
202           "Auto detection", "auto" },
203         { GST_VAAPI_DISPLAY_TYPE_X11,
204           "VA/X11 display", "x11" },
205 #if USE_GLX
206         { GST_VAAPI_DISPLAY_TYPE_GLX,
207           "VA/GLX display", "glx" },
208 #endif
209         { 0, NULL, NULL },
210     };
211
212     if (!g_type)
213         g_type = g_enum_register_static("GstVaapiDisplayType", display_types);
214     return g_type;
215 }