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 "display", 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 if (gst_structure_get (s, "display", G_TYPE_POINTER, &display, NULL))
63 return display;
64 if (gst_structure_get (s, "handle", G_TYPE_POINTER, &display, NULL))
65 return display;
66 return NULL;
67 }
68
69
70 G_DEFINE_INTERFACE (GstWaylandVideo, gst_wayland_video, GST_TYPE_VIDEO_OVERLAY);
71
72 static void
gst_wayland_video_default_init(GstWaylandVideoInterface * klass)73 gst_wayland_video_default_init (GstWaylandVideoInterface * klass)
74 {
75 (void) klass;
76 }
77
78 /**
79 * gst_wayland_video_begin_geometry_change:
80 *
81 * Notifies the video sink that we are about to change its
82 * geometry (probably using set_render_rectangle()). This is useful
83 * in order to allow the sink to synchronize resizing/moving of the
84 * video area with the parent surface and avoid glitches, in cases
85 * where the video area is being painted asynchronously from another
86 * thread, like in waylandsink.
87 *
88 * Please note that any calls to this method MUST be matched by
89 * calls to end_geometry_change() and AFTER the parent surface has
90 * committed its geometry changes.
91 */
92 void
gst_wayland_video_begin_geometry_change(GstWaylandVideo * video)93 gst_wayland_video_begin_geometry_change (GstWaylandVideo * video)
94 {
95 GstWaylandVideoInterface *iface;
96
97 g_return_if_fail (video != NULL);
98 g_return_if_fail (GST_IS_WAYLAND_VIDEO (video));
99
100 iface = GST_WAYLAND_VIDEO_GET_INTERFACE (video);
101
102 if (iface->begin_geometry_change) {
103 iface->begin_geometry_change (video);
104 }
105 }
106
107 /**
108 * gst_wayland_video_end_geometry_change:
109 *
110 * Notifies the video sink that we just finished changing the
111 * geometry of both itself and its parent surface. This should
112 * have been earlier preceded by a call to begin_geometry_change()
113 * which notified the sink before any of these changes had happened.
114 *
115 * It is important to call this method only AFTER the parent surface
116 * has committed its geometry changes, otherwise no synchronization
117 * is actually achieved.
118 */
119 void
gst_wayland_video_end_geometry_change(GstWaylandVideo * video)120 gst_wayland_video_end_geometry_change (GstWaylandVideo * video)
121 {
122 GstWaylandVideoInterface *iface;
123
124 g_return_if_fail (video != NULL);
125 g_return_if_fail (GST_IS_WAYLAND_VIDEO (video));
126
127 iface = GST_WAYLAND_VIDEO_GET_INTERFACE (video);
128
129 if (iface->end_geometry_change) {
130 iface->end_geometry_change (video);
131 }
132 }
133