Re: Initialize v4l2_requestbuffers struct to avoid invalid mmap

2020-05-29 Thread Ingo Feinerer
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

2020-05-28 Thread Martin Pieuchot
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, );
>   if (r == -1) {
>   warn("ioctl VIDIOC_REQBUFS");
> 



Initialize v4l2_requestbuffers struct to avoid invalid mmap

2020-05-26 Thread Ingo Feinerer
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:

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).

OK?

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, );
if (r == -1) {
warn("ioctl VIDIOC_REQBUFS");