UDP Receiver должен запуститься перед отправителем udp - PullRequest
1 голос
/ 10 января 2020

Я пытаюсь отправить видео с Raspine Buster с Raspine Buster на Raspberry Buster на машину с Ubuntu 18.04. Я использую ffmpeg для кодирования в h264 с использованием аппаратного обеспечения на конце raspi, а затем отправляю данные с gst-launch-1.0 по UDP. Проблема в том, что если я запускаю поток распи, а затем запускаю приемник, приемник никогда не подключается. Если я запускаю приемник, а затем запускаю поток распи, тогда они соединяются идеально.

Команда Raspi кодирования и отправки:

ffmpeg -f video4linux2 -framerate 30 -video_size 1280x720 -i /dev/video0 -c:v h264_omx -b:v 2000k -f avi pipe:1 | gst-launch-1.0 --gst-debug=3 fdsrc ! udpsink host=192.168.1.142 port=8090

Команда приема и декодирования и отображения:

gst-launch-1.0 udpsrc port=8090 ! queue ! h264parse ! avdec_h264 ! xvimagesink sync=false

I Я посмотрел на свойства udpsink и udpsrc и попытался бездельничать с buffer-size, blocksize и sync. Я также пытался использовать ffmpeg из python, чтобы увидеть, была ли проблема на стороне получателя, с точно такой же проблемой.


import cv2

cap = cv2.VideoCapture('udp://127.0.0.1:8090',cv2.CAP_FFMPEG)
if not cap.isOpened():
    print('VideoCapture not opened')
    exit(-1)

while True:
    ret, frame = cap.read()

    if not ret:
        print('frame empty')
        break

    cv2.imshow('image', frame)

    if cv2.waitKey(1)&0XFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

В конце я мог бы просто написать небольшой протокол это переключает отправителя, если пакеты не проходят, но я надеялся, что UDP лучше обработает соединение.

Этот вопрос казался похожим: UDP: Клиент запустился до сервера , но не решил мою проблему, так как у меня нет возможности блокировки с помощью gstreamer / ffmpeg.

Ответы [ 2 ]

2 голосов
/ 10 января 2020

Вам необходимо периодически отправлять данные SPS / PPS, если вы хотите иметь произвольный доступ. Если вы этого не сделаете, эти данные будут отправлены только в самом начале. Эта информация важна для декодирования потока H.264. Попробуйте добавить h264parse перед udpsink и настроить его config-interval свойство.

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

Вы на правильном пути. Ниже (немного изменена) ваша ffmpeg команда

ffmpeg -f video4linux2 -video_size 1280x720 -i /dev/video0 -c:v h264_omx -b:v 2000k -an -f mpegts udp://192.168.1.142:8090?pkt_size=1316

, которая упаковывает видео в транспортный поток MPEG . Обратите внимание, что я добавил pkt_size=1316 в конце, чтобы заставить ffmpeg выполнять передачу UDP, отправляя пакеты одинакового размера. Это поможет приемнику догнать и не переполниться.

Чтобы принять, демультиплексировать и проанализировать MPEG TS по UDP, вы можете использовать команду GStreamer

gst-launch-1.0 udpsrc port=8090 \
! queue max-size-buffers=10000000 max-size-time=5000000000 max-size-bytes=20000000 \
! tsdemux name=demux \
demux.video_0_0100 ! queue ! h264parse ! avdec_h264 ! autovideosink

, где demux.video_0_0100 захватывает демультиплексированное видео из MPEG TS по его PID (идентификатор видео в качестве элементарного потока). На стороне получателя вы можете узнать все детали вашего входящего потока, включая PID, с помощью команды

gst-discoverer-1.0 -v -t 20 udp://0.0.0.0:8090
...