summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward@centricular.com>2021-04-22 08:57:23 +0200
committerTim-Philipp Müller <tim@centricular.com>2021-04-22 15:24:47 +0100
commit9155b21a552c2894561ebf11dc1bf5e42848c552 (patch)
tree6cd138ac1bd4b15a9e068f6d943a09d34cb56aad
parent8e1e45ab70ce8751fc85693b95dc2ac74d7e3d31 (diff)
downloadgstreamer-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.c35
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 (&timestamp, timestamp, priv->ts_offset))
+ timestamp = 0;
/* add the offset, this is used when buffering */
timestamp += priv->out_offset;