Имеется сервис на 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 инференса