对于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
元素的不兼容/缺点吗?我是否错过了管道中的关键部分以确保时间同步?还有什么可能导致这个?
答案 0 :(得分:2)
GStreamer可能只是使用dejitter缓冲区来平滑数据包到(音频)输出的路上。这并不罕见,它是dejittering的最低限度。
它可能会重新排序无序数据包或删除重复数据包,但数据包丢失隐藏(您的方案)可能非常复杂。
基本实现只复制最后收到的数据包,而更高级的实现分析并重建最后收到的数据包的音调以平滑音频。
听起来您的应用程序性能将取决于丢失隐藏的确切实现,因此即使GStreamer确实执行了“某些操作”,您也可能很难量化其对结果的影响,除非您非常详细地了解它。 / p>
也许你可以尝试使用带有几个无序和重复数据包的pcap,并检查GStreamer是否至少重新排序/删除它们,这将在某种程度上澄清正在发生的事情。
答案 1 :(得分:2)
这个问题可以通过稍微改变管道来解决:
需要在audiorate
“produces a perfect stream by inserting or dropping samples as needed”之前添加wavenc
元素。
但是,仅当audiorate
收到数据包丢失事件时,此方法才有效。为此,do-lost
的{{1}}属性需要设置为true。
以下是更正的管道:
gstjitterbuffer