简而言之:如果您坚持使用gstreamer,请检查updsrc
缓冲区的大小。我建议使用Ravenna实现。
这个问题非常关注gstreamer,但是可能并不需要它来实现您的目标。
这个答案更多地涉及到在ARM Linux上进行音频IP(AoIP)的一般性问题,就像问题2和3一样。
首先,您提到了视频和音频。如果以专业方式完成,这将需要一个AV over IP解决方案,以保持音频和视频同步。例如DanteAV或符合SMPTE 2110标准的解决方案。对于业余项目,您的方法似乎很好。请记住,Dante在AES67模式下有一些限制。
2. 低延迟AoIP:
是的,如果您的设备具有与NXP i.MX8相当的规格,那么肯定可以将Dante/AES67/RTP延迟降至50毫秒以下。
作为参考:使用Dante和专业硬件很容易实现4-5毫秒的往返延迟。
如果您的目标是:“将低延迟AES67流传输到RPi”,我建议查看Linux的Ravenna实现。 Ravenna类似于Dante,但更符合AES67标准。 Ravenna和AES67完全以相同的方式使用RTP。
有两个主要的开源Linux实现:
提供商业支持的"
原版"。控制工具是专有的,仅限x86。
有一个分支包含有用的补丁和开源控制软件。
- 在这两种情况下,您仍然需要为ARM/RPi交叉编译代码。
- 个人建议使用分支。
Dante为制造商提供Linux实现,但您可能无法获得该实现:https://www.audinate.com/products/manufacturer-products/dante-embedded-platform。
3.延迟来源
对于AoIP,有不同的延迟来源:
- 数据包时间:计算数据包中样本的时间,约为1毫秒。
- 网络:取决于您的硬件和设置,大约为< 1毫秒到几秒钟。
- 接收缓冲区:可配置,大约为< 1毫秒到多毫秒。
- 接收器上的处理和DAC。
数据包时间应为1毫秒,因为Dante使用AES67强制配置文件(48 kHz,每个数据包48个样本)。我假设您的发送器正确处理此问题,但我无法确定。
在网络上,您应该至少使用千兆交换机和Cat 5e电缆。
确保遵循
建议的交换机和配置(特别是禁用
EEE)。
如果发送方和接收方的时钟同步,则在两者上运行tcpdump或Wireshark以获得网络延迟的良好估计。
按端口过滤有效载荷最容易,例如RTP:
port 5004或port 9875
Dante:
portrange 14336-14591
。在捕获中轻松发现静音/取消静音(
延迟= T_send-T_recv
)。
如果以上都没有问题,可以查看接收缓冲区或者接收端的处理。
树莓派低延迟音频 似乎 可行。
此外,您可以测量RPi上的ADC / DAC速度并优化您的Linux系统(从无头到实时补丁内核再到使用Yocto构建优化的发行版等)。
1. 4. Gstreamer
如前所述,如果您能够这样做,请使用Ravenna Linux实现。 它的整个目的是有效地接收AES67流。 尽管如此,请考虑一些有关您的管道的想法:
文档中提到udpsrc
会添加一个约50KB至100KB可配置的缓冲区。
以1ms数据包时间和48kHz采样率的AES67 RTP数据包大小为342字节。
因此,该缓冲区相当于 50kB / 342字节 * 1ms = 146ms
-> 这可能是罪魁祸首。
我认为您不需要使用rtpjitterbuffer
。它的文档中提到了“重传”功能。AES67不会重新传输有效负载(据我所知)。
此外,管道还会添加另一个200个数据包的缓冲区,对于1ms数据包时间而言为200ms。
排序等应该仍然可以正常工作,因为AES67使用标准RTP时间戳。但这将增加延迟,在局域网上可能是不必要的。
看起来,rtpjitterbuffer更适用于广域网RTP,而不是本地网络AES67。
还发现了这篇文章, 它使用的和你一样的pipeline。
如果这不能解决你的问题,找出延迟是在哪里引入的。并告诉我们延迟是如何测量的。