我正在尝试使用gstreamer传输Raspberry Pi相机。这是我的管道:
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数据包。
我在我的Pi上安装了iptraf
,可以看到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.99GiB(这使我认为与raspivid的旧的已知2GB限制有关),但是第二次它停止在发送的775MiB的数据。
答案 0 :(得分:0)
我在其他一些“嵌入式”设备上也遇到过类似的情况,因此我将分享当时获得的经验知识。
就我而言,我通过以下方法成功制作了稳定的视频流:
在udpsink
之前添加queue元素。 queue
将“在源极板上创建一个新线程以解耦接收器和源极板上的处理”,因此,从理论上讲,如果CPU具有多个内核,它将带来好处。就我而言,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
帧速率,比特率..并观察行为。