我正在尝试优化一个播放视频的软件,它在内部使用 FFmpeg 库进行解码。我们发现,在一些大型(4K、60fps)视频中,解码一帧的时间有时比显示该帧的时间要长;可悲的是,由于问题域,简单地缓冲/跳过帧不是一种选择。
但是,似乎 FFmpeg 可执行文件能够以大约 2 倍的速度很好地解码有问题的视频,所以我一直在努力找出我们做错了什么。
我为测试编写了一个非常精简的解码器程序;源代码在这里(大约 200 行)。从分析来看,解码过程中的一个主要瓶颈似乎是avcodec_send_packet()
函数,每次调用最多可能需要 50 毫秒。但是,在 FFmpeg 中测量相同的调用会显示出奇怪的行为:
(这些是解码 4K 25fps VP9 编码视频时,每次调用 avcodec_send_packet() 所需的时间(以毫秒为单位。)
基本上,当 FFmpeg 使用这个函数时,似乎只需要花费任何时间来完成每 N 次调用,其中 N 是用于解码的线程数。但是,我的测试解码器和实际产品都使用 4 个线程进行解码,这不会发生;使用基于帧的线程时,测试解码器的行为类似于 FFmpeg,仅使用 1 个线程。这似乎表明我们根本没有使用多线程,但我们仍然看到通过使用更多线程来提高性能。
FFmpeg 的结果平均比我们的解码器快两倍,所以很明显我们做错了什么。我一直在阅读 FFmpeg 的源代码以试图找到任何线索,但到目前为止我还没有找到。
我的问题是:FFmpeg 在这里做什么而我们不是?或者,我们如何提高解码器的性能?
任何帮助是极大的赞赏。