Я понимаю, что нельзя обновлять пользовательский интерфейс из других потоков в gtk
или сталкиваться с последствиями, но я не уверен, как я могу избежать этого при использовании gstreamer
.
Мое приложение время от времени падает во время инициализации видеопотока со следующей жалобой:
[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.
В моем коде я добавил вызов gtk.thread_init()
прямо в начале класса GUI:
import pygtk, gtk, gobject
gtk.gdk.threads_init()
(Я также пробовал gobject.threads_init()
, но это ничем не отличается). В отдельном классе, который запускается в отдельном потоке, я запускаю поток gstreamer в tcpserversink
(этот поток gstreamer уже является третьим потоком, если кто-то ведет счет). И затем другой поток получает эти данные перед тем, как отправить данные в xvimagesink
в конце.
xvimagesink
нуждается в области просмотра, и я считаю, что эта функция обратного вызова gstreamer — это то место, где gtk иногда сходит с ума, когда я его назначаю:
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)
self.window_handle
— это указатель на self.movie_window = gtk.DrawingArea()
, назначенный во время инициализации GUI.
TL;DR Есть ли безопасный способ использования gtk с gstreamer, поскольку я не могу избежать многопоточности при вызове gst.Pipeline("name").set_state(gst.STATE_PLAYING)
, а представление будет областью рисования GTK?