2011-05-09 89 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