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

时间:2011-08-16 16:16:38

标签: c++ voip gstreamer

我有一个gstreamer管道,它将所有数据丢弃到appink中:

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个1个通道/ 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缓冲区的同时处理采样率变化,但问题是它不会让我以单声道捕获音频:仅在立体声中。

1 个答案:

答案 0 :(得分:0)

我摆脱了autoaudiosrc并插入了alsasrc。脉冲IC插件是导致缓冲器拉动的不稳定阻塞行为的原因,这给了我不同的缓冲区长度。唯一的问题是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

这给了我所需的缓冲长度。但是,这是否会给我带来任何重大的性能问题,因为这将出现在嵌入式设备上?