diff options
author | Edward Hervey <edward@centricular.com> | 2021-04-22 08:57:23 +0200 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2021-04-22 15:24:47 +0100 |
commit | 9155b21a552c2894561ebf11dc1bf5e42848c552 (patch) | |
tree | 6cd138ac1bd4b15a9e068f6d943a09d34cb56aad | |
parent | 8e1e45ab70ce8751fc85693b95dc2ac74d7e3d31 (diff) | |
download | gstreamer-plugins-good-9155b21a552c2894561ebf11dc1bf5e42848c552.tar.gz |
rtpjitterbuffer: Avoid generation of invalid timestamps
When updating timestamps and timer timeouts with a new offset, make sure that
the resulting value is valid (and not a negative (signed) value which ends up in
a massive (unsigned) value).
Fixes #571
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/963>
-rw-r--r-- | gst/rtpmanager/gstrtpjitterbuffer.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c index e7c284db3..5bd15b3f4 100644 --- a/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/gst/rtpmanager/gstrtpjitterbuffer.c @@ -2088,6 +2088,27 @@ get_pts_timeout (const RtpTimer * timer) return timer->timeout - timer->offset; } +static inline gboolean +safe_add (guint64 * res, guint64 val, gint64 offset) +{ + if (val <= G_MAXINT64) { + gint64 tmp = (gint64) val + offset; + if (tmp >= 0) { + *res = tmp; + return TRUE; + } + return FALSE; + } + /* From here, val > G_MAXINT64 */ + + /* Negative value */ + if (offset < 0 && val < -offset) + return FALSE; + + *res = val + offset; + return TRUE; +} + static void update_timer_offsets (GstRtpJitterBuffer * jitterbuffer) { @@ -2097,8 +2118,15 @@ update_timer_offsets (GstRtpJitterBuffer * jitterbuffer) while (test) { if (test->type != RTP_TIMER_EXPECTED) { - test->timeout = get_pts_timeout (test) + new_offset; - test->offset = new_offset; + GstClockTime pts = get_pts_timeout (test); + if (safe_add (&test->timeout, pts, new_offset)) { + test->offset = new_offset; + } else { + GST_DEBUG_OBJECT (jitterbuffer, + "Invalidating timeout (pts lower than new offset)"); + test->timeout = GST_CLOCK_TIME_NONE; + test->offset = 0; + } /* as we apply the offset on all timers, the order of timers won't * change and we can skip updating the timer queue */ } @@ -2146,7 +2174,8 @@ apply_offset (GstRtpJitterBuffer * jitterbuffer, GstClockTime timestamp) return -1; /* apply the timestamp offset, this is used for inter stream sync */ - timestamp += priv->ts_offset; + if (!safe_add (×tamp, timestamp, priv->ts_offset)) + timestamp = 0; /* add the offset, this is used when buffering */ timestamp += priv->out_offset; |