Some video apps like ffmpeg are quite aggressive in requesting stream
buffers from the driver.  E.g. when I want to record 1920x1080 with
ffmpeg and my Logitech Webcam C930e, ffmpeg will request 256 buffers
via VIDIOC_REQBUFS which we will limit to 32 first, but still will end
up in a ~132MB (!) malloc request - Which finally fails.

Instead of just hard aborting in that case, the following diff will try
to decrease the buffers by a quarter until we are low enough to malloc
the memory.

This makes 1920x1080 work for me finally with 8 buffers, which is still
high enough IMO.

OK?


Index: uvideo.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uvideo.c,v
retrieving revision 1.205
diff -u -p -u -p -r1.205 uvideo.c
--- uvideo.c    14 Oct 2019 09:20:48 -0000      1.205
+++ uvideo.c    23 Nov 2019 07:49:09 -0000
@@ -3294,12 +3294,15 @@ uvideo_reqbufs(void *v, struct v4l2_requ
                sc->sc_mmap_count = 0;
                return (EINVAL);
        }
-       buf_size_total = sc->sc_mmap_count * buf_size;
-       buf_size_total = round_page(buf_size_total); /* page align buffer */
-       sc->sc_mmap_buffer = malloc(buf_size_total, M_DEVBUF, M_NOWAIT);
+       while (sc->sc_mmap_count > 0) {
+               buf_size_total = round_page(sc->sc_mmap_count * buf_size);
+               sc->sc_mmap_buffer = malloc(buf_size_total, M_DEVBUF, M_NOWAIT);
+               if (sc->sc_mmap_buffer != NULL)
+                       break;
+               sc->sc_mmap_count = sc->sc_mmap_count / 4;
+       }
        if (sc->sc_mmap_buffer == NULL) {
                printf("%s: can't allocate mmap buffer!\n", DEVNAME(sc));
-               sc->sc_mmap_count = 0;
                return (EINVAL);
        }
        sc->sc_mmap_buffer_size = buf_size_total;

Reply via email to