From feec7dd735a92d1d390cc0669f879e2b6d36389e Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Wed, 30 Jul 2008 20:05:21 -0700 Subject: libv4l: silence the creation of pkg-config files Signed-off-by: Brandon Philips --- v4l2-apps/lib/libv4l/libv4l2/Makefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/Makefile b/v4l2-apps/lib/libv4l/libv4l2/Makefile index 0e63eae71..8e5ba1f82 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/Makefile +++ b/v4l2-apps/lib/libv4l/libv4l2/Makefile @@ -34,14 +34,14 @@ $(V4L2_LIB): $(V4L2_OBJS) $(V4L2CONVERT): $(V4L2CONVERT_O) $(V4L2_LIB) libv4l2.pc: - echo prefix=$(PREFIX) > libv4l2.pc - echo libdir=$(LIBDIR) >> libv4l2.pc - echo >> libv4l2.pc - echo 'Name: libv4l2' >> libv4l2.pc - echo 'Description: v4l2 device access library' >> libv4l2.pc - echo 'Version: '$(V4L2_LIB_VERSION) >> libv4l2.pc - echo 'Libs: -L$${libdir} -lv4l2' >> libv4l2.pc - echo 'Cflags: -I$${prefix}/include' >> libv4l2.pc + @echo prefix=$(PREFIX) > libv4l2.pc + @echo libdir=$(LIBDIR) >> libv4l2.pc + @echo >> libv4l2.pc + @echo 'Name: libv4l2' >> libv4l2.pc + @echo 'Description: v4l2 device access library' >> libv4l2.pc + @echo 'Version: '$(V4L2_LIB_VERSION) >> libv4l2.pc + @echo 'Libs: -L$${libdir} -lv4l2' >> libv4l2.pc + @echo 'Cflags: -I$${prefix}/include' >> libv4l2.pc install: all mkdir -p $(DESTDIR)$(PREFIX)/include -- cgit v1.2.3 From a9cbfb5bdc82fdb04c1023f3a4bc1f5bd4a6a4a8 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Wed, 30 Jul 2008 20:07:58 -0700 Subject: libv4l: add /dev/v4l/ to the paths supported by open() override Signed-off-by: Brandon Philips --- v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 12 ++++++------ v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index f71d176b5..174c05b36 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -35,12 +35,12 @@ capture devices. 2) libv4l2 is the base of the v4l2convert.so wrapper lib, which is a .so which can be LD_PRELOAD-ed and the overrules the libc's open/close/etc, - and when opening /dev/videoX calls v4l2_open. Because we behave as the - regular counterpart when the fd is not known (instead of say throwing - an error), v4l2convert.so can simply call the v4l2_ prefixed function - for all wrapped functions (except for v4l2_open which will fail when not - called on a v4l2 device). This way the wrapper does not have to keep - track of which fd's are being handled by libv4l2, as libv4l2 already + and when opening /dev/videoX or /dev/v4l/ calls v4l2_open. Because we + behave as the regular counterpart when the fd is not known (instead of say + throwing an error), v4l2convert.so can simply call the v4l2_ prefixed + function for all wrapped functions (except for v4l2_open which will fail + when not called on a v4l2 device). This way the wrapper does not have to + keep track of which fd's are being handled by libv4l2, as libv4l2 already keeps track of this itself. This also means that libv4l2 may not use any of the regular functions diff --git a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c index 7db1ca6d6..7b64bc018 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c +++ b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c @@ -66,7 +66,7 @@ int open (const char *file, int oflag, ...) return fd; /* check if we're opening a video4linux2 device */ - if (strncmp(file, "/dev/video", 10)) + if (strncmp(file, "/dev/video", 10) && strncmp(file, "/dev/v4l/", 9)) return fd; /* check that this is an v4l2 device, libv4l2 only supports v4l2 devices */ -- cgit v1.2.3 From 474932fcb19fc298b8786e737bd1ae5115c9a6d2 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Thu, 31 Jul 2008 09:37:27 +0200 Subject: libv4l: fixup copyright headers From: Brandon Philips Part of the copyright headers refered GPL instead of LGPL due to a copy and paste error (Brandon Philips) Signed-off-by: Brandon Philips Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h | 4 ++-- v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 4 ++-- v4l2-apps/lib/libv4l/libv4l2/log.c | 4 ++-- v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h b/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h index fb6f9718e..d9e73b612 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h @@ -8,8 +8,8 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index 174c05b36..a16e4801d 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -8,8 +8,8 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software diff --git a/v4l2-apps/lib/libv4l/libv4l2/log.c b/v4l2-apps/lib/libv4l/libv4l2/log.c index 982a185c6..42051ea46 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/log.c +++ b/v4l2-apps/lib/libv4l/libv4l2/log.c @@ -8,8 +8,8 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software diff --git a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c index 7b64bc018..e30fb307c 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c +++ b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c @@ -12,8 +12,8 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software -- cgit v1.2.3 From f07be0b40ae3cbb2ae809d5f4151782f68eabb42 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Sun, 3 Aug 2008 11:42:57 +0200 Subject: libv4l: make xawtv happy From: Hans de Goede Be more relaxed in our checks for mixing read and mmap access, we were being more strict in this then certain kernel drivers (bttv) making xawtv unhappy Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h | 3 - v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 237 +++++++++++++++------------- v4l2-apps/lib/libv4l/libv4l2/log.c | 8 + 3 files changed, 138 insertions(+), 110 deletions(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h b/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h index d9e73b612..8724832e1 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h @@ -68,8 +68,6 @@ #define MIN(a,b) (((a)<(b))?(a):(b)) -enum v4l2_io { v4l2_io_none, v4l2_io_read, v4l2_io_mmap }; - struct v4l2_dev_info { int fd; int flags; @@ -81,7 +79,6 @@ struct v4l2_dev_info { pthread_mutex_t stream_lock; unsigned int no_frames; unsigned int nreadbuffers; - enum v4l2_io io; struct v4lconvert_data *convert; unsigned char *convert_mmap_buf; /* Frame bookkeeping is only done when in read or mmap-conversion mode */ diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index a16e4801d..2a0dd4837 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -72,7 +72,9 @@ /* Note these flags are stored together with the flags passed to v4l2_fd_open() in v4l2_dev_info's flags member, so care should be taken that the do not use the same bits! */ -#define V4L2_STREAMON 0x0100 +#define V4L2_STREAMON 0x0100 +#define V4L2_BUFFERS_REQUESTED_BY_READ 0x0200 +#define V4L2_STREAM_CONTROLLED_BY_READ 0x0400 #define V4L2_MMAP_OFFSET_MAGIC 0xABCDEF00u @@ -89,52 +91,46 @@ static int v4l2_request_read_buffers(int index) int result; struct v4l2_requestbuffers req; - /* No-op if already done */ - if (devices[index].no_frames) - return 0; - - /* Request buffers */ - req.count = devices[index].nreadbuffers; + /* Note we re-request the buffers if they are already requested as the format + and thus the needed buffersize may have changed. */ + req.count = (devices[index].no_frames)? devices[index].no_frames: + devices[index].nreadbuffers; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_REQBUFS, &req)) < 0){ int saved_err = errno; - V4L2_LOG_ERR("requesting buffers: %s\n", strerror(errno)); + V4L2_LOG_ERR("requesting %u buffers: %s\n", req.count, strerror(errno)); errno = saved_err; return result; } + if (!devices[index].no_frames && req.count) + devices[index].flags |= V4L2_BUFFERS_REQUESTED_BY_READ; + devices[index].no_frames = MIN(req.count, V4L2_MAX_NO_FRAMES); return 0; } -static int v4l2_unrequest_read_buffers(int index) +static void v4l2_unrequest_read_buffers(int index) { int result; struct v4l2_requestbuffers req; - /* No-op of already done */ - if (devices[index].no_frames == 0) - return 0; + if (!(devices[index].flags & V4L2_BUFFERS_REQUESTED_BY_READ) || + devices[index].no_frames == 0) + return; - /* (Un)Request buffers */ + /* (Un)Request buffers, note not all driver support this, and those + who do not support it don't need it. */ req.count = 0; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; - if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_REQBUFS, &req)) < 0) { - int saved_err = errno; - V4L2_LOG_ERR("unrequesting buffers: %s\n", strerror(errno)); - errno = saved_err; - return result; - } + if(syscall(SYS_ioctl, devices[index].fd, VIDIOC_REQBUFS, &req) < 0) + return; devices[index].no_frames = MIN(req.count, V4L2_MAX_NO_FRAMES); - if (devices[index].no_frames) { - V4L2_LOG_ERR("number of buffers > 0 after requesting 0 buffers\n"); - errno = EBUSY; - return -1; - } - return 0; + if (devices[index].no_frames == 0) + devices[index].flags &= ~V4L2_BUFFERS_REQUESTED_BY_READ; } static int v4l2_map_buffers(int index) @@ -159,7 +155,7 @@ static int v4l2_map_buffers(int index) } devices[index].frame_pointers[i] = (void *)syscall(SYS_mmap2, NULL, - (size_t)buf.length, PROT_READ, MAP_SHARED, devices[index].fd, + (size_t)buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, devices[index].fd, (__off_t)(buf.m.offset >> MMAP2_PAGE_SHIFT)); if (devices[index].frame_pointers[i] == MAP_FAILED) { int saved_err = errno; @@ -241,6 +237,7 @@ static int v4l2_queue_read_buffer(int index, int buffer_index) if (devices[index].frame_queued & (1 << buffer_index)) return 0; + memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = buffer_index; @@ -310,6 +307,8 @@ static int v4l2_activate_read_stream(int index) if ((result = v4l2_queue_read_buffers(index))) return result; + devices[index].flags |= V4L2_STREAM_CONTROLLED_BY_READ; + return result = v4l2_streamon(index); } @@ -324,12 +323,48 @@ static int v4l2_deactivate_read_stream(int index) v4l2_unmap_buffers(index); - if ((result = v4l2_unrequest_read_buffers(index))) - return result; + v4l2_unrequest_read_buffers(index); + + devices[index].flags &= ~V4L2_STREAM_CONTROLLED_BY_READ; return 0; } +static int v4l2_buffers_mapped(int index) +{ + unsigned int i; + + if (devices[index].src_fmt.fmt.pix.pixelformat == + devices[index].dest_fmt.fmt.pix.pixelformat) { + /* Normal (no conversion) mode */ + struct v4l2_buffer buf; + + for (i = 0; i < devices[index].no_frames; i++) { + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; + if (syscall(SYS_ioctl, devices[index].fd, VIDIOC_QUERYBUF, &buf)) { + int saved_err = errno; + V4L2_LOG_ERR("querying buffer %u: %s\n", i, strerror(errno)); + errno = saved_err; + break; + } + if (buf.flags & V4L2_BUF_FLAG_MAPPED) + break; + } + } else { + /* Conversion mode */ + for (i = 0; i < devices[index].no_frames; i++) + if (devices[index].frame_map_count[i]) + break; + } + + if (i != devices[index].no_frames) + V4L2_LOG("v4l2_buffers_mapped(): buffers still mapped\n"); + + return i != devices[index].no_frames; +} + int v4l2_open (const char *file, int oflag, ...) { @@ -430,7 +465,6 @@ int v4l2_fd_open(int fd, int v4l2_flags) devices[index].no_frames = 0; devices[index].nreadbuffers = V4L2_DEFAULT_NREADBUFFERS; - devices[index].io = v4l2_io_none; devices[index].convert = convert; devices[index].convert_mmap_buf = MAP_FAILED; for (i = 0; i < V4L2_MAX_NO_FRAMES; i++) { @@ -469,7 +503,7 @@ static int v4l2_get_index(int fd) int v4l2_close(int fd) { - int index, result, i; + int index, result; if ((index = v4l2_get_index(fd)) == -1) return syscall(SYS_close, fd); @@ -488,12 +522,8 @@ int v4l2_close(int fd) v4l2_unmap_buffers(index); v4lconvert_destroy(devices[index].convert); if (devices[index].convert_mmap_buf != MAP_FAILED) { - for (i = 0; i < V4L2_MAX_NO_FRAMES; i++) - if (devices[index].frame_map_count[i]) - break; - - if (i != V4L2_MAX_NO_FRAMES) - V4L2_LOG("v4l2 mmap buffers still mapped on close()\n"); + if (v4l2_buffers_mapped(index)) + V4L2_LOG_WARN("v4l2 mmap buffers still mapped on close()\n"); else syscall(SYS_munmap, devices[index].convert_mmap_buf, devices[index].no_frames * V4L2_FRAME_BUF_SIZE); @@ -528,6 +558,34 @@ int v4l2_dup(int fd) return fd; } +static int v4l2_check_buffer_change_ok(int index) +{ + v4l2_unmap_buffers(index); + + /* Check if the app itself still is using the stream */ + if (v4l2_buffers_mapped(index) || + (!(devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) && + ((devices[index].flags & V4L2_STREAMON) || + devices[index].frame_queued))) { + V4L2_LOG("v4l2_check_buffer_change_ok(): stream busy\n"); + errno = EBUSY; + return -1; + } + + /* We may change from convert to non conversion mode and + v4l2_unrequest_read_buffers may change the no_frames, so free the + convert mmap buffer */ + syscall(SYS_munmap, devices[index].convert_mmap_buf, + devices[index].no_frames * V4L2_FRAME_BUF_SIZE); + devices[index].convert_mmap_buf = MAP_FAILED; + + if (devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) { + V4L2_LOG("deactivating read-stream for settings change\n"); + return v4l2_deactivate_read_stream(index); + } + + return 0; +} int v4l2_ioctl (int fd, unsigned long int request, ...) { @@ -636,17 +694,6 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) break; } - /* Don't allow changing the format when mmap-ed IO is active, we could - allow this to happen in certain special circumstances, but it is - best to consistently deny this so that application developers do not - go expect this to work, because in their test setup it happens to - work. This also keeps the code much saner. */ - if (devices[index].io == v4l2_io_mmap) { - errno = EBUSY; - result = -1; - break; - } - if (devices[index].flags & V4L2_DISABLE_CONVERSION) { result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_TRY_FMT, dest_fmt); @@ -667,16 +714,8 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) break; } - if (devices[index].io == v4l2_io_read) { - V4L2_LOG("deactivating read-stream for format change\n"); - if ((result = v4l2_deactivate_read_stream(index))) { - /* Undo what we've done to leave things in a consisten state */ - if (v4l2_activate_read_stream(index)) - V4L2_LOG_ERR( - "reactivating stream after deactivate failure (AAIIEEEE)\n"); - break; - } - } + if ((result = v4l2_check_buffer_change_ok(index))) + break; result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_S_FMT, &src_fmt); if (result) { @@ -707,26 +746,6 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) int i; struct v4l2_requestbuffers *req = arg; - /* Don't allow mixing read / mmap io, either we control the buffers - (read based io), or the app does */ - if (devices[index].io == v4l2_io_read) { - V4L2_LOG_ERR("to change from read io to mmap io open and close the device first!\n"); - errno = EBUSY; - result = -1; - break; - } - - /* Are any of our fake (convert_mmap_buf) buffers still mapped ? */ - for (i = 0; i < V4L2_MAX_NO_FRAMES; i++) - if (devices[index].frame_map_count[i]) - break; - - if (i != V4L2_MAX_NO_FRAMES) { - errno = EBUSY; - result = -1; - break; - } - /* IMPROVEME (maybe?) add support for userptr's? */ if (req->memory != V4L2_MEMORY_MMAP) { errno = EINVAL; @@ -734,30 +753,20 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) break; } + if ((result = v4l2_check_buffer_change_ok(index))) + break; + /* No more buffers then we can manage please */ if (req->count > V4L2_MAX_NO_FRAMES) req->count = V4L2_MAX_NO_FRAMES; - /* Stop stream and unmap our real mapping of the buffers - (only relevant when we're converting, otherwise a no-op) */ - v4l2_streamoff(index); - v4l2_unmap_buffers(index); - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_REQBUFS, req); if (result < 0) break; result = 0; /* some drivers return the number of buffers on success */ - /* If we got more frames then we can handle lie to the app */ - if (req->count > V4L2_MAX_NO_FRAMES) - req->count = V4L2_MAX_NO_FRAMES; - - /* Force reallocation of convert_mmap_buf to fit the new no_frames */ - syscall(SYS_munmap, devices[index].convert_mmap_buf, - devices[index].no_frames * V4L2_FRAME_BUF_SIZE); - devices[index].convert_mmap_buf = MAP_FAILED; - devices[index].no_frames = req->count; - devices[index].io = req->count? v4l2_io_mmap:v4l2_io_none; + devices[index].no_frames = MIN(req->count, V4L2_MAX_NO_FRAMES); + devices[index].flags &= ~V4L2_BUFFERS_REQUESTED_BY_READ; } break; @@ -765,6 +774,10 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) { struct v4l2_buffer *buf = arg; + if (devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) + if ((result = v4l2_deactivate_read_stream(index))) + break; + /* Do a real query even when converting to let the driver fill in things like buf->field */ result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QUERYBUF, buf); @@ -781,6 +794,10 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) break; case VIDIOC_QBUF: + if (devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) + if ((result = v4l2_deactivate_read_stream(index))) + break; + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QBUF, arg); break; @@ -788,6 +805,10 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) { struct v4l2_buffer *buf = arg; + if (devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) + if ((result = v4l2_deactivate_read_stream(index))) + break; + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_DQBUF, buf); if (result) { V4L2_LOG_ERR("dequeing buffer: %s\n", strerror(errno)); @@ -849,11 +870,9 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) case VIDIOC_STREAMON: case VIDIOC_STREAMOFF: - if (devices[index].io != v4l2_io_mmap) { - errno = EINVAL; - result = -1; - break; - } + if (devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) + if ((result = v4l2_deactivate_read_stream(index))) + break; if (request == VIDIOC_STREAMON) result = v4l2_streamon(index); @@ -886,22 +905,27 @@ ssize_t v4l2_read (int fd, void* buffer, size_t n) pthread_mutex_lock(&devices[index].stream_lock); - if (devices[index].io == v4l2_io_mmap) { - V4L2_LOG_ERR("to change from mmap io to read io first do request_buffers with a count of 0\n"); - errno = EBUSY; - result = -1; - goto leave; + if (!(devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ)) { + if ((devices[index].flags & V4L2_STREAMON) || + devices[index].frame_queued) { + errno = EBUSY; + result = -1; + goto leave; + } + if ((result = v4l2_activate_read_stream(index))) + goto leave; } - devices[index].io = v4l2_io_read; - - if ((result = v4l2_activate_read_stream(index))) - goto leave; if ((frame_index = v4l2_dequeue_read_buffer(index, &bytesused)) < 0) { result = -1; goto leave; } + /* ensure buffers are mapped before using them (they could have been + unmapped by a s_fmt ioctl) */ + if ((result = v4l2_map_buffers(index))) + goto leave; + result = v4lconvert_convert(devices[index].convert, &devices[index].src_fmt, &devices[index].dest_fmt, devices[index].frame_pointers[frame_index], bytesused, @@ -948,7 +972,6 @@ void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, buffer_index = offset & 0xff; if (buffer_index >= devices[index].no_frames || - devices[index].io != v4l2_io_mmap || /* Got magic offset and not converting ?? */ devices[index].src_fmt.fmt.pix.pixelformat == devices[index].dest_fmt.fmt.pix.pixelformat) { diff --git a/v4l2-apps/lib/libv4l/libv4l2/log.c b/v4l2-apps/lib/libv4l/libv4l2/log.c index 42051ea46..05f6c46d7 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/log.c +++ b/v4l2-apps/lib/libv4l/libv4l2/log.c @@ -131,6 +131,14 @@ void v4l2_log_ioctl(unsigned long int request, void *arg, int result) } } break; + case VIDIOC_REQBUFS: + { + struct v4l2_requestbuffers *req = arg; + + fprintf(v4l2_log_file, " count: %u type: %d memory: %d\n", + req->count, req->type, req->memory); + } + break; } fprintf(v4l2_log_file, "result == %d\n", result); -- cgit v1.2.3 From 1d60339ee5ca9a861de510dc4c57576ec9f2e5be Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Sun, 3 Aug 2008 13:15:46 +0200 Subject: libv4l: makefile and pkgconfig improvements From: Gregor Jasny Various Makefile and pkgconfig file improvements by Gregor Jasny (Debian) Signed-off-by: Gregor Jasny Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/Makefile | 36 ++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/Makefile b/v4l2-apps/lib/libv4l/libv4l2/Makefile index 8e5ba1f82..38449b44d 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/Makefile +++ b/v4l2-apps/lib/libv4l/libv4l2/Makefile @@ -1,20 +1,23 @@ -CC = gcc -LD = gcc - -CPPFLAGS = -fPIC -I../include -I../../../../linux/include +CPPFLAGS = -I../include -I../../../../linux/include CFLAGS := -g -O1 CFLAGS += -Wall -W -Wno-unused -Wpointer-arith -Wstrict-prototypes -LDFLAGS = -shared - -V4L2_OBJS = libv4l2.o log.o ../libv4lconvert/libv4lconvert.so -V4L2_LIB = libv4l2.so +V4L2_OBJS = libv4l2.o log.o V4L2CONVERT = v4l2convert.so V4L2CONVERT_O = v4l2convert.o libv4l2.so -TARGETS = $(V4L2_LIB) $(V4L2CONVERT) libv4l2.pc +TARGETS = $(V4L2_LIB) libv4l2.pc INCLUDES = ../include/libv4l2.h +ifeq ($(LINKTYPE),static) +V4L2_LIB = libv4l2.a +else +V4L2_LIB = libv4l2.so +V4L2_OBJS += ../libv4lconvert/libv4lconvert.so +TARGETS += $(V4L2CONVERT) +CPPFLAGS += -fPIC +endif + ifeq ($(LIB_RELEASE),) LIB_RELEASE = 0 endif @@ -40,27 +43,38 @@ libv4l2.pc: @echo 'Name: libv4l2' >> libv4l2.pc @echo 'Description: v4l2 device access library' >> libv4l2.pc @echo 'Version: '$(V4L2_LIB_VERSION) >> libv4l2.pc + @echo 'Requires: libv4lconvert' >> libv4l2.pc @echo 'Libs: -L$${libdir} -lv4l2' >> libv4l2.pc + @echo 'Libs.private: -lpthread' >> libv4l2.pc @echo 'Cflags: -I$${prefix}/include' >> libv4l2.pc install: all mkdir -p $(DESTDIR)$(PREFIX)/include install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include +ifeq ($(LINKTYPE),static) + mkdir -p $(DESTDIR)$(LIBDIR) + install -m 644 $(V4L2_LIB) $(DESTDIR)$(LIBDIR) +else mkdir -p $(DESTDIR)$(LIBDIR)/libv4l install -m 755 $(V4L2_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR) cd $(DESTDIR)$(LIBDIR) && \ ln -f -s $(V4L2_LIB).$(LIB_RELEASE) $(V4L2_LIB) install -m 755 $(V4L2CONVERT).$(LIB_RELEASE) \ $(DESTDIR)$(LIBDIR)/libv4l/$(V4L2CONVERT) +endif mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig install -m 644 libv4l2.pc $(DESTDIR)$(LIBDIR)/pkgconfig clean:: - rm -f *.so* *.o *.d libv4l2.pc log *~ + rm -f *.a *.so* *.o *.d libv4l2.pc log *~ %.o: %.c $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< %.so: - $(CC) $(LDFLAGS) -Wl,-soname,$@.$(LIB_RELEASE) -o $@.$(LIB_RELEASE) $^ + $(CC) -shared $(LDFLAGS) -Wl,-soname,$@.$(LIB_RELEASE) -o $@.$(LIB_RELEASE) $^ ln -f -s $@.$(LIB_RELEASE) $@ + +%.a: + $(AR) cqs $@ $^ + -- cgit v1.2.3 From 3dbcf4e987933e8e41ff496e76223f457a7609e5 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Sun, 3 Aug 2008 13:21:19 +0200 Subject: libv4l: link against pthread From: Hans de Goede libv4l: link against pthread Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/Makefile b/v4l2-apps/lib/libv4l/libv4l2/Makefile index 38449b44d..d8ac01c34 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/Makefile +++ b/v4l2-apps/lib/libv4l/libv4l2/Makefile @@ -3,6 +3,8 @@ CPPFLAGS = -I../include -I../../../../linux/include CFLAGS := -g -O1 CFLAGS += -Wall -W -Wno-unused -Wpointer-arith -Wstrict-prototypes +LIBS = -lpthread + V4L2_OBJS = libv4l2.o log.o V4L2CONVERT = v4l2convert.so V4L2CONVERT_O = v4l2convert.o libv4l2.so @@ -72,7 +74,7 @@ clean:: $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< %.so: - $(CC) -shared $(LDFLAGS) -Wl,-soname,$@.$(LIB_RELEASE) -o $@.$(LIB_RELEASE) $^ + $(CC) -shared $(LDFLAGS) -Wl,-soname,$@.$(LIB_RELEASE) -o $@.$(LIB_RELEASE) $^ $(LIBS) ln -f -s $@.$(LIB_RELEASE) $@ %.a: -- cgit v1.2.3 From bad01ca943742b5a2938b3718abc8590a0f3929d Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Sun, 3 Aug 2008 14:35:38 +0200 Subject: libv4l: mpa buffers before queuing From: Hans de Goede With some drivers the buffers must be mapped before queuing, so when converting map the (real) buffers before calling the qbuf ioctl Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index 2a0dd4837..d6a8a6d2a 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -798,6 +798,11 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) if ((result = v4l2_deactivate_read_stream(index))) break; + /* With some drivers the buffers must be mapped before queuing */ + if (converting) + if ((result = v4l2_map_buffers(index))) + break; + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QBUF, arg); break; -- cgit v1.2.3 From a1c8635315d9fcc9768035549e3ff5ea61f1faf2 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Sun, 3 Aug 2008 18:47:06 +0200 Subject: libv4l: remove 2 unused variable declarations From: Hans de Goede libv4l: remove 2 unused variable declarations Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index d6a8a6d2a..fc41c665d 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -113,7 +113,6 @@ static int v4l2_request_read_buffers(int index) static void v4l2_unrequest_read_buffers(int index) { - int result; struct v4l2_requestbuffers req; if (!(devices[index].flags & V4L2_BUFFERS_REQUESTED_BY_READ) || @@ -743,7 +742,6 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) case VIDIOC_REQBUFS: { - int i; struct v4l2_requestbuffers *req = arg; /* IMPROVEME (maybe?) add support for userptr's? */ -- cgit v1.2.3 From 7ab958ab10b1a5c28dc0c0c798939c57e41e40a4 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Sun, 3 Aug 2008 19:25:44 +0200 Subject: libv4l: use driver read() when possible From: Hans de Goede When the driver supports read() and we are not converting let the driver handle read() instead of emulating it with mmap mode Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index fc41c665d..a40ab4ffe 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -75,6 +75,7 @@ #define V4L2_STREAMON 0x0100 #define V4L2_BUFFERS_REQUESTED_BY_READ 0x0200 #define V4L2_STREAM_CONTROLLED_BY_READ 0x0400 +#define V4L2_SUPPORTS_READ 0x0800 #define V4L2_MMAP_OFFSET_MAGIC 0xABCDEF00u @@ -456,6 +457,8 @@ int v4l2_fd_open(int fd, int v4l2_flags) } devices[index].flags = v4l2_flags; + if (cap.capabilities & V4L2_CAP_READWRITE) + devices[index].flags |= V4L2_SUPPORTS_READ; devices[index].open_count = 1; devices[index].src_fmt = fmt; devices[index].dest_fmt = fmt; @@ -908,6 +911,15 @@ ssize_t v4l2_read (int fd, void* buffer, size_t n) pthread_mutex_lock(&devices[index].stream_lock); + /* When not converting and the device supports read let the kernel handle + it */ + if ((devices[index].flags & V4L2_SUPPORTS_READ) && + devices[index].src_fmt.fmt.pix.pixelformat == + devices[index].dest_fmt.fmt.pix.pixelformat) { + result = syscall(SYS_read, fd, buffer, n); + goto leave; + } + if (!(devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ)) { if ((devices[index].flags & V4L2_STREAMON) || devices[index].frame_queued) { -- cgit v1.2.3 From e0e6d4a7982b61a901c49c1b099b067a0e613eb6 Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Sun, 3 Aug 2008 21:20:08 +0200 Subject: libv4l: mmap return value should be void * not void From: Hans de Goede libv4l: mmap return value should be void * not void Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2') diff --git a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c index e30fb307c..f312828c6 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c +++ b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c @@ -134,13 +134,13 @@ ssize_t read (int fd, void* buffer, size_t n) return v4l2_read (fd, buffer, n); } -void mmap(void *start, size_t length, int prot, int flags, int fd, +void *mmap(void *start, size_t length, int prot, int flags, int fd, __off_t offset) { return v4l2_mmap(start, length, prot, flags, fd, offset); } -void mmap64(void *start, size_t length, int prot, int flags, int fd, +void *mmap64(void *start, size_t length, int prot, int flags, int fd, __off64_t offset) { return v4l2_mmap(start, length, prot, flags, fd, offset); -- cgit v1.2.3