From 086ac4ee81ddf281239f69bcda615d04b1fe1c16 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Tue, 11 Mar 2014 13:14:00 +0200 Subject: [PATCH] waylandsink: Use wl_scaler/wl_viewport to scale the surface in the compositor/hardware --- ext/wayland/gstwaylandsink.c | 37 +++++++----------------------------- ext/wayland/gstwaylandsink.h | 1 - ext/wayland/wldisplay.c | 2 ++ ext/wayland/wldisplay.h | 2 ++ ext/wayland/wlwindow.c | 6 ++++++ ext/wayland/wlwindow.h | 1 + 6 files changed, 18 insertions(+), 31 deletions(-) diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c index 06e6fd9e7b..2400e6f403 100644 --- a/ext/wayland/gstwaylandsink.c +++ b/ext/wayland/gstwaylandsink.c @@ -275,23 +275,11 @@ gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) { GstWaylandSink *sink; GstCaps *caps; - gint width, height; sink = GST_WAYLAND_SINK (bsink); caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink)); - /* If we don't have a window yet, it will - * be created using the upstream size. - * Otherwise, we should tell upstream exactly - * what size we want. We don't resize ourselves. */ - if (sink->window) { - caps = gst_caps_make_writable (caps); - gst_wl_window_get_size (sink->window, &width, &height); - gst_caps_set_simple (caps, "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, NULL); - } - if (filter) { GstCaps *intersection; @@ -334,16 +322,13 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) sink->video_height = info.height; /* create the output window if needed */ - if (!sink->window || sink->video_width != sink->window->width || - sink->video_height != sink->window->height) { - + if (!sink->window) { if (!sink->display) sink->display = gst_wl_display_new (sink->display_name, &error); if (sink->display == NULL) goto display_failed; - g_clear_object (&sink->window); sink->window = gst_wl_window_new_toplevel (sink->display, sink->video_width, sink->video_height); } @@ -372,7 +357,6 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); gst_object_unref (newpool); - sink->negotiated = TRUE; GST_OBJECT_UNLOCK (sink); return TRUE; @@ -527,7 +511,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) GST_LOG_OBJECT (sink, "render buffer %p", buffer); /* surface is resizing - drop buffers until finished */ - if (sink->drawing_frozen || !sink->negotiated) + if (sink->drawing_frozen) goto done; /* drop buffers until we get a frame callback */ @@ -579,6 +563,11 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) wl_surface_attach (surface, meta->wbuffer, 0, 0); wl_surface_damage (surface, 0, 0, res.w, res.h); + + wl_viewport_set (sink->window->viewport, wl_fixed_from_int (0), + wl_fixed_from_int (0), wl_fixed_from_int (src.w), + wl_fixed_from_int (src.h), res.w, res.h); + callback = wl_surface_frame (surface); wl_callback_add_listener (callback, &frame_callback_listener, sink); wl_surface_commit (surface); @@ -690,7 +679,6 @@ static void gst_wayland_sink_set_surface_size (GstWaylandVideo * video, gint w, gint h) { GstWaylandSink *sink = GST_WAYLAND_SINK (video); - GstPad *peer; g_return_if_fail (sink != NULL); g_return_if_fail (sink->window != NULL); @@ -704,18 +692,7 @@ gst_wayland_sink_set_surface_size (GstWaylandVideo * video, gint w, gint h) } gst_wl_window_set_size (sink->window, w, h); - sink->negotiated = FALSE; GST_OBJECT_UNLOCK (sink); - - /* upstream must change video size because we can't resize ourselves. - * This can be removed when we move to wl_viewport */ - if (GST_STATE (sink) > GST_STATE_READY) { - peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink)); - if (peer) { - gst_pad_send_event (peer, gst_event_new_reconfigure ()); - gst_object_unref (peer); - } - } } static void diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h index 06c2b2c5dc..929dfbb534 100644 --- a/ext/wayland/gstwaylandsink.h +++ b/ext/wayland/gstwaylandsink.h @@ -63,7 +63,6 @@ struct _GstWaylandSink gboolean redraw_pending; gboolean drawing_frozen; - gboolean negotiated; GCond render_cond; }; diff --git a/ext/wayland/wldisplay.c b/ext/wayland/wldisplay.c index 590fc98541..8973f79f96 100644 --- a/ext/wayland/wldisplay.c +++ b/ext/wayland/wldisplay.c @@ -140,6 +140,8 @@ registry_handle_global (void *data, struct wl_registry *registry, } else if (g_strcmp0 (interface, "wl_shm") == 0) { self->shm = wl_registry_bind (registry, id, &wl_shm_interface, 1); wl_shm_add_listener (self->shm, &shm_listener, self); + } else if (g_strcmp0 (interface, "wl_scaler") == 0) { + self->scaler = wl_registry_bind (registry, id, &wl_scaler_interface, 1); } } diff --git a/ext/wayland/wldisplay.h b/ext/wayland/wldisplay.h index dbe49d9cf6..2a90a40c07 100644 --- a/ext/wayland/wldisplay.h +++ b/ext/wayland/wldisplay.h @@ -23,6 +23,7 @@ #include #include +#include "scaler-client-protocol.h" #define GST_TYPE_WL_DISPLAY (gst_wl_display_get_type ()) #define GST_WL_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WL_DISPLAY, GstWlDisplay)) @@ -47,6 +48,7 @@ struct _GstWlDisplay struct wl_compositor *compositor; struct wl_shell *shell; struct wl_shm *shm; + struct wl_scaler *scaler; GArray *formats; /* private */ diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c index f1d103a658..11fe0bcd48 100644 --- a/ext/wayland/wlwindow.c +++ b/ext/wayland/wlwindow.c @@ -74,6 +74,8 @@ gst_wl_window_finalize (GObject * gobject) { GstWlWindow *self = GST_WL_WINDOW (gobject); + wl_viewport_destroy (self->viewport); + if (self->shell_surface) { wl_shell_surface_destroy (self->shell_surface); } @@ -100,6 +102,8 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, gint width, gint height) window->surface = wl_compositor_create_surface (display->compositor); window->own_surface = TRUE; + window->viewport = wl_scaler_get_viewport (display->scaler, window->surface); + window->shell_surface = wl_shell_get_shell_surface (display->shell, window->surface); @@ -133,6 +137,8 @@ gst_wl_window_new_from_surface (GstWlDisplay * display, window->surface = surface; window->own_surface = FALSE; + window->viewport = wl_scaler_get_viewport (display->scaler, window->surface); + return window; } diff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h index ebdd000e39..51461e4c87 100644 --- a/ext/wayland/wlwindow.h +++ b/ext/wayland/wlwindow.h @@ -39,6 +39,7 @@ struct _GstWlWindow GstWlDisplay *display; struct wl_surface *surface; + struct wl_viewport *viewport; struct wl_shell_surface *shell_surface; gint width, height; gboolean own_surface;