@@ -747,10 +747,10 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
spin_lock_irqsave(&clock->lock, flags);
- if (clock->count < clock->size)
+ if (clock->count < 2)
goto done;
- first = &clock->samples[clock->head];
+ first = &clock->samples[(clock->head - clock->count) % clock->size];
last = &clock->samples[(clock->head - 1) % clock->size];
/* First step, PTS to SOF conversion. */
@@ -765,6 +765,15 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
if (y2 < y1)
y2 += 2048 << 16;
+ /*
+ * Have at least 1/4 of a second of timestamps before we
+ * try to do any calculation. Otherwise we do not have enough
+ * precision. This value was determined by running Android CTS
+ * on different devices.
+ */
+ if ((y2 - y1) < (256 << 16))
+ goto done;
+
y = (u64)(y2 - y1) * (1ULL << 31) + (u64)y1 * (u64)x2
- (u64)y2 * (u64)x1;
y = div_u64(y, x2 - x1);