我正在开发一款Android视频播放器。我在本机代码中使用ffmpeg来解码视频帧。在本机代码中,我有一个名为decode_thread的线程,它调用avcodec_decode_video2()
int decode_thread(void *arg) {
avcodec_decode_video2(codecCtx, pFrame, &frameFinished,pkt);
}
我有另一个名为display_thread的线程,它使用aNativeWindow
在SurfaceView上显示已解码的帧。
问题在于,如果我让decode_thread连续运行而没有延迟。它显着降低了avcodec_decode_video2()
的性能。有时解码帧需要大约0.1秒。但是,如果我在decode_thread上加上延迟。有点喜欢这个。
int decode_thread(void *arg) {
avcodec_decode_video2(codecCtx, pFrame, &frameFinished,pkt);
usleep(20*1000);
}
avcodec_decode_video2()
的表现非常好,约为0.001秒。但是在decode_thread上放置延迟并不是一个好的解决方案,因为它会影响播放。任何人都可以解释avcodec_decode_video2()的行为并建议我一个解决方案吗?
答案 0 :(得分:1)
视频解码功能的性能看起来不可能因为你的线程休眠而改善。很可能视频解码线程被另一个线程抢占,因此你得到了增加的时间(因此你的线程不起作用)。当您向usleep
添加调用时,这会将上下文切换到另一个线程。因此,当您的解码线程下次再次调度时,它将以完整的CPU片开始,并且不会再被decode_ video2
函数中断。
你应该怎么做?你肯定想要比你显示它们稍微解码数据包 - avcodec_decode_video2
的性能当然不是恒定的,如果你试图保持前一帧,你可能没有足够的时间来解码其中一个框架。
我创建了一个带有解码帧的生产者 - 消费者队列,并带有上限。解码器线程是一个生产者,它应该运行直到它填满队列,然后它应该等到有另一个帧的空间。显示线程是消费者,它将从此队列中获取帧并显示它们。