FFmpeg对avcodec_send_packet()做了什么?

时间:2019-03-15 16:22:08

标签: multithreading performance video ffmpeg avcodec

我正在尝试优化用于播放视频的软件,该软件内部使用FFmpeg库进行解码。我们发现,在某些大型(4K,60fps)视频上,解码一帧所需的时间有时会比该帧要显示的时间长;可悲的是,由于存在问题域,仅缓冲/跳过帧是不可行的。

但是,似乎FFmpeg可执行文件能够以大约2倍的速度很好地解码有问题的视频,因此我一直在尝试找出我们做错了什么。

我编写了一个非常简化的解码器程序进行测试;来源是here(大约200行)。从配置上看,似乎在解码过程中的一个主要瓶颈是avcodec_send_packet()函数,每个调用可能要花费50ms。但是,在FFmpeg中测量相同的呼叫会显示出奇怪的行为:

Yes, you can embed images

(这些是解码4K 25fps VP9编码的视频时,每次调用avcodec_send_packet()所花费的时间,以毫秒为单位。)

基本上,似乎当FFmpeg使用此功能时,实际上仅花费任何时间即可完成每N个调用,其中N是用于解码的线程数。但是,我的测试解码器和实际产品都使用4个线程进行解码,但这并没有发生。使用基于帧的线程时,测试解码器的行为类似于仅使用1个线程的FFmpeg。这似乎表明我们根本没有使用多线程,但是通过使用更多的线程,我们仍然看到性能提高。

FFmpeg的结果平均速度约为解码器的两倍,因此显然我们在做错事。我一直在阅读FFmpeg的资源以尝试找到任何线索,但是到目前为止,这一直困扰着我。

我的问题是: FFmpeg在这里做什么?或者,我们如何提高解码器的性能?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

avcodec_send_packet()avcodec_receive_frame()是包装函数,最重要的是调用选定的编解码器的解码函数并返回解码的帧(或错误)。

尝试调整编解码器选项,例如,低延迟可能无法满足您的需求。有时旧的api(我相信它仍然存在)avcodec_decode_video2()胜过较新的api,您也可以尝试使用。