[PATCH v2 2/5] media: uvcvideo: Use hw timestaming if the clock buffer is full
From: Ricardo Ribalda
Date: Tue May 12 2026 - 08:35:53 EST
In some situations, even with a full clock buffer, it does not contain
250msec of data. This results in the driver jumping back from software
to hardware timestapsing creating a nasty artifact in the video.
If the clock buffer is full, use it to calculate the timestamp instead
of defaulting to software stamps, the reduced accuracy is less visible
than jumping from one timestamping mechanism to the other.
Fixes: 6243c83be6ee8 ("media: uvcvideo: Allow hw clock updates with buffers not full")
Cc: stable@xxxxxxxxxxxxxxx
Reviewed-by: Hans de Goede <johannes.goede@xxxxxxxxxxxxxxxx>
Tested-by: Yunke Cao <yunkec@xxxxxxxxxx>
Signed-off-by: Ricardo Ribalda <ribalda@xxxxxxxxxxxx>
---
drivers/media/usb/uvc/uvc_video.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index cbf67c17a49a..19a2880e0dc9 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -834,15 +834,22 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
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 the buffer is not full, we want to gather at least 1/4th of
+ * timestamps before using HW timestamping. We do this to avoid jitter
+ * on the initial frames.
+ *
+ * If the buffer is full we would use it regardless of how much data
+ * it represents. This could be solved with an infinite big circular
+ * buffer, but RAM is expensive these days, specially the infinitely
+ * big.
+ *
+ * The value of 1/4th of a second was determined by running Android's
+ * CTS on different devices.
*
* dev_sof runs at 1KHz, and we have a fixed point precision of
* 16 bits.
*/
- if ((y2 - y1) < ((1000 / 4) << 16))
+ if (clock->size != clock->count && (y2 - y1) < ((1000 / 4) << 16))
goto done;
y = (u64)(y2 - y1) * (1ULL << 31) + (u64)y1 * (u64)x2
--
2.54.0.563.g4f69b47b94-goog