【发布时间】:2020-02-16 12:33:15
【问题描述】:
我有一个与 ffmpeg 库链接的 C++ 计算机视觉应用程序,该库提供从视频流到分析例程的帧。这个想法可以提供一个中等通用的视频流标识符,并且视频源将被解压缩并逐帧传递给分析例程(运行用户的分析功能)。“中等通用视频标识符”涵盖 3 个通用视频流类型:磁盘上视频文件的路径、IP 视频流(摄像机或视频流服务)以及具有所需格式和速率的 USB 网络摄像头引脚。
我当前的视频播放器尽可能通用:仅视频,忽略音频和其他流。它有一个 switch case,用于根据流的源和编解码器检索流的帧速率,用于估计解压缩帧之间的延迟。我在尝试从流中获取可靠的时间戳时遇到了很多问题,所以我目前忽略了 pts 和 dts。我知道忽略 pts/dts 对可变帧速率流不利。我计划稍后对它们进行特殊处理。播放器当前检查最后一个解压缩帧是否延迟超过 2 帧(假设帧速率恒定),如果是,则“丢弃帧” - 不将其传递给用户的分析例程。
本质上,视频播放器的逻辑是确定何时跳过帧(而不是将它们传递给耗时的分析例程),以便分析尽可能接近实时地提供视频帧。
我正在寻找示例或讨论如何使用(可能但不限于)AVDictionary 选项来初始化和/或维护其 AVFormatContext、AVStream 和 AVCodecContext,以便在libav 库级别,而不是我的视频播放器级别。如果实现这一点需要为每种流类型和编解码器提供单独的 AVDictionaies(或更多),那就这样吧。我有兴趣了解这两种方法的优缺点:在播放器级别或在 libav 级别丢帧。
(当某些分析需要每一帧时,禁用丢帧的现有播放器实现很好。我怀疑如果我可以在 libav 级别发生丢帧,我也会将数据包保存到帧解压缩时间,比我当前的版本减少了更多的处理。)
【问题讨论】:
-
据我所知,libav 没有此功能。您需要自己处理此案。
-
我正在尝试首先检测编解码器是否仅提供全帧,例如 USB 相机常见的 mjpeg 编解码器。如果是真的,通过使用非常小的 768K 的 rtbuffsize,我会丢帧,使得最大实时延迟低于 2 秒,通常低于 1 秒。我知道丢帧发生在我的逻辑之下,因为 av_log 回调正在获取消息,宣布每个丢帧,因为 rtbuffer 太满了。
-
在这种情况下,我认为 ffmpeg 中不会发生丢帧。它给摄像头施加网络背压,摄像头在到达网络之前丢帧。
-
USB 摄像头丢帧(由于网络背压)一定是坏事吗?
标签: ffmpeg video-streaming libav libavcodec libavformat