From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Ricardo Ribalda <ribalda@chromium.org>,
stable@kernel.org, Hans de Goede <hansg@kernel.org>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
Hans de Goede <johannes.goede@oss.qualcomm.com>,
Hans Verkuil <hverkuil+cisco@kernel.org>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.1.y 7/7] media: uvcvideo: Fix sequence number when no EOF
Date: Wed, 22 Jul 2026 09:54:57 -0400 [thread overview]
Message-ID: <20260722135457.1366301-7-sashal@kernel.org> (raw)
In-Reply-To: <20260722135457.1366301-1-sashal@kernel.org>
From: Ricardo Ribalda <ribalda@chromium.org>
[ Upstream commit f078966ca1fb1b3865d8e6bbe2705cfd277fc637 ]
If the driver could not detect the EOF, the sequence number is increased
twice:
1) When we enter uvc_video_decode_start() with the old buffer and FID has
flipped => We return -EAGAIN and last_fid is not flipped
2) When we enter uvc_video_decode_start() with the new buffer.
Fix this issue by moving the new frame detection logic earlier in
uvc_video_decode_start().
This also has some nice side affects:
- The error status from the new packet will no longer get propagated
to the previous frame-buffer.
- uvc_video_clock_decode() will no longer update the previous frame
buf->stf with info from the new packet.
- uvc_video_clock_decode() and uvc_video_stats_decode() will no longer
get called twice for the same packet.
Cc: stable@kernel.org
Fixes: 650b95feee35 ("[media] uvcvideo: Generate discontinuous sequence numbers when frames are lost")
Reported-by: Hans de Goede <hansg@kernel.org>
Closes: https://lore.kernel.org/linux-media/CANiDSCuj4cPuB5_v2xyvAagA5FjoN8V5scXiFFOeD3aKDMqkCg@mail.gmail.com/T/#me39fb134e8c2c085567a31548c3403eb639625e4
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/usb/uvc/uvc_video.c | 92 ++++++++++++++++---------------
1 file changed, 47 insertions(+), 45 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 1a92cbe728ce87..3a056738c04e6e 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1116,6 +1116,53 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
header_len = data[0];
fid = data[1] & UVC_STREAM_FID;
+ /*
+ * Mark the buffer as done if we're at the beginning of a new frame.
+ * End of frame detection is better implemented by checking the EOF
+ * bit (FID bit toggling is delayed by one frame compared to the EOF
+ * bit), but some devices don't set the bit at end of frame (and the
+ * last payload can be lost anyway). We thus must check if the FID has
+ * been toggled.
+ *
+ * stream->last_fid is initialized to -1, and buf->bytesused to 0,
+ * so the first isochronous frame will never trigger an end of frame
+ * detection.
+ *
+ * Empty buffers (bytesused == 0) don't trigger end of frame detection
+ * as it doesn't make sense to return an empty buffer. This also
+ * avoids detecting end of frame conditions at FID toggling if the
+ * previous payload had the EOF bit set.
+ */
+ if (fid != stream->last_fid && buf && buf->bytesused != 0) {
+ uvc_dbg(stream->dev, FRAME,
+ "Frame complete (FID bit toggled)\n");
+ buf->state = UVC_BUF_STATE_READY;
+
+ return -EAGAIN;
+ }
+
+ /*
+ * Some cameras, when running two parallel streams (one MJPEG alongside
+ * another non-MJPEG stream), are known to lose the EOF packet for a frame.
+ * We can detect the end of a frame by checking for a new SOI marker, as
+ * the SOI always lies on the packet boundary between two frames for
+ * these devices.
+ */
+ if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
+ (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
+ stream->cur_format->fcc == V4L2_PIX_FMT_JPEG) &&
+ buf && buf->bytesused != 0) {
+ const u8 *packet = data + header_len;
+
+ if (len >= header_len + 2 &&
+ packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI) {
+ buf->state = UVC_BUF_STATE_READY;
+ buf->error = 1;
+ stream->last_fid ^= UVC_STREAM_FID;
+ return -EAGAIN;
+ }
+ }
+
/*
* Increase the sequence number regardless of any buffer states, so
* that discontinuous sequence numbers always indicate lost frames.
@@ -1172,51 +1219,6 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
buf->state = UVC_BUF_STATE_ACTIVE;
}
- /*
- * Mark the buffer as done if we're at the beginning of a new frame.
- * End of frame detection is better implemented by checking the EOF
- * bit (FID bit toggling is delayed by one frame compared to the EOF
- * bit), but some devices don't set the bit at end of frame (and the
- * last payload can be lost anyway). We thus must check if the FID has
- * been toggled.
- *
- * stream->last_fid is initialized to -1, so the first isochronous
- * frame will never trigger an end of frame detection.
- *
- * Empty buffers (bytesused == 0) don't trigger end of frame detection
- * as it doesn't make sense to return an empty buffer. This also
- * avoids detecting end of frame conditions at FID toggling if the
- * previous payload had the EOF bit set.
- */
- if (fid != stream->last_fid && buf->bytesused != 0) {
- uvc_dbg(stream->dev, FRAME,
- "Frame complete (FID bit toggled)\n");
- buf->state = UVC_BUF_STATE_READY;
- return -EAGAIN;
- }
-
- /*
- * Some cameras, when running two parallel streams (one MJPEG alongside
- * another non-MJPEG stream), are known to lose the EOF packet for a frame.
- * We can detect the end of a frame by checking for a new SOI marker, as
- * the SOI always lies on the packet boundary between two frames for
- * these devices.
- */
- if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF &&
- (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG ||
- stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) {
- const u8 *packet = data + header_len;
-
- if (len >= header_len + 2 &&
- packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI &&
- buf->bytesused != 0) {
- buf->state = UVC_BUF_STATE_READY;
- buf->error = 1;
- stream->last_fid ^= UVC_STREAM_FID;
- return -EAGAIN;
- }
- }
-
stream->last_fid = fid;
return header_len;
--
2.53.0
next prev parent reply other threads:[~2026-07-22 13:55 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 9:51 FAILED: patch "[PATCH] media: uvcvideo: Fix sequence number when no EOF" failed to apply to 6.1-stable tree gregkh
2026-07-22 13:54 ` [PATCH 6.1.y 1/7] media: Add common header file with JPEG marker definitions Sasha Levin
2026-07-22 13:54 ` [PATCH 6.1.y 2/7] media: uvcvideo: Fix power line control for SunplusIT camera Sasha Levin
2026-07-22 13:54 ` [PATCH 6.1.y 3/7] media: uvcvideo: Add quirk for Logitech Rally Bar Sasha Levin
2026-07-22 13:54 ` [PATCH 6.1.y 4/7] media: uvcvideo: Disable autosuspend for Insta360 Link Sasha Levin
2026-07-22 13:54 ` [PATCH 6.1.y 5/7] media: uvcvideo: Quirk for invalid dev_sof in Logitech C922 Sasha Levin
2026-07-22 13:54 ` [PATCH 6.1.y 6/7] media: uvcvideo: Implement dual stream quirk to fix loss of usb packets Sasha Levin
2026-07-22 13:54 ` Sasha Levin [this message]
2026-07-31 10:52 ` [PATCH 6.1.y 1/2] " Ricardo Ribalda
2026-07-31 10:52 ` [PATCH 6.1.y 2/2] media: uvcvideo: Fix sequence number when no EOF Ricardo Ribalda
2026-08-01 1:40 ` [PATCH 6.1.y 1/2] media: uvcvideo: Implement dual stream quirk to fix loss of usb packets Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260722135457.1366301-7-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=hansg@kernel.org \
--cc=hverkuil+cisco@kernel.org \
--cc=johannes.goede@oss.qualcomm.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=ribalda@chromium.org \
--cc=stable@kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox