Download raw body.
sys/uvideo: treat frame as done when mmap queue is overflowed
sys/uvideo: treat frame as done when mmap queue is overflowed
On Mon, Feb 24, 2025 at 02:09:01PM GMT, Kirill A. Korinsky wrote:
> tech@,
>
> when a completed frame cannot be added to the mmap queue due to
> overflow, we do not reset the sample, FID, or error flags. Instead, we
> discard subsequent frames and samples until the stream flips the FID
> bit.
>
> Here is a diff that prevents this behavior.
>
> Ok?
ok mglocker@
PS:
I've noticed that the for loop in uvideo_vs_cb() is checking
sc->sc_decode_stream_header() for an USBD_CANCELLED return code, but
sc->sc_decode_stream_header() is never returning that. Probably we
should better check for 'error != USBD_NORMAL_COMPLETION' to break
the for loop, and then always reset the frame buffers sample, fid, and
error flags to zero in sc->sc_decode_stream_header() return error case.
I can come up with a diff for that later.
> Index: sys/dev/usb/uvideo.c
> ===================================================================
> RCS file: /home/cvs/src/sys/dev/usb/uvideo.c,v
> diff -u -p -r1.240 uvideo.c
> --- sys/dev/usb/uvideo.c 23 Feb 2025 14:12:15 -0000 1.240
> +++ sys/dev/usb/uvideo.c 24 Feb 2025 00:09:13 -0000
> @@ -2244,6 +2244,7 @@ uvideo_vs_decode_stream_header(struct uv
> struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
> struct usb_video_stream_header *sh;
> int sample_len;
> + usbd_status ret = USBD_NORMAL_COMPLETION;
>
> if (frame_size < UVIDEO_SH_MIN_LEN)
> /* frame too small to contain a valid stream header */
> @@ -2327,7 +2328,7 @@ uvideo_vs_decode_stream_header(struct uv
> /* mmap */
> if (uvideo_mmap_queue(sc, fb->buf, fb->offset,
> fb->error))
> - return (USBD_NOMEM);
> + ret = USBD_NOMEM;
> } else if (fb->error) {
> DPRINTF(1, "%s: %s: error frame, skipped!\n",
> DEVNAME(sc), __func__);
> @@ -2341,7 +2342,7 @@ uvideo_vs_decode_stream_header(struct uv
> fb->error = 0;
> }
>
> - return (USBD_NORMAL_COMPLETION);
> + return (ret);
> }
>
> /*
> @@ -2366,6 +2367,7 @@ uvideo_vs_decode_stream_header_isight(st
> {
> struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
> int sample_len, header = 0;
> + usbd_status ret = USBD_NORMAL_COMPLETION;
> uint8_t magic[] = {
> 0x11, 0x22, 0x33, 0x44,
> 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce };
> @@ -2384,7 +2386,7 @@ uvideo_vs_decode_stream_header_isight(st
> if (sc->sc_mmap_flag) {
> /* mmap */
> if (uvideo_mmap_queue(sc, fb->buf, fb->offset, 0))
> - return (USBD_NOMEM);
> + ret = USBD_NOMEM;
> } else {
> /* read */
> uvideo_read(sc, fb->buf, fb->offset);
> @@ -2399,7 +2401,7 @@ uvideo_vs_decode_stream_header_isight(st
> }
> }
>
> - return (USBD_NORMAL_COMPLETION);
> + return (ret);
> }
>
> int
> @@ -2416,7 +2418,7 @@ uvideo_mmap_queue(struct uvideo_softc *s
> break;
> }
> if (i == sc->sc_mmap_count) {
> - DPRINTF(1, "%s: %s: mmap queue is full!",
> + DPRINTF(1, "%s: %s: mmap queue is full!\n",
> DEVNAME(sc), __func__);
> return ENOMEM;
> }
>
sys/uvideo: treat frame as done when mmap queue is overflowed
sys/uvideo: treat frame as done when mmap queue is overflowed