我正在使用 ffmpeg 从 Cisco 3050 IP 摄像机读取 h264 RTSP 流并将其重新编码为 h264 到磁盘(这也是我不使用 -codec:copy
的原因)。
ffmpeg版本如下:
ffmpeg version 3.2.6 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 6.3.0 (Alpine 6.3.0)
我也尝试过使用 ffmpeg 2.8.14-0ubuntu0.16.04.1 和从源代码构建的最新 ffmpeg(我使用 this commit)并看到与下面相同的行为。
我正在运行的命令是:
ffmpeg -rtsp_transport udp -i 'rtsp://<user>:<pw>@<ip>:554/StreamingSetting?version=1.0&action=getRTSPStream&ChannelID=1&ChannelName=Channel1' -r 10 -c:v h264 -crf 23 -x264-params keyint=60:min-keyint=60 -an -f ssegment -segment_time 60 -strftime 1 /output/%Y%m%d_%H%M%S.ts -abort_on empty_output
我以每秒至少一个的相当稳定的速度收到各种错误。这是一个示例:
[rtsp @ 0x7f268c5e9220] max delay reached. need to consume packet
[rtsp @ 0x7f268c5e9220] RTP: missed 40 packets
[h264 @ 0x55b1e115d400] left block unavailable for requested intra mode
[h264 @ 0x55b1e115d400] error while decoding MB 0 12, bytestream 114567
[h264 @ 0x55b1e115d400] concealing 3889 DC, 3889 AC, 3889 MV errors in I frame
最常见的是“解码 MB x x,字节流 x 时出错”。这对应于播放时视频文件中的严重损坏。
我在 stackoverflow 和其他地方看到很多关于该错误消息的引用,但我还没有找到令人满意的解释或解决方法。它来自 this line,它似乎对应于流末尾的缺失数据。 'left block unavailable' 来自 here,看起来也像是缺失数据。
其他人建议改用 -rtsp_transport tcp
( 1 、 2 、 3 ),在我的例子中,它只是给出了稍微不同的错误组合,并且仍然是视频损坏:
[h264 @ 0x557923191b00] left block unavailable for requested intra4x4 mode -1
[h264 @ 0x557923191b00] error while decoding MB 0 28, bytestream 31068
[h264 @ 0x557923191b00] concealing 2609 DC, 2609 AC, 2609 MV errors in I frame
[rtsp @ 0x7f88e817b220] CSeq 5 expected, 0 received.
使用 Wireshark,我确认在 UDP 和 TCP 模式下,所有数据包都从相机发送到 PC(连续的 RTP 序列号,没有任何丢失),这让我觉得数据在到达后丢失了ffmpeg.
在对 Panasonic WV-SFV110 相机运行相同的命令时,我也看到了类似的行为,但总体上错误频率较低。在 Panasonic 相机上从 UDP 切换到 TCP 会减少但不会完全消除错误/损坏。
我还用 VLC 尝试了一个类似的命令并得到了类似的错误 (cvlc rtsp://<user>:<pw>@<ip>/MediaInput/h264 :sout='#transcode{vcodec=h264}:std{access=file, mux=ts, dst="output.ts"}
)——大概自从 libav 从 ffmpeg fork 以来代码没有太大差异。
摄像头直接插入 PC 上的 PoE 端口,因此网络拥塞不会成为问题。鉴于 PC 有足够的 CPU 来保持对实时流的编码,在我看来,ffmpeg 的一个问题是它仍然从 TCP 流中丢弃数据。
定性地,有几个因素似乎使问题变得更糟:
- 更高的视频分辨率
- 运行 ffmpeg 的机器上的系统负载更高(例如,与转码为 h264 VBR 相比,转码为低分辨率 .avi 文件产生的错误更少;使用
-codec:copy
消除了除 ffmpeg 启动时的几个错误之外的所有错误) - 在相机 View 中有更大的运动
错误是什么意思?我能做些什么呢?
最佳答案
查看初始错误消息:
[rtsp @ 0x7f268c5e9220] max delay reached. need to consume packet
[rtsp @ 0x7f268c5e9220] RTP: missed 40 packets
我猜你正在丢失 UDP 数据包。其余的 H.264 错误消息是由接收到不完整的比特流引起的。 现在关键是隔离问题。您的网络是否丢包?或者您的服务器接收 UDP (RTP) 时速度太慢或过载。
首先,我会检查您操作系统的 UDP 缓冲区大小。 https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/Administration_And_Configuration_Guide/jgroups-perf-udpbuffer.html
如果增加 UDP 缓冲区大小没有帮助 - 使用带有 -codec:copy
的 ffmpeg 来降低 CPU 负载。你仍然有错误吗?
由于您想重新编码,请考虑使用 Intel Quicksync -vcodec h264_qsv
或其他一些降低 CPU 负载的硬件编码器。
问题不在于 PC 是否有 足够的 CPU。但更多关于识别处理管道中的瓶颈。您的 H.264 编码器 (x264) 可能会过度订阅您的 CPU,从而导致您获得导致数据包丢失的瞬时峰值负载。尝试限制 x264 的线程数和/或将质量降低到“快”或“更快”。
关于opencv - 解码 MB 时出现 ffmpeg RTSP 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50063707/