summaryrefslogtreecommitdiff
path: root/ext/wayland
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2014-03-11 17:45:05 +0200
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2014-06-17 13:51:25 +0200
commit66f8c1389ba4258a7235ca559b69c96ed90f6772 (patch)
tree41ade4960f8051d1380765f58ed16eb382d61f73 /ext/wayland
parent086ac4ee81ddf281239f69bcda615d04b1fe1c16 (diff)
downloadgstreamer-plugins-bad-66f8c1389ba4258a7235ca559b69c96ed90f6772.tar.gz
waylandsink: Implement expose() and handle resizing properly in non-PLAYING states
Diffstat (limited to 'ext/wayland')
-rw-r--r--ext/wayland/gstwaylandsink.c95
-rw-r--r--ext/wayland/gstwaylandsink.h1
2 files changed, 62 insertions, 34 deletions
diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
index 2400e6f40..ad2474e85 100644
--- a/ext/wayland/gstwaylandsink.c
+++ b/ext/wayland/gstwaylandsink.c
@@ -202,6 +202,8 @@ gst_wayland_sink_finalize (GObject * object)
GST_DEBUG_OBJECT (sink, "Finalizing the sink..");
+ if (sink->last_buffer)
+ gst_buffer_unref (sink->last_buffer);
if (sink->display) {
/* see comment about this call in gst_wayland_sink_change_state() */
gst_wayland_compositor_release_all_buffers (GST_WAYLAND_BUFFER_POOL
@@ -258,6 +260,7 @@ gst_wayland_sink_change_state (GstElement * element, GstStateChange transition)
*/
gst_wayland_compositor_release_all_buffers (GST_WAYLAND_BUFFER_POOL
(sink->pool));
+ gst_buffer_replace (&sink->last_buffer, NULL);
g_clear_object (&sink->window);
g_clear_object (&sink->display);
g_clear_object (&sink->pool);
@@ -495,16 +498,52 @@ static const struct wl_callback_listener frame_callback_listener = {
frame_redraw_callback
};
+/* must be called with the object lock */
+static void
+render_last_buffer (GstWaylandSink * sink)
+{
+ GstWlMeta *meta;
+ struct wl_surface *surface;
+ struct wl_callback *callback;
+ GstVideoRectangle src, dst, res;
+
+ meta = gst_buffer_get_wl_meta (sink->last_buffer);
+ surface = gst_wl_window_get_wl_surface (sink->window);
+
+ g_atomic_int_set (&sink->redraw_pending, TRUE);
+ callback = wl_surface_frame (surface);
+ wl_callback_add_listener (callback, &frame_callback_listener, sink);
+
+ /* Here we essentially add a reference to the buffer. This represents
+ * the fact that the compositor is using the buffer and it should
+ * not return back to the pool and be reused until the compositor
+ * releases it. The release is handled internally in the pool */
+ gst_wayland_compositor_acquire_buffer (meta->pool, sink->last_buffer);
+
+ src.w = sink->video_width;
+ src.h = sink->video_height;
+ dst.w = sink->window->width;
+ dst.h = sink->window->height;
+ gst_video_sink_center_rect (src, dst, &res, FALSE);
+
+ 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);
+
+ wl_surface_attach (surface, meta->wbuffer, 0, 0);
+ wl_surface_damage (surface, 0, 0, res.w, res.h);
+
+ wl_surface_commit (surface);
+ wl_display_flush (sink->display->display);
+}
+
static GstFlowReturn
gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
{
GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
- GstVideoRectangle src, dst, res;
GstBuffer *to_render;
GstWlMeta *meta;
GstFlowReturn ret = GST_FLOW_OK;
- struct wl_surface *surface;
- struct wl_callback *callback;
GST_OBJECT_LOCK (sink);
@@ -540,38 +579,10 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
gst_buffer_map (buffer, &src, GST_MAP_READ);
gst_buffer_fill (to_render, 0, src.data, src.size);
gst_buffer_unmap (buffer, &src);
-
- meta = gst_buffer_get_wl_meta (to_render);
}
- src.w = sink->video_width;
- src.h = sink->video_height;
- dst.w = sink->window->width;
- dst.h = sink->window->height;
-
- gst_video_sink_center_rect (src, dst, &res, FALSE);
-
- surface = gst_wl_window_get_wl_surface (sink->window);
-
- /* Here we essentially add a reference to the buffer. This represents
- * the fact that the compositor is using the buffer and it should
- * not return back to the pool and be reused until the compositor
- * releases it. The release is handled internally in the pool */
- gst_wayland_compositor_acquire_buffer (meta->pool, to_render);
-
- g_atomic_int_set (&sink->redraw_pending, TRUE);
-
- 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);
- wl_display_flush (sink->display->display);
+ gst_buffer_replace (&sink->last_buffer, to_render);
+ render_last_buffer (sink);
/* notify _resume_rendering() in case it's waiting */
g_cond_broadcast (&sink->render_cond);
@@ -664,7 +675,17 @@ static void
gst_wayland_sink_expose (GstVideoOverlay * overlay)
{
GstWaylandSink *sink = GST_WAYLAND_SINK (overlay);
+
g_return_if_fail (sink != NULL);
+
+ GST_DEBUG_OBJECT (sink, "expose");
+
+ GST_OBJECT_LOCK (sink);
+ if (sink->last_buffer && g_atomic_int_get (&sink->redraw_pending) == FALSE) {
+ GST_DEBUG_OBJECT (sink, "redrawing last buffer");
+ render_last_buffer (sink);
+ }
+ GST_OBJECT_UNLOCK (sink);
}
static void
@@ -714,7 +735,13 @@ gst_wayland_sink_resume_rendering (GstWaylandVideo * video)
GST_OBJECT_LOCK (sink);
sink->drawing_frozen = FALSE;
- g_cond_wait (&sink->render_cond, GST_OBJECT_GET_LOCK (sink));
+
+ if (GST_STATE (sink) == GST_STATE_PLAYING)
+ g_cond_wait (&sink->render_cond, GST_OBJECT_GET_LOCK (sink));
+ else if (sink->window && sink->last_buffer &&
+ g_atomic_int_get (&sink->redraw_pending) == FALSE)
+ render_last_buffer (sink);
+
GST_OBJECT_UNLOCK (sink);
}
diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h
index 929dfbb53..bbbdbb6c4 100644
--- a/ext/wayland/gstwaylandsink.h
+++ b/ext/wayland/gstwaylandsink.h
@@ -64,6 +64,7 @@ struct _GstWaylandSink
gboolean redraw_pending;
gboolean drawing_frozen;
GCond render_cond;
+ GstBuffer *last_buffer;
};
struct _GstWaylandSinkClass