解码MB时ffmpeg RTSP错误 [英] ffmpeg RTSP error while decoding MB

查看:2257
本文介绍了解码MB时ffmpeg RTSP错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ffmpeg从Cisco 3050 IP摄像机读取h264 RTSP流,并将其重新编码为h264到磁盘(这是我不仅仅使用-codec:copy的原因).

I'm using ffmpeg to read an h264 RTSP stream from a Cisco 3050 IP camera and reencode it to disk as h264 (there are reasons why I'm not just using -codec:copy).

ffmpeg版本如下:

The ffmpeg version is as follows:

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(我使用了提交),然后看到与以下相同的行为.

I've also tried with ffmpeg 2.8.14-0ubuntu0.16.04.1 and the latest ffmpeg built from source (I used this commit) and see the same behaviour as below.

我正在运行的命令是:

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

我以每秒至少一个的相当稳定的速度收到各种错误.这是一个示例:

I get a variety of errors at a fairly steady rate of at least one per second. Here's a sample:

[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时出错".这对应于播放时视频文件中的严重损坏.

The most common one is 'error while decoding MB x x, bytestream x'. This corresponds to severe corruption in the video file when played back.

我在stackoverflow和其他地方看到了很多对该错误消息的引用,但是我还没有找到令人满意的解释或解决方法.它来自此行,它似乎与在流的末尾丢失数据. 左块不可用"来自此处看起来也好像缺少数据.

I see many references to that error message on stackoverflow and elsewhere, but I've yet to find a satisfying explanation or workaround. It comes from this line which appears to correspond to missing data at the end of the stream. 'left block unavailable' comes from here and also looks like missing data.

其他人建议改用-rtsp_transport tcp(( 1 3 ),在我的情况下,它给出的错误混合稍有不同,并且仍然是视频损坏:

Others have suggested using -rtsp_transport tcp instead (1, 2, 3) which in my case just gives a slightly different mix of errors, and still video corruption:

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

Using Wireshark I confirmed that in both UDP and TCP mode, all of the packets are making it from the camera to the PC (sequential RTP sequence numbers without any missing) which makes me think the data is being lost after it arrives at ffmpeg.

在Panasonic WV-SFV110相机上运行相同命令时,我也看到类似的行为,但总的来说出错频率较低.在Panasonic摄像机上从UDP切换到TCP可以减少但不能完全消除错误/损坏.

I also see similar behaviour when running the same command against a Panasonic WV-SFV110 camera, but with less frequent errors overall. Switching from UDP to TCP on the Panasonic camera reduces but does not completely eliminate the errors/corruption.

我还在VLC上尝试了类似的命令,并得到了类似的错误(cvlc rtsp://<user>:<pw>@<ip>/MediaInput/h264 :sout='#transcode{vcodec=h264}:std{access=file, mux=ts, dst="output.ts"})-大概自libav从ffmpeg派生以来,代码并没有太大差异.

I also tried a similar command with VLC and got similar errors (cvlc rtsp://<user>:<pw>@<ip>/MediaInput/h264 :sout='#transcode{vcodec=h264}:std{access=file, mux=ts, dst="output.ts"}) -- presumably the code hasn't diverged much since libav forked from ffmpeg.

摄像机直接插入PC上的PoE端口,因此网络拥塞不会成为问题.鉴于PC有足够的CPU来保持对实时流进行编码,在我看来ffmpeg仍然存在问题,它仍然会从TCP流中删除数据.

The camera is plugged directly into a PoE port on the PC so network congestion can't be a problem. Given that the PC has enough CPU to keep up encoding the live stream, it seems to me a problem with ffmpeg that it still drops data from the TCP stream.

从质量上讲,似乎有几个因素使问题变得更糟:

Qualitatively, there are several factors which seem to make the problem worse:

  • 更高的视频分辨率
  • 运行ffmpeg的计算机上较高的系统负载(例如,转码为低分辨率.avi文件比转码为h264 VBR产生的错误更少;使用-codec:copy可以消除所有错误,但在ffmpeg启动时会产生一些错误)
  • 相机视图中的动作更加动感
  • Higher video resolution
  • Higher system load on the machine running ffmpeg (e.g. transcoding to a low res .avi file produces fewer errors than transcoding to h264 VBR; using -codec:copy eliminates all errors except a couple while ffmpeg is starting up)
  • Greater motion within the camera view

错误是什么意思?那我该怎么办?

What the does the error mean? And what can I do about it?

推荐答案

听起来确实丢包是一个问题.更高的视频分辨率和更大的运动都增加了编码视频流的比特率,这将增加您的数据包丢失.根据丢失的数据包,您将在解码过程中看到各种错误,如您在帖子中所指出的.

It does sound like packet loss is an issue. Higher video resolution and greater motion both increase the bitrate of the encoded video stream which will increase your packet loss. Depending on which packet is lost, you will see varying errors in the decoding process as you indicated in your post.

运行ffmpeg的较高的系统负载还表明您的网卡可能会在以下情况下丢弃数据包: ffmpeg在忙于对视频进行转码时需要花费很长时间才能阅读它们.

The higher system load running ffmpeg also indicates that your network card might be dropping packets, when e.g. ffmpeg takes too long to read them while it is busy transcoding the video.

第一个问题是您的网络拓扑是什么?通过公共Internet进行流传输比通过LAN进行流传输要困难得多.网络中使用哪种交换机/路由器?

First question is what is your network topology? Streaming over the public Internet is a lot harder than streaming over your LAN. What kind of switches/routers are in the network?

下一个问题,您的相机以什么样的比特率传输?尝试减少它并检查结果.保持系统性,即

Next question, what bitrate is your camera streaming at? Try reducing this and check the results. Be systematic in your approach i.e.

  • 一开始不要转码.
  • 只接收视频.
  • 将其写入文件.
  • 检查数据包丢失/视频失真.
  • 以较低的比特率开始,例如100kbps并在没有明显损失的情况下增加它

我接下来要做的是增加接收器缓冲区的大小.虽然我对ffmpeg不太熟悉,但是您似乎可以通过recv_buffer_size进行设置,如此处.然后,您需要根据相机配置算出足够大的尺寸来存储例如几(5?)秒的视频数据.随着接收器缓冲区大小的增加,请检查是否有更少的伪像或更长的时间没有伪像.

The next thing I would try to do is to increase the size of the receiver buffers. While I am not that familiar with ffmpeg, it looks like you can set it via recv_buffer_size as indicated here. You then need to work out a reasonably big enough size based on your camera configuration to store e.g. a couple (5?) of seconds of video data. Check if there are less artifacts as you increase the receiver buffer size or longer periods without artifacts.

当然,如果处理器太慢而无法实时对视频进行转码,则迟早会耗尽空间,在这种情况下,您可能必须将代码转码为较低的分辨率/比特率或使用强度较低的编码器设置等,或在速度更快的计算机上运行转码.

Of course if your processor is too slow to transcode the video in real-time, you will run out of space sooner or later, in which case, you might have to transcode to a lower resolution/bitrate or use less intensive encoder settings, etc or run the transcoding on a faster machine.

此外,请注意,调整接收器缓冲区大小不会补偿在公共Internet上发生的数据包丢失,因此,如果您在支持摄像机比特率的本地网络上进行流传输,则上述内容将有所帮助.如果超出网络带宽,则可能会出现丢包现象.在那种情况下,通过TCP进行流传输可能会有所帮助(至少直到接收器缓冲区最终溢出).

Also, note that adjusting receiver buffer size will not compensate for packet loss occurring on the public Internet so the above will help assuming you're streaming on a local network that supports the bitrate of the camera. If you exceed the bandwidth of the network you can expect packet loss. In that case streaming over TCP could help somewhat (at least until the receiver buffer overruns eventually).

如果以上方法不能解决问题或完全解决问题,您可以尝试其他操作:

More things you can try if the above does not help or solve the problem completely:

  • 使用wireshark或tcpdump嗅探传入的流量. 看一下痕迹.使用"RTSP"过滤跟踪. 您应该能够看到连续的RTP数据包的序列号不断增加的RTP流量,例如20、21、22、23等.如果您看到缺少序列号,则说明数据包丢失,请尝试通过TCP流式传输.通过TCP流式传输时重复跟踪.另外,请记住在通过TCP流式传输时也要增加接收器缓冲区的大小.
  • Sniff the incoming traffic with wireshark or tcpdump. Have a look at the traces. Filter the trace using "RTSP". You should be able to see the RTP traffic where consecutive RTP packets have increasing sequence numbers e.g. 20, 21, 22, 23, etc. If you see missing sequence numbers, then you've got packet loss and try streaming over TCP. Repeat the trace while streaming over TCP. Also, remember to increase the receiver buffer size also when streaming over TCP.

总而言之,您具有管道架构,您需要确定在管道中的何处发生损失:

In summary you have a pipeline architecture and you need to determine where in the pipeline the loss is occurring:

camera -> network -> receiver buffer (OS) -> application (ffmpeg)

camera -> network -> receiver buffer (OS) -> application (ffmpeg)

这篇关于解码MB时ffmpeg RTSP错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