2011-05-09 46 views
5

當與音頻重放工作我用以下模式:哪個線程用於音頻解碼?

  • 一個磁盤(或網絡)螺紋,其從磁盤讀取(或網絡)的數據,並填充一個ringbuffer
  • 一個聲音線程,其讀取從ringbuffer數據,可能執行DSP,並寫入音頻硬件 (拉或推API)

這工作得很好,而且也有,比如說,WAV文件工作時沒有問題。

現在,如果源數據以Vorbis或MP3等壓縮格式編碼,則解碼需要一些時間。

而且在磁盤/網絡線程中執行解碼似乎很常見。

但是這不是錯誤的設計?當磁盤或網絡訪問被阻塞時,一些CPU時間可用於解碼,但是如果解碼發生在同一線程中則會浪費時間。

在我看來,如果網絡變慢,那麼如果解碼順序發生,那麼緩衝區欠載的風險就會更高。

那麼,不應該在音頻線程中執行解碼?

在我的情況下,我寧願避免添加專用的解碼線程。它適用於移動平臺,SMP現在非常罕見。但是請告訴您一個專用的解碼線程是否真的對您有意義。

回答

2

音頻線程可用於平滑播放音頻比網絡線程保持完美的大小緩衝更重要。如果你只使用兩個線程,那麼解碼應該在網絡線程上完成。如果您要在播放線程上解碼,那麼有可能會出現這樣的情況,您需要將更多音頻輸出到硬件,但線程正忙於解碼。如果您維護已解碼音頻的緩衝區會更好。

理想情況下,你會使用三個線程。一個用於閱讀網絡,一個用於解碼,另一個用於播放。在我們處理音頻/視頻捕獲,錄製和數據流的應用程序中,我們每個流有八個線程(最近由於我們最近增加了新功能而增加了六個線程)。每個線程都擁有自己的功能要容易得多,然後它可以適當地衡量它的輸入/輸出緩衝區的性能。這也有利於分析和優化。

+0

你說得對,在2線程的情況下,解碼應該在網絡線程中執行。我在寫完後意識到,由於音頻解碼是基於數據包的,因此它可能會在每N個音頻週期阻塞很長時間,這會導致xrun。也就是說,專用解碼線程對我來說越來越有吸引力,特別是對於網絡(或慢速磁盤/存儲)流。 – olivierg 2011-05-09 20:24:48

2

如果您的設備具有單個CPU,則所有線程正在共享它。 OS線程交換通常非常高效(您不會失去任何有意義的CPU交換功能)。因此,如果它能簡化你的邏輯,你應該創建更多的線程。

在你的情況下,有一個管道。管道每個階段的不同線程是一個很好的模式。正如您注意到的,替代方案涉及複雜的邏輯,同步,事件,中斷或其他任何事情。有時候根本沒有好的選擇。

因此,我的建議 - 爲音頻解碼創建一個專用線程。

如果您將擁有多個CPU,您甚至可以通過爲每個管道步驟使用一個線程獲得更高的效率。

+0

我讀過很多次,有太多的線程可能會很重。所以我通常在添加新的線程之前考慮兩次,在移動平臺上工作時更多。我不確定簡化邏輯是在管道中添加線程的好理由。但在這種情況下,專用解碼線程似乎是有意義的。 – olivierg 2011-05-09 20:30:47

+0

我認爲100個線程可能是一個問題(儘管我在Windows下使用300個線程沒有任何問題)。但是,其他同步機制/策略也有其成本。這個成本可以更高或更低,但通常效果很小。如果管道線程正確實現,大多數時候他們只是睡覺並等待事件。 – 2011-05-10 07:33:34