问题
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 ?
回答1:
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()
).
来源:https://stackoverflow.com/questions/22626989/multithreaded-gstreamer-w-pygtk-crashing-xcb-xlib-threads-sequence-lost