diff --git a/zbar.spec b/zbar.spec index 4e1b407..bc6333e 100644 --- a/zbar.spec +++ b/zbar.spec @@ -3,7 +3,7 @@ Name: zbar Version: 0.10 -Release: 22%{?dist} +Release: 23%{?dist} Summary: Bar code reader Group: User Interface/X Hardware Support @@ -13,6 +13,7 @@ Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar. Patch0: zbar_update_to_hg.patch Patch1: zbar_use_libv4l.patch Patch2: zbar_choose_supported_format_first.patch +Patch3: zbar_use_REQBUFS_properly.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf automake libtool python-devel gettext-devel @@ -86,6 +87,7 @@ scanning widget. %patch0 -p1 %patch1 -p1 %patch2 -p1 +%patch3 -p1 %build autoreconf -vfi @@ -179,6 +181,9 @@ rm -rf $RPM_BUILD_ROOT %{_includedir}/zbar/QZBar*.h %changelog +* Sat Jun 06 2015 Douglas Schilling Landgraf - 0.10-23 +- Add patch to use REQBUFS properly + * Sat May 02 2015 Kalev Lember - 0.10-22 - Rebuilt for GCC 5 C++11 ABI change diff --git a/zbar_use_REQBUFS_properly.patch b/zbar_use_REQBUFS_properly.patch new file mode 100644 index 0000000..b1793d8 --- /dev/null +++ b/zbar_use_REQBUFS_properly.patch @@ -0,0 +1,124 @@ +From a8ed8c04c119e5a323a2c79fcd0d28b4d29fc28a Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +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 + +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); + }