GNOME Bugzilla – Bug 541787
incorrect timestamp
Last modified: 2008-08-05 09:11:29 UTC
In RTP Speex Depayloader (possibly others as well) buffer timestamps are generated and not taken from RTP packets. In case of packet loss the timestamps are incorrect. Take for example such a command for sending speech data: $ gst-launch -v filesrc location=file.mp3 ! mad ! audioconvert ! audioresample ! capsfilter caps="audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, rate=(int)8000, channels=(int)1" ! speexenc quality=10 ! rtpspeexpay ! udpsink host=172.16.154.1 port=9011 and for receiving: $ gst-launch -v udpsrc port=9011 caps="application/x-rtp, clock-rate=(int)8000, encoding-name=(string)SPEEX" ! rtpspeexdepay ! speexdec ! fakesink For 10% packet loss and transmission that lasts 5,5 minutes on the receiving side the last timestamp is 5 minutes. This causes huge problems when I use alsasink instead of fakesink.
Created attachment 114070 [details] [review] Patch to take timestamp from RTP packet This patch calculates buffer timestamp from RTP packet. This is the first step to fix problems with transmission over RTP when network is not reliable.
Thanks, committed with a small change (use gst_util_uint64_scale) 2008-07-07 Sebastian Dröge <sebastian.droege@collabora.co.uk> Patch by: Tomasz Grobelny <tomasz at grobelny dot oswiecenia dot net> * gst/rtp/gstrtpspeexdepay.c: (gst_rtp_speex_depay_init), (gst_rtp_speex_depay_process): * gst/rtp/gstrtpspeexdepay.h: Take timestamp from the RTP packet as a first step to fix problems with transmission over RTP when the network is not reliable. Fixes bug #541787.
Please revert, this patch is wrong. Only the jitterbuffer is able to convert RTP timestamps to gstreamer timestamps. A normal depayloader or decoder always simply copies the incomming gstreamer timestamp to the output. See here for the documentation about how timestamps are handled in RTP: http://webcvs.freedesktop.org/gstreamer/gst-plugins-good/gst/rtp/README?revision=1.13&view=markup
Ok, reverted, sorry. So in theory a jitterbuffer added in the receiver pipeline should already fix everything?
It's likely fixed with the speexdec fixes that were done earlier: * ext/speex/gstspeexdec.c: (speex_dec_chain_parse_data), (speex_dec_chain): Try to preserve input timestamps when we can. Do beginnings of error concealment. A jitterbuffer smooths the timestamps, fixes packet reordering, detects packet loss and tries to match the rate of the sender but is not strictly needed to get some sort of playback on the receiver.
(In reply to comment #3) > Please revert, this patch is wrong. Only the jitterbuffer is able to convert > RTP timestamps to gstreamer timestamps. A normal depayloader or decoder always > simply copies the incomming gstreamer timestamp to the output. > > See here for the documentation about how timestamps are handled in RTP: > > http://webcvs.freedesktop.org/gstreamer/gst-plugins-good/gst/rtp/README?revision=1.13&view=markup > It was somehow suspicious that every depayloader would have to do the same thing over and over again. I tried using gstjitterbuffer and the results are not what I would expect: /pipeline0/fakesink0: last-message = "chain ******* < ( 110 bytes, timestamp: 0:00:04.022375993, duration: none, offset: -1, offset_end: -1, flags: 1) 0x8145a68" /pipeline0/fakesink0: last-message = "chain ******* < ( 110 bytes, timestamp: 0:00:04.062365698, duration: none, offset: -1, offset_end: -1, flags: 33) 0x8145ac0" /pipeline0/fakesink0: last-message = "chain ******* < ( 110 bytes, timestamp: 0:00:04.082355485, duration: none, offset: -1, offset_end: -1, flags: 1) 0x8145b18" The difference between timestamps should be exactly 20ms and not 19,98ms or the like. Is it by design or is it fixed in latest gstreamer version?
This is by design, the timestamps are reconstructed from the reception time and the estimated clock drift between sender and receiver. We are thinking of adding a capture mode to rtpbin so that it simply copies the RTP timestamps. This will not allow for playback at the receiver but it would allow for encoding the stream with timestamps as it was sent on the server.