Fix short descriptions.
[platform/upstream/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapidisplay_x11.c
1 /*
2  *  gstvaapidisplay_x11.c - VA/X11 display abstraction
3  *
4  *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
19  */
20
21 /**
22  * SECTION:gstvaapidisplay_x11
23  * @short_description: VA/X11 display abstraction
24  */
25
26 #include "config.h"
27 #include "gstvaapiutils.h"
28 #include "gstvaapidisplay_x11.h"
29
30 #define DEBUG 1
31 #include "gstvaapidebug.h"
32
33 G_DEFINE_TYPE(GstVaapiDisplayX11,
34               gst_vaapi_display_x11,
35               GST_VAAPI_TYPE_DISPLAY);
36
37 #define GST_VAAPI_DISPLAY_X11_GET_PRIVATE(obj)                  \
38     (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
39                                  GST_VAAPI_TYPE_DISPLAY_X11,    \
40                                  GstVaapiDisplayX11Private))
41
42 struct _GstVaapiDisplayX11Private {
43     gboolean    create_display;
44     gchar      *display_name;
45     Display    *x11_display;
46     int         x11_screen;
47     VADisplay  *va_display;
48 };
49
50 enum {
51     PROP_0,
52
53     PROP_DISPLAY_NAME,
54     PROP_X11_DISPLAY
55 };
56
57 static void
58 gst_vaapi_display_x11_finalize(GObject *object)
59 {
60     G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class)->finalize(object);
61 }
62
63 static void
64 set_display_name(GstVaapiDisplayX11 *display, const gchar *display_name)
65 {
66     GstVaapiDisplayX11Private * const priv = display->priv;
67
68     g_free(priv->display_name);
69
70     if (display_name)
71         priv->display_name = g_strdup(display_name);
72     else
73         priv->display_name = NULL;
74 }
75
76 static void
77 gst_vaapi_display_x11_set_property(
78     GObject      *object,
79     guint         prop_id,
80     const GValue *value,
81     GParamSpec   *pspec
82 )
83 {
84     GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object);
85
86     switch (prop_id) {
87     case PROP_DISPLAY_NAME:
88         set_display_name(display, g_value_get_string(value));
89         break;
90     case PROP_X11_DISPLAY:
91         display->priv->x11_display = g_value_get_pointer(value);
92         break;
93     default:
94         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
95         break;
96     }
97 }
98
99 static void
100 gst_vaapi_display_x11_get_property(
101     GObject    *object,
102     guint       prop_id,
103     GValue     *value,
104     GParamSpec *pspec
105 )
106 {
107     GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object);
108
109     switch (prop_id) {
110     case PROP_DISPLAY_NAME:
111         g_value_set_string(value, display->priv->display_name);
112         break;
113     case PROP_X11_DISPLAY:
114         g_value_set_pointer(value, gst_vaapi_display_x11_get_display(display));
115         break;
116     default:
117         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
118         break;
119     }
120 }
121
122 static void
123 gst_vaapi_display_x11_constructed(GObject *object)
124 {
125     GstVaapiDisplayX11 * const display = GST_VAAPI_DISPLAY_X11(object);
126     GObjectClass *parent_class;
127
128     display->priv->create_display = display->priv->x11_display == NULL;
129
130     /* Reset display-name if the user provided his own X11 display */
131     if (!display->priv->create_display)
132         set_display_name(display, XDisplayString(display->priv->x11_display));
133
134     parent_class = G_OBJECT_CLASS(gst_vaapi_display_x11_parent_class);
135     if (parent_class->constructed)
136         parent_class->constructed(object);
137 }
138
139 static gboolean
140 gst_vaapi_display_x11_open_display(GstVaapiDisplay *display)
141 {
142     GstVaapiDisplayX11Private * const priv =
143         GST_VAAPI_DISPLAY_X11(display)->priv;
144
145     /* XXX: maintain an X11 display cache */
146     if (!priv->x11_display && priv->create_display)
147         priv->x11_display = XOpenDisplay(priv->display_name);
148     if (!priv->x11_display)
149         return FALSE;
150
151     priv->x11_screen = DefaultScreen(priv->x11_display);
152     priv->va_display = vaGetDisplay(priv->x11_display);
153     return priv->va_display != NULL;
154 }
155
156 static void
157 gst_vaapi_display_x11_close_display(GstVaapiDisplay *display)
158 {
159     GstVaapiDisplayX11Private * const priv =
160         GST_VAAPI_DISPLAY_X11(display)->priv;
161
162     if (priv->x11_display) {
163         if (priv->create_display)
164             XCloseDisplay(priv->x11_display);
165         priv->x11_display = NULL;
166     }
167
168     if (priv->display_name) {
169         g_free(priv->display_name);
170         priv->display_name = NULL;
171     }
172
173     priv->va_display = NULL;
174 }
175
176 static VADisplay
177 gst_vaapi_display_x11_get_va_display(GstVaapiDisplay *display)
178 {
179     return GST_VAAPI_DISPLAY_X11(display)->priv->va_display;
180 }
181
182 static void
183 gst_vaapi_display_x11_get_size(
184     GstVaapiDisplay *display,
185     guint           *pwidth,
186     guint           *pheight
187 )
188 {
189     GstVaapiDisplayX11Private * const priv =
190         GST_VAAPI_DISPLAY_X11(display)->priv;
191
192     if (!priv->x11_display)
193         return;
194
195     if (pwidth)
196         *pwidth = DisplayWidth(priv->x11_display, priv->x11_screen);
197
198     if (pheight)
199         *pheight = DisplayHeight(priv->x11_display, priv->x11_screen);
200 }
201
202 static void
203 gst_vaapi_display_x11_get_size_mm(
204     GstVaapiDisplay *display,
205     guint           *pwidth,
206     guint           *pheight
207 )
208 {
209     GstVaapiDisplayX11Private * const priv =
210         GST_VAAPI_DISPLAY_X11(display)->priv;
211
212     if (!priv->x11_display)
213         return;
214
215     if (pwidth)
216         *pwidth = DisplayWidthMM(priv->x11_display, priv->x11_screen);
217
218     if (pheight)
219         *pheight = DisplayHeightMM(priv->x11_display, priv->x11_screen);
220 }
221
222 static void
223 gst_vaapi_display_x11_class_init(GstVaapiDisplayX11Class *klass)
224 {
225     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
226     GstVaapiDisplayClass * const dpy_class = GST_VAAPI_DISPLAY_CLASS(klass);
227
228     g_type_class_add_private(klass, sizeof(GstVaapiDisplayX11Private));
229
230     object_class->finalize      = gst_vaapi_display_x11_finalize;
231     object_class->set_property  = gst_vaapi_display_x11_set_property;
232     object_class->get_property  = gst_vaapi_display_x11_get_property;
233     object_class->constructed   = gst_vaapi_display_x11_constructed;
234
235     dpy_class->open_display     = gst_vaapi_display_x11_open_display;
236     dpy_class->close_display    = gst_vaapi_display_x11_close_display;
237     dpy_class->get_display      = gst_vaapi_display_x11_get_va_display;
238     dpy_class->get_size         = gst_vaapi_display_x11_get_size;
239     dpy_class->get_size_mm      = gst_vaapi_display_x11_get_size_mm;
240
241     /**
242      * GstVaapiDisplayX11:x11-display:
243      *
244      * The X11 #Display that was created by gst_vaapi_display_x11_new()
245      * or that was bound from gst_vaapi_display_x11_new_with_display().
246      */
247     g_object_class_install_property
248         (object_class,
249          PROP_X11_DISPLAY,
250          g_param_spec_pointer("x11-display",
251                               "X11 display",
252                               "X11 display",
253                               G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
254
255     /**
256      * GstVaapiDisplayX11:display-name:
257      *
258      * The X11 display name.
259      */
260     g_object_class_install_property
261         (object_class,
262          PROP_DISPLAY_NAME,
263          g_param_spec_string("display-name",
264                              "X11 display name",
265                              "X11 display name",
266                              NULL,
267                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
268 }
269
270 static void
271 gst_vaapi_display_x11_init(GstVaapiDisplayX11 *display)
272 {
273     GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display);
274
275     display->priv        = priv;
276     priv->create_display = TRUE;
277     priv->x11_display    = NULL;
278     priv->x11_screen     = 0;
279     priv->display_name   = NULL;
280 }
281
282 /**
283  * gst_vaapi_display_x11_new:
284  * @display_name: the X11 display name
285  *
286  * Opens an X11 #Display using @display_name and returns a newly
287  * allocated #GstVaapiDisplay object. The X11 display will be cloed
288  * when the reference count of the object reaches zero.
289  *
290  * Return value: a newly allocated #GstVaapiDisplay object
291  */
292 GstVaapiDisplay *
293 gst_vaapi_display_x11_new(const gchar *display_name)
294 {
295     return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11,
296                         "display-name", display_name,
297                         NULL);
298 }
299
300 /**
301  * gst_vaapi_display_x11_new_with_display:
302  * @x11_display: an X11 #Display
303  *
304  * Creates a #GstVaapiDisplay based on the X11 @x11_display
305  * display. The caller still owns the display and must call
306  * XCloseDisplay() when all #GstVaapiDisplay references are
307  * released. Doing so too early can yield undefined behaviour.
308  *
309  * Return value: a newly allocated #GstVaapiDisplay object
310  */
311 GstVaapiDisplay *
312 gst_vaapi_display_x11_new_with_display(Display *x11_display)
313 {
314     return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11,
315                         "x11-display", x11_display,
316                         NULL);
317 }
318
319 /**
320  * gst_vaapi_display_x11_get_display:
321  * @display: a #GstVaapiDisplayX11
322  *
323  * Returns the underlying X11 #Display that was created by
324  * gst_vaapi_display_x11_new() or that was bound from
325  * gst_vaapi_display_x11_new_with_display().
326  *
327  * Return value: the X11 #Display attached to @display
328  */
329 Display *
330 gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display)
331 {
332     g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL);
333
334     return display->priv->x11_display;
335 }