1 /*
2 * GStreamer Wayland Library
3 * Copyright (C) 2014 Collabora Ltd.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <gst/wayland/wayland.h>
26 #include <gst/video/videooverlay.h>
27
28 gboolean
gst_is_wayland_display_handle_need_context_message(GstMessage * msg)29 gst_is_wayland_display_handle_need_context_message (GstMessage * msg)
30 {
31 const gchar *type = NULL;
32
33 g_return_val_if_fail (GST_IS_MESSAGE (msg), FALSE);
34
35 if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_NEED_CONTEXT &&
36 gst_message_parse_context_type (msg, &type)) {
37 return !g_strcmp0 (type, GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE);
38 }
39
40 return FALSE;
41 }
42
43 GstContext *
gst_wayland_display_handle_context_new(struct wl_display * display)44 gst_wayland_display_handle_context_new (struct wl_display * display)
45 {
46 GstContext *context =
47 gst_context_new (GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE, TRUE);
48 gst_structure_set (gst_context_writable_structure (context),
49 "handle", G_TYPE_POINTER, display, NULL);
50 return context;
51 }
52
53 struct wl_display *
gst_wayland_display_handle_context_get_handle(GstContext * context)54 gst_wayland_display_handle_context_get_handle (GstContext * context)
55 {
56 const GstStructure *s;
57 struct wl_display *display;
58
59 g_return_val_if_fail (GST_IS_CONTEXT (context), NULL);
60
61 s = gst_context_get_structure (context);
62 gst_structure_get (s, "handle", G_TYPE_POINTER, &display, NULL);
63 return display;
64 }
65
66
67 G_DEFINE_INTERFACE (GstWaylandVideo, gst_wayland_video, GST_TYPE_VIDEO_OVERLAY);
68
69 static void
gst_wayland_video_default_init(GstWaylandVideoInterface * klass)70 gst_wayland_video_default_init (GstWaylandVideoInterface * klass)
71 {
72 (void) klass;
73 }
74
75 /**
76 * gst_wayland_video_begin_geometry_change:
77 *
78 * Notifies the video sink that we are about to change its
79 * geometry (probably using set_render_rectangle()). This is useful
80 * in order to allow the sink to synchronize resizing/moving of the
81 * video area with the parent surface and avoid glitches, in cases
82 * where the video area is being painted asynchronously from another
83 * thread, like in waylandsink.
84 *
85 * Please note that any calls to this method MUST be matched by
86 * calls to end_geometry_change() and AFTER the parent surface has
87 * commited its geometry changes.
88 */
89 void
gst_wayland_video_begin_geometry_change(GstWaylandVideo * video)90 gst_wayland_video_begin_geometry_change (GstWaylandVideo * video)
91 {
92 GstWaylandVideoInterface *iface;
93
94 g_return_if_fail (video != NULL);
95 g_return_if_fail (GST_IS_WAYLAND_VIDEO (video));
96
97 iface = GST_WAYLAND_VIDEO_GET_INTERFACE (video);
98
99 if (iface->begin_geometry_change) {
100 iface->begin_geometry_change (video);
101 }
102 }
103
104 /**
105 * gst_wayland_video_end_geometry_change:
106 *
107 * Notifies the video sink that we just finished changing the
108 * geometry of both itself and its parent surface. This should
109 * have been earlier preceeded by a call to begin_geometry_change()
110 * which notified the sink before any of these changes had happened.
111 *
112 * It is important to call this method only AFTER the parent surface
113 * has commited its geometry changes, otherwise no synchronization
114 * is actually achieved.
115 */
116 void
gst_wayland_video_end_geometry_change(GstWaylandVideo * video)117 gst_wayland_video_end_geometry_change (GstWaylandVideo * video)
118 {
119 GstWaylandVideoInterface *iface;
120
121 g_return_if_fail (video != NULL);
122 g_return_if_fail (GST_IS_WAYLAND_VIDEO (video));
123
124 iface = GST_WAYLAND_VIDEO_GET_INTERFACE (video);
125
126 if (iface->end_geometry_change) {
127 iface->end_geometry_change (video);
128 }
129 }
130