【问题标题】:Playing non-blocking data on AudioTrack在 AudioTrack 上播放非阻塞数据
【发布时间】:2013-01-21 20:47:05
【问题描述】:

我正在实现一个 RTP 接收器。它接收 UDP 数据包,解码编解码器并将 PCM 样本写入AudioTrack 以进行播放。一个问题似乎是,AudioTrack.write 正在阻塞,因此我会同时错过 UDP 数据包。

是否有任何已知的解决方案来解决这个问题?

我尝试使用我自己的音频数据缓冲区和setNotificationMarkerPosition,但似乎只有在缓冲区被填充到一定程度时才会播放audioTrack,因此永远不会到达标记位置或audioTrack.write 再次阻塞.

我还尝试在每次写入之前先执行audioTrack.pause(),然后再执行.play(),但这似乎会显着影响音质。

【问题讨论】:

    标签: android audiotrack


    【解决方案1】:

    我不知道你的问题是否解决了,我有一些问题。我能做的最好的就是将一个线程中的 UDP 数据包抓取到 ArrayBlockingQueue(ABQ) 中,然后在另一个线程中从 ABQ 中一个接一个地播放它们。但是这次播放会受到影响(不是所有设备,有些设备是双线程的)并且 ABQ 的大小增加,这意味着延迟增加。因此,我检查了大小并系统地丢弃了一些数据包(只是不写入 AudioTrack)以减少延迟,但如果您可以接受延迟,那就由您来决定。

    还有一件事,我正在增加线程的优先级:

    private class Player extends Thread {
      public void run() {
         Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO );
           ....
      }
    }
    

    速度更快。

    解决方案仍然以某种方式阻塞,但 UDP 数据包不会被播放器阻塞,直到 ABQ 大小随容量增加。

    【讨论】:

    • 我确实在使用类似的解决方案:我有一个用于 audioData 的手动环形缓冲区。一个线程读取并播放它,另一个线程写入它。如果已满,则丢弃数据包。还不完美,但目前还可以。
    • 我猜延迟量取决于 ringbuffer 的大小,如果你正在写入器线程。如果出现问题会像这样被丢弃(假设 * 很好 _ 被丢弃): *************___________************ 相反,如果你使用丢包在玩家方面,这次你会得到一些东西: *********** **** 对耳朵更友好,延迟更好,而不是真正取决于环形缓冲区的大小。丢弃的最后一件事,你不必丢弃整个数据包,我只是将数据包分成 8 个,如果缓冲区好则不丢弃,如果缓冲区一般则丢弃两个。
    • 如果缓冲区真的受到影响,则丢弃所有内容。在两者之间,从 0 更改为 8,您的电话。如果您找到更好的方法,请告诉我,我也应该检查一下。
    【解决方案2】:

    我想我可能有一个比“添加缓冲区和线程”解决方案更有吸引力的解决方案。该解决方案为您的(可能)延迟敏感系统增加了一些延迟。您可以执行以下操作:

    注意 AudioTrack 的缓冲区大小。然后跟踪在最后 X 毫秒内有多少字节写入缓冲区(这应该以不太计算密集的方式可行),其中 X 是您可以放入的音频的毫秒数缓冲区(基于缓冲区大小和采样率和量化率(位/样本)和通道数的简单计算)。如果您在 X 毫秒内写入了“缓冲区大小”的数据量,那么您应该丢弃音频数据包。请注意,丢弃数据包也将成为“添加缓冲区和线程”解决方案的症状。

    您可能希望添加一个小阈值,这样您就不会真正填满缓冲区(假设缓冲区比实际小一点)。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2013-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-07
      • 2012-02-07
      • 1970-01-01
      • 1970-01-01
      • 2015-05-08
      相关资源
      最近更新 更多