[Bug 770446] pulsesrc, audiosrc: No audio captured with new GStreamer 1.8.2

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Thu Sep 8 10:53:22 UTC 2016


https://bugzilla.gnome.org/show_bug.cgi?id=770446

--- Comment #8 from Przemek <przemyslaw.gajos at gmail.com> ---
Hello,

I have further debugged this issue and now I know better why audio stopped
working with our capture cards since this change:
https://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/ext/pulse/pulsesrc.c?id=8e236fa2e1a5873b664401342a026a943d482bfe

I think the above change in gst-plugins-good introduced a limitation which may
break audio capture not only for our cards but with any hardware.

See the explanation below (apologies for shortcuts taken and please correct me
where I may be wrong - this was my first delve into GStreamer sources). 
For my case, this happens when audio is started:
1) Initially, default buffer_time is used for pulsesrc: 200000 usec = 200 msec. 
   With 48000 samples/sec, 2 bytes/sample, 2 channels we have 192000 bytes/sec.
   Taking above into account, 200 msec translates into buffer size of 38400
bytes as initial spec.     

2) Source is created (note that "hardware" (kernel) buffer in our audio driver
is fixed to 32768 bytes):
   Our hardware buffer's size 32768 bytes is retrieved from ALSA and used to
set latency by Pulseaudio:
     pa_alsa_source_new -> pa_source_set_fixed_latency(32768)
   PulseAudio default rate is 44100 which with 2 channels, 2 bytes per sample
makes it 185.758 msec.

3) Taking a shortcut now: 185.758 msec is used to set buffer_attr.fragsize
   185.758 msec is translated back into bytes, this time rate 48000 is used as
requested by GStreamer so there is a mismatch between initial Pulse's 44100 and
Gstreamer's 48000 in this calculation but it is not that relevant to the
problem we are experiencing (or in other words, the mismatch is not the cause
of the problem).
   Continuing, 185.758 msec (48000 Hz, 4 bytes per frame) is translated into
35664 bytes and this is set as:
     s->buffer_attr.fragsize = 35664;  

4) gst_audio_src_ring_buffer_acquire calls gst_pulsesrc_prepare and because:
     actual->fragsize(35664) > spec->segsize(1920)
   segment size is set as:
       spec->segsize = actual->fragsize(35664)

   So in GStreamer we end up with:
     buffer of size 38400
     segment of size 35664

   And gst_audio_ring_buffer_read fails to read in such configuration! (If we
look into gst_audio_ring_buffer_read, we can see that it cannot work with only
1 segment within the buffer! It needs at least 2)

To sum up, it looks that the way it works is that when source is created,
PulseAudio retrieves hardware buffer size from ALSA (in my example: 35664) and
uses it to set to fragsize. Then GStreamer uses that fragsize(35664) as segment
size. 
Now, why the capture does not work? Because gst_audio_ring_buffer_read needs >=
2 segments within a buffer to work properly.

I noticed that capture works if I revert this change in gst_pulsesrc_prepare:
   wanted.maxlength = spec->segsize * spec->segtotal;
to:
   wanted.maxlength = -1;

Note that with new GStreamer my buffer size is 38400 (it is limited in
gst_pulsesrc_prepare to wanted.maxlength = spec->segsize(1920) *
spec->segtotal(20) = 38400).
If I use wanted.maxlength = -1 in gst_pulsesrc_prepare, I end up with much
bigger buffer which consists of many segments of size 35664 and then reading
audio with gst_audio_ring_buffer_read works fine.

Therefore I think in new GStreamer in gst_pulsesrc_prepare:
   wanted.maxlength = spec->segsize * spec->segtotal;
limits the size of the buffer to some value (by default it is the equivalent of
200 ms). 

Because segment size is always set to the hardware_buffer size as retrieved
from ALSA by PulseAudio: if the segment size (~ hardware buffer on the card) is
big enough so that the GStreamer buffer only accommodates 1 such segment, audio
capture gets broken which happens in my case. But I think it can happen for any
hardware with a reasonably big audio buffer.

Could you do something to not limit the size of the buffer to the initial spec
but instead make it choose something reasonable based on the segment size
(hardware buf size) got from ALSA. I think it was working in such way before
this change:
https://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/ext/pulse/pulsesrc.c?id=8e236fa2e1a5873b664401342a026a943d482bfe

Or is there any other solution? I need the audio capture to be working for our
audio buffer of size 32768 with default gst-launch-1.0 pipelines. 

I am looking forward for a fix for this as at the moment audio capture from our
cards is broken for one of our customers.

Thanks for your help,
Przemek

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list