LINUX.ORG.RU

gstreamer: Deadlock в gst_element_set_state

 ,


0

1

Имеется сервис на gstreamer, обрабатывающие видеопотоки из сети, и эти потоки добавляются/удаляются во время работы сервиса. Схема пайплайна: Левая часть (создаётся для каждого нового потока):

souphttpsrc ! parsebin ! rtph264pay ! rtph264depay ! capsfilter ! h264parse ! queue ! nvv4l2decoder

Правая часть (статическая, в единственном экземпляре):

nvstreammux -> nvinfer -> nvinfer -> appsink

Левая часть соединяется с правой через nvv4l2decoder src pad к заранее созданным request sink pad в nvstreammux.

Проблема в том, что иногда происходит дедлок в gst_element_set_state(left_part_bin, NULL) во время удаления левой части. Я удаляю левую часть пайплайна, когда сервис получает команду на удаление потока, либо в потоке происходит ошибка. Псевдокод удаления:

void removeSource(...) {
  deleteMutex.lock();

  gst_element_set_locked_state(left_part_bin, TRUE);
  gst_element_set_state(left_part_bin, GST_STATE_NULL); <- дедлок бывает тут

  auto src_pad = gst_element_get_static_pad(left_part_bin, "src");
  gst_pad_unlink(src_pad, stream_muxer_sink_pad); // отключает от правой части
  gst_bin_remove(pipeline, left_part_bin);

  deleteMutex.unlock();
}

Эта ф-ция removeSource вызывается из BusCallback ф-ции, когда «nvstreammux» элемент получает nv_eos событие (это специфичное событие для deepstream плагина). Почитал форумы: говорят, что нельзя это делать из streaming thread’ов, но я и так вроде бы не делаю. Ещё часть проблем у других людей была при асинхронных state changes, но они у меня синхронные.

Кто-то встречал подобное? Что делаю не так? Спасибо!

Все ошибки в gst ф-циях на самом деле чекаются и логируются. Gstreamer: 1.14.5 Плагины: Deepstream 5.0 для neural-network инференса

Ответ на: комментарий от Yukigaru

декодирование, управление/запуск cuda, кодирование, ресайз, реконфигурация всего этого добра на лету

max_lapshin ★★★★★
()
Ответ на: комментарий от max_lapshin

с gstreamer больно везде, помнится начинали на FreeScale iMX35, но после полной реализации функционала посмотрели на производительность, вздохнули и переписали через API FreeScale

imb ★★
()

Тоже ловил дедлоки с жистримером. В итоге переделал конвейер так, чтобы не приходилось ничего удалять. Использую компонент valve, чтобы отключать ненужные ветки. Он просто начинает дропать буферы. Но нужно у sink элементов правильно выставить свойство async. Не помню толи в true, толи в false. Иначе конвейер будет зависать.

Почитал форумы: говорят, что нельзя это делать из streaming thread’ов, но я и так вроде бы не делаю.

Правильно говорят. По твоему колбэк в каком потоке вызывается? Тебе в колбэке нужно кинуть весточку в другой поток и уже из него менять конвейер. Но мне это не помогло. Только valve спас отца русской демократии.

ox55ff ★★★★★
()
Ответ на: комментарий от max_lapshin

а тут без вариантов если gstreamer не даёт нужную производительно, но что странно, не знаю как сейчас, а лет 5 назад производители чипов, говорю за TexasInstruments и FreeScale, стали активно «впаривать» gstreamer

imb ★★
()
Ответ на: комментарий от imb

с ним можно быстро получить щупабельный результат. А возиться с чужими начинающими кодерами и учить их коллбечному программированию никому не хочется

max_lapshin ★★★★★
()
Ответ на: комментарий от max_lapshin

это понятно, к сожалению при этом техподдержка часто встаёт в позицию - мы предоставили gstreamer, используйте его, и всё равно приходится возиться с API, но с сожалению в более неудобном варианте - продираясь через gstreamer

imb ★★
()
Ответ на: комментарий от imb

ну да, так и живем =)

Показываем, что без их сраного гстримера выжимаем на 30% больше из их железки, а они говорят: ай молодцы, мы вам принесем новую железку, в которой оно всё не будет работать, заново ковыряйтесь.

max_lapshin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.