audiobasesrc: Skew slave method only skew in one direction
Submitted by Nicolas Dufresne
GstAudioBaseSrc implements a property called slave-method. The default for this is "skew". Similarly to audiobasesink, I believe this is supposed to skew uppon clock drift, regardless of the direction of the drift. Unlike audiobasesink, there is no drift-tolerance configuration.
There is multiple issues in this code, but the main issues right now is that it only handle drift in one situation, if downstream clock is faster.
The situation I came across, is that when downstream clock is slower, it will never skew, unless ring buffer becomes full. But as soon as you have a queue downstream (I do, because I have a tee), it will never reach that situation. Instead, the latency will start growing, and when all the queues are full, the skew code will never manage to recover, because it does not delay the clock, so when this state is reached, all the audio goes wrong forever.
On the other end, when the downstream clock is faster, it will skew when the ringbuffer reaches segtotal in term of skew duration (nearest value the driver / library have picked around buffer-time property value). This value can be quite big, in fact, on the TI Sitara I get a buffer-time that is 16 time the size of the latency time (20ms), so 320ms. So if downstream clock is faster, it takes several minutes before the skew situation is reached and audio buffer stops being late downstream. But at least it does skew, and does change the output of the associate audioclock. Though, the implementation is racy, as we now have two thread calling ring_buffer_advance at the same time. As a side, the next buffer is often not the one we just capture, but whatever was left there last time we used the segment. This skew method need to be reworked, hence why I think this second detail should be considered.
It's clear in my case that a skew with a tolerance of 320ms and more is not acceptable (I'm using this in a VoIP application).