python – 多线程Gstreamer w / PyGTK崩溃(xcb_xlib_threads_sequence_lost)

我明白一个人不应该从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是指向GUI初始化期间分配的self.movi​​e_window = gtk.DrawingArea()的指针.

TL; DR是否有一种安全的方式使用gtk和gstreamer,因为我在调用gst.Pipeline(“name”)时无法避免线程.set_state(gst.STATE_PLAYING)和视图将是GTK绘图区域?

解决方法:

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

gtk.gdk.threads_init()在类型系统初始化后已经被调用(如果我没记错的话,如果我错了,请纠正我).

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

上一篇:使用Python管理多平台视频流的最佳方法是什么?


下一篇:python – 如何将Discoverer模块与pygi GstPbutils一起使用?