spin_lock_irqsave(&clock->lock, flags);
- if (clock->count > 0 && clock->last_sof > sample->dev_sof) {
+ if (clock->count > 0 && clock->last_sof_processed > sample->dev_sof) {
/*
* Remove data from the circular buffer that is older than the
* last SOF overflow. We only support one SOF overflow per
if (!has_scr)
return;
- sample.dev_sof = get_unaligned_le16(&data[header_size - 2]);
+ sample.dev_sof = get_unaligned_le16(&data[header_size - 2]) & 2047;
+ /* If the sample SOF is identical to the previous one, quit early. */
+ if (stream->clock.last_sof_raw == sample.dev_sof)
+ return;
+ stream->clock.last_sof_raw = sample.dev_sof;
+
sample.dev_stc = get_unaligned_le32(&data[header_size - 6]);
/*
* all the data packets of the same frame contains the same SOF. In that
* case only the first one will match the host_sof.
*/
- if (sof_diff(sample.dev_sof, stream->clock.last_sof) <=
+ if (sof_diff(sample.dev_sof, stream->clock.last_sof_processed) <=
(UVC_MIN_HW_TIMESTAMP_DIFF / stream->clock.size))
return;
uvc_video_clock_add_sample(&stream->clock, &sample);
- stream->clock.last_sof = sample.dev_sof;
+ stream->clock.last_sof_processed = sample.dev_sof;
}
static void uvc_video_clock_reset(struct uvc_clock *clock)
{
clock->head = 0;
clock->count = 0;
- clock->last_sof = -1;
+ clock->last_sof_processed = -1;
+ clock->last_sof_raw = -1;
clock->last_sof_overflow = -1;
clock->sof_offset = -1;
}