2014-01-26 44 views
0

我正在开发一款Android视频播放器。我在本地代码中使用ffmpeg来解码视频帧。在本机代码,我有一个线程调用decode_thread调用avcodec_decode_video2()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()的行为,并建议我一个解决方案?

回答

1

视频解码功能的性能看起来不可能仅仅因为你的线程睡眠而改善。视频解码线程很有可能被另一个线程抢占,因此你会得到更多的时间(因此你的线程无法工作)。当您将呼叫添加到usleep时,会将上下文切换到另一个线程。因此,当您的解码线程下一次再次安排时,它将从完整的CPU片开始,并且不会在decode_ video2函数中中断。

你应该怎么做?你肯定想要比你向他们展示的数据包提前一点点解码数据包 - avcodec_decode_video2的性能当然不是恒定的,并且如果你试图只保留一帧,你可能没有足够的时间来解码其中一帧。

我会创建一个生产者 - 消费者队列与解码帧,与上限。解码器线程是一个生产者,它应该运行直到它填满队列,然后它应该等到另一个帧有余地。显示线程是消费者,它会从这个队列中取出帧并显示它们。

+0

我使用SDL_CreateThread()创建线程。你能提供关于如何检测哪个线程抢占decode_thread的建议吗? –

+0

不可能检测到接下来调度的是哪个线程,而不会搞乱OS内核。你也不应该这样做,因为这可能不是你的应用程序线程,并且在任何情况下,这可能是一个不同的线程 - 请注意,你的Android操作系统正在运行许多不同的进程,许多多线程,并且最多只有4个CPU在您的设备中。 –

+0

如果你有兴趣测量原始性能,我感觉你需要性能计数器;请参阅http://stackoverflow.com/questions/13729717/does-androidon-arm-have-the-hardware-performance-counters –