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)
{
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 */
}
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;