【问题标题】:libavcodec initialization to achieve real time playback with frame dropping when necessarylibavcodec 初始化实现实时播放,必要时丢帧
【发布时间】: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


【解决方案1】:

如果我可以在 libav 级别发生丢帧,我也会将数据包保存到帧解压缩时间

不,你不会,除非你愿意丢弃所有帧直到下一个关键帧。在典型的 mp4 视频中,这很容易是几秒钟。

您可以跳过色彩空间转换和调整大小,但这些通常由播放器处理。

【讨论】:

  • 我意识到这一点,但我不只是处理 mp4 视频;相当多的摄像机提供 mjpeg,由于这是一个技术用户应用程序,我们提供了一些指导,例如调整流的 GOP/GOV 设置以最小化关键帧之间的跨度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 2013-03-05
相关资源
最近更新 更多