libavcodec 初始化实现实时回放,必要时丢帧

libavcodec initialization to achieve real time playback with frame dropping when necessary

我有一个与 ffmpeg 库链接的 C++ 计算机视觉应用程序,它提供从视频流到分析例程的帧。这个想法是一个可以提供一个适度通用的视频流标识符,并且该视频源将被解压缩并逐帧传递给分析例程(运行用户的分析功能)。"moderately generic video identifier" 涵盖 3 种通用视频流类型:磁盘上的视频文件路径、IP 视频流(摄像头或视频流服务)以及具有所需格式和速率的 USB 网络摄像头引脚。

我目前的视频播放器尽可能通用:仅视频,忽略音频和其他流。它有一个开关盒,用于根据流的源和编解码器检索流的帧速率,用于估计解压缩帧之间的延迟。我在尝试从流中获取可靠的时间戳时遇到了很多问题,所以我目前忽略了 pts 和 dts。我知道忽略 pts/dts 对可变帧率流不利。我计划稍后对它们进行特殊处理。播放器当前检查最后一个解压帧是否晚了 2 帧以上(假设帧速率恒定),如果是 "drops the frame" - 不会将其传递给用户的分析例程。

本质上,视频播放器的逻辑是确定何时跳过帧(而不是将它们传递给耗时的分析例程),以便尽可能接近实时地提供视频帧分析。

我正在寻找示例或讨论如何初始化 and/or 使用(大概但不限于)AVDictionary 选项维护他们的 AVFormatContext、AVStream 和 AVCodecContext,以便保持实时性所必需的帧丢弃在 libav 库级别执行,而不是在我的视频播放器级别执行。如果实现这一点需要为每个流类型和编解码器单独的 AVDictionaies(或更多),那就这样吧。我有兴趣了解这两种方法的优缺点:在播放器级别或 libav 级别丢帧。

(当某些分析需要每一帧时,禁用丢帧的现有播放器实现很好。我怀疑是否可以在 libav 级别发生丢帧,我会将数据包保存到帧解压缩时间为好吧,比我当前的版本减少了更多的处理。)

if I can get frame dropping to occur at the libav level, I'll save the packet to frame decompression time as well

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

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