Заставить буферы gstreamer приложения удерживать только 10 мс данных - PullRequest
1 голос
/ 16 августа 2011

У меня есть конвейер 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, которая запрашивает данные, будет запрашивать только 960 байтов (10 мс 48 кГц / 1 1 канал / 16 бит), но буферы будут иметь длину от 10 мс до 26 мс. Очень важно, чтобы этот конвейер возвращал только 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 использует плагин pulsesrc для захвата, и по любой причине сервер импульсов замедляется после нескольких повторных выборок. Я тестировал с alsasrc, и он, кажется, обрабатывает изменения частоты дискретизации, сохраняя буферы 10 мс, но проблема в том, что он не позволяет мне захватывать звук в моно: только в стерео.

1 Ответ

0 голосов
/ 17 августа 2011

Я избавился от autoaudiosrc и подключил вместо него alsasrc. Плагин pulsesrc был причиной ошибочного поведения блокировки буфера, что давало мне переменную длину буфера. Единственной проблемой тогда было то, что alsasrc не будет захватывать в моно. Я исправил это, добавив элемент аудиоконвертации в конвейер. Моя последняя труба была:

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

Это дало мне необходимую длину буфера. Тем не менее, это вызовет у меня какие-либо существенные проблемы с производительностью, поскольку это будет на встроенном устройстве?

...