1

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

有没有关于如何处理这个问题的已知解决方案?

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

我也尝试audioTrack.pause()在每次写入之前.play()再做一次,但这似乎会显着影响音质。

4

2 回答 2

3

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

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

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

这提供了更好的速度。

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

于 2013-02-25T18:56:27.790 回答
0

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

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

您可能想要添加一个小阈值,这样您就不会实际填充缓冲区(假设缓冲区比实际值小一点)。

祝你好运!

于 2013-08-30T05:51:57.343 回答