4

对于 VoIP 语音质量监控应用程序,我需要将传入的 RTP 音频流与参考信号进行比较。对于信号比较本身,我使用预先存在的专用工具。对于其他部分(数据包捕获除外),Gstreamer 库似乎是一个不错的选择。我使用以下管道来模拟一个简单的 VoIP 客户端:

filesrc location=foobar.pcap ! pcapparse ! "application/x-rtp, payload=0, clock-rate=8000"
  ! gstrtpjitterbuffer ! rtppcmudepay ! mulawdec ! audioconvert
  ! audioresample ! wavenc ! filesink location=foobar.wav

pcap 文件包含单个 RTP 媒体流。我制作了一个丢失原始 400 个 UDP 数据报中的 50 个的捕获文件。对于给定的音频样本(我的示例长 8 秒):

[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]

随着一定数量的连续丢包,我希望输出这样的音频信号(' -'表示静音):

[XXXXXXXXXXXXXXXXXXXXXXXX-----XXXXXXXXXXX]

但是实际保存在音频文件中的是这个(我的例子短了 1 秒):

[XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]

似乎抖动缓冲区(此应用程序的关键部分)无法正常工作。pcapparse这可能是与元素的不兼容/缺点吗?我是否错过了确保时间同步的管道中的关键部分?还有什么可能导致这种情况?

4

2 回答 2

2

GStreamer 可能只使用去抖动缓冲区来平滑传输到(音频)输出的数据包。这并不罕见,它是去抖动的最低限度定义。

它可能会重新排序无序数据包或删除重复数据包,但数据包丢失隐藏(您的场景)可能非常复杂。

基本实现只是复制最后收到的数据包,而更高级的实现会分析和重建最后收到的数据包的音调以平滑音频。

听起来您的应用程序性能将取决于丢失隐藏的确切实现,因此即使 GStreamer 确实做了“某事”,除非您非常详细地了解它,否则您可能很难量化它对结果的影响。

也许您可以尝试使用带有几个乱序和重复数据包的 pcap,并检查 GStreamer 是否至少重新排序/删除它们,这将在某种程度上澄清正在发生的事情。

于 2011-01-11T03:10:18.957 回答
2

这个问题可以通过稍微改变管道来解决:在此audiorate之前需要添加一个元素wavenc通过根据需要插入或删除样本来产生完美的流”。但是,这仅在audiorate接收到丢包事件时才有效。为此,需要将的do-lost属性设置为 true。gstjitterbuffer

这是更正后的管道:

filesrc location=foobar.pcap ! pcapparse
  ! "application/x-rtp, payload=0, clock-rate=8000"
  ! gstrtpjitterbuffer do-lost=true ! rtppcmudepay ! mulawdec
  ! audioconvert ! audioresample ! audiorate ! wavenc
  ! filesink location=foobar.wav
于 2011-01-13T15:48:50.850 回答