[pinpoint] Don't run gstreamer in a sub mainloop with the same maincontext
- From: Lionel Landwerlin <llandwerlin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pinpoint] Don't run gstreamer in a sub mainloop with the same maincontext
- Date: Wed, 30 May 2012 22:03:06 +0000 (UTC)
commit f95713006bdb900bcc2b1231f4ba5aedca8591ce
Author: Lionel Landwerlin <llandwerlin gmail com>
Date: Wed May 30 22:39:28 2012 +0100
Don't run gstreamer in a sub mainloop with the same maincontext
When generating a speaker thumbnail for a slide containing a video,
you can't generate this thumbnail using Gstreamer under a callback
triggered by Clutter AND at the same time run the mainloop in the
current context because rerunning the mainloop on the same context
implies that you are going to re-enter the clutter thread lock, which
means you're going to end up in a dead lock situation.
This patch prevents the dead lock by running the gstreamer commands on
a different context (even though still on the same thread).
The drawback of this fix is that it is going block the UI rendering
until the video thumbnail has been generated (depending on the video
that can be noticable).
gst-video-thumbnailer.c | 16 +++++++++++++---
1 files changed, 13 insertions(+), 3 deletions(-)
---
diff --git a/gst-video-thumbnailer.c b/gst-video-thumbnailer.c
index f33acf7..8f0a3ea 100644
--- a/gst-video-thumbnailer.c
+++ b/gst-video-thumbnailer.c
@@ -177,6 +177,9 @@ gst_video_thumbnailer_get_shot (const gchar *location,
GdkPixbuf *shot = NULL;
int count = 0;
gchar *uri = g_strconcat ("file://", location, NULL);
+ GMainContext *context = g_main_context_new ();
+
+ g_main_context_push_thread_default (context);
playbin = gst_element_factory_make ("playbin", "playbin");
audio_sink = gst_element_factory_make ("fakesink", "audiosink");
@@ -198,11 +201,12 @@ gst_video_thumbnailer_get_shot (const gchar *location,
count++;
/* Spin mainloop so we can pick up the cancels */
- while (g_main_context_pending (NULL)) {
- g_main_context_iteration (NULL, FALSE);
+ while (g_main_context_pending (context)) {
+ g_main_context_iteration (context, FALSE);
}
}
+
if (g_cancellable_is_cancelled (cancellable)) {
g_print ("Video %s was cancelled\n", uri);
state = GST_STATE_CHANGE_FAILURE;
@@ -245,7 +249,8 @@ gst_video_thumbnailer_get_shot (const gchar *location,
NULL);
if (frame == NULL) {
g_warning ("No frame for %s", uri);
- return NULL;
+ shot = NULL;
+ goto finish;
}
shot = convert_buffer_to_pixbuf (frame, cancellable);
@@ -256,6 +261,11 @@ gst_video_thumbnailer_get_shot (const gchar *location,
g_object_unref (playbin);
g_free (uri);
+ finish:
+
+ g_main_context_pop_thread_default (context);
+ g_main_context_unref (context);
+
return shot;
}
#endif /* USE_CLUTTER_GST */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]