Сбой многопоточного Gstreamer с PyGTK (xcb_xlib_threads_sequence_lost)

Я понимаю, что нельзя обновлять пользовательский интерфейс из других потоков в 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?


person julumme    schedule 25.03.2014    source источник
comment
Я действительно получил эту точную ошибку xcb и Aborted (основной дамп) с представлением webkit с воспроизведением видео HTML5. Как ни странно, это произошло в конце видео или рядом с ним, поэтому я предполагаю, что это может быть что-то с самим python или GTK? Я не добавляю специальную обработку html5.   -  person NoBugs    schedule 11.10.2014


Ответы (1)


Я думаю, ваша проблема заключается в том, что вы получаете доступ к незащищенным Xlib/xcb из 2 потоков - один раз неявно из вашего пользовательского интерфейса Gtk + и один раз в потоке, где выполняется ваш обратный вызов gstreamer - который по умолчанию является основным циклом, который вы сказали использовать gstreamer ( или основной цикл потока по умолчанию).


gtk.gdk.threads_init() уже вызывается после инициализации системы типов (если я правильно помню, поправьте меня, если я ошибаюсь).


Используйте g_idle_add (или используйте GSource с более высоким приоритетом) (которые являются потокобезопасными) с обратным вызовом, который планирует изменения пользовательского интерфейса в основном цикле Gtk (запускается gtk_main()).

person drahnr    schedule 25.03.2014
comment
Спасибо за ответ! Но, хм, я не совсем уверен, как правильно использовать g_idle_add в этом контексте. Могу ли я просто обернуть imagesink.set_xwindow_id( self.window_handle.window.xid) в gobject.idle_add(imagesink.set_xwindow_id, self.window_handle.window.xid) ? - person julumme; 25.03.2014
comment
Я не совсем уверен, как делается магия py-›C-›py, но я бы попробовал. - person drahnr; 25.03.2014