从Raspberry Cam传输H.264的现代方法


16

我得到了Pi B +和Pi摄像机,现在正试图找到最高效的(低CPU)和最低的延迟配置,以将H.264编码的视频从摄像机传输到我的家庭服务器。

我已阅读以下内容:

  1. http://pi.gbaman.info/?p=150

  2. http://blog.tkjelectronics.dk/2013/06/how-to-stream-video-and-audio-from-a-raspberry-pi-with-no-latency/comment-page-1/#comments

  3. http://www.raspberrypi.org/forums/viewtopic.php?p=464522

(所有链接都使用的gstreamer-1.0 deb http://vontaene.de/raspbian-updates/ . main。)

过去几年在这方面已经做了很多工作。

最初,我们必须将输出连接raspividgst-launch-1.0(请参阅链接1)。

然后(链接2)创建了官方的V4L2驱动程序,该驱动程序现在是标准驱动程序,它允许仅使用gstreamer而不用管道直接获取数据(特别是towolf发表的帖子»Sat Dec 07,2013 3:34 pm in link 2):

发件人(Pi): gst-launch-1.0 -e v4l2src do-timestamp=true ! video/x-h264,width=640,height=480,framerate=30/1 ! h264parse ! rtph264pay config-interval=1 ! gdppay ! udpsink host=192.168.178.20 port=5000

接收方: gst-launch-1.0 -v udpsrc port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! fpsdisplaysink sync=false text-overlay=false

如果我理解正确,那么两种方法都可以使用GPU进行H264解码,但是后者效率更高,因为它不需要再次经历内核,因为进程之间没有管道。


现在我对此有一些疑问。

  1. 后者仍然是从相机有效获取H264的最新方法吗?我读过有关的信息gst-omx,它允许使用gstreamer管道... video/x-raw ! omxh264enc ! ...。这是否与仅使用有所不同video/x-h264,或者可能更有效?有什么不同?

  2. 使用video/x-h264 ...管道时,如何找出实际使用的gstreamer编码插件?与其他管道部分(我明确命名(代码)组件(例如h264parsefpsdisplaysink))相比,这似乎只是在指定我想要的格式。

  3. 对链接1的回复中, MikaelLepistö提到“我从流式传输的一侧删除了一个不必要的过滤器通道”,这意味着他剪切了gdppaygdpdepay。这些是做什么的?为什么需要它们?我真的可以剥离它们吗?

  4. 他还提到,通过在接收端指定caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96"参数udpsrc,他就可以在流的中间开始/恢复流。这些上限实现了什么,为什么要选择这些特定的选项,在哪里可以阅读更多有关它们的信息?

  5. 当我按照问题3和4的建议进行操作时(添加caps,删除gdppaygdpdepay),我的视频延迟变得更糟(并且似乎在累积,延迟随着时间的流逝而增加,并且几分钟后视频停止)!为什么会这样呢?我希望获得使用原始命令获得的延迟,但是还具有可以随时加入流的功能。

  6. 我已经读过RTSP + RTP通常将TCP和UDP结合使用:TCP用于控制消息和其他必不可少的内容,而UDP用于实际的视频数据传输。在上面的设置中,我实际上是在使用它,还是仅在使用UDP?对于gstreamer照顾与否,这对我来说有点不透明。

对于这些问题中的任何一个,我都将不胜感激!


|在这种情况下,使用管道会产生任何问题的想法是BS不可思议的一环。您是否尝试过任何raspivid | cvlc方法?我没有很长时间或没有相机来使用它,但是用它来产生一个http流(可在另一端在linux上查看w / vlc)似乎还可以。
goldilocks

@goldilocks我并不是说管道是一个“问题”,只是它不是必需的,并且有一些开销,就像cat file | grep ...代替一样grep ... file。管道在内核之间增加了另一层复制,这很容易测量,尤其是在内存带宽较低的设备上。如果gstreamer可以直接读取设备文件,为什么不使用它呢?关于您的raspivid | cvlc建议:在切换到基于gstreamer的解决方案之前,我一直在使用它,它的延迟比gstreamer多3秒钟(我不知道为什么)。
nh2 2015年

是的,肯定有一些延迟。WRT管道,我对“上下文”的观点是,这里不可能成为瓶颈-网络I / O将变慢几个数量级,以此类推。您是对的,不过,这可能会给CPU增加一点点时间。我只是不敢下注。我认为,以全分辨率运行该程序会cvlc消耗〜45%的内存,但是仅以该数据速率运行一个管道(再次注意,管道并不会降低速度)就几乎不会动针。如<5%。当然,如果您想尽可能高效地执行此操作并不完全无关紧要……
goldilocks

...我只是不想让其他人读到这篇文章,以给人留下的印象是,在此处使用管道可能会导致延迟问题或其他问题。那是一条红鲱鱼。否则我可能错了;)
goldilocks

