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