Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreaded Gstreamer w/ PyGTK crashing (xcb_xlib_threads_sequence_lost)

I understand that one is not supposed to update the UI from other threads in gtk, or face consequences, but I am not sure how I can avoid that while using gstreamer.

My application crashes from time to time during video stream initialization with a following complaint:

[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.

In my code I have added gtk.thread_init() call right in the beginning of the GUI class:

import pygtk, gtk, gobject
gtk.gdk.threads_init()

(I have also tried gobject.threads_init(), but this doesnt seem any different). In a separate class, which is run in a separate thread, I start a gstreamer stream to a tcpserversink (this gstreamer thread is already a third thread, if someone is keeping count). And then another thread receives this data before pushing the data to xvimagesink in the end.

The xvimagesink needs a viewport, and I believe this gstreamer callback function is where sometimes gtk goes crazy, when I assign it:

def on_sync_message(self, bus, message):
...
if message_name == "prepare-xwindow-id":

  # Assign the viewport
  imagesink = message.src
  imagesink.set_property("force-aspect-ratio", True)
  imagesink.set_xwindow_id(self.window_handle.window.xid)

The self.window_handle is a pointer to self.movie_window = gtk.DrawingArea(), assigned during GUI initialization.

TL;DR Is there a safe way of using gtk with gstreamer, since I cannot avoid threading when calling gst.Pipeline("name").set_state(gst.STATE_PLAYING) and view will be a GTK drawing area ?

like image 606
julumme Avatar asked Oct 20 '22 11:10

julumme


1 Answers

I think your issue is the fact that you are accessing unprotected Xlib/xcb from 2 threads - once impicitly from your Gtk+ UI and once in the thread where your gstreamer backend callback is executed - which by default is the mainloop you told gstreamer to use (or the thread default mainloop).


gtk.gdk.threads_init() is already called once the type system is initialized (if I recall correctly, correct me if I am wrong).


Use g_idle_add (or use GSource with a higher priority) (which are threadsafe) with a callback which schedules UI changes in the Gtk mainloop (run by gtk_main()).

like image 97
drahnr Avatar answered Oct 23 '22 03:10

drahnr