[v2,8/8] media: uvcvideo: Fix hw timestampt handling for slow FPS
Commit Message
In UVC 1.5, when working with FPS under 32, there is a chance that the
circular buffer contains two dev_sof overflows, but the clock interpolator
is only capable of handle a single overflow.
Remove all the samples from the circular buffer that are two overflows
old.
Tested-by: HungNien Chen <hn.chen@sunplusit.com>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
@@ -471,6 +471,20 @@ static void uvc_video_clock_add_sample(struct uvc_clock *clock,
spin_lock_irqsave(&clock->lock, flags);
+ /* Delete last overflows */
+ if (clock->head == clock->last_sof_overflow)
+ clock->last_sof_overflow = -1;
+
+ /* Handle overflows */
+ if (clock->count > 0 && clock->last_sof > sample->dev_sof) {
+ /* Remove data from the last^2 overflows */
+ if (clock->last_sof_overflow != -1)
+ clock->count = (clock->head - clock->last_sof_overflow)
+ % clock->count;
+ clock->last_sof_overflow = clock->head;
+ }
+
+ /* Add sample */
memcpy(&clock->samples[clock->head], sample, sizeof(*sample));
clock->last_sof = sample->dev_sof;
clock->head = (clock->head + 1) % clock->size;
@@ -594,6 +608,7 @@ static void uvc_video_clock_reset(struct uvc_clock *clock)
clock->head = 0;
clock->count = 0;
clock->last_sof = -1;
+ clock->last_sof_overflow = -1;
clock->sof_offset = -1;
}
@@ -647,6 +647,7 @@ struct uvc_streaming {
unsigned int head;
unsigned int count;
unsigned int size;
+ unsigned int last_sof_overflow;
u16 last_sof;
u16 sof_offset;