我正在使用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(我使用了此提交)并看到与下面相同的行为。
我运行的命令是:
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和其他地方看到了许多与该错误消息相关的参考资料,但我尚未找到令人满意的解释或解决方法。这来自于这一行,似乎对应于流末端缺失数据。'left block unavailable' 来自 这里,也看起来像是数据缺失。
其他人建议改用
-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模式下,所有的数据包都从摄像头传输到了电脑(有序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分叉以来并没有太大的分歧。摄像头直接插入PC上的PoE端口,因此网络拥塞不可能成为问题。鉴于PC具有足够的CPU来保持编码实时流,我认为它仍然会从TCP流中删除数据是ffmpeg的问题。
在定性上,有几个因素似乎会加剧问题:
- 更高的视频分辨率 - 在运行ffmpeg的机器上增加系统负载(例如,将转码为低分辨率.avi文件会产生比转码为h264 VBR更少的错误;使用
-codec:copy
可以消除所有错误,除了ffmpeg启动时的几个错误)
- 摄像机视野内的运动更大这个错误是什么意思?我该怎么办?