强制 gstreamer appsink 缓冲区仅保存 10 毫秒的数据
我有一个 gstreamer 管道,它将所有数据放入 appsink 中:
command = g_strdup_printf ("autoaudiosrc ! audio/x-raw-int, signed=true, endianness=1234, depth=%d, width=%d, channels=%d, rate=%d !"
" appsink name=soundSink max_buffers=2 drop=true ",
bitDepthIn, bitDepthIn, channelsIn, sampleRateIn);
在运行时通常看起来像这样
autoaudiosrc ! audio/x-raw-int, signed=true, endianness=1234, depth=16, width=16, channels=1, rate=16000 ! appsink name=soundSink max_buffers=2 drop=true
。
它捕获音频很好,问题是它倾向于捕获它想要的任何随机数量的数据,而不是设定的大小或时间间隔。例如,请求数据的 rtp lib 仅请求 960 字节(10ms 的 48khz/1 1channel/16 位深度),但缓冲区的长度将在 10ms 到 26ms 之间。非常重要的是,该管道每个缓冲区仅返回 10 毫秒。有办法做到这一点吗?这是获取数据的代码。
void GSTMediaStream::GetAudioInputData(void* data, int max_size, int& written)
{
if (soundAppSink != NULL)
{
GstBuffer* buffer = gst_app_sink_pull_buffer (GST_APP_SINK (soundAppSink));
if (buffer)
{
uint bufSize = MIN (GST_BUFFER_SIZE (buffer), max_size);
uint offset = 0;
std::cout << "buffer time length is " << GST_BUFFER_DURATION(buffer) << "ns buffer size is " << GST_BUFFER_SIZE (buffer)
<< " while max size is " << max_size << "\n";
//if max_size is smaller than the buffer, then only grab the last 10ms captured.
//I am assuming that the reason for the occasional difference is because the buffers are larger
//in the amount of audio frames than the rtp stream wants.
if(bufSize > 0)
uint offset = GST_BUFFER_SIZE (buffer)- bufSize;
memcpy (data, buffer->data + offset, bufSize);
written = bufSize;
gst_buffer_unref(buffer);
}
}
}
更新 好的,所以我已将问题范围缩小到 gstreamer 的脉冲音频插件。 autoaudiosrc 使用pulssrc 插件进行捕获,无论出于何种原因,脉冲服务器在几次重新采样后速度都会变慢。我用 alsasrc 进行了测试,它似乎可以处理采样率变化,同时保持 10ms 缓冲区,但问题是它不允许我以单声道捕获音频:只能以立体声捕获。
I have a gstreamer pipeline which drops all of its data into an appsink:
command = g_strdup_printf ("autoaudiosrc ! audio/x-raw-int, signed=true, endianness=1234, depth=%d, width=%d, channels=%d, rate=%d !"
" appsink name=soundSink max_buffers=2 drop=true ",
bitDepthIn, bitDepthIn, channelsIn, sampleRateIn);
Which usually looks something like,
autoaudiosrc ! audio/x-raw-int, signed=true, endianness=1234, depth=16, width=16, channels=1, rate=16000 ! appsink name=soundSink max_buffers=2 drop=true
at runtime.
It captures the audio fine, the problem is that it tends to capture any random amount of data it wants instead of a set size or time interval. So For Instance, the rtp lib that is asking for the data will only ask for 960 bytes (10ms of 48khz/1 1channel/16 bit depth) but the buffers will be anywhere from 10ms to 26ms in length. It is very important that this pipeline only return 10ms per buffer. Is there a way to do this? Here is the code that grabs the data.
void GSTMediaStream::GetAudioInputData(void* data, int max_size, int& written)
{
if (soundAppSink != NULL)
{
GstBuffer* buffer = gst_app_sink_pull_buffer (GST_APP_SINK (soundAppSink));
if (buffer)
{
uint bufSize = MIN (GST_BUFFER_SIZE (buffer), max_size);
uint offset = 0;
std::cout << "buffer time length is " << GST_BUFFER_DURATION(buffer) << "ns buffer size is " << GST_BUFFER_SIZE (buffer)
<< " while max size is " << max_size << "\n";
//if max_size is smaller than the buffer, then only grab the last 10ms captured.
//I am assuming that the reason for the occasional difference is because the buffers are larger
//in the amount of audio frames than the rtp stream wants.
if(bufSize > 0)
uint offset = GST_BUFFER_SIZE (buffer)- bufSize;
memcpy (data, buffer->data + offset, bufSize);
written = bufSize;
gst_buffer_unref(buffer);
}
}
}
Update
Ok, so I've narrowed the problem down to the pulse audio plugin for gstreamer. The autoaudiosrc is using the pulsesrc plugin for capture and for whatever reason, the pulse server slows down after a few resamplings. I tested with alsasrc and it seems to handle the sample rate changes while keeping the 10ms buffers but the problem is that it will not let me capture the audio in mono: only in stereo.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我摆脱了 autoaudiosrc 并插入了 alsasrc 。 pulssrc 插件是导致缓冲区拉取不稳定的阻塞行为的原因,这给了我不同的缓冲区长度。唯一的问题是 alsasrc 无法以单声道捕获。我通过在管道中添加一个 audioconvert 元素来解决这个问题。我的最终管道是:
这给了我所需的缓冲区长度。但是,这是否会给我带来任何重大的性能问题,因为这是在嵌入式设备上?
I got rid of the autoaudiosrc and plugged in alsasrc instead. The pulsesrc plugin was what was causing the erratic blocking behavior on the buffer pull which was giving me varying buffer lengths. The only problem then was that alsasrc wouldn't capture in mono. I remedied that by adding in an audioconvert element to the pipeline. My final pipe was:
This gave me the buffer lengths I needed. However, is this going to give me any significant performance issues as this is going to be on an embedded device?