From bda600ed92327444841e893d6899d2674dcbace2 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Fri, 13 Jun 2014 15:58:08 +0200 Subject: [PATCH] waylandsink: improve the way the video size is passed to wlwindow and also improve the code for window creation --- ext/wayland/gstwaylandsink.c | 52 +++++++++++++++++++++++++++++--------------- ext/wayland/gstwaylandsink.h | 6 ++--- ext/wayland/wlwindow.c | 20 ++++++++--------- ext/wayland/wlwindow.h | 6 ++--- 4 files changed, 49 insertions(+), 35 deletions(-) diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c index f87eaca..2cc28e2 100644 --- a/ext/wayland/gstwaylandsink.c +++ b/ext/wayland/gstwaylandsink.c @@ -465,10 +465,6 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) if (format == -1) goto invalid_format; - /* store the video size */ - sink->video_width = info.width; - sink->video_height = info.height; - /* verify we support the requested format */ formats = sink->display->formats; for (i = 0; i < formats->len; i++) { @@ -490,6 +486,10 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) if (!gst_buffer_pool_set_config (newpool, structure)) goto config_failed; + /* store the video info */ + sink->video_info = info; + sink->video_info_changed = TRUE; + gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool); gst_object_unref (newpool); @@ -654,30 +654,46 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) GstWlMeta *meta; GstFlowReturn ret = GST_FLOW_OK; - /* ask for window handle. do that before locking the sink, because - * set_window_handle & friends will lock it in this context */ - if (!sink->window) - gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink)); - g_mutex_lock (&sink->render_lock); GST_LOG_OBJECT (sink, "render buffer %p", buffer); + if (G_UNLIKELY (!sink->window)) { + /* ask for window handle. Unlock render_lock while doing that because + * set_window_handle & friends will lock it in this context */ + g_mutex_unlock (&sink->render_lock); + gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink)); + g_mutex_lock (&sink->render_lock); + + if (sink->window) { + /* inform the window about our caps */ + gst_wl_window_set_video_info (sink->window, &sink->video_info); + } else { + /* if we were not provided a window, create one ourselves */ + sink->window = + gst_wl_window_new_toplevel (sink->display, &sink->video_info); + } + sink->video_info_changed = FALSE; + } + /* drop buffers until we get a frame callback */ if (g_atomic_int_get (&sink->redraw_pending) == TRUE) goto done; - /* if we were not provided a window, create one ourselves */ - if (!sink->window) { - sink->window = gst_wl_window_new_toplevel (sink->display, sink->video_width, - sink->video_height); - } else { - gst_wl_window_set_video_size (sink->window, sink->video_width, - sink->video_height); - if (sink->window->surface_width == 0 || sink->window->surface_height == 0) - goto no_window_size; + if (G_UNLIKELY (sink->video_info_changed)) { + gst_wl_window_set_video_info (sink->window, &sink->video_info); + sink->video_info_changed = FALSE; } + /* now that we have for sure set the video info on the window, it must have + * a valid size, otherwise this means that the application has called + * set_window_handle() without calling set_render_rectangle(), which is + * absolutely necessary for us. + */ + if (G_UNLIKELY (sink->window->surface_width == 0 || + sink->window->surface_height == 0)) + goto no_window_size; + meta = gst_buffer_get_wl_meta (buffer); if (meta && meta->pool->display == sink->display) { diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h index 85265e8..afbed40 100644 --- a/ext/wayland/gstwaylandsink.h +++ b/ext/wayland/gstwaylandsink.h @@ -23,7 +23,7 @@ #define __GST_WAYLAND_VIDEO_SINK_H__ #include -#include +#include #include @@ -57,8 +57,8 @@ struct _GstWaylandSink GstWlWindow *window; GstBufferPool *pool; - gint video_width; - gint video_height; + gboolean video_info_changed; + GstVideoInfo video_info; gchar *display_name; diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c index a75e2fa..8ecf9ea 100644 --- a/ext/wayland/wlwindow.c +++ b/ext/wayland/wlwindow.c @@ -116,16 +116,16 @@ gst_wl_window_new_internal (GstWlDisplay * display, struct wl_surface *surface) } GstWlWindow * -gst_wl_window_new_toplevel (GstWlDisplay * display, gint video_width, - gint video_height) +gst_wl_window_new_toplevel (GstWlDisplay * display, GstVideoInfo * video_info) { GstWlWindow *window; window = gst_wl_window_new_internal (display, wl_compositor_create_surface (display->compositor)); - gst_wl_window_set_video_size (window, video_width, video_height); - gst_wl_window_set_render_rectangle (window, 0, 0, video_width, video_height); + gst_wl_window_set_video_info (window, video_info); + gst_wl_window_set_render_rectangle (window, 0, 0, video_info->width, + video_info->height); window->shell_surface = wl_shell_get_shell_surface (display->shell, window->surface); @@ -207,17 +207,15 @@ gst_wl_window_resize_internal (GstWlWindow * window) } void -gst_wl_window_set_video_size (GstWlWindow * window, gint w, gint h) +gst_wl_window_set_video_info (GstWlWindow * window, GstVideoInfo * info) { g_return_if_fail (window != NULL); - if (w != window->video_width || h != window->video_height) { - window->video_width = w; - window->video_height = h; + window->video_width = info->width; + window->video_height = info->height; - if (window->render_rectangle.w != 0) - gst_wl_window_resize_internal (window); - } + if (window->render_rectangle.w != 0) + gst_wl_window_resize_internal (window); } void diff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h index 21ecdce..f4cb360 100644 --- a/ext/wayland/wlwindow.h +++ b/ext/wayland/wlwindow.h @@ -22,7 +22,7 @@ #define __GST_WL_WINDOW_H__ #include "wldisplay.h" -#include +#include G_BEGIN_DECLS @@ -62,7 +62,7 @@ struct _GstWlWindowClass GType gst_wl_window_get_type (void); GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display, - gint video_width, gint video_height); + GstVideoInfo * video_info); GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display, struct wl_surface * parent); @@ -71,7 +71,7 @@ struct wl_surface *gst_wl_window_get_wl_surface (GstWlWindow * window); gboolean gst_wl_window_is_toplevel (GstWlWindow *window); /* functions to manipulate the size on non-toplevel windows */ -void gst_wl_window_set_video_size (GstWlWindow * window, gint w, gint h); +void gst_wl_window_set_video_info (GstWlWindow * window, GstVideoInfo * info); void gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, gint w, gint h); -- 2.7.4