Принудете gstreamer appsink буферите да задържат само 10 ms данни

Имам тръбопровод на 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 1 канал/16 бита дълбочина), но буферите ще бъдат с дължина от 10ms до 26ms. Много е важно този тръбопровод да връща само 10 ms на буфер. Има ли начин това да стане? Ето кода, който грабва данните.

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 ms, но проблемът е, че не ми позволява да заснема звука в моно: само в стерео.


person Jonathan Henson    schedule 16.08.2011    source източник


Отговори (1)


Отървах се от 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

Това ми даде необходимите дължини на буфера. Това обаче ще ми създаде ли някакви значителни проблеми с производителността, тъй като това ще бъде на вградено устройство?

person Jonathan Henson    schedule 16.08.2011