【问题标题】:Which thread to use for audio decoding?哪个线程用于音频解码?
【发布时间】:2011-08-21 22:15:26
【问题描述】:

在处理音频播放时,我习惯了以下模式:

  • 一个磁盘(或网络)线程从磁盘(或网络)读取数据并填充环形缓冲区
  • 一个音频线程,从环形缓冲区读取数据,可能执行 DSP,并写入音频硬件 (拉取或推送 API)

这很好用,并且在处理 WAV 文件时没有问题。

现在,如果源数据以压缩格式(如 Vorbis 或 MP3)编码,则解码需要一些时间。

在磁盘/网络线程中执行解码似乎很常见。

但这不是错误的设计吗?当磁盘或网络访问阻塞时,一些 CPU 时间可用于解码,但如果解码发生在同一个线程中,则会被浪费。

在我看来,如果网络变慢,如果按顺序进行解码,则缓冲区欠载的风险会更高。

那么,解码不应该在音频线程中执行吗?

在我的上下文中,我宁愿避免添加专用的解码线程。它适用于移动平台,而 SMP 现在非常罕见。但是请告诉你一个专用的解码线程是否真的对你有意义。

【问题讨论】:

    标签: multithreading audio audio-streaming decoding


    【解决方案1】:

    音频线程可用于流畅地播放音频比网络线程保持完美大小的缓冲区更重要。如果你只使用两个线程,那么解码应该在网络线程上完成。如果您要在播放线程上解码,那么您可能需要将更多音频推送到硬件但线程正忙于解码。最好保留一个已解码音频的缓冲区。

    理想情况下,您会使用三个线程。一个读网络,一个解码,一个播放。在我们处理音频/视频捕获、录制和流式传输的应用程序中,每个流有 8 个线程(最近增加了 6 个线程,因为我们最近添加了新功能)。每个线程拥有自己的功能要容易得多,然后它可以根据传入/传出缓冲区的性能适当地衡量其性能。这也有利于分析和优化。

    【讨论】:

    • 你是对的,在2线程的情况下,解码应该在网络线程中执行。写完才发现,由于音频解码是基于包的,每N个音频周期它可能会阻塞很长时间,这会导致xrun。也就是说,专用解码线程对我越来越有吸引力,尤其是对于网络(或慢速磁盘/存储)流。
    【解决方案2】:

    如果您的设备只有一个 CPU,则所有线程都在共享它。操作系统线程交换通常非常有效(您不会因为交换而失去任何有意义的 CPU 能力)。因此,如果可以简化您的逻辑,您应该创建更多线程。

    在您的情况下,有一个管道。管道的每个阶段使用不同的线程是一个很好的模式。正如您所注意到的,替代方案涉及复杂的逻辑、同步、事件、中断或其他任何东西。有时根本没有好的选择。

    因此,我的建议 - 为音频解码创建一个专用线程。

    如果您拥有多个 CPU,您甚至可以通过在每个流水线步骤中使用一个线程来提高效率。

    【讨论】:

    • 我读过很多次,线程太多会很重。所以我通常在添加新线程之前会三思而后行,在移动平台上工作时更是如此。我不确定简化逻辑是否一定是在管道中添加线程的好理由。但在这种情况下,一个专用的解码线程似乎是有意义的。
    • 我认为 100 个线程可能是个问题(尽管我在 Windows 下使用了 300 个线程没有任何问题)。然而,其他同步机制/策略也有其成本。这个成本可高可低,但通常影响很小。如果管道线程正确实现,大多数时候它们只会休眠并等待事件。
    猜你喜欢
    • 2017-04-09
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    相关资源
    最近更新 更多