如果您追求的是效率,则可能需要包括在特定分辨率/帧频下各种方法观察到的总CPU使用率。我尝试过的唯一方法是raspivid | cvlc40-50%。人们可能会更好地回答一个挑战,要求他们改善特定的数字。现在,您在问很多原因,而没有解释每个为什么很重要的原因。
goldilocks

Answers:


8

选项:

  1. raspivid -t 0 -o - | nc -k -l 1234

  2. raspivid -t 0 -o - | cvlc stream:///dev/stdin --sout "#rtp{sdp=rtsp://:1234/}" :demux=h264

  3. cvlc v4l2:///dev/video0 --v4l2-chroma h264 --sout '#rtp{sdp=rtsp://:8554/}'

  4. raspivid -t 0 -o - | gst-launch-1.0 fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=SERVER_IP port=1234

  5. gst-launch-1.0 -e v4l2src do-timestamp=true ! video/x-h264,width=640,height=480,framerate=30/1 ! h264parse ! rtph264pay config-interval=1 ! gdppay ! udpsink host=SERVER_IP port=1234

  6. uv4l --driver raspicam

  7. picam --alsadev hw:1,0

要考虑的事情

  • 延迟[ms](有无要求客户端要求比服务器更高的fps)
  • CPU空闲[%](以计top -d 10
  • CPU 1客户端[%]
  • 内存[MB](RES)
  • 相同的编码设置
  • 相同的功能
    • 音讯
    • 重新连接
    • 与操作系统无关的客户端(vlc,webrtc等)

比较:

            1    2    3    4    5    6    7
latency     2000 5000 ?    ?    ?    ?    1300
CPU         ?    1.4  ?    ?    ?    ?    ?
CPU 1       ?    1.8  ?    ?    ?    ?    ?
RAM         ?    14   ?    ?    ?    ?    ?
encoding    ?    ?    ?    ?    ?    ?    ?
audio       n    ?    ?    ?    ?    y    ?
reconnect   y    y    ?    ?    ?    y    ?
any OS      n    y    ?    ?    ?    y    ?
latency fps ?    ?    ?    ?    ?    ?    ?

1
为什么该表中的所有值都是“ ?”?
larsk's

@larsks,因为没有人愿意测试并填写此“社区Wiki”上的数据
user1133275

6

将H264流传输到浏览器的唯一现代方法是使用UV4L:无延迟,无配置,可选音频,可选双向音频/视频。没有神奇的GStreamer调味料,但是可以扩展其用途。


由于我想流式传输到服务器和可能的智能手机,因此不需要流式传输到浏览器。而且,浏览器可能对此施加了额外的限制(例如,没有RTSP,除非您使用WebRTC,否则可能没有TCP,但这很奇怪)。但是UV4L看起来仍然很有希望。您能链接到一个我可以阅读如何使用它/从其中获取数据以进行网络流传输的地方吗?
nh2

天哪,我想我找到了示例页面 ...这一点似乎是能够做的一切!RTMP,RTSP,HTTPS流,WebRTC,“实时对象检测和对象跟踪+人脸检测” -到底是什么?每个都有一些简单的命令行标志uv4l?我的gstreamer管道现在看起来已经过时了!等不及要测试延迟时间了!
nh2

1
哦,不,它是封闭源:(这使它不符合我想起的家庭监视用途:(
nh2

它确实支持WebRTC,2向WebRTC。音频/视频的延迟约为200ms,音频的
可能性

@ nh2,链接似乎已断开,您对该示例页面有任何更新的位置吗?
Punit Soni

1

1.)h264es通过网络流式传输(仅示例)

在服务器上:

raspivid -v -a 524 -a 4 -a "rpi-0 %Y-%m-%d %X" -fps 15 -n -md 2 -ih -t 0 -l -o tcp://0.0.0.0:5001

在客户端上:

mplayer -nostop-xscreensaver -nolirc -fps 15 -vo xv -vf rotate=2,screenshot -xy 1200 -demuxer h264es ffmpeg://tcp://<rpi-ip-address>:5001

2.)通过网络流式传输mjpeg(仅示例)

在服务器上:

/usr/local/bin/mjpg_streamer -o output_http.so -w ./www -i input_raspicam.so -x 1920 -y 1440 -fps 3

在客户端上:

mplayer -nostop-xscreensaver -nolirc -fps 15 -vo xv -vf rotate=2,screenshot -xy 1200 -demuxer lavf http://<rpi-ip-address>:8080/?action=stream

所有这些甚至都可以在RPi Zero W(配置为服务器)上使用


嘿,谢谢你的回答,这sample only是什么意思?
nh2

我想说的只是“一个例子”。您可以根据自己的需要进行调整。
sparkie
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.