Я пытаюсь использовать gst-launch-1.0 для отправки видеоданных RAW из файла .avi через UDP с одного компьютера в моей сети на другой, чтобы наконец сохранить их как файл .y4m. Конвейер на исходном компьютере не возвращает ошибок, но конвейер на компьютере-приемнике возвращает.
Вот конвейер, который я использовал для исходного компьютера:
gst-launch-1.0 -v -e filesrc location=input.avi ! h264parse ! avdec_h264 ! rtpvrawpay ! \
udpsink host=192.168.1.167 port=7001
Для компьютера-приемника (192.168.1.167) я использовал:
gst-launch-1.0 -v -e udpsrc uri=udp://0.0.0.0 port=7001 ! \
"application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)RAW,\
sampling=(string)YCbCr-4:2:0,depth=(string)8,width=(string)1280,height=(string)720,\
colorimetry=(string)SMPTE240M,payload=(int)96,ssrc=(uint)878094790,\
timestamp-offset=(uint)1636480077,seqnum-offset=(uint)25415,a-framerate=(string)60,\
timestamp=(uint)1636480077,seqnum=(uint)25515" ! \
rtpvrawdepay ! videoconvert ! video/x-raw,framerate=60/1,format=I420 ! filesink location=output.y4m
Этот конвейер возвращает ошибку:
ERROR: from element /GstPipeline:pipeline0/GstUDPSrc:udpsrc0: Internal data stream error.
Additional debug info:
../gstreamer/subprojects/gstreamer/libs/gst/base/gstbasesrc.c(3132): gst_base_src_loop (): /GstPipeline:pipeline0/GstUDPSrc:udpsrc0:
streaming stopped, reason not-negotiated (-4)
У меня есть шапки для application/x-rtp из подробного вывода gst-launch-1.0 на исходном компьютере. Я пробовал заглавные буквы с параметрами {ssrc, timestamp-offset, seqnum-offset, timestamp, seqnum} и без них, так как замечал, что они меняются при каждом запуске, но это все равно не помогло.
Более того, аналогичная конвейерная система для отправки видео H.264 через UDP работает отлично; В качестве примера я оставляю исходный и принимающий конвейеры ниже:
gst-launch-1.0 -v -e filesrc location=input.avi ! decodebin ! videoconvert ! \
x264enc key-int-max=30 ! h264parse config-interval=-1 ! rtph264pay ! \
udpsink host=192.168.1.167 port=7001
gst-launch-1.0 udpsrc uri=udp://0.0.0.0 port=7001 ! \
application/x-rtp,media=video,clock-rate=90000,encoding-name=H264,payload=96 ! \
rtph264depay ! avdec_h264 ! queue ! autovideosink sync=false
Эта комбинация отображает видео на экране без каких-либо проблем.
В чем здесь проблема?





Сначала убедитесь, что ваш источник input.avi содержит видео H264 (decodebin будет управлять другими кодеками, а ваш конвейер — нет).
gst-discoverer-1.0 input.avi
Вы можете попробовать добавить avidemux между filesrc и h264parse.
Если это не помогает, возможной причиной может быть то, что видео в формате RAW может создавать пакеты гораздо большего размера, чем видео, сжатое H264.
Вы можете попробовать увеличить максимальный размер буфера сокета ядра (для этого вам потребуются права root на отправителе и получателе):
# Increase max kernel socket buffer size to 1M or more on receiver side with:
sudo sysctl -w net.core.rmem_max=1000000
# Then use property buffer-size of udpsrc such as:
gst-launch-1.0 -v udpsrc uri=udp://0.0.0.0 port=7001 buffer-size=1000000 ! 'application/x-rtp,media=video,clock-rate=90000,encoding-name=RAW,sampling=YCbCr-4:2:0, depth=(string)8, width=(string)1280, height=(string)720,colorimetry=(string)SMPTE240M,payload=(int)96,a-framerate=(string)60' ! rtpvrawdepay ! videorate ! y4menc ! queue ! filesink location=output.y4m -e
# Increase max kernel socket buffer size to 1M or more on sender side with:
sudo sysctl -w net.core.wmem_max=1000000
# and use buffer-size property of udpsink as well:
gst-launch-1.0 filesrc location=input.avi ! avidemux ! h264parse ! avdec_h264 ! rtpvrawpay ! 'application/x-rtp, media=(string)video, encoding-name=(string)RAW' ! udpsink host=192.168.1.167 port=7001 buffer-size=1000000
Да, поначалу в моем случае мне это было не нужно, но после некоторых (неотслеживаемых) испытаний я увидел, что частота кадров установлена на 0/1, поэтому я добавил частоту видео, и все получилось. Рад видеть, что это помогло, хотя вы можете исследовать и поделиться дальше.
немного поигрался и понял, что проблема была в элементе
videoconvertв конвейере приемника, поскольку он, вероятно, также пытался преобразовать частоту кадров (исходное видео — 200 кадров в секунду, а мне нужно было 60 кадров в секунду); оказывается, мне следует использоватьvideorateinstread. Я попробовал ваше решение, и оно работает, хотя мне вообще не пришлось менять размер мультиплексирования или буфера - хотя спасибо!