waylandsink: Replace the OBJECT_LOCK with a private render_lock to lock render operations

This is because:
* GST_ELEMENT_WARNING/ERROR do lock the OBJECT_LOCK and we deadlock instantly
* In future commits I want to make use of GstBaseSink functions that also
  lock the OBJECT_LOCK inside this code
This commit is contained in:
George Kiagiadakis 2014-05-28 13:10:43 +03:00
parent cffb38993d
commit db8caa9da4
2 changed files with 18 additions and 15 deletions

View File

@ -162,6 +162,7 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
static void static void
gst_wayland_sink_init (GstWaylandSink * sink) gst_wayland_sink_init (GstWaylandSink * sink)
{ {
g_mutex_init (&sink->render_lock);
g_cond_init (&sink->render_cond); g_cond_init (&sink->render_cond);
} }
@ -222,6 +223,7 @@ gst_wayland_sink_finalize (GObject * object)
if (sink->display_name) if (sink->display_name)
g_free (sink->display_name); g_free (sink->display_name);
g_mutex_clear (&sink->render_lock);
g_cond_clear (&sink->render_cond); g_cond_clear (&sink->render_cond);
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
@ -590,7 +592,7 @@ static const struct wl_callback_listener frame_callback_listener = {
frame_redraw_callback frame_redraw_callback
}; };
/* must be called with the object lock */ /* must be called with the render lock */
static void static void
render_last_buffer (GstWaylandSink * sink) render_last_buffer (GstWaylandSink * sink)
{ {
@ -632,7 +634,7 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
if (!sink->window) if (!sink->window)
gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink)); gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (sink));
GST_OBJECT_LOCK (sink); g_mutex_lock (&sink->render_lock);
GST_LOG_OBJECT (sink, "render buffer %p", buffer); GST_LOG_OBJECT (sink, "render buffer %p", buffer);
@ -719,7 +721,7 @@ activate_failed:
} }
done: done:
{ {
GST_OBJECT_UNLOCK (sink); g_mutex_unlock (&sink->render_lock);
return ret; return ret;
} }
} }
@ -740,7 +742,7 @@ gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle)
g_return_if_fail (sink != NULL); g_return_if_fail (sink != NULL);
GST_OBJECT_LOCK (sink); g_mutex_lock (&sink->render_lock);
GST_DEBUG_OBJECT (sink, "Setting window handle %" GST_PTR_FORMAT, GST_DEBUG_OBJECT (sink, "Setting window handle %" GST_PTR_FORMAT,
(void *) handle); (void *) handle);
@ -765,7 +767,7 @@ gst_wayland_sink_set_window_handle (GstVideoOverlay * overlay, guintptr handle)
} }
} }
GST_OBJECT_UNLOCK (sink); g_mutex_unlock (&sink->render_lock);
} }
static void static void
@ -776,9 +778,9 @@ gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay,
g_return_if_fail (sink != NULL); g_return_if_fail (sink != NULL);
GST_OBJECT_LOCK (sink); g_mutex_lock (&sink->render_lock);
if (!sink->window) { if (!sink->window) {
GST_OBJECT_UNLOCK (sink); g_mutex_unlock (&sink->render_lock);
GST_WARNING_OBJECT (sink, GST_WARNING_OBJECT (sink,
"set_render_rectangle called without window, ignoring"); "set_render_rectangle called without window, ignoring");
return; return;
@ -788,7 +790,7 @@ gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay,
x, y, w, h); x, y, w, h);
gst_wl_window_set_render_rectangle (sink->window, x, y, w, h); gst_wl_window_set_render_rectangle (sink->window, x, y, w, h);
GST_OBJECT_UNLOCK (sink); g_mutex_unlock (&sink->render_lock);
} }
static void static void
@ -800,12 +802,12 @@ gst_wayland_sink_expose (GstVideoOverlay * overlay)
GST_DEBUG_OBJECT (sink, "expose"); GST_DEBUG_OBJECT (sink, "expose");
GST_OBJECT_LOCK (sink); g_mutex_lock (&sink->render_lock);
if (sink->last_buffer && g_atomic_int_get (&sink->redraw_pending) == FALSE) { if (sink->last_buffer && g_atomic_int_get (&sink->redraw_pending) == FALSE) {
GST_DEBUG_OBJECT (sink, "redrawing last buffer"); GST_DEBUG_OBJECT (sink, "redrawing last buffer");
render_last_buffer (sink); render_last_buffer (sink);
} }
GST_OBJECT_UNLOCK (sink); g_mutex_unlock (&sink->render_lock);
} }
static void static void
@ -821,9 +823,9 @@ gst_wayland_sink_pause_rendering (GstWaylandVideo * video)
GstWaylandSink *sink = GST_WAYLAND_SINK (video); GstWaylandSink *sink = GST_WAYLAND_SINK (video);
g_return_if_fail (sink != NULL); g_return_if_fail (sink != NULL);
GST_OBJECT_LOCK (sink); g_mutex_lock (&sink->render_lock);
sink->drawing_frozen = TRUE; sink->drawing_frozen = TRUE;
GST_OBJECT_UNLOCK (sink); g_mutex_unlock (&sink->render_lock);
} }
static void static void
@ -834,13 +836,13 @@ gst_wayland_sink_resume_rendering (GstWaylandVideo * video)
GST_DEBUG_OBJECT (sink, "resuming rendering"); GST_DEBUG_OBJECT (sink, "resuming rendering");
GST_OBJECT_LOCK (sink); g_mutex_lock (&sink->render_lock);
sink->drawing_frozen = FALSE; sink->drawing_frozen = FALSE;
if (GST_STATE (sink) == GST_STATE_PLAYING) { if (GST_STATE (sink) == GST_STATE_PLAYING) {
sink->rendered = FALSE; sink->rendered = FALSE;
while (sink->rendered == FALSE) while (sink->rendered == FALSE)
g_cond_wait (&sink->render_cond, GST_OBJECT_GET_LOCK (sink)); g_cond_wait (&sink->render_cond, &sink->render_lock);
GST_DEBUG_OBJECT (sink, "synchronized with render()"); GST_DEBUG_OBJECT (sink, "synchronized with render()");
} else if (sink->window && sink->last_buffer && } else if (sink->window && sink->last_buffer &&
g_atomic_int_get (&sink->redraw_pending) == FALSE) { g_atomic_int_get (&sink->redraw_pending) == FALSE) {
@ -848,7 +850,7 @@ gst_wayland_sink_resume_rendering (GstWaylandVideo * video)
GST_DEBUG_OBJECT (sink, "last buffer redrawn"); GST_DEBUG_OBJECT (sink, "last buffer redrawn");
} }
GST_OBJECT_UNLOCK (sink); g_mutex_unlock (&sink->render_lock);
} }
static gboolean static gboolean

View File

@ -64,6 +64,7 @@ struct _GstWaylandSink
gboolean redraw_pending; gboolean redraw_pending;
gboolean drawing_frozen; gboolean drawing_frozen;
gboolean rendered; gboolean rendered;
GMutex render_lock;
GCond render_cond; GCond render_cond;
GstBuffer *last_buffer; GstBuffer *last_buffer;
}; };