summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2016-09-22 15:35:44 -0400
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2016-09-22 19:12:22 -0400
commitecf88d0d4384cf49a4ab9bb5b5deae1500d0888a (patch)
treec8a90cfdcb82ac6d7e4c099038eb3dcf78d46f58
parent1489e73df4ec06257d4e56f10f713a8a83bd56cc (diff)
downloadgstreamer-plugins-bad-ecf88d0d4384cf49a4ab9bb5b5deae1500d0888a.tar.gz
waylandsink: Properly draw black border in absence of viewporter
When we don't have a viewporter (scaling support), we can't use the 1x1 scaleup image trick. Instead, we need to allocate a buffer with the same size as the area that need to have black background.
-rw-r--r--ext/wayland/wlwindow.c86
-rw-r--r--ext/wayland/wlwindow.h10
2 files changed, 60 insertions, 36 deletions
diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c
index 9051b5b1b..febf55247 100644
--- a/ext/wayland/wlwindow.c
+++ b/ext/wayland/wlwindow.c
@@ -102,11 +102,6 @@ static GstWlWindow *
gst_wl_window_new_internal (GstWlDisplay * display)
{
GstWlWindow *window;
- GstVideoInfo info;
- GstBuffer *buf;
- GstMapInfo mapinfo;
- struct wl_buffer *wlbuf;
- GstWlBuffer *gwlbuf;
struct wl_region *region;
window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
@@ -132,30 +127,6 @@ gst_wl_window_new_internal (GstWlDisplay * display)
window->video_surface);
}
- /* draw the area_subsurface */
- gst_video_info_set_format (&info,
- /* we want WL_SHM_FORMAT_XRGB8888 */
-#if G_BYTE_ORDER == G_BIG_ENDIAN
- GST_VIDEO_FORMAT_xRGB,
-#else
- GST_VIDEO_FORMAT_BGRx,
-#endif
- 1, 1);
-
- buf = gst_buffer_new_allocate (gst_wl_shm_allocator_get (), info.size, NULL);
- gst_buffer_map (buf, &mapinfo, GST_MAP_WRITE);
- *((guint32 *) mapinfo.data) = 0; /* paint it black */
- gst_buffer_unmap (buf, &mapinfo);
- wlbuf =
- gst_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0),
- display, &info);
- gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display);
- gst_wl_buffer_attach (gwlbuf, window->area_surface);
-
- /* at this point, the GstWlBuffer keeps the buffer
- * alive and will free it on wl_buffer::release */
- gst_buffer_unref (buf);
-
/* do not accept input */
region = wl_compositor_create_region (display->compositor);
wl_surface_set_input_region (window->area_surface, region);
@@ -261,7 +232,6 @@ gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
wl_subsurface_set_position (window->video_subsurface, res.x, res.y);
-
if (commit) {
wl_surface_damage (window->video_surface, 0, 0, res.w, res.h);
wl_surface_commit (window->video_surface);
@@ -278,8 +248,7 @@ gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
}
/* this is saved for use in wl_surface_damage */
- window->surface_width = res.w;
- window->surface_height = res.h;
+ window->video_rectangle = res;
}
void
@@ -300,8 +269,8 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer,
else
wl_surface_attach (window->video_surface, NULL, 0, 0);
- wl_surface_damage (window->video_surface, 0, 0, window->surface_width,
- window->surface_height);
+ wl_surface_damage (window->video_surface, 0, 0, window->video_rectangle.w,
+ window->video_rectangle.h);
wl_surface_commit (window->video_surface);
if (G_UNLIKELY (info)) {
@@ -316,6 +285,53 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer,
wl_display_flush (window->display->display);
}
+/* Update the buffer used to draw black borders. When we have viewporter
+ * support, this is a scaled up 1x1 image, and without we need an black image
+ * the size of the rendering areay. */
+static void
+gst_wl_window_update_borders (GstWlWindow * window)
+{
+ GstVideoFormat format;
+ GstVideoInfo info;
+ gint width, height;
+ GstBuffer *buf;
+ struct wl_buffer *wlbuf;
+ GstWlBuffer *gwlbuf;
+
+ if (window->no_border_update)
+ return;
+
+ if (window->display->viewporter) {
+ width = height = 1;
+ window->no_border_update = TRUE;
+ } else {
+ width = window->render_rectangle.w;
+ height = window->render_rectangle.h;
+ }
+
+ /* we want WL_SHM_FORMAT_XRGB8888 */
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+ format = GST_VIDEO_FORMAT_xRGB;
+#else
+ format = GST_VIDEO_FORMAT_BGRx;
+#endif
+
+ /* draw the area_subsurface */
+ gst_video_info_set_format (&info, format, width, height);
+
+ buf = gst_buffer_new_allocate (gst_wl_shm_allocator_get (), info.size, NULL);
+ gst_buffer_memset (buf, 0, 0, info.size);
+ wlbuf =
+ gst_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0),
+ window->display, &info);
+ gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, window->display);
+ gst_wl_buffer_attach (gwlbuf, window->area_surface);
+
+ /* at this point, the GstWlBuffer keeps the buffer
+ * alive and will free it on wl_buffer::release */
+ gst_buffer_unref (buf);
+}
+
void
gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
gint w, gint h)
@@ -335,6 +351,8 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
if (window->area_viewport)
wp_viewport_set_destination (window->area_viewport, w, h);
+ gst_wl_window_update_borders (window);
+
if (window->video_width != 0) {
wl_subsurface_set_sync (window->video_subsurface);
gst_wl_window_resize_video_surface (window, TRUE);
diff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h
index 8018df431..9b2d6483f 100644
--- a/ext/wayland/wlwindow.h
+++ b/ext/wayland/wlwindow.h
@@ -52,10 +52,16 @@ struct _GstWlWindow
/* the size and position of the area_(sub)surface */
GstVideoRectangle render_rectangle;
+
+ /* the size and position of the video_subsurface */
+ GstVideoRectangle video_rectangle;
+
/* the size of the video in the buffers */
gint video_width, video_height;
- /* the size of the video_(sub)surface */
- gint surface_width, surface_height;
+
+ /* this will be set when viewporter is available and black background has
+ * already been set on the area_subsurface */
+ gboolean no_border_update;
};
struct _GstWlWindowClass