On Wed, Mar 12, 2025 at 11:30:03AM GMT, Marcus Glocker wrote:

> On Wed, Mar 12, 2025 at 10:24:04AM GMT, Landry Breuil wrote:
> 
> > Le Wed, Mar 12, 2025 at 10:05:30AM +0100, Landry Breuil a ?crit :
> > > hi,
> > > 
> > > updated my t470s from '#564: Tue Feb 25 21:20:18 MST 2025' to '#591: Tue
> > > Mar 11 20:48:18 MDT 2025' and my webcam now shows weird 'stripes' on top
> > > of the image (that works).
> > 
> > the 'weird stripes' only show up from some webrtc clients (ive noticed
> > it with jitsi in firefox 137.0b4), using video(1) i havent been able to
> > replicate (yet)..
> > 
> > no issue in https://mozilla.github.io/webrtc-landing/gum_test.html so
> > might be the way jitsi queries the video device.
> > 
> > Landry
> 
> I have the same cam in my X1 Carbon.  I can't reproduce the issue on
> video(1) either, because it's using YUYV422 as the default input format.
> When using ffplay with MJPEG as input format, I can reproduce the issue.
> 
> I'll try to figure out which of the recent commits has introduced the
> regression.

The issue was introduced by:

***

Revision 1.247 / (download) - annotate - [select for diffs], Sat Mar 1 12:30:19 
2025 UTC (11 days ago) by mglocker
Branch: MAIN
Changes since 1.246: +55 -32 lines
Diff to previous 1.246 (colored)

Copy frames directly in to the mmap'ed buffer.  This saves us one bcopy()
down the frame queuing path.

Original idea and diff from kirill@, with some modifications.

ok kirill@

***

Unfortunately, I couldn't figure out yet what the issue is with this
commit.  Hence, following the back out diff for uvideo.c 1.247.  It
fixes the issue for me.  What about you?


Index: sys/dev/usb/uvideo.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uvideo.c,v
diff -u -p -u -p -r1.251 uvideo.c
--- sys/dev/usb/uvideo.c        10 Mar 2025 07:38:12 -0000      1.251
+++ sys/dev/usb/uvideo.c        12 Mar 2025 12:39:01 -0000
@@ -66,7 +66,6 @@ struct uvideo_softc {
        struct uvideo_frame_buffer               sc_frame_buffer;
 
        struct uvideo_mmap                       sc_mmap[UVIDEO_MAX_BUFFERS];
-       struct uvideo_mmap                      *sc_mmap_cur;
        uint8_t                                 *sc_mmap_buffer;
        size_t                                   sc_mmap_buffer_size;
        q_mmap                                   sc_mmap_q;
@@ -104,7 +103,7 @@ struct uvideo_softc {
        const struct uvideo_devs                *sc_quirk;
        void                                    (*sc_decode_stream_header)
                                                    (struct uvideo_softc *,
-                                                   uint8_t *, int, uint8_t *);
+                                                   uint8_t *, int);
 };
 
 int            uvideo_open(void *, int, int *, uint8_t *, void (*)(void *),
@@ -170,11 +169,10 @@ void              uvideo_vs_start_isoc_ixfer(struct 
 void           uvideo_vs_cb(struct usbd_xfer *, void *,
                    usbd_status);
 void           uvideo_vs_decode_stream_header(struct uvideo_softc *,
-                   uint8_t *, int, uint8_t *); 
+                   uint8_t *, int);
 void           uvideo_vs_decode_stream_header_isight(struct uvideo_softc *,
-                   uint8_t *, int, uint8_t *);
-uint8_t                *uvideo_mmap_getbuf(struct uvideo_softc *);
-void           uvideo_mmap_queue(struct uvideo_softc *, int, int);
+                   uint8_t *, int);
+void           uvideo_mmap_queue(struct uvideo_softc *, uint8_t *, int, int);
 void           uvideo_read(struct uvideo_softc *, uint8_t *, int);
 usbd_status    uvideo_usb_control(struct uvideo_softc *, uint8_t, uint8_t,
                    uint16_t, uint8_t *, size_t);
@@ -2232,7 +2230,6 @@ uvideo_vs_start_bulk_thread(void *arg)
        struct uvideo_softc *sc = arg;
        usbd_status error;
        int size;
-       uint8_t *buf;
 
        usbd_ref_incr(sc->sc_udev);
        while (sc->sc_vs_cur->bulk_running) {
@@ -2259,14 +2256,7 @@ uvideo_vs_start_bulk_thread(void *arg)
 
                DPRINTF(2, "%s: *** buffer len = %d\n", DEVNAME(sc), size);
 
-               if (sc->sc_mmap_flag) {
-                       if ((buf = uvideo_mmap_getbuf(sc)) == NULL)
-                               continue;
-               } else
-                       buf = sc->sc_frame_buffer.buf;
-
-               sc->sc_decode_stream_header(sc, sc->sc_vs_cur->bxfer.buf, size,
-                   buf);
+               sc->sc_decode_stream_header(sc, sc->sc_vs_cur->bxfer.buf, size);
        }
        usbd_ref_decr(sc->sc_udev);
 
@@ -2320,7 +2310,7 @@ uvideo_vs_cb(struct usbd_xfer *xfer, voi
        struct uvideo_isoc_xfer *ixfer = priv;
        struct uvideo_softc *sc = ixfer->sc;
        int len, i, frame_size;
-       uint8_t *frame, *buf;
+       uint8_t *frame;
 
        DPRINTF(2, "%s: %s\n", DEVNAME(sc), __func__);
 
@@ -2335,12 +2325,6 @@ uvideo_vs_cb(struct usbd_xfer *xfer, voi
        if (len == 0)
                goto skip;
 
-       if (sc->sc_mmap_flag) {
-               if ((buf = uvideo_mmap_getbuf(sc)) == NULL)
-                       goto skip;
-       } else
-               buf = sc->sc_frame_buffer.buf;
-
        for (i = 0; i < sc->sc_nframes; i++) {
                frame = ixfer->buf + (i * sc->sc_vs_cur->psize);
                frame_size = ixfer->size[i];
@@ -2349,7 +2333,7 @@ uvideo_vs_cb(struct usbd_xfer *xfer, voi
                        /* frame is empty */
                        continue;
 
-               sc->sc_decode_stream_header(sc, frame, frame_size, buf);
+               sc->sc_decode_stream_header(sc, frame, frame_size);
        }
 
 skip:  /* setup new transfer */
@@ -2358,7 +2342,7 @@ skip:     /* setup new transfer */
 
 void
 uvideo_vs_decode_stream_header(struct uvideo_softc *sc, uint8_t *frame,
-    int frame_size, uint8_t *buf)
+    int frame_size)
 {
        struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
        struct usb_video_stream_header *sh;
@@ -2421,7 +2405,7 @@ uvideo_vs_decode_stream_header(struct uv
                fb->error = 1;
        }
        if (sample_len > 0) {
-               bcopy(frame + sh->bLength, buf + fb->offset, sample_len);
+               bcopy(frame + sh->bLength, fb->buf + fb->offset, sample_len);
                fb->offset += sample_len;
        }
 
@@ -2444,7 +2428,7 @@ uvideo_vs_decode_stream_header(struct uv
 #endif
                if (sc->sc_mmap_flag) {
                        /* mmap */
-                       uvideo_mmap_queue(sc, fb->offset, fb->error);
+                       uvideo_mmap_queue(sc, fb->buf, fb->offset, fb->error);
                } else if (fb->error) {
                        DPRINTF(1, "%s: %s: error frame, skipped!\n",
                            DEVNAME(sc), __func__);
@@ -2477,7 +2461,7 @@ uvideo_vs_decode_stream_header(struct uv
  */
 void
 uvideo_vs_decode_stream_header_isight(struct uvideo_softc *sc, uint8_t *frame,
-    int frame_size, uint8_t *buf)
+    int frame_size)
 {
        struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
        int sample_len, header = 0;
@@ -2498,7 +2482,7 @@ uvideo_vs_decode_stream_header_isight(st
        if (header) {
                if (sc->sc_mmap_flag) {
                        /* mmap */
-                       uvideo_mmap_queue(sc, fb->offset, 0);
+                       uvideo_mmap_queue(sc, fb->buf, fb->offset, 0);
                } else {
                        /* read */
                        uvideo_read(sc, fb->buf, fb->offset);
@@ -2508,14 +2492,14 @@ uvideo_vs_decode_stream_header_isight(st
                /* save sample */
                sample_len = frame_size;
                if ((fb->offset + sample_len) <= fb->buf_size) {
-                       bcopy(frame, buf + fb->offset, sample_len);
+                       bcopy(frame, fb->buf + fb->offset, sample_len);
                        fb->offset += sample_len;
                }
        }
 }
 
-uint8_t *
-uvideo_mmap_getbuf(struct uvideo_softc *sc)
+void
+uvideo_mmap_queue(struct uvideo_softc *sc, uint8_t *buf, int len, int err)
 {
        int i;
 
@@ -2530,38 +2514,32 @@ uvideo_mmap_getbuf(struct uvideo_softc *
        if (i == sc->sc_mmap_count) {
                DPRINTF(1, "%s: %s: mmap queue is full!\n",
                    DEVNAME(sc), __func__);
-               return NULL;
+               return;
        }
 
-       sc->sc_mmap_cur = &sc->sc_mmap[i];
-
-       return sc->sc_mmap_cur->buf;
-}
-
-void
-uvideo_mmap_queue(struct uvideo_softc *sc, int len, int err)
-{
        /* copy frame to mmap buffer and report length */
-       sc->sc_mmap_cur->v4l2_buf.bytesused = len;
+       bcopy(buf, sc->sc_mmap[i].buf, len);
+       sc->sc_mmap[i].v4l2_buf.bytesused = len;
 
        /* timestamp it */
-       getmicrouptime(&sc->sc_mmap_cur->v4l2_buf.timestamp);
-       sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMESTAMP_MASK;
-       sc->sc_mmap_cur->v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-       sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
-       sc->sc_mmap_cur->v4l2_buf.flags |= V4L2_BUF_FLAG_TSTAMP_SRC_EOF;
-       sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMECODE;
+       getmicrouptime(&sc->sc_mmap[i].v4l2_buf.timestamp);
+       sc->sc_mmap[i].v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMESTAMP_MASK;
+       sc->sc_mmap[i].v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       sc->sc_mmap[i].v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
+       sc->sc_mmap[i].v4l2_buf.flags |= V4L2_BUF_FLAG_TSTAMP_SRC_EOF;
+       sc->sc_mmap[i].v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMECODE;
 
        /* forward error bit */
-       sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_ERROR;
+       sc->sc_mmap[i].v4l2_buf.flags &= ~V4L2_BUF_FLAG_ERROR;
        if (err)
-               sc->sc_mmap_cur->v4l2_buf.flags |= V4L2_BUF_FLAG_ERROR;
+               sc->sc_mmap[i].v4l2_buf.flags |= V4L2_BUF_FLAG_ERROR;
 
        /* queue it */
-       sc->sc_mmap_cur->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
-       sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
-       SIMPLEQ_INSERT_TAIL(&sc->sc_mmap_q, sc->sc_mmap_cur, q_frames);
-       DPRINTF(2, "%s: %s: frame queued\n", DEVNAME(sc), __func__);
+       sc->sc_mmap[i].v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
+       sc->sc_mmap[i].v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
+       SIMPLEQ_INSERT_TAIL(&sc->sc_mmap_q, &sc->sc_mmap[i], q_frames);
+       DPRINTF(2, "%s: %s: frame queued on index %d\n",
+           DEVNAME(sc), __func__, i);
 
        wakeup(sc);
 

Reply via email to