parent
0753972d93
commit
7f2721935e
@ -0,0 +1,124 @@
|
||||
From a8ed8c04c119e5a323a2c79fcd0d28b4d29fc28a Mon Sep 17 00:00:00 2001
|
||||
From: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
|
||||
Date: Thu, 23 Apr 2015 22:56:09 -0300
|
||||
Subject: [PATCH] v4l2: use REQBUFS properly
|
||||
|
||||
There are two issues on this driver with regards to buffer
|
||||
request:
|
||||
|
||||
1) it is not calling VIDIOC_REQBUFS for USERPTR;
|
||||
|
||||
2) It is calling VIDIOC_REQBUFS at probe, to check the max
|
||||
number of supported buffers, but it doesn't deallocate
|
||||
the buffers at the end of the probe function.
|
||||
|
||||
Fix those issues. Also, improve the error/warning messages
|
||||
associated with possible problems.
|
||||
|
||||
This is based on the issues detected by the patch proposed
|
||||
to fix this bug:
|
||||
https://bugs.archlinux.org/task/44091
|
||||
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
|
||||
|
||||
diff --git a/zbar/video/v4l2.c b/zbar/video/v4l2.c
|
||||
index aabd16643ddc..f6662d3707f9 100644
|
||||
--- a/zbar/video/v4l2.c
|
||||
+++ b/zbar/video/v4l2.c
|
||||
@@ -201,21 +201,6 @@ static int v4l2_cleanup (zbar_video_t *vdo)
|
||||
|
||||
static int v4l2_mmap_buffers (zbar_video_t *vdo)
|
||||
{
|
||||
- struct v4l2_requestbuffers rb;
|
||||
- memset(&rb, 0, sizeof(rb));
|
||||
- rb.count = vdo->num_images;
|
||||
- rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
- rb.memory = V4L2_MEMORY_MMAP;
|
||||
- if(v4l2_ioctl(vdo->fd, VIDIOC_REQBUFS, &rb) < 0)
|
||||
- return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
|
||||
- "requesting video frame buffers (VIDIOC_REQBUFS)"));
|
||||
- zprintf(1, "mapping %u buffers (of %d requested)\n",
|
||||
- rb.count, vdo->num_images);
|
||||
- if(!rb.count)
|
||||
- return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
|
||||
- "driver returned 0 buffers"));
|
||||
- if(vdo->num_images > rb.count)
|
||||
- vdo->num_images = rb.count;
|
||||
|
||||
struct v4l2_buffer vbuf;
|
||||
memset(&vbuf, 0, sizeof(vbuf));
|
||||
@@ -313,8 +298,32 @@ static int v4l2_set_format (zbar_video_t *vdo,
|
||||
static int v4l2_init (zbar_video_t *vdo,
|
||||
uint32_t fmt)
|
||||
{
|
||||
+ struct v4l2_requestbuffers rb;
|
||||
if(v4l2_set_format(vdo, fmt))
|
||||
return(-1);
|
||||
+
|
||||
+ memset(&rb, 0, sizeof(rb));
|
||||
+ rb.count = vdo->num_images;
|
||||
+ rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
+ if(vdo->iomode == VIDEO_MMAP)
|
||||
+ rb.memory = V4L2_MEMORY_MMAP;
|
||||
+ else
|
||||
+ rb.memory = V4L2_MEMORY_USERPTR;
|
||||
+
|
||||
+ if(v4l2_ioctl(vdo->fd, VIDIOC_REQBUFS, &rb) < 0)
|
||||
+ return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
|
||||
+ "requesting video frame buffers (VIDIOC_REQBUFS)"));
|
||||
+
|
||||
+ if(!rb.count)
|
||||
+ return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
|
||||
+ "driver returned 0 buffers"));
|
||||
+
|
||||
+ if(vdo->num_images > rb.count)
|
||||
+ vdo->num_images = rb.count;
|
||||
+
|
||||
+ zprintf(1, "using %u buffers (of %d requested)\n",
|
||||
+ rb.count, vdo->num_images);
|
||||
+
|
||||
if(vdo->iomode == VIDEO_MMAP)
|
||||
return(v4l2_mmap_buffers(vdo));
|
||||
return(0);
|
||||
@@ -324,7 +333,7 @@ static int v4l2_probe_iomode (zbar_video_t *vdo)
|
||||
{
|
||||
struct v4l2_requestbuffers rb;
|
||||
memset(&rb, 0, sizeof(rb));
|
||||
- rb.count = vdo->num_images; /* FIXME workaround broken drivers */
|
||||
+ rb.count = vdo->num_images;
|
||||
rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if(vdo->iomode == VIDEO_MMAP)
|
||||
rb.memory = V4L2_MEMORY_MMAP;
|
||||
@@ -340,14 +349,31 @@ static int v4l2_probe_iomode (zbar_video_t *vdo)
|
||||
return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
|
||||
"querying streaming mode (VIDIOC_REQBUFS)"));
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
+ err_capture(vdo, SEV_WARNING, ZBAR_ERR_SYSTEM, __func__,
|
||||
+ "USERPTR failed. Falling back to mmap");
|
||||
vdo->iomode = VIDEO_MMAP;
|
||||
+#else
|
||||
+ return err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__,
|
||||
+ "Userptr not supported, and zbar was compiled without mmap support"));
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if(!vdo->iomode)
|
||||
- vdo->iomode = VIDEO_USERPTR;
|
||||
+ rb.memory = V4L2_MEMORY_USERPTR;
|
||||
+ /* Update the num_images with the max supported by the driver */
|
||||
if(rb.count)
|
||||
vdo->num_images = rb.count;
|
||||
+ else
|
||||
+ err_capture(vdo, SEV_WARNING, ZBAR_ERR_SYSTEM, __func__,
|
||||
+ "Something is wrong: number of buffers returned by REQBUF is zero!");
|
||||
+
|
||||
+ /* requesting 0 buffers
|
||||
+ * This cleans up the buffers allocated previously on probe
|
||||
+ */
|
||||
+ rb.count = 0;
|
||||
+ if(v4l2_ioctl(vdo->fd, VIDIOC_REQBUFS, &rb) < 0)
|
||||
+ err_capture(vdo, SEV_WARNING, ZBAR_ERR_SYSTEM, __func__,
|
||||
+ "releasing video frame buffers (VIDIOC_REQBUFS)");
|
||||
}
|
||||
return(0);
|
||||
}
|
Loading…
Reference in new issue