Re: Initialize v4l2_requestbuffers struct to avoid invalid mmap
On Thu, May 28, 2020 at 12:23:58PM +0200, Martin Pieuchot wrote: > On 26/05/20(Tue) 11:30, Ingo Feinerer wrote: > > video(1) supports reading frames from a webcam via mmap(). To inform the > > V4L2 device about the number of desired buffers containing the frames to > > be memory-mapped, a VIDIOC_REQBUFS ioctl call is used. > > > > At the moment the v4l2_requestbuffers struct used for the VIDIOC_REQBUFS > > ioctl > > is only partially initialized which leads to an invalid mmap for my webcam: > > The kernel driver, uvideo(4) or utvfu(4) is responsible for the rest of > the initialization. Thanks for the hint. uvideo_reqbufs() is ignoring both struct members `type` and `memory` so it makes no difference when using video(1) as is. I wrote a small program that just fetches one frame and can confirm it works. However, I have a camera that only supports the MJPEG encoding which video(1) cannot handle. So I am using libv4l (pkg_add libv4l) which can convert encodings on the fly: LD_PRELOAD=/usr/local/lib/v4l2convert.so video libv4l inspects the `type` and `memory` struct members (https://git.linuxtv.org/v4l-utils.git/tree/lib/libv4l2/libv4l2.c#n1308) and fails if `memory != V4L2_MEMORY_MMAP`. So the real question is if video(1) should "support" libv4l ... Best regards, Ingo
Re: Initialize v4l2_requestbuffers struct to avoid invalid mmap
On 26/05/20(Tue) 11:30, Ingo Feinerer wrote: > video(1) supports reading frames from a webcam via mmap(). To inform the > V4L2 device about the number of desired buffers containing the frames to > be memory-mapped, a VIDIOC_REQBUFS ioctl call is used. > > At the moment the v4l2_requestbuffers struct used for the VIDIOC_REQBUFS ioctl > is only partially initialized which leads to an invalid mmap for my webcam: The kernel driver, uvideo(4) or utvfu(4) is responsible for the rest of the initialization. > video: mmap: Invalid argument > > With the following diff applied my camera works (only on EHCI ports with USB > 3.0 disabled in BIOS but that is a different story). I'm afraid this might mask a real bug. Did you try building a kernel with UVIDEO_DEBUG and run it to see what the error is? The function you're interested in is uvideo_reqbufs() which correspond to the VIDIOC_REQBUFS ioctl(2). > Index: video.c > === > RCS file: /cvs/xenocara/app/video/video.c,v > retrieving revision 1.29 > diff -u -p -r1.29 video.c > --- video.c 6 Nov 2019 05:46:51 - 1.29 > +++ video.c 26 May 2020 09:14:39 - > @@ -1354,6 +1354,8 @@ mmap_init(struct video *vid) > > /* request buffers */ > rb.count = MMAP_NUM_BUFS; > + rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; > + rb.memory = V4L2_MEMORY_MMAP; > r = ioctl(vid->dev.fd, VIDIOC_REQBUFS, &rb); > if (r == -1) { > warn("ioctl VIDIOC_REQBUFS"); >