2 * gstvaapisink.c - VA-API video sink
4 * gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems
5 * Copyright (C) 2011 Intel Corporation
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.
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.
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
24 * SECTION:gstvaapisink
25 * @short_description: A VA-API based videosink
27 * vaapisink renders video frames to a drawable (X #Window) on a local
28 * display using the Video Acceleration (VA) API. The element will
29 * create its own internal window and render into it.
34 #include <gst/video/video.h>
35 #include <gst/gstutils_version.h>
36 #include <gst/vaapi/gstvaapivideobuffer.h>
37 #include <gst/vaapi/gstvaapivideosink.h>
38 #include <gst/vaapi/gstvaapidisplay_x11.h>
39 #include <gst/vaapi/gstvaapiwindow_x11.h>
41 #include <gst/vaapi/gstvaapidisplay_glx.h>
42 #include <gst/vaapi/gstvaapiwindow_glx.h>
44 #include "gstvaapisink.h"
46 /* Supported interfaces */
47 #include <gst/interfaces/xoverlay.h>
49 #define HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE \
50 GST_PLUGINS_BASE_CHECK_VERSION(0,10,31)
52 #define GST_PLUGIN_NAME "vaapisink"
53 #define GST_PLUGIN_DESC "A VA-API based videosink"
55 GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapisink);
56 #define GST_CAT_DEFAULT gst_debug_vaapisink
58 /* ElementFactory information */
59 static const GstElementDetails gst_vaapisink_details =
64 "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");
66 /* Default template */
67 static GstStaticPadTemplate gst_vaapisink_sink_factory =
68 GST_STATIC_PAD_TEMPLATE(
72 GST_STATIC_CAPS(GST_VAAPI_SURFACE_CAPS));
74 static void gst_vaapisink_iface_init(GType type);
81 gst_vaapisink_iface_init);
93 /* GstImplementsInterface interface */
96 gst_vaapisink_implements_interface_supported(
97 GstImplementsInterface *iface,
101 return (type == GST_VAAPI_TYPE_VIDEO_SINK ||
102 type == GST_TYPE_X_OVERLAY);
106 gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface)
108 iface->supported = gst_vaapisink_implements_interface_supported;
111 /* GstVaapiVideoSink interface */
113 static GstVaapiDisplay *
114 gst_vaapisink_get_display(GstVaapiSink *sink);
116 static GstVaapiDisplay *
117 gst_vaapi_video_sink_do_get_display(GstVaapiVideoSink *sink)
119 return gst_vaapisink_get_display(GST_VAAPISINK(sink));
123 gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface)
125 iface->get_display = gst_vaapi_video_sink_do_get_display;
128 /* GstXOverlay interface */
131 gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id);
134 gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer);
137 _gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, guintptr window_id)
139 GstVaapiSink * const sink = GST_VAAPISINK(overlay);
141 /* Disable GLX rendering when vaapisink is using a foreign X
142 window. It's pretty much useless */
143 sink->use_glx = FALSE;
145 sink->foreign_window = TRUE;
146 gst_vaapisink_ensure_window_xid(sink, window_id);
149 #if HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE
151 gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window_id)
153 _gst_vaapisink_xoverlay_set_xid(overlay, window_id);
157 gst_vaapisink_xoverlay_set_xid(GstXOverlay *overlay, XID xid)
159 _gst_vaapisink_xoverlay_set_xid(overlay, xid);
164 gst_vaapisink_xoverlay_expose(GstXOverlay *overlay)
166 GstBaseSink * const base_sink = GST_BASE_SINK(overlay);
169 buffer = gst_base_sink_get_last_buffer(base_sink);
171 gst_vaapisink_show_frame(base_sink, buffer);
172 gst_buffer_unref(buffer);
177 gst_vaapisink_xoverlay_iface_init(GstXOverlayClass *iface)
179 #if HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE
180 iface->set_window_handle = gst_vaapisink_xoverlay_set_window_handle;
182 iface->set_xwindow_id = gst_vaapisink_xoverlay_set_xid;
184 iface->expose = gst_vaapisink_xoverlay_expose;
188 gst_vaapisink_iface_init(GType type)
190 const GType g_define_type_id = type;
192 G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE,
193 gst_vaapisink_implements_iface_init);
194 G_IMPLEMENT_INTERFACE(GST_VAAPI_TYPE_VIDEO_SINK,
195 gst_vaapi_video_sink_iface_init);
196 G_IMPLEMENT_INTERFACE(GST_TYPE_X_OVERLAY,
197 gst_vaapisink_xoverlay_iface_init);
201 gst_vaapisink_destroy(GstVaapiSink *sink)
204 g_object_unref(sink->display);
205 sink->display = NULL;
208 if (sink->display_name) {
209 g_free(sink->display_name);
210 sink->display_name = NULL;
214 /* Checks whether a ConfigureNotify event is in the queue */
215 typedef struct _ConfigureNotifyEventPendingArgs ConfigureNotifyEventPendingArgs;
216 struct _ConfigureNotifyEventPendingArgs {
224 configure_notify_event_pending_cb(Display *dpy, XEvent *xev, XPointer arg)
226 ConfigureNotifyEventPendingArgs * const args =
227 (ConfigureNotifyEventPendingArgs *)arg;
229 if (xev->type == ConfigureNotify &&
230 xev->xconfigure.window == args->window &&
231 xev->xconfigure.width == args->width &&
232 xev->xconfigure.height == args->height)
235 /* XXX: this is a hack to traverse the whole queue because we
236 can't use XPeekIfEvent() since it could block */
241 configure_notify_event_pending(
248 ConfigureNotifyEventPendingArgs args;
251 args.window = window;
253 args.height = height;
256 /* XXX: don't use XPeekIfEvent() because it might block */
258 gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)),
260 configure_notify_event_pending_cb, (XPointer)&args
265 static inline gboolean
266 gst_vaapisink_ensure_display(GstVaapiSink *sink)
268 if (!sink->display) {
269 #if USE_VAAPISINK_GLX
271 sink->display = gst_vaapi_display_glx_new(sink->display_name);
274 sink->display = gst_vaapi_display_x11_new(sink->display_name);
275 if (!sink->display || !gst_vaapi_display_get_display(sink->display))
277 g_object_set(sink, "synchronous", sink->synchronous, NULL);
279 return sink->display != NULL;
283 gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height)
285 GstVaapiRectangle * const display_rect = &sink->display_rect;
286 guint num, den, display_par_n, display_par_d;
287 double display_ratio;
290 GST_DEBUG("ensure render rect within %ux%u bounds", width, height);
292 gst_vaapi_display_get_pixel_aspect_ratio(
294 &display_par_n, &display_par_d
296 GST_DEBUG("display pixel-aspect-ratio %d/%d",
297 display_par_n, display_par_d);
299 success = gst_video_calculate_display_ratio(
301 sink->video_width, sink->video_height,
302 sink->video_par_n, sink->video_par_d,
303 display_par_n, display_par_d
307 GST_DEBUG("video size %dx%d, calculated ratio %d/%d",
308 sink->video_width, sink->video_height, num, den);
310 if ((sink->video_height % den) == 0) {
311 GST_DEBUG("keeping video height");
312 display_rect->width =
313 gst_util_uint64_scale_int(sink->video_height, num, den);
314 display_rect->height = sink->video_height;
316 else if ((sink->video_width % num) == 0) {
317 GST_DEBUG("keeping video width");
318 display_rect->width = sink->video_width;
319 display_rect->height =
320 gst_util_uint64_scale_int(sink->video_width, den, num);
323 GST_DEBUG("approximating while keeping video height");
324 display_rect->width =
325 gst_util_uint64_scale_int(sink->video_height, num, den);
326 display_rect->height = sink->video_height;
328 display_ratio = (gdouble)display_rect->width / display_rect->height;
329 GST_DEBUG("scaling to %ux%u", display_rect->width, display_rect->height);
331 if (sink->fullscreen || sink->foreign_window ||
332 display_rect->width > width || display_rect->height > height) {
333 if (sink->video_width > sink->video_height) {
334 display_rect->width = width;
335 display_rect->height = width / display_ratio;
338 display_rect->width = height * display_ratio;
339 display_rect->height = height;
343 if (sink->fullscreen) {
344 display_rect->x = (width - display_rect->width) / 2;
345 display_rect->y = (height - display_rect->height) / 2;
352 GST_DEBUG("render rect (%d,%d):%ux%u",
353 display_rect->x, display_rect->y,
354 display_rect->width, display_rect->height);
358 static inline gboolean
359 gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height)
361 GstVaapiDisplay * const display = sink->display;
364 #if USE_VAAPISINK_GLX
366 sink->window = gst_vaapi_window_glx_new(display, width, height);
369 sink->window = gst_vaapi_window_x11_new(display, width, height);
371 gst_x_overlay_got_xwindow_id(
373 gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window))
376 return sink->window != NULL;
380 gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id)
383 unsigned int width, height, border_width, depth;
387 if (!gst_vaapisink_ensure_display(sink))
390 gst_vaapi_display_lock(sink->display);
392 gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)),
395 &x, &y, &width, &height, &border_width, &depth
397 gst_vaapi_display_unlock(sink->display);
399 if ((width != sink->window_width || height != sink->window_height) &&
400 !configure_notify_event_pending(sink, xid, width, height)) {
401 if (!gst_vaapisink_ensure_render_rect(sink, width, height))
403 sink->window_width = width;
404 sink->window_height = height;
408 gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid)
412 g_object_unref(sink->window);
416 #if USE_VAAPISINK_GLX
418 sink->window = gst_vaapi_window_glx_new_with_xid(sink->display, xid);
421 sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid);
422 return sink->window != NULL;
426 gst_vaapisink_start(GstBaseSink *base_sink)
428 GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
430 if (!gst_vaapisink_ensure_display(sink))
436 gst_vaapisink_stop(GstBaseSink *base_sink)
438 GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
441 g_object_unref(sink->window);
446 g_object_unref(sink->display);
447 sink->display = NULL;
453 gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
455 GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
456 GstStructure * const structure = gst_caps_get_structure(caps, 0);
457 guint display_width, display_height, win_width, win_height;
458 gint video_width, video_height, video_par_n = 1, video_par_d = 1;
462 if (!gst_structure_get_int(structure, "width", &video_width))
464 if (!gst_structure_get_int(structure, "height", &video_height))
466 sink->video_width = video_width;
467 sink->video_height = video_height;
469 gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d);
470 sink->video_par_n = video_par_n;
471 sink->video_par_d = video_par_d;
472 GST_DEBUG("video pixel-aspect-ratio %d/%d", video_par_n, video_par_d);
474 gst_vaapi_display_get_size(sink->display, &display_width, &display_height);
475 if (!gst_vaapisink_ensure_render_rect(sink, display_width, display_height))
478 if (sink->fullscreen) {
479 win_width = display_width;
480 win_height = display_height;
483 win_width = sink->display_rect.width;
484 win_height = sink->display_rect.height;
488 gst_vaapi_window_set_size(sink->window, win_width, win_height);
490 gst_vaapi_display_lock(sink->display);
491 gst_x_overlay_prepare_xwindow_id(GST_X_OVERLAY(sink));
492 gst_vaapi_display_unlock(sink->display);
495 if (!gst_vaapisink_ensure_window(sink, win_width, win_height))
497 gst_vaapi_window_set_fullscreen(sink->window, sink->fullscreen);
498 gst_vaapi_window_show(sink->window);
500 sink->window_width = win_width;
501 sink->window_height = win_height;
506 gst_vaapisink_buffer_alloc(
507 GstBaseSink *base_sink,
511 GstBuffer **pout_buffer
514 GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
515 GstStructure *structure;
518 structure = gst_caps_get_structure(caps, 0);
519 if (!gst_structure_has_name(structure, "video/x-vaapi-surface"))
520 goto error_invalid_caps;
522 buffer = gst_vaapi_video_buffer_new(sink->display);
524 goto error_create_buffer;
526 gst_buffer_set_caps(buffer, caps);
527 *pout_buffer = buffer;
533 GST_ERROR("failed to validate input caps");
534 return GST_FLOW_UNEXPECTED;
538 GST_ERROR("failed to create video buffer");
539 return GST_FLOW_UNEXPECTED;
543 #if USE_VAAPISINK_GLX
545 render_background(GstVaapiSink *sink)
547 /* Original code from Mirco Muller (MacSlow):
548 <http://cgit.freedesktop.org/~macslow/gl-gst-player/> */
549 GLfloat fStartX = 0.0f;
550 GLfloat fStartY = 0.0f;
551 GLfloat fWidth = (GLfloat)sink->window_width;
552 GLfloat fHeight = (GLfloat)sink->window_height;
554 glClear(GL_COLOR_BUFFER_BIT);
557 /* top third, darker grey to white */
558 glColor3f(0.85f, 0.85f, 0.85f);
559 glVertex3f(fStartX, fStartY, 0.0f);
560 glColor3f(0.85f, 0.85f, 0.85f);
561 glVertex3f(fStartX + fWidth, fStartY, 0.0f);
562 glColor3f(1.0f, 1.0f, 1.0f);
563 glVertex3f(fStartX + fWidth, fStartY + fHeight / 3.0f, 0.0f);
564 glColor3f(1.0f, 1.0f, 1.0f);
565 glVertex3f(fStartX, fStartY + fHeight / 3.0f, 0.0f);
567 /* middle third, just plain white */
568 glColor3f(1.0f, 1.0f, 1.0f);
569 glVertex3f(fStartX, fStartY + fHeight / 3.0f, 0.0f);
570 glVertex3f(fStartX + fWidth, fStartY + fHeight / 3.0f, 0.0f);
571 glVertex3f(fStartX + fWidth, fStartY + 2.0f * fHeight / 3.0f, 0.0f);
572 glVertex3f(fStartX, fStartY + 2.0f * fHeight / 3.0f, 0.0f);
574 /* bottom third, white to lighter grey */
575 glColor3f(1.0f, 1.0f, 1.0f);
576 glVertex3f(fStartX, fStartY + 2.0f * fHeight / 3.0f, 0.0f);
577 glColor3f(1.0f, 1.0f, 1.0f);
578 glVertex3f(fStartX + fWidth, fStartY + 2.0f * fHeight / 3.0f, 0.0f);
579 glColor3f(0.62f, 0.66f, 0.69f);
580 glVertex3f(fStartX + fWidth, fStartY + fHeight, 0.0f);
581 glColor3f(0.62f, 0.66f, 0.69f);
582 glVertex3f(fStartX, fStartY + fHeight, 0.0f);
588 render_frame(GstVaapiSink *sink)
590 const guint x1 = sink->display_rect.x;
591 const guint x2 = sink->display_rect.x + sink->display_rect.width;
592 const guint y1 = sink->display_rect.y;
593 const guint y2 = sink->display_rect.y + sink->display_rect.height;
595 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
598 glTexCoord2f(0.0f, 0.0f); glVertex2i(x1, y1);
599 glTexCoord2f(0.0f, 1.0f); glVertex2i(x1, y2);
600 glTexCoord2f(1.0f, 1.0f); glVertex2i(x2, y2);
601 glTexCoord2f(1.0f, 0.0f); glVertex2i(x2, y1);
607 render_reflection(GstVaapiSink *sink)
609 const guint x1 = sink->display_rect.x;
610 const guint x2 = sink->display_rect.x + sink->display_rect.width;
611 const guint y1 = sink->display_rect.y;
612 const guint rh = sink->display_rect.height / 5;
613 GLfloat ry = 1.0f - (GLfloat)rh / (GLfloat)sink->display_rect.height;
617 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
618 glTexCoord2f(0.0f, 1.0f); glVertex2i(x1, y1);
619 glTexCoord2f(1.0f, 1.0f); glVertex2i(x2, y1);
621 glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
622 glTexCoord2f(1.0f, ry); glVertex2i(x2, y1 + rh);
623 glTexCoord2f(0.0f, ry); glVertex2i(x1, y1 + rh);
629 gst_vaapisink_show_frame_glx(
631 GstVaapiSurface *surface,
635 GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window);
639 gst_vaapi_window_glx_make_current(window);
640 if (!sink->texture) {
641 sink->texture = gst_vaapi_texture_new(
649 goto error_create_texture;
651 if (!gst_vaapi_texture_put_surface(sink->texture, surface, flags))
652 goto error_transfer_surface;
654 target = gst_vaapi_texture_get_target(sink->texture);
655 texture = gst_vaapi_texture_get_id(sink->texture);
656 if (target != GL_TEXTURE_2D || !texture)
659 if (sink->use_reflection)
660 render_background(sink);
663 glBindTexture(target, texture);
665 if (sink->use_reflection) {
667 glRotatef(20.0f, 0.0f, 1.0f, 0.0f);
668 glTranslatef(50.0f, 0.0f, 0.0f);
671 if (sink->use_reflection) {
673 glTranslatef(0.0, (GLfloat)sink->display_rect.height + 5.0f, 0.0f);
674 render_reflection(sink);
679 glBindTexture(target, 0);
681 gst_vaapi_window_glx_swap_buffers(window);
685 error_create_texture:
687 GST_DEBUG("could not create VA/GLX texture");
690 error_transfer_surface:
692 GST_DEBUG("could not transfer VA surface to texture");
698 static inline gboolean
699 gst_vaapisink_show_frame_x11(
701 GstVaapiSurface *surface,
705 if (!gst_vaapi_window_put_surface(sink->window, surface,
706 NULL, &sink->display_rect, flags)) {
707 GST_DEBUG("could not render VA surface");
714 gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer)
716 GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
717 GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);
718 GstVaapiSurface *surface;
723 return GST_FLOW_UNEXPECTED;
725 surface = gst_vaapi_video_buffer_get_surface(vbuffer);
727 return GST_FLOW_UNEXPECTED;
729 GST_DEBUG("render surface %" GST_VAAPI_ID_FORMAT,
730 GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface)));
732 flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
734 #if USE_VAAPISINK_GLX
736 success = gst_vaapisink_show_frame_glx(sink, surface, flags);
739 success = gst_vaapisink_show_frame_x11(sink, surface, flags);
740 return success ? GST_FLOW_OK : GST_FLOW_UNEXPECTED;
744 gst_vaapisink_finalize(GObject *object)
746 gst_vaapisink_destroy(GST_VAAPISINK(object));
748 G_OBJECT_CLASS(parent_class)->finalize(object);
752 gst_vaapisink_set_property(
759 GstVaapiSink * const sink = GST_VAAPISINK(object);
763 sink->use_glx = g_value_get_boolean(value);
766 g_free(sink->display_name);
767 sink->display_name = g_strdup(g_value_get_string(value));
769 case PROP_FULLSCREEN:
770 sink->fullscreen = g_value_get_boolean(value);
772 case PROP_SYNCHRONOUS:
773 sink->synchronous = g_value_get_boolean(value);
775 case PROP_USE_REFLECTION:
776 sink->use_reflection = g_value_get_boolean(value);
779 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
785 gst_vaapisink_get_property(
792 GstVaapiSink * const sink = GST_VAAPISINK(object);
796 g_value_set_boolean(value, sink->use_glx);
799 g_value_set_string(value, sink->display_name);
801 case PROP_FULLSCREEN:
802 g_value_set_boolean(value, sink->fullscreen);
804 case PROP_SYNCHRONOUS:
805 g_value_set_boolean(value, sink->synchronous);
807 case PROP_USE_REFLECTION:
808 g_value_set_boolean(value, sink->use_reflection);
811 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
817 gst_vaapisink_base_init(gpointer klass)
819 GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
821 gst_element_class_set_details(element_class, &gst_vaapisink_details);
823 gst_element_class_add_pad_template(
825 gst_static_pad_template_get(&gst_vaapisink_sink_factory)
830 gst_vaapisink_class_init(GstVaapiSinkClass *klass)
832 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
833 GstBaseSinkClass * const basesink_class = GST_BASE_SINK_CLASS(klass);
835 GST_DEBUG_CATEGORY_INIT(gst_debug_vaapisink,
836 GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
838 object_class->finalize = gst_vaapisink_finalize;
839 object_class->set_property = gst_vaapisink_set_property;
840 object_class->get_property = gst_vaapisink_get_property;
842 basesink_class->start = gst_vaapisink_start;
843 basesink_class->stop = gst_vaapisink_stop;
844 basesink_class->set_caps = gst_vaapisink_set_caps;
845 basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc;
846 basesink_class->preroll = gst_vaapisink_show_frame;
847 basesink_class->render = gst_vaapisink_show_frame;
849 #if USE_VAAPISINK_GLX
850 g_object_class_install_property
853 g_param_spec_boolean("use-glx",
855 "Enables GLX rendering",
859 g_object_class_install_property
862 g_param_spec_boolean("use-reflection",
864 "Enables OpenGL reflection effect",
869 g_object_class_install_property
872 g_param_spec_string("display",
878 g_object_class_install_property
881 g_param_spec_boolean("fullscreen",
883 "Requests window in fullscreen state",
888 * GstVaapiSink:synchronous:
890 * When enabled, runs the X display in synchronous mode. Note that
891 * this is used only for debugging.
893 g_object_class_install_property
896 g_param_spec_boolean("synchronous",
898 "Toggles X display synchronous mode",
904 gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass)
906 sink->display_name = NULL;
907 sink->display = NULL;
909 sink->window_width = 0;
910 sink->window_height = 0;
911 sink->texture = NULL;
912 sink->video_width = 0;
913 sink->video_height = 0;
914 sink->video_par_n = 1;
915 sink->video_par_d = 1;
916 sink->foreign_window = FALSE;
917 sink->fullscreen = FALSE;
918 sink->synchronous = FALSE;
919 sink->use_glx = USE_VAAPISINK_GLX;
920 sink->use_reflection = FALSE;
924 gst_vaapisink_get_display(GstVaapiSink *sink)
926 if (!gst_vaapisink_ensure_display(sink))
928 return sink->display;