2

我有一堆 RTP 数据包,我想将它们重新组合成音频流。对于每个数据包,我都有序列号、SSRC、时间戳和一个表示数据本身的字节数组。

目前,我通过它们的 SSRC 获取每个数据包子集,然后按时间戳对它们进行排序,并按该顺序组合字节数组。之后,我混合字节数组。生成的音频数据听起来很棒(很好,我的意思是一切都及时),但我担心这是由于没有太多的数据包丢失。

所以,有几个问题...

  1. 对于丢失的数据包,丢失的序列号显示我需要添加一些空音频的位置。我相信序列号经常“环绕”,所以我需要使用时间戳将它们分解为子集。然后我可以在这些子集中查找缺失的序列号并根据需要添加。这听起来像是正确的做法吗?

  2. 我还没有完全弄清楚时间戳还有什么好处。由于我正在记录已经存在的数据包并填写丢失的数据包,也许我不需要太担心这个?

4

3 回答 3

2

1) 避免在算法中使用时间戳。如果您从不良客户端(不正确的时间戳)接收流,您的算法将失败。并且“时间戳增量”值随编解码器类型而变化。在这种情况下,您可能需要针对不同编解码器的不同子集。序列号没有限制。序号单调递增。使用序列号,您可以轻松跟踪丢失的数据包。

2)时间戳用于音频和视频之间的同步。主要用于口型同步。建立音频和视频时间戳之间的关系以实现同步。在您的情况下,它是唯一的音频,因此您可以避免使用时间戳。

编辑:根据 RFC 3389(舒适噪声的实时传输协议(RTP)有效载荷(CN))

RTP 允许在任何音频有效负载格式上进行不连续传输(静音抑制)。接收方可以通过观察 RTP 时间戳与前一个数据包所覆盖的时间间隔的结尾不连续,即使 RTP 序列号仅增加了 1,也可以检测静音后收到的第一个数据包的静音抑制。RTP 标记位通常也设置在这样的数据包上。

于 2010-08-11T04:54:07.907 回答
1

1)我认为序列号不会很快“环绕”。这是 16 位的值,因此它每 65536 条消息包装一次,即使每 10 毫秒发送一次消息,这也会产生超过 10 分钟的传输时间。数据包丢失这么长时间的可能性很小。所以在我看来你应该只检查序列号,检查时间戳是没有意义的。

2)我认为你不应该太担心时间戳。我知道有些协议甚至没有填充这个值,只在序列号上中继。

于 2010-08-09T17:53:01.640 回答
0

我认为 Zulijn 在上面的回答中得到的是,如果您的数据包按照捕获的顺序存储,那么您可以使用一些简单的规则来查找无序数据包 - 例如回顾 50 个数据包并转发 50 个数据包。如果它不存在,则它被视为丢失的数据包。

这应该避免序列号被环绕的任何问题。要处理任何丢失的数据包,您可以使用许多技术,因此谷歌搜索“音频数据包丢失”或“VOIP 数据包丢失隐藏”会很有用。正如亚当提到的时间戳会随编解码器而变化,所以如果你要使用它,你需要了解这一点。

您没有提及实际应用程序是什么,但如果您想了解接收到的音频实际上听起来像什么,您确实需要更多信息,特别是抖动缓冲区大小 - 这有效地确定了接收器将等待多长时间在确定它丢失之前,乱序数据包。这对您意味着什么是您的文件中可能有乱序的数据包,“真实世界”的接收者会放弃并且不会播放 - 即您从文件中重建的质量可能比“真实世界”的更高时间的经验。

如果是双向传输,那么延迟也很重要(即使它是恒定延迟,因此不会影响抖动和丢包)。这是您过去在某些无线电话上获得的效果类型,并且在某些卫星电话(或 VoIP 电话)上仍然存在,它会显着影响用户体验。

最后,不同的编解码器和客户端可能会应用不同的技术来纠正丢失的数据包,为音频中的任何间隙插入“静音”(例如对话中的暂停),抑制背景噪音等。

为了获得对用户体验的正确感觉,您必须尝试使用​​相同的编解码器、抖动缓冲区和接收器也使用的任何纠错/数据包丢失技术尽可能准确地“重放”捕获的数据包。

于 2010-08-11T11:39:30.110 回答