Re: uvideo(4) stream buffer malloc

2019-12-07 Thread Marcus Glocker
It turned out that the last diff didn't work out so well.
Depending on the resolution it could happen that uvideo just could
allocate enough memory for the buffers, but xhci didn't had enough
left to allocate the ring buffers.

What worked out best for me is to limit the max. buffers to 8.
I still can capture 1920x1080 (H.264) with constantly 30fps with
this.

If I don't hear back about any concerns in the next few days,
I would commit the following diff.


Index: uvideo.h
===
RCS file: /cvs/src/sys/dev/usb/uvideo.h,v
retrieving revision 1.59
diff -u -p -u -p -r1.59 uvideo.h
--- uvideo.h7 Aug 2019 11:14:16 -   1.59
+++ uvideo.h2 Dec 2019 06:43:53 -
@@ -455,7 +455,7 @@ struct uvideo_frame_buffer {
uint32_t fmt_flags;
 };
 
-#define UVIDEO_MAX_BUFFERS 32
+#define UVIDEO_MAX_BUFFERS 8
 struct uvideo_mmap {
SIMPLEQ_ENTRY(uvideo_mmap)  q_frames;
uint8_t *buf;


On Sat, Nov 23, 2019 at 09:13:05AM +0100, Marcus Glocker wrote:

> 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 -  1.205
> +++ uvideo.c  23 Nov 2019 07:49:09 -
> @@ -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;
> 



uvideo(4) stream buffer malloc

2019-11-23 Thread Marcus Glocker
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.c14 Oct 2019 09:20:48 -  1.205
+++ uvideo.c23 Nov 2019 07:49:09 -
@@ -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;