waylandsink: Use wl_scaler/wl_viewport to scale the surface in the compositor/hardware

This commit is contained in:
George Kiagiadakis 2014-03-11 13:14:00 +02:00
parent 1cbfba5034
commit 086ac4ee81
6 changed files with 18 additions and 31 deletions

View file

@ -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

View file

@ -63,7 +63,6 @@ struct _GstWaylandSink
gboolean redraw_pending;
gboolean drawing_frozen;
gboolean negotiated;
GCond render_cond;
};

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;