audio chopped after running for several hours
Paixao Julien
J.Paixao at TELEVIC.com
Fri Feb 5 08:51:55 UTC 2016
Hi,
Let's start with a small summary of the situation.
I have two IP devices:
- Device#1 streams audio from its audio input
- Device#2 plays the stream on its audio output
The goal is to never exceed a latency higher than 150ms and of course avoid dropping of audio.
The stream is an RTP stream containing L16 mono audio at 16kHz.
The two IP devices are running an ntp daemon and are synchronized over an ntp server.
Here are the pipeline used:
Device#1:
- gst-launch-1.0 -vv alsasrc device=hw:0 latency-time=16000 buffer-time=32000 ! audio/x-raw, format=S16LE, layout=interleaved, rate=16000, channels=1 ! audioconvert dithering=0 ! audio/x-raw, format=S16BE, rate=16000, channels=1 ! rtpL16pay ! udpsink max-lateness=100000000 host=10.20.1.39 port=5004
Device#2:
- gst-launch-1.0 -vv udpsrc buffer-size=1024 port=5004 caps='application/x-rtp, media=(string)audio, clock-rate=(int)16000, encoding-name=(string)L16, encoding-params=(string)1, channels=(int)1, payload=(int)96' ! rtpjitterbuffer latency=32 ! rtpL16depay ! audioconvert dithering=0 ! audio/x-raw, format=S16LE, rate=16000, channels=1 ! alsasink max-lateness=100000000 latency-time=16000 buffer-time=32000
By setting correctly the buffer sizes on the sending and receiving pipeline, the latency is now under control.
But like it has been mentioned in this thread, between the two different IP devices the clock will drift.
By debugging the pipelines I could see that:
- pipeline from device#1 is using the clock provided by the alsasrc.
- pipeline from device#2 is using the clock provided by the system.
At some point it's possible that the clock of pipeline#2 will run slightly faster than the one on pipeline#1.
What will happen is that the udpsrc element will start to buffer the packets coming in (in fact it's done on kernel level) since they are not consumed fast enough by the upper layer (GStreamer).
And if the kernel buffer for udpsrc is full then packets will start to be dropped by the kernel.
I tried to run pipeline#1 on the system clock but then the pipeline is not well working anymore, too much drop on the sending side already.
Do you have any suggestions in order that device#2 re-synchronize correctly, I thought about using RTCP, but is it well supported in GStreamer? (see http://lists.freedesktop.org/archives/gstreamer-devel/2016-February/056516.html)
Is it the only solution?
At some point, Device#2 must be able to say that a RTP packet coming from the udpsrc is too old and discards it... This will allow to empty the kernel buffer used for udpsrc, and avoid continues packet drop and get the latency going down...
I am sure I am not the first one trying to build such an application using GStreamer and facing the same issues.
Is there any valuable knowledge base where people who have used GStreamer to build a certain application can input their experience, information?
If not, what do you think about the idea of creating such a knowledge base?
Best regards,
Julien.
More information about the gstreamer-devel
mailing list