iface);
static void gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay,
guintptr handle);
+static void gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay,
+ gint x, gint y, gint w, gint h);
static void gst_wayland_sink_expose (GstVideoOverlay * overlay);
/* WaylandVideo interface */
static void gst_wayland_sink_waylandvideo_init (GstWaylandVideoInterface *
iface);
-static void gst_wayland_sink_set_surface_size (GstWaylandVideo * video,
- gint w, gint h);
static void gst_wayland_sink_pause_rendering (GstWaylandVideo * video);
static void gst_wayland_sink_resume_rendering (GstWaylandVideo * video);
src.h = sink->video_height;
dst.w = sink->window->width;
dst.h = sink->window->height;
- gst_video_sink_center_rect (src, dst, &res, FALSE);
+ gst_video_sink_center_rect (src, dst, &res, TRUE);
+ if (sink->window->subsurface)
+ wl_subsurface_set_position (sink->window->subsurface,
+ sink->window->x + res.x, sink->window->y + res.y);
wl_viewport_set_destination (sink->window->viewport, res.w, res.h);
wl_surface_attach (surface, meta->wbuffer, 0, 0);
- wl_surface_damage (surface, 0, 0, res.w, res.h);
+ wl_surface_damage (surface, 0, 0, dst.w, dst.h);
wl_surface_commit (surface);
wl_display_flush (sink->display->display);
gst_wayland_sink_videooverlay_init (GstVideoOverlayInterface * iface)
{
iface->set_window_handle = gst_wayland_sink_set_window_handle;
+ iface->set_render_rectangle = gst_wayland_sink_set_render_rectangle;
iface->expose = gst_wayland_sink_expose;
}
"an externally-supplied display handle. Consider providing a "
"display handle from your application with GstContext"));
} else {
- sink->window = gst_wl_window_new_from_surface (sink->display, surface);
+ sink->window = gst_wl_window_new_in_surface (sink->display, surface);
}
} else {
GST_ERROR_OBJECT (sink, "Failed to find display handle, "
}
static void
+gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay,
+ gint x, gint y, gint w, gint h)
+{
+ GstWaylandSink *sink = GST_WAYLAND_SINK (overlay);
+
+ g_return_if_fail (sink != NULL);
+
+ GST_OBJECT_LOCK (sink);
+ if (!sink->window) {
+ GST_OBJECT_UNLOCK (sink);
+ GST_WARNING_OBJECT (sink,
+ "set_render_rectangle called without window, ignoring");
+ return;
+ }
+
+ GST_DEBUG_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d",
+ x, y, w, h);
+ gst_wl_window_set_size (sink->window, x, y, w, h);
+ GST_OBJECT_UNLOCK (sink);
+}
+
+static void
gst_wayland_sink_expose (GstVideoOverlay * overlay)
{
GstWaylandSink *sink = GST_WAYLAND_SINK (overlay);
static void
gst_wayland_sink_waylandvideo_init (GstWaylandVideoInterface * iface)
{
- iface->set_surface_size = gst_wayland_sink_set_surface_size;
iface->pause_rendering = gst_wayland_sink_pause_rendering;
iface->resume_rendering = gst_wayland_sink_resume_rendering;
}
static void
-gst_wayland_sink_set_surface_size (GstWaylandVideo * video, gint w, gint h)
-{
- GstWaylandSink *sink = GST_WAYLAND_SINK (video);
-
- g_return_if_fail (sink != NULL);
- g_return_if_fail (sink->window != NULL);
-
- GST_OBJECT_LOCK (sink);
- if (!sink->window) {
- GST_OBJECT_UNLOCK (sink);
- GST_WARNING_OBJECT (sink,
- "set_surface_size called without window, ignoring");
- return;
- }
-
- GST_DEBUG_OBJECT (sink, "changing window size to %d x %d", w, h);
- gst_wl_window_set_size (sink->window, w, h);
- GST_OBJECT_UNLOCK (sink);
-}
-
-static void
gst_wayland_sink_pause_rendering (GstWaylandVideo * video)
{
GstWaylandSink *sink = GST_WAYLAND_SINK (video);
if (self->compositor)
wl_compositor_destroy (self->compositor);
+ if (self->subcompositor)
+ wl_subcompositor_destroy (self->subcompositor);
+
if (self->registry)
wl_registry_destroy (self->registry);
if (g_strcmp0 (interface, "wl_compositor") == 0) {
self->compositor = wl_registry_bind (registry, id, &wl_compositor_interface,
MIN (version, 3));
+ } else if (g_strcmp0 (interface, "wl_subcompositor") == 0) {
+ self->subcompositor =
+ wl_registry_bind (registry, id, &wl_subcompositor_interface, 1);
} else if (g_strcmp0 (interface, "wl_shell") == 0) {
self->shell = wl_registry_bind (registry, id, &wl_shell_interface, 1);
} else if (g_strcmp0 (interface, "wl_shm") == 0) {
wl_surface_destroy (self->surface);
}
+ if (self->subsurface) {
+ wl_subsurface_destroy (self->subsurface);
+ }
+
g_clear_object (&self->display);
G_OBJECT_CLASS (gst_wl_window_parent_class)->finalize (gobject);
wl_compositor_create_surface (display->compositor));
window->own_surface = TRUE;
- gst_wl_window_set_size (window, width, height);
+ gst_wl_window_set_size (window, 0, 0, width, height);
window->shell_surface = wl_shell_get_shell_surface (display->shell,
window->surface);
}
GstWlWindow *
+gst_wl_window_new_in_surface (GstWlDisplay * display,
+ struct wl_surface * parent)
+{
+ GstWlWindow *window;
+
+ window = gst_wl_window_new_from_surface (display,
+ wl_compositor_create_surface (display->compositor));
+ window->own_surface = TRUE;
+
+ window->subsurface = wl_subcompositor_get_subsurface (display->subcompositor,
+ window->surface, parent);
+ wl_subsurface_set_desync (window->subsurface);
+
+ return window;
+}
+
+GstWlWindow *
gst_wl_window_new_from_surface (GstWlDisplay * display,
struct wl_surface * surface)
{
window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
window->display = g_object_ref (display);
+ window->x = 0;
+ window->y = 0;
window->width = 0;
window->height = 0;
}
void
-gst_wl_window_set_size (GstWlWindow * window, gint w, gint h)
+gst_wl_window_set_size (GstWlWindow * window, gint x, gint y, gint w, gint h)
{
g_return_if_fail (window != NULL);
+ window->x = x;
+ window->y = y;
window->width = w;
window->height = h;
}
GstWlDisplay *display;
struct wl_surface *surface;
+ struct wl_subsurface *subsurface;
struct wl_viewport *viewport;
struct wl_shell_surface *shell_surface;
- gint width, height;
+ gint x, y, width, height;
gboolean own_surface;
};
GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display,
gint width, gint height);
+GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display,
+ struct wl_surface * parent);
GstWlWindow *gst_wl_window_new_from_surface (GstWlDisplay * display,
struct wl_surface * surface);
struct wl_surface *gst_wl_window_get_wl_surface (GstWlWindow * window);
gboolean gst_wl_window_is_toplevel (GstWlWindow *window);
-void gst_wl_window_set_size (GstWlWindow * window, gint w, gint h);
+void gst_wl_window_set_size (GstWlWindow * window, gint x, gint y, gint w,
+ gint h);
G_END_DECLS