我正在尝试优化用于播放视频的软件,该软件内部使用FFmpeg库进行解码。我们发现,在某些大型(4K,60fps)视频上,解码一帧所需的时间有时会比该帧要显示的时间长;可悲的是,由于存在问题域,仅缓冲/跳过帧是不可行的。
但是,似乎FFmpeg可执行文件能够以大约2倍的速度很好地解码有问题的视频,因此我一直在尝试找出我们做错了什么。
我编写了一个非常简化的解码器程序进行测试;来源是here(大约200行)。从配置上看,似乎在解码过程中的一个主要瓶颈是avcodec_send_packet()
函数,每个调用可能要花费50ms。但是,在FFmpeg中测量相同的呼叫会显示出奇怪的行为:
(这些是解码4K 25fps VP9编码的视频时,每次调用avcodec_send_packet()所花费的时间,以毫秒为单位。)
基本上,似乎当FFmpeg使用此功能时,实际上仅花费任何时间即可完成每N个调用,其中N是用于解码的线程数。但是,我的测试解码器和实际产品都使用4个线程进行解码,但这并没有发生。使用基于帧的线程时,测试解码器的行为类似于仅使用1个线程的FFmpeg。这似乎表明我们根本没有使用多线程,但是通过使用更多的线程,我们仍然看到性能提高。
FFmpeg的结果平均速度约为解码器的两倍,因此显然我们在做错事。我一直在阅读FFmpeg的资源以尝试找到任何线索,但是到目前为止,这一直困扰着我。
我的问题是: FFmpeg在这里做什么?或者,我们如何提高解码器的性能?
非常感谢您的帮助。
答案 0 :(得分:0)
avcodec_send_packet()
和avcodec_receive_frame()
是包装函数,最重要的是调用选定的编解码器的解码函数并返回解码的帧(或错误)。
尝试调整编解码器选项,例如,低延迟可能无法满足您的需求。有时旧的api(我相信它仍然存在)avcodec_decode_video2()
胜过较新的api,您也可以尝试使用。