On Wed May 13 11:49:24 2026 +0000, Ricardo Ribalda wrote:
> We only save relevant samples into the circular buffer. If the data is
> very similar to the previous one, exit early, this allows us to avoid
> some expensive operations such as usb_get_current_frame_number().
>
> Suggested-by: Laurent Pinchart <[email protected]>
> Signed-off-by: Ricardo Ribalda <[email protected]>
> Tested-by: Yunke Cao <[email protected]>
> Reviewed-by: Hans de Goede <[email protected]>
> Link:
> https://patch.msgid.link/[email protected]
> Signed-off-by: Hans de Goede <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
drivers/media/usb/uvc/uvc_video.c | 16 +++++++++++-----
drivers/media/usb/uvc/uvcvideo.h | 3 ++-
2 files changed, 13 insertions(+), 6 deletions(-)
---
diff --git a/drivers/media/usb/uvc/uvc_video.c
b/drivers/media/usb/uvc/uvc_video.c
index 09d6baf87ec5..c104ffe3b3c1 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -524,7 +524,7 @@ static void uvc_video_clock_add_sample(struct uvc_clock
*clock,
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
@@ -599,7 +599,12 @@ uvc_video_clock_decode(struct uvc_streaming *stream,
struct uvc_buffer *buf,
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]);
/*
@@ -678,19 +683,20 @@ uvc_video_clock_decode(struct uvc_streaming *stream,
struct uvc_buffer *buf,
* 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;
}
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 4ba35727e954..b6bcee4a222f 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -522,7 +522,8 @@ struct uvc_streaming {
unsigned int size;
unsigned int last_sof_overflow;
- u16 last_sof;
+ u16 last_sof_processed;
+ u16 last_sof_raw;
u16 sof_offset;
u8 last_scr[6];
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]