强制gstreamer appsink缓冲区只能容纳10ms的数据

Force gstreamer appsink buffers to only hold 10ms of data

本文关键字:10ms 数据 能容纳 gstreamer appsink 缓冲区 强制      更新时间:2023-10-16

我有一个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库将只请求960字节(10ms的48khz/11通道/16位深度),但缓冲区的长度将从10ms到26ms不等。非常重要的是,这个管道每个缓冲区只返回10ms。有办法做到这一点吗?下面是获取数据的代码。

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使用pulsesrc插件进行捕获,无论出于什么原因,脉冲服务器在几次重采样后变慢了。我测试了alsasrc,它似乎处理采样率的变化,同时保持10ms缓冲,但问题是,它不会让我捕捉音频单声道:只有在立体声。

我去掉了autoaudiosrc并插入了alsasrc。pulsesrc插件是导致缓冲区拉上不稳定的阻塞行为的原因,这给了我不同的缓冲区长度。唯一的问题是,alsasrc不会捕获单声道。我通过在管道中添加audioconvert元素来解决这个问题。我的最后一个管道是:

alsasrc ! audioconvert ! audio/x-raw-int, signed=true, endianness=1234, depth=16, width=16, channels=1, rate=16000 ! appsink name=soundSink max_buffers=2 drop=true

这给了我所需要的缓冲区长度。然而,这会给我带来任何显著的性能问题吗,因为这将在嵌入式设备上进行?