alsasink: single segment audio glitch after 200ms at startup
@thaytan
Submitted by Jan Schmidt Link to original bug (#765115)
Description
with some audio sinks (alsasink), we can get a single segment glitch at startup after processing 200ms of data, because the GStreamer ringbuffer is sized exactly the same as the target hardware ringbuffer.
alsasink starts pushing samples to ALSA after the ringbuffer fills up / prerolls with 200ms (default buffer-size) of samples. At that point, it writes samples as quickly as possible to ALSA until the write() call to ALSA blocks.
What that means is we read and write 20 10ms segments very rapidly to the audio device, and then on the 21st write it will block for ~10ms
until the hardware plays 1 segment. What gets written in the 21st segment may be correct audio, if upstream was given a timeslice to write those samples, but commonly (especially on single core machines), alsasink gets to the 21st segment and it's not ready yet, so it generates a silence fragment and then blocks writing that out.
If upstream is then woken up, it will find that it is too late and drop that 1 segment.
The simple fix is to allocate 1 more segment in the GStreamer ringbuffer for upstream to write into, which uses slightly more memory but otherwise doesn't affect overall playback latency since the ringbuffer in the hardware is still configured with 20 segments.
Most audio sinks need that extra segment to avoid this glitch. I think pulsesink where we write directly to their ringbuffer is the only one that doesn't.
I propose we make the ringbuffer expand spec->segtotal += 1 in gst_audio_ring_buffer_parse_caps() when indicated by setting a flag using a new gst_audio_ring_buffer_enable_extra_segment () function (or so).