[pinpoint] Don't run gstreamer in a sub mainloop with the same maincontext



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]