udpsink от gstreamer прекращает потоковую передачу после отправки ~ 1000 пакетов - PullRequest
5 голосов
/ 16 января 2020

Я пытаюсь транслировать свою камеру Raspberry Pi с помощью gstreamer. Это мой конвейер:

raspivid --nopreview -ih -hf -vf --width 800 --height 600 --framerate 20 --bitrate 2000000 --profile main --timeout 0 -g 4 -o - | gst-launch-1.0 -vvv fdsrc do-timestamp=true \
 ! h264parse ! omxh264dec ! clockoverlay time-format="%A | %d %B %Y | %H:%M:%S" ! omxh264enc target-bitrate=2000000 control-rate=1 ! h264parse ! rtph264pay config-interval=1 pt=96 ! udpsink host=targethost port=8004 sync=false

И это работает ... ну почти. Я могу получить поток на моем целевом хосте в течение секунды или около того, затем он останавливается. Gstreamer не выводит никаких ошибок, не завершает работу, просто прекращает отправку пакетов UDP.

Я установил iptraf на свой Pi и вижу, что отправка пакетов UDP прекращается примерно после ~ 1000 пакетов. Он может останавливаться на ~ 800 пакетах или ~ 1500 пакетах, это примерно эти цифры.

Теперь интересно то, что ИНОГДА он работает дольше, например, на несколько часов. Но иногда это просто останавливается почти мгновенно. Я наблюдаю это уже около двух дней, и, возможно, он лучше работает ночью, может быть потому, что поток становится черным, поэтому при лучшем сжатии у него меньше пакетов для отправки? Я не знаю. Что может остановить отправку пакета без такой ошибки? Кто-нибудь знает, что здесь происходит?

Добавлено # 1: Кроме того, в случае проблем с инфраструктурой, Pi подключается к локальной сети через интерфейс Wi-Fi, и он на самом деле подключен к расширителю Wi-Fi. Так что это не очень чистая настройка, но, кажется, она работает ночью, по крайней мере, судя по последним двум дням, но даже если бы было какое-то узкое место в пропускной способности, могло ли это остановить поток UDP таким образом? Это не имеет смысла для меня.

Добавлено # 2:

$ gst-launch-1.0 --version
gst-launch-1.0 version 1.14.4
GStreamer 1.14.4

Добавлено # 3:

Я запускаю это с GST_DEBUG=3. когда он останавливается, он не показывает ничего нового, перестают появляться только новые сообщения.

Вот полный вывод до тех пор, пока поток не прекратится без каких-либо дальнейших сообщений: https://pastebin.com/raw/kTfbCW37 (эти предупреждения случаются даже если поток работает без проблем в течение длительного времени в некоторых конфигурациях, описанных ниже).

Я также обнаружил, что пропускная способность не является проблемой. Я измерил его с iperf, и поток использует не более 1/10 доступной полосы пропускания.

Я также обнаружил, что если я увеличу разрешение до --width 1920 --height 1080, то поток, похоже, будет работать дольше ... (остановился ночью). Так что происходит что-то очень странное. Любые идеи, что это может быть или что еще я могу сделать, чтобы выяснить, что происходит?

Добавлено # 4: Я установил pv и поместил его между raspivid и gstreamer. Оказывается, что это может не быть проблемой с gstreamer в конце концов, потому что похоже, что поток из raspivid просто останавливается в одной точке. Однажды он остановился на 1,99 ГБ отправленных данных (это заставило меня подумать, что это связано со старым, известным пределом raspivid в 2 ГБ), но во второй раз он остановился на 775 МБ отправленных данных.

1 Ответ

0 голосов
/ 16 января 2020

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

В моем случае мне удалось создать стабильный поток с использованием следующего подхода:

  • добавить очередь элемент перед udpsink. queue "создаст новый поток на исходной панели, чтобы отделить обработку на приемнике и исходной панели", поэтому, теоретически, это должно принести выгоду, если ЦП имеет несколько ядер. В моем случае queue «буферизация» была выше, чем по умолчанию:

    ... ! queue max-size-time=5000000000 max-size-buffers=10000000 max-size-bytes=50000000 ! udpsink ...
    
  • увеличение buffer-size свойство элемента udpsink. Например,

    ... ! updsink buffer-size=50000000 ...
    

должно позволять ядру буферизовать больше пакетов, когда udpsink не может обрабатывать пакеты достаточно быстро.

В моем случае вышеупомянутые настройки стабилизировали поток и устранение узких мест инфраструктуры.

И, как подсказывает @vermeate, дополнительная отладка всегда полезна: установите для уровня GST_DEBUG более высокое значение, попробуйте уменьшить raspivid частоту кадров, битрейт ... и наблюдать за поведением.

...