mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 21:16:24 +00:00
waylandsink: Use wl_scaler/wl_viewport to scale the surface in the compositor/hardware
This commit is contained in:
parent
1cbfba5034
commit
086ac4ee81
6 changed files with 18 additions and 31 deletions
|
@ -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
|
||||
|
|
|
@ -63,7 +63,6 @@ struct _GstWaylandSink
|
|||
|
||||
gboolean redraw_pending;
|
||||
gboolean drawing_frozen;
|
||||
gboolean negotiated;
|
||||
GCond render_cond;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
#include <wayland-client.h>
|
||||
#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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue