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