Многонишков 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 грешка и прекъснато (ядрото е изхвърлено), с изглед на webkit с възпроизвеждане на HTML5 видео. Колкото и да е странно, това се случи в или близо до края на видеото, така че предполагам, че може да е нещо с python или самия GTK? Не добавям специална обработка на html5.   -  person NoBugs    schedule 11.10.2014


Отговори (1)


Мисля, че проблемът ви е фактът, че осъществявате достъп до незащитен Xlib/xcb от 2 нишки - веднъж неявно от вашия Gtk+ UI и веднъж в нишката, където се изпълнява обратното извикване на вашия 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