我知道不应该从gtk
中的其他线程更新UI,或者面临后果,但我不确定在使用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.
在我的代码中,我在GUI类的开头添加了gtk.thread_init()
调用权:
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绘图区域?
答案 0 :(得分:2)
我认为你的问题是你从两个线程访问不受保护的Xlib / xcb - 一次是从你的Gtk + UI中隐含的,一次是在执行你的gstreamer后端回调的线程中 - 这默认是你告诉gstreamer的主循环使用(或线程默认主循环)。
gtk.gdk.threads_init()
已被调用(如果我没记错的话,如果我错了,请纠正我。)
使用g_idle_add
(或使用具有更高优先级的GSource
(线程安全)并使用回调来调度Gtk主循环中的UI更改(由gtk_main()
运行)。