我正在使用 Ubuntu 14.04 处理来自 IP 摄像机的视频流。一切都很顺利,摄像头的参数如下(来自 FFMPEG):
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 352x192, 29.97 tbr, 90k tbn, 180k tbc
然后我换了一台新相机,其参数如下:
Stream #0:0: Video: h264 (High), yuvj420p(pc, bt709, progressive), 1280x720, 25 fps, 25 tbr, 90k tbn, 50 tbc
我的C++程序使用OpenCV3来处理流数据。默认情况下,OpenCV使用ffmpeg来解码和显示流数据,使用VideoCapture函数。
VideoCapture vc;
vc.open(input_stream);
while ((vc >> frame), !frame.empty()) {
*do work*
}
使用新的相机流时,我会遇到像这样的错误(来自ffmpeg):
[h264 @ 0x7c6980] cabac decode of qscale diff failed at 41 38
[h264 @ 0x7c6980] error while decoding MB 41 38, bytestream (3572)
[h264 @ 0x7c6980] left block unavailable for requested intra mode at 0 44
[h264 @ 0x7bc2c0] SEI type 25 truncated at 208
图像有时会出现故障,有时完全冻结。然而,在VLC上播放完美。我使用最新版本(3.2.2)的FFmpeg播放器安装了它。
./configure --enable-gpl --enable-libx264
现在直接使用ffplay进行播放(而不是通过OpenCV函数VideoCapture从源代码中启动),流媒体播放效果更好,但有时仍会显示警告:
[NULL @ 0x7f834c008c00] SEI type 25 size 896 truncated at 320=1/1
[h264 @ 0x7f834c0d5d20] SEI type 25 size 896 truncated at 319=1/1
[rtsp @ 0x7f834c0008c0] max delay reached. need to consume packet
[rtsp @ 0x7f834c0008c0] RTP: missed 1 packets
[h264 @ 0x7f834c094740] concealing 675 DC, 675 AC, 675 MV errors in P frame
更换摄像机硬件不是一个选项。 摄像机可以设置为编码为h265或mjpeg格式。 当编码为mjpeg格式时,它可以输出5帧每秒的速度,这是不够的。另外,解码为静态视频也不是一个选项,因为我需要实时显示有关流的结果。在这里有一个可以在函数VideoCapture中使用的API后端列表。也许我应该切换到其他解码器和播放器?
从我的研究中,我得出以下选项:
- 以某种方式使OpenCV使用libVlc而不是ffmpeg
切换到vlc的一个例子可以在这里找到,但我不理解它是否符合我的需求。或者也许我应该在代码中对流进行解析?
- 使用vlc预处理流,如此处所建议。
这可能会很慢,这对于实时结果来说又是不好的。
任何建议和评论都将不胜感激。
ffplay
进行测试,请使用-rtsp_transport tcp
。 - aergistal