After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 593354 - rtpjitterbuffer sometimes outputs packets with timestamps in the past
rtpjitterbuffer sometimes outputs packets with timestamps in the past
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
git master
Other Linux
: Normal normal
: 0.10.18
Assigned To: GStreamer Maintainers
GStreamer Maintainers
: 602231 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2009-08-28 03:09 UTC by Olivier Crête
Modified: 2009-11-18 10:03 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Test program (1.49 KB, text/plain)
2009-08-28 03:09 UTC, Olivier Crête
  Details
rtpjitterbuffer: Reset computation if result is in the past (5.14 KB, patch)
2009-08-28 03:09 UTC, Olivier Crête
none Details | Review
rtpjitterbuffer: Reset computation if result is in the past (5.14 KB, patch)
2009-08-28 03:11 UTC, Olivier Crête
none Details | Review
Release/take lock before/after call to gst_rtp_jitter_buffer_get_clock_rate (617 bytes, patch)
2009-11-11 13:15 UTC, Patrick Radizi
none Details | Review
improved patch (2.63 KB, patch)
2009-11-11 14:54 UTC, Wim Taymans
accepted-commit_after_freeze Details | Review

Description Olivier Crête 2009-08-28 03:09:11 UTC
Created attachment 141909 [details]
Test program

Under the right conditions, the jitterbuffer can output packets that have
timestamps in the past. I guess the solution is to reset the jb's state if that
happens. I'm not sure how to properly do that without having to query the clock
on every buffer. Attaching a patch that tries to do that.. but there must be a
smarter solution.

One case I can see is if the skew ends up being so much that its more than the
length of the jb. It also happens if for some reason the rtp and gst timestamps
get desynchronized (like if the other sides does a "hold" in a voip call and
just stops its clock entirely while on hold).
Comment 1 Olivier Crête 2009-08-28 03:09:57 UTC
Created attachment 141910 [details] [review]
rtpjitterbuffer: Reset computation if result is in the past

If the jitterbuffer's computation would result in a timestamp that is
in the past, then reset it. It means that either there was too much
skew or that the sender did something wrong.
Comment 2 Olivier Crête 2009-08-28 03:11:03 UTC
Created attachment 141911 [details] [review]
rtpjitterbuffer: Reset computation if result is in the past

If the jitterbuffer's computation would result in a timestamp that is
in the past, then reset it. It means that either there was too much
skew or that the sender did something wrong.
Comment 3 Wim Taymans 2009-08-31 10:50:13 UTC
The test did not cause any problems for me. I commited this patch that I had laying around and fixed something related.

commit e254936e3417d283c72b49496c927fb5a8248e4b
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Mon Aug 31 12:47:15 2009 +0200

    jitterbuffer: make sure time never goes invalid
    
    Since the skew can be negative, we might end up with invalid timestamps. Check
    for negative results and clamp to 0.
    
    See #593354
Comment 4 Wim Taymans 2009-08-31 11:00:24 UTC
Another patch I had to improve robustness:

commit 4814d899c27df764e2e9ad15a0765235d59abc22
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Mon Aug 31 12:57:32 2009 +0200

    jitterbuffer: reset skew when timestamps change
    
    Refactor the jitterbuffer resync code.
    Reset the skew correction when we detect a big timestamp discont.
    
    See #593354
Comment 5 Wim Taymans 2009-08-31 11:29:34 UTC
The case with this testcase is that the client thresholds are not exceeded and thus the client thinks that packets were just 0.5 seconds queued on the network somewhere. It then tries its best to still play those packets and eventually caches up when the skew correction figures it out.

During the period where the skew algorithm has to adapt, we produce timestamps that are past the time of the clock (and will thus be late depending on the downstream latency)

I don't know exactly what to do here. Your patch checks against the current clock time but that might be suboptimal as it is not known how much downstream latency there is.
Comment 6 Olivier Crête 2009-08-31 16:10:49 UTC
Do we really care about downstream latency ? If the downstream elements add latency, they will probably delay the packets too. I guess the jb should assume that there is a sink with 0 latency afterwards (and hence that only upstream latency matters).

That said, I have no idea what the right solution is. But it should probably cap the correction to make sure that if the packets are received in line, they should go out on time..
Comment 7 Wim Taymans 2009-09-01 09:28:08 UTC
If the output timestamp (after skew correction and latency adjustment) is less than the incomming timestamp, we have a problem. I'm going to try to implement this.
Comment 8 Wim Taymans 2009-09-01 10:52:10 UTC
This one pretty much fixes it.

commit 8d924611e74ba8b6c36fe24db5b3648850751bf7
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Tue Sep 1 12:41:36 2009 +0200

    jitterbuffer: make sure time does not go backwards
    
    When we construct a timestamp that would result in a timestamp that is earlier
    than when the packet was received, reset the skew calculation as this is
    probably a sign that the sender restarted or paused.
    
    Fixes #593354
Comment 9 Patrick Radizi 2009-11-11 11:07:38 UTC
After applying the patch by Wim from Comment 8 I have started to get dead locks. 

The following happens:

- Thread 1 sets rtspsrc to PLAYING. As a result of this it hangs trying to take a gstrtpjitterbuffer lock in gst_rtp_jitter_buffer_clear_pt_map() called from gst_rtp_bin_clear_pt_map() where it also takes a gstrtpsession lock

Thread 1 hangs because thread 2 has already taken the gstrtpjitterbuffer lock in gst_rtp_jitter_buffer_chain(). But then thread 1 hangs trying to take the gstrtpsession lock held by thread 1 when it calls gst_rtp_jitter_buffer_get_clock_rate()->get_pt_map() 

I'm not sure what the best solution is but perhaps it would be ok to release the lock taken in gst_rtp_jitter_buffer_chain before calling gst_rtp_jitter_buffer_get_clock_rate() and taking it again afterwards?
Comment 10 Patrick Radizi 2009-11-11 13:15:18 UTC
Created attachment 147472 [details] [review]
Release/take lock before/after call to gst_rtp_jitter_buffer_get_clock_rate
Comment 11 Wim Taymans 2009-11-11 14:54:22 UTC
Created attachment 147479 [details] [review]
improved patch

Improved patch. We should call get_clock_rate with the lock so we must release the lock right before the signal emission.
Comment 12 Wim Taymans 2009-11-18 10:01:54 UTC
*** Bug 602231 has been marked as a duplicate of this bug. ***
Comment 13 Wim Taymans 2009-11-18 10:03:39 UTC
commit f52859432f780d3540002f25a6412ae34c231ef3
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Wed Nov 11 15:50:19 2009 +0100

    jitterbuffer: release lock before emiting signals
    
    Release the jbuf lock before emiting the request-pt-map signal to avoid
    deadlocks. We also need to catch the shutdown case when locking again.
    
    Fixes #593354