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;