Latency with AVTP plugin
nicolas at ndufresne.ca
Tue Nov 23 15:57:56 UTC 2021
Le lundi 22 novembre 2021 à 21:39 +0000, Ian Steele via gstreamer-devel a
> Hello, hopefully I'm in the right place for this issue.
> I 'm using the AVTP plugin to run audio between 2 Raspberry PI CM4 systems
> I've built to evaluate different audio streaming protocols. However I seem to
> have about 150-200mS latency which seems high.
> I'm setting up following these guidelines and everything is working ok.
> I'm playing audio from system A to its local i2s soundcard DAC (PCM5122)
> and at the same time sending via AVTP to System B and playing out the audio
> with the same type of audio card. No droputs, gPTP sync working well, no drift
> The 2networkcards ( intel i210) are connected directly to each other, no
> switch involved.
> I'm mixing the analog audio output from the 2 soundcards together so I can
> hear the latency.
> My playout pipeline (system A):
> gst-launch-1.0 clockselect. \( clock-id=realtime filesrc location=babylon.wav
> ! wavparse ! tee name=t ! queue max-size-buffers=0 max-size-time=0 !
> audioconvert ! audiobuffersplit output-buffer-duration=12/48000 !
> avtpaafpay mtt=50000000 tu=1000000 streamid=0xAABBCCDDEEFF000B processing-
> deadline=0 ! avtpsink ifname=eth0.5 address=01:AA:AA:AA:AA:AA priority=2
> processing-deadline=0 t. ! queue ! alsasink \)
1. processing-deadline is a BaseSink property, so shall be moved from avtpaafpay
to avtpsink element. This will reduce by 20ms you latency. Might introduce a bit
more jitter, but 20ms is ridiculously high for that use case.
2. You can remove the processing-deadline from alsasink.
3. For this use case, you likely want to reconfigured alsasink, here's some
AlsaSink is using GstAudioRingBuffer. This ring buffer is an adpter to
compensate the fact the GStreamer is not a real-time process. It will be
configured to buffer the HW audio data further, and keep writing as fast as
possible to try hard to avoid underrun. The ring buffer is configured with
segment which is hinted by the property period-size. This period might be
modified to a value the suite your driver. The size of the ring buffer will be
set to a multiple of that period and hinted by buffer-time. As the sink will
filling the entire ring-buffer before it starts, it introduce by itself buffer-
time of latency, but the GstAudioSink implement add 1 period to that to try and
avoid the clock phase miss-alignment with upstream.
Short story, the alsasink latency is buffer-time + latency-time. You cannot
achieve super low latency with GStreamer, but you can get decent telephony grade
latency. I would suggest using latency-time=10000, buffer-time=30000. That would
cost 40ms latency. This setting will depends on your CPU speed and system load
> My listen pipeline (system B)
> gst-launch-1.0 clockselect. \( clock-id=realtime \
> avtpsrc ifname=eth0.5 address=01:AA:AA:AA:AA:AA ! \
> queue max-size-buffers=0 max-size-time=0 ! \
> avtpaafdepay streamid=0xAABBCCDDEEFF000B ! audioconvert ! alsasink buffer-
> time=1 \)
buffer-time=1 is clearly not going to be respected by your driver. You can use
GST_DEBUG="alsa:7", on the very start of the trace, the element will dump the HW
> Is there any way to improve the latency?
p.s. realtime clock is also known as the wallclock. It is not guarantied to be
monotonic . If you want to use this one, make sure not to run a generic clock
synchronization program, and limit synchronisation to once at boot-time and
adjtime syscall for everything else. Also, disable daylight saving.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the gstreamer-devel