带有PyGTK崩溃的多线程Gstreamer(xcb_xlib_threads_sequence_lost)

时间:2014-03-25 06:31:45

标签: python multithreading gtk pygtk gstreamer

我知道不应该从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绘图区域?

1 个答案:

答案 0 :(得分:2)

我认为你的问题是你从两个线程访问不受保护的Xlib / xcb - 一次是从你的Gtk + UI中隐含的,一次是在执行你的gstreamer后端回调的线程中 - 这默认是你告诉gstreamer的主循环使用(或线程默认主循环)。


类型系统初始化后,

gtk.gdk.threads_init()已被调用(如果我没记错的话,如果我错了,请纠正我。)


使用g_idle_add(或使用具有更高优先级的GSource(线程安全)并使用回调来调度Gtk主循环中的UI更改(由gtk_main()运行)。