繁体   English   中英

在Ubuntu上使用OpenCV的ffmpeg解码h264(High)流

[英]Decoding a h264 (High) stream with OpenCV's ffmpeg on Ubuntu

我正在使用来自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上,它的播放效果非常好 我安装了ffmpeg播放器的最新版本(3.2.2)

./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 fps,这还不够。 解码为静态视频也不是一种选择,因为我需要显示有关流的实时结果。 是可以在功能VideoCapture中使用的API后端的列表。 也许我应该切换到其他解码器和播放器? 根据我的研究,我得出以下结论:

  • 以某种方式使OpenCV使用libVlc而不是ffmpeg

这里是切换到vlc的一个示例,但是我对它的理解还不够,无法说出我是否需要它。 还是我应该在代码中解析流?

  • 使用VLC来预处理流,如建议在这里

这可能很慢,这又不利于实时结果。
任何建议和评论将不胜感激。

由于默认情况下使用RTP,因此错误是由数据包丢失引起的。 您现在看到了更多错误,因为您已切换到更高的比特率输入。

?tcp附加到您的输入,例如。 rtsp://*private*/media/video2?tcp在OpenCV的open功能中可以强制TCP, rtsp://*private*/media/video2?tcp是您的硬件和/或使用情况支持该功能。

我已经基本解决了这个问题。

  • 首先,我使用必要的设置将ffmpeg的最新版本手动安装在设备上,重新编译了OpenCV。
  • 我使用VLC 工具 > 编解码器信息检查了流,以检查流是否有损坏的帧,没有。
  • 我降低了流分辨率。 这带来了最大的改进。
  • 我仍然留下的最后一个错误是

    [NULL @ 0x7f834c008c00] SEI类型25大小896被截断为320 = 1/1
    [h264 @ 0x7f834c0d5d20] SEI类型25大小896被截断为319 = 1/1

但它不会明显损坏框架。 但是,我尚未解决流冻结问题,但这与我的代码有关,而不与软件有关。 如果我可以帮助任何有类似问题的人,请随时询问其他信息。

经过4天的研究最终我遇到了同样的问题,我通过以下代码轻松解决了这个问题:

for(;;) {
        if(!vcap.read(image)) {
            std::cout << "No frame" << std::endl;
            cv::waitKey();
        }
        cv::imshow("Output Window", image);
        if(cv::waitKey(1) >= 0) break;
    }   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM