opencv - 解码 MB 时出现 ffmpeg RTSP 错误

标签 opencv video ffmpeg h.264

我正在使用 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( 123 ),在我的例子中,它只是给出了稍微不同的错误组合,并且仍然是视频损坏:

[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/

相关文章:

video - 有没有办法从在线视频中提取每第 n 帧而不下载整个视频?

cordova - 仅使用音频编码 mp4 视频

java - FrameGrabber 空指针异常

video - 使用 ffmpeg 将 avi 视频剪切为另一个 avi 而不会损失质量

python-3.x - 提取动画人物的头像时,我遇到了UnboundLocalError

javascript - 您认为视频内容可以用 JavaScript 编码吗?

python - TensorFlow - tf.data.Dataset 读取大型 HDF5 文件

audio - 添加音频过滤器时保持原始格式,从原始文件中自动检测格式

android - 运行用于人脸检测的 OpenCV 示例时,将网络摄像头与 Android 模拟器结合使用

python - 用均值减去当前像素时如何处理负值