2014-01-26 76 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 –