diff options
Diffstat (limited to 'v4l2-apps/lib/libv4l/libv4l2')
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l2/Makefile | 82 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h | 95 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 1145 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l2/log.c | 148 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c | 166 |
5 files changed, 0 insertions, 1636 deletions
diff --git a/v4l2-apps/lib/libv4l/libv4l2/Makefile b/v4l2-apps/lib/libv4l/libv4l2/Makefile deleted file mode 100644 index 648d27c0c..000000000 --- a/v4l2-apps/lib/libv4l/libv4l2/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -override CPPFLAGS += -I../include -I../../../include -fvisibility=hidden - -CFLAGS := -g -O1 -CFLAGS += -Wall -Wno-unused -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes - -LIBS = -lpthread - -V4L2_OBJS = libv4l2.o log.o -V4L2CONVERT = v4l2convert.so -V4L2CONVERT_O = v4l2convert.o libv4l2.so -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) -override CPPFLAGS += -fPIC -endif - -ifeq ($(LIB_RELEASE),) -LIB_RELEASE = 0 -endif - -ifeq ($(PREFIX),) -PREFIX = /usr/local -endif - -ifeq ($(LIBDIR),) -LIBDIR = $(PREFIX)/lib -endif - -all: $(TARGETS) - -$(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 '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 *.a *.so* *.o *.d libv4l2.pc log *~ - -%.o: %.c - $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< - -%.so: - $(CC) -shared $(LDFLAGS) -Wl,-soname,$@.$(LIB_RELEASE) -o $@.$(LIB_RELEASE) $^ $(LIBS) - ln -f -s $@.$(LIB_RELEASE) $@ - -%.a: - $(AR) cqs $@ $^ - diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h b/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h deleted file mode 100644 index 8724832e1..000000000 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# 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 -# 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 -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef __LIBV4L2_PRIV_H -#define __LIBV4L2_PRIV_H - -#include <stdio.h> -#include <pthread.h> -#include <libv4lconvert.h> /* includes videodev2.h for us */ - -/* On 32 bits archs we always use mmap2, on 64 bits archs there is no mmap2 */ -#ifdef __NR_mmap2 -#define SYS_mmap2 __NR_mmap2 -#define MMAP2_PAGE_SHIFT 12 -#else -#define SYS_mmap2 SYS_mmap -#define MMAP2_PAGE_SHIFT 0 -#endif - -#define V4L2_MAX_DEVICES 16 -/* Warning when making this larger the frame_queued and frame_mapped members of - the v4l2_dev_info struct can no longer be a bitfield, so the code needs to - be adjusted! */ -#define V4L2_MAX_NO_FRAMES 32 -#define V4L2_DEFAULT_NREADBUFFERS 4 -#define V4L2_FRAME_BUF_SIZE (4096 * 4096) - -#define V4L2_LOG_ERR(...) \ - do { \ - if (v4l2_log_file) { \ - fprintf(v4l2_log_file, "libv4l2: error " __VA_ARGS__); \ - fflush(v4l2_log_file); \ - } else \ - fprintf(stderr, "libv4l2: error " __VA_ARGS__); \ - } while(0) - -#define V4L2_LOG_WARN(...) \ - do { \ - if (v4l2_log_file) { \ - fprintf(v4l2_log_file, "libv4l2: warning " __VA_ARGS__); \ - fflush(v4l2_log_file); \ - } else \ - fprintf(stderr, "libv4l2: warning " __VA_ARGS__); \ - } while(0) - -#define V4L2_LOG(...) \ - do { \ - if (v4l2_log_file) { \ - fprintf(v4l2_log_file, "libv4l2: " __VA_ARGS__); \ - fflush(v4l2_log_file); \ - } \ - } while(0) - -#define MIN(a,b) (((a)<(b))?(a):(b)) - -struct v4l2_dev_info { - int fd; - int flags; - int open_count; - /* actually format of the cam */ - struct v4l2_format src_fmt; - /* fmt as seen by the application (iow after conversion) */ - struct v4l2_format dest_fmt; - pthread_mutex_t stream_lock; - unsigned int no_frames; - unsigned int nreadbuffers; - struct v4lconvert_data *convert; - unsigned char *convert_mmap_buf; - /* Frame bookkeeping is only done when in read or mmap-conversion mode */ - unsigned char *frame_pointers[V4L2_MAX_NO_FRAMES]; - int frame_sizes[V4L2_MAX_NO_FRAMES]; - int frame_queued; /* 1 status bit per frame */ - /* mapping tracking of our fake (converting mmap) frame buffers */ - unsigned char frame_map_count[V4L2_MAX_NO_FRAMES]; -}; - -/* From log.c */ -void v4l2_log_ioctl(unsigned long int request, void *arg, int result); - -#endif diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c deleted file mode 100644 index b4a10afac..000000000 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ /dev/null @@ -1,1145 +0,0 @@ -/* -# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# 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 -# 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 -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* MAKING CHANGES TO THIS FILE?? READ THIS FIRST!!! - - This file implements libv4l2, which offers v4l2_ prefixed versions of - open/close/etc. The API is 100% the same as directly opening /dev/videoX - using regular open/close/etc, the big difference is that format conversion - is done if necessary when capturing. That is if you (try to) set a capture - format which is not supported by the cam, but is supported by libv4lconvert, - then the try_fmt / set_fmt will succeed as if the cam supports the format - and on dqbuf / read the data will be converted for you and returned in - the request format. - - Important note to people making changes to this file: All functions - (v4l2_close, v4l2_ioctl, etc.) are designed to function as their regular - counterpart when they get passed a fd that is not "registered" by libv4l2, - there are 2 reasons for this: - 1) This allows us to get completely out of the way when dealing with non - 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 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 - it mimics, as for example open could be a symbol in v4l2convert.so, which - in turn will call v4l2_open, so therefor v4l2_open (for example) may not - use the regular open()! - - Another important note: libv4l2 does conversion for capture usage only, if - any calls are made which are passed a v4l2_buffer or v4l2_format with a - v4l2_buf_type which is different from V4L2_BUF_TYPE_VIDEO_CAPTURE, then - the v4l2_ methods behave exactly the same as their regular counterparts. - When modifications are made, one should be carefull that this behavior is - preserved. -*/ -#include <errno.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <syscall.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include "libv4l2.h" -#include "libv4l2-priv.h" - -/* 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_BUFFERS_REQUESTED_BY_READ 0x0200 -#define V4L2_STREAM_CONTROLLED_BY_READ 0x0400 -#define V4L2_SUPPORTS_READ 0x0800 - -#define V4L2_MMAP_OFFSET_MAGIC 0xABCDEF00u - -static pthread_mutex_t v4l2_open_mutex = PTHREAD_MUTEX_INITIALIZER; -static struct v4l2_dev_info devices[V4L2_MAX_DEVICES] = { { .fd = -1 }, - { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, - { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, - { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }, { .fd = -1 }}; -static int devices_used = 0; - - -static int v4l2_request_read_buffers(int index) -{ - int result; - struct v4l2_requestbuffers req; - - /* 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 %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 void v4l2_unrequest_read_buffers(int index) -{ - struct v4l2_requestbuffers req; - - if (!(devices[index].flags & V4L2_BUFFERS_REQUESTED_BY_READ) || - devices[index].no_frames == 0) - return; - - /* (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(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 == 0) - devices[index].flags &= ~V4L2_BUFFERS_REQUESTED_BY_READ; -} - -static int v4l2_map_buffers(int index) -{ - int result = 0; - unsigned int i; - struct v4l2_buffer buf; - - for (i = 0; i < devices[index].no_frames; i++) { - if (devices[index].frame_pointers[i] != MAP_FAILED) - continue; - - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = i; - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QUERYBUF, &buf); - if (result) { - int saved_err = errno; - V4L2_LOG_ERR("querying buffer %u: %s\n", i, strerror(errno)); - errno = saved_err; - break; - } - - devices[index].frame_pointers[i] = (void *)syscall(SYS_mmap2, NULL, - (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; - V4L2_LOG_ERR("mmapping buffer %u: %s\n", i, strerror(errno)); - errno = saved_err; - result = -1; - break; - } - V4L2_LOG("mapped buffer %u at %p\n", i, - devices[index].frame_pointers[i]); - - devices[index].frame_sizes[i] = buf.length; - } - - return result; -} - -static void v4l2_unmap_buffers(int index) -{ - unsigned int i; - - /* unmap the buffers */ - for (i = 0; i < devices[index].no_frames; i++) { - if (devices[index].frame_pointers[i] != MAP_FAILED) { - syscall(SYS_munmap, devices[index].frame_pointers[i], - devices[index].frame_sizes[i]); - devices[index].frame_pointers[i] = MAP_FAILED; - V4L2_LOG("unmapped buffer %u\n", i); - } - } -} - -static int v4l2_streamon(int index) -{ - int result; - enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - if (!(devices[index].flags & V4L2_STREAMON)) { - if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_STREAMON, - &type))) { - int saved_err = errno; - V4L2_LOG_ERR("turning on stream: %s\n", strerror(errno)); - errno = saved_err; - return result; - } - devices[index].flags |= V4L2_STREAMON; - } - - return 0; -} - -static int v4l2_streamoff(int index) -{ - int result; - enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - if (devices[index].flags & V4L2_STREAMON) { - if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_STREAMOFF, - &type))) { - int saved_err = errno; - V4L2_LOG_ERR("turning off stream: %s\n", strerror(errno)); - errno = saved_err; - return result; - } - devices[index].flags &= ~V4L2_STREAMON; - - /* Stream off also unqueues all our buffers! */ - devices[index].frame_queued = 0; - } - - return 0; -} - -static int v4l2_queue_read_buffer(int index, int buffer_index) -{ - int result; - struct v4l2_buffer buf; - - 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; - if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QBUF, &buf))) { - int saved_err = errno; - V4L2_LOG_ERR("queuing buf %d: %s\n", buffer_index, strerror(errno)); - errno = saved_err; - return result; - } - - devices[index].frame_queued |= 1 << buffer_index; - return 0; -} - -static int v4l2_dequeue_and_convert(int index, struct v4l2_buffer *buf, - unsigned char *dest, int dest_size) -{ - const int max_tries = 10; - int result, tries = max_tries; - - /* Make sure we have the real v4l2 buffers mapped */ - if ((result = v4l2_map_buffers(index))) - return result; - - do { - if ((result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_DQBUF, buf))) { - int saved_err = errno; - V4L2_LOG_ERR("dequeuing buf: %s\n", strerror(errno)); - errno = saved_err; - return result; - } - - devices[index].frame_queued &= ~(1 << buf->index); - - result = v4lconvert_convert(devices[index].convert, - &devices[index].src_fmt, &devices[index].dest_fmt, - devices[index].frame_pointers[buf->index], - buf->bytesused, dest ? dest : (devices[index].convert_mmap_buf + - buf->index * V4L2_FRAME_BUF_SIZE), dest_size); - - if (result < 0) { - int saved_err = errno; - - if(errno == EAGAIN) - V4L2_LOG("warning error while converting frame data: %s\n", - v4lconvert_get_error_message(devices[index].convert)); - else - V4L2_LOG_ERR("converting / decoding frame data: %s\n", - v4lconvert_get_error_message(devices[index].convert)); - - v4l2_queue_read_buffer(index, buf->index); - errno = saved_err; - } - tries--; - } while (result < 0 && errno == EAGAIN && tries); - - if (result < 0 && errno == EAGAIN) { - V4L2_LOG_ERR("got %d consecutive frame decode errors, last error: %s\n", - max_tries, v4lconvert_get_error_message(devices[index].convert)); - } - - return result; -} - -static int v4l2_queue_read_buffers(int index) -{ - unsigned int i; - int last_error = EIO, queued = 0; - - for (i = 0; i < devices[index].no_frames; i++) { - /* Don't queue unmapped buffers (should never happen) */ - if (devices[index].frame_pointers[i] != MAP_FAILED) { - if (v4l2_queue_read_buffer(index, i)) { - last_error = errno; - continue; - } - queued++; - } - } - - if (!queued) { - errno = last_error; - return -1; - } - return 0; -} - -static int v4l2_activate_read_stream(int index) -{ - int result; - - if ((result = v4l2_request_read_buffers(index))) - return result; - - if ((result = v4l2_map_buffers(index))) - return result; - - if ((result = v4l2_queue_read_buffers(index))) - return result; - - devices[index].flags |= V4L2_STREAM_CONTROLLED_BY_READ; - - return result = v4l2_streamon(index); -} - -static int v4l2_deactivate_read_stream(int index) -{ - int result; - - if ((result = v4l2_streamoff(index))) - return result; - - /* No need to unqueue our buffers, streamoff does that for us */ - - v4l2_unmap_buffers(index); - - 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, ...) -{ - int fd; - - /* original open code */ - if (oflag & O_CREAT) - { - va_list ap; - mode_t mode; - - va_start (ap, oflag); - mode = va_arg (ap, mode_t); - - fd = syscall(SYS_open, file, oflag, mode); - - va_end(ap); - } - else - fd = syscall(SYS_open, file, oflag); - /* end of original open code */ - - if (fd == -1) - return fd; - - if (v4l2_fd_open(fd, 0) == -1) { - int saved_err = errno; - syscall(SYS_close, fd); - errno = saved_err; - return -1; - } - - return fd; -} - -int v4l2_fd_open(int fd, int v4l2_flags) -{ - int i, index; - char *lfname; - struct v4l2_capability cap; - struct v4l2_format fmt; - struct v4lconvert_data *convert; - - /* If no log file was set by the app, see if one was specified through the - environment */ - if (!v4l2_log_file && (lfname = getenv("LIBV4L2_LOG_FILENAME"))) - v4l2_log_file = fopen(lfname, "w"); - - /* check that this is an v4l2 device */ - if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap)) { - int saved_err = errno; - V4L2_LOG_ERR("getting capabilities: %s\n", strerror(errno)); - errno = saved_err; - return -1; - } - - /* we only add functionality for video capture devices, and we do not - handle devices which don't do mmap */ - if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) || - !(cap.capabilities & V4L2_CAP_STREAMING)) - return fd; - - /* Get current cam format */ - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (syscall(SYS_ioctl, fd, VIDIOC_G_FMT, &fmt)) { - int saved_err = errno; - V4L2_LOG_ERR("getting pixformat: %s\n", strerror(errno)); - errno = saved_err; - return -1; - } - - /* init libv4lconvert */ - if (!(convert = v4lconvert_create(fd))) - return -1; - - /* So we have a v4l2 capture device, register it in our devices array */ - pthread_mutex_lock(&v4l2_open_mutex); - for (index = 0; index < V4L2_MAX_DEVICES; index++) - if(devices[index].fd == -1) { - devices[index].fd = fd; - break; - } - pthread_mutex_unlock(&v4l2_open_mutex); - - if (index == V4L2_MAX_DEVICES) { - V4L2_LOG_ERR("attempting to open more then %d video devices\n", - V4L2_MAX_DEVICES); - errno = EBUSY; - return -1; - } - - 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; - - pthread_mutex_init(&devices[index].stream_lock, NULL); - - devices[index].no_frames = 0; - devices[index].nreadbuffers = V4L2_DEFAULT_NREADBUFFERS; - devices[index].convert = convert; - devices[index].convert_mmap_buf = MAP_FAILED; - for (i = 0; i < V4L2_MAX_NO_FRAMES; i++) { - devices[index].frame_pointers[i] = MAP_FAILED; - devices[index].frame_map_count[i] = 0; - } - devices[index].frame_queued = 0; - - if (index >= devices_used) - devices_used = index + 1; - - V4L2_LOG("open: %d\n", fd); - - return fd; -} - -/* Is this an fd for which we are emulating v4l1 ? */ -static int v4l2_get_index(int fd) -{ - int index; - - /* We never handle fd -1 */ - if (fd == -1) - return -1; - - for (index = 0; index < devices_used; index++) - if (devices[index].fd == fd) - break; - - if (index == devices_used) - return -1; - - return index; -} - - -int v4l2_close(int fd) -{ - int index, result; - - if ((index = v4l2_get_index(fd)) == -1) - return syscall(SYS_close, fd); - - /* Abuse stream_lock to stop 2 closes from racing and trying to free the - resources twice */ - pthread_mutex_lock(&devices[index].stream_lock); - devices[index].open_count--; - result = devices[index].open_count != 0; - pthread_mutex_unlock(&devices[index].stream_lock); - - if (result) - return 0; - - /* Free resources */ - v4l2_unmap_buffers(index); - v4lconvert_destroy(devices[index].convert); - if (devices[index].convert_mmap_buf != MAP_FAILED) { - 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); - devices[index].convert_mmap_buf = MAP_FAILED; - } - - /* Remove the fd from our list of managed fds before closing it, because as - soon as we've done the actual close the fd maybe returned by an open in - another thread and we don't want to intercept calls to this new fd. */ - devices[index].fd = -1; - - /* Since we've marked the fd as no longer used, and freed the resources, - redo the close in case it was interrupted */ - do { - result = syscall(SYS_close, fd); - } while (result == -1 && errno == EINTR); - - V4L2_LOG("close: %d\n", fd); - - return result; -} - -int v4l2_dup(int fd) -{ - int index; - - if ((index = v4l2_get_index(fd)) == -1) - return syscall(SYS_dup, fd); - - devices[index].open_count++; - - 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, ...) -{ - void *arg; - va_list ap; - int result, converting, index, saved_err; - int is_capture_request = 0, stream_needs_locking = 0; - - va_start (ap, request); - arg = va_arg (ap, void *); - va_end (ap); - - if ((index = v4l2_get_index(fd)) == -1) - return syscall(SYS_ioctl, fd, request, arg); - - /* Appearantly the kernel and / or glibc ignore the 32 most significant bits - when long = 64 bits, and some applications pass an int holding the req to - ioctl, causing it to get sign extended, depending upon this behavior */ - request = (unsigned int)request; - - /* Is this a capture request and do we need to take the stream lock? */ - switch (request) { - case VIDIOC_QUERYCAP: - is_capture_request = 1; - break; - case VIDIOC_ENUM_FMT: - if (((struct v4l2_fmtdesc *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && - (devices[index].flags & V4L2_ENABLE_ENUM_FMT_EMULATION)) - is_capture_request = 1; - break; - case VIDIOC_ENUM_FRAMESIZES: - case VIDIOC_ENUM_FRAMEINTERVALS: - if (devices[index].flags & V4L2_ENABLE_ENUM_FMT_EMULATION) - is_capture_request = 1; - break; - case VIDIOC_TRY_FMT: - if (((struct v4l2_format *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - is_capture_request = 1; - break; - case VIDIOC_S_FMT: - case VIDIOC_G_FMT: - if (((struct v4l2_format *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - is_capture_request = 1; - stream_needs_locking = 1; - } - break; - case VIDIOC_REQBUFS: - if (((struct v4l2_requestbuffers *)arg)->type == - V4L2_BUF_TYPE_VIDEO_CAPTURE) { - is_capture_request = 1; - stream_needs_locking = 1; - } - break; - case VIDIOC_QUERYBUF: - case VIDIOC_QBUF: - case VIDIOC_DQBUF: - if (((struct v4l2_buffer *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - is_capture_request = 1; - stream_needs_locking = 1; - } - break; - case VIDIOC_STREAMON: - case VIDIOC_STREAMOFF: - if (*((enum v4l2_buf_type *)arg) == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - is_capture_request = 1; - stream_needs_locking = 1; - } - } - - if (!is_capture_request) { - result = syscall(SYS_ioctl, fd, request, arg); - saved_err = errno; - v4l2_log_ioctl(request, arg, result); - errno = saved_err; - return result; - } - - - if (stream_needs_locking) - pthread_mutex_lock(&devices[index].stream_lock); - - converting = v4lconvert_needs_conversion(devices[index].convert, - &devices[index].src_fmt, &devices[index].dest_fmt); - - switch (request) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QUERYCAP, cap); - if (result == 0) - /* We always support read() as we fake it using mmap mode */ - cap->capabilities |= V4L2_CAP_READWRITE; - } - break; - - case VIDIOC_ENUM_FMT: - result = v4lconvert_enum_fmt(devices[index].convert, arg); - break; - - case VIDIOC_ENUM_FRAMESIZES: - result = v4lconvert_enum_framesizes(devices[index].convert, arg); - break; - - case VIDIOC_ENUM_FRAMEINTERVALS: - result = v4lconvert_enum_frameintervals(devices[index].convert, arg); - break; - - case VIDIOC_TRY_FMT: - result = v4lconvert_try_format(devices[index].convert, arg, NULL); - break; - - case VIDIOC_S_FMT: - { - struct v4l2_format src_fmt, *dest_fmt = arg; - - if (!memcmp(&devices[index].dest_fmt, dest_fmt, sizeof(*dest_fmt))) { - result = 0; - break; - } - - if (devices[index].flags & V4L2_DISABLE_CONVERSION) { - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_TRY_FMT, - dest_fmt); - src_fmt = *dest_fmt; - } else { - result = v4lconvert_try_format(devices[index].convert, dest_fmt, - &src_fmt); - } - - if (result) - break; - - if (src_fmt.fmt.pix.pixelformat != dest_fmt->fmt.pix.pixelformat && - v4l2_log_file) { - int pixfmt = src_fmt.fmt.pix.pixelformat; - - fprintf(v4l2_log_file, "VIDIOC_S_FMT converting from: %c%c%c%c\n", - pixfmt & 0xff, - (pixfmt >> 8) & 0xff, - (pixfmt >> 16) & 0xff, - pixfmt >> 24); - } - - /* Maybe after try format has adjusted width/height etc, to whats - available nothing has changed (on the cam side) ? */ - if (!memcmp(&devices[index].src_fmt, &src_fmt, sizeof(src_fmt))) { - devices[index].dest_fmt = *dest_fmt; - result = 0; - break; - } - - if ((result = v4l2_check_buffer_change_ok(index))) - break; - - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_S_FMT, &src_fmt); - if (result) { - saved_err = errno; - V4L2_LOG_ERR("setting pixformat: %s\n", strerror(errno)); - /* Report to the app dest_fmt has not changed */ - *dest_fmt = devices[index].dest_fmt; - errno = saved_err; - break; - } - - devices[index].src_fmt = src_fmt; - devices[index].dest_fmt = *dest_fmt; - } - break; - - case VIDIOC_G_FMT: - { - struct v4l2_format* fmt = arg; - - *fmt = devices[index].dest_fmt; - result = 0; - } - break; - - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *req = arg; - - /* IMPROVEME (maybe?) add support for userptr's? */ - if (req->memory != V4L2_MEMORY_MMAP) { - errno = EINVAL; - result = -1; - 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; - - 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 */ - - devices[index].no_frames = MIN(req->count, V4L2_MAX_NO_FRAMES); - devices[index].flags &= ~V4L2_BUFFERS_REQUESTED_BY_READ; - } - break; - - case VIDIOC_QUERYBUF: - { - 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); - if (result || !converting) - break; - - buf->m.offset = V4L2_MMAP_OFFSET_MAGIC | buf->index; - buf->length = V4L2_FRAME_BUF_SIZE; - if (devices[index].frame_map_count[buf->index]) - buf->flags |= V4L2_BUF_FLAG_MAPPED; - else - buf->flags &= ~V4L2_BUF_FLAG_MAPPED; - } - break; - - case VIDIOC_QBUF: - if (devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) - 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; - - case VIDIOC_DQBUF: - { - struct v4l2_buffer *buf = arg; - - if (devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) - if ((result = v4l2_deactivate_read_stream(index))) - break; - - if (!converting) { - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_DQBUF, buf); - if (result) { - int saved_err = errno; - V4L2_LOG_ERR("dequeuing buf: %s\n", strerror(errno)); - errno = saved_err; - } - break; - } - - /* An application can do a DQBUF before mmap-ing in the buffer, - but we need the buffer _now_ to write our converted data - to it! */ - if (devices[index].convert_mmap_buf == MAP_FAILED) { - devices[index].convert_mmap_buf = (void *)syscall(SYS_mmap2, - (size_t)( - devices[index].no_frames * - V4L2_FRAME_BUF_SIZE), - PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, - -1, 0); - if (devices[index].convert_mmap_buf == MAP_FAILED) { - saved_err = errno; - V4L2_LOG_ERR("allocating conversion buffer\n"); - errno = saved_err; - result = -1; - break; - } - } - - result = v4l2_dequeue_and_convert(index, buf, 0, V4L2_FRAME_BUF_SIZE); - if (result < 0) - break; - - buf->bytesused = result; - buf->m.offset = V4L2_MMAP_OFFSET_MAGIC | buf->index; - buf->length = V4L2_FRAME_BUF_SIZE; - if (devices[index].frame_map_count[buf->index]) - buf->flags |= V4L2_BUF_FLAG_MAPPED; - else - buf->flags &= ~V4L2_BUF_FLAG_MAPPED; - - result = 0; - } - break; - - case VIDIOC_STREAMON: - case VIDIOC_STREAMOFF: - 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); - else - result = v4l2_streamoff(index); - break; - - default: - result = syscall(SYS_ioctl, fd, request, arg); - } - - if (stream_needs_locking) - pthread_mutex_unlock(&devices[index].stream_lock); - - saved_err = errno; - v4l2_log_ioctl(request, arg, result); - errno = saved_err; - - return result; -} - - -ssize_t v4l2_read (int fd, void* dest, size_t n) -{ - ssize_t result; - int index; - struct v4l2_buffer buf; - - if ((index = v4l2_get_index(fd)) == -1) - return syscall(SYS_read, fd, dest, 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) && - !v4lconvert_needs_conversion(devices[index].convert, - &devices[index].src_fmt, &devices[index].dest_fmt)) { - result = syscall(SYS_read, fd, dest, n); - 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; - } - - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - result = v4l2_dequeue_and_convert(index, &buf, dest, n); - - if (result >= 0) - v4l2_queue_read_buffer(index, buf.index); - -leave: - pthread_mutex_unlock(&devices[index].stream_lock); - - return result; -} - -void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, - __off64_t offset) -{ - int index; - unsigned int buffer_index; - void *result; - - if ((index = v4l2_get_index(fd)) == -1 || - /* Check if the mmap data matches our answer to QUERY_BUF, if it doesn't - let the kernel handle it (to allow for mmap based non capture use) */ - start || length != V4L2_FRAME_BUF_SIZE || - ((unsigned int)offset & ~0xFFu) != V4L2_MMAP_OFFSET_MAGIC) { - if (index != -1) - V4L2_LOG("Passing mmap(%p, %d, ..., %x, through to the driver\n", - start, (int)length, (int)offset); - - if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) { - errno = EINVAL; - return MAP_FAILED; - } - - return (void *)syscall(SYS_mmap2, start, length, prot, flags, fd, - (__off_t)(offset >> MMAP2_PAGE_SHIFT)); - } - - pthread_mutex_lock(&devices[index].stream_lock); - - buffer_index = offset & 0xff; - if (buffer_index >= devices[index].no_frames || - /* Got magic offset and not converting ?? */ - !v4lconvert_needs_conversion(devices[index].convert, - &devices[index].src_fmt, &devices[index].dest_fmt)) { - errno = EINVAL; - result = MAP_FAILED; - goto leave; - } - - if (devices[index].convert_mmap_buf == MAP_FAILED) { - devices[index].convert_mmap_buf = (void *)syscall(SYS_mmap2, NULL, - (size_t)( - devices[index].no_frames * - V4L2_FRAME_BUF_SIZE), - PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, - -1, 0); - if (devices[index].convert_mmap_buf == MAP_FAILED) { - int saved_err = errno; - V4L2_LOG_ERR("allocating conversion buffer\n"); - errno = saved_err; - result = MAP_FAILED; - goto leave; - } - } - - devices[index].frame_map_count[buffer_index]++; - - result = devices[index].convert_mmap_buf + - buffer_index * V4L2_FRAME_BUF_SIZE; - - V4L2_LOG("Fake (conversion) mmap buf %u, seen by app at: %p\n", - buffer_index, result); - -leave: - pthread_mutex_unlock(&devices[index].stream_lock); - - return result; -} - -int v4l2_munmap(void *_start, size_t length) -{ - int index; - unsigned int buffer_index; - unsigned char *start = _start; - - /* Is this memory ours? */ - if (start != MAP_FAILED && length == V4L2_FRAME_BUF_SIZE) { - for (index = 0; index < devices_used; index++) - if (devices[index].fd != -1 && - devices[index].convert_mmap_buf != MAP_FAILED && - start >= devices[index].convert_mmap_buf && - (start - devices[index].convert_mmap_buf) % length == 0) - break; - - if (index != devices_used) { - int unmapped = 0; - - pthread_mutex_lock(&devices[index].stream_lock); - - buffer_index = (start - devices[index].convert_mmap_buf) / length; - - /* Redo our checks now that we have the lock, things may have changed */ - if (devices[index].convert_mmap_buf != MAP_FAILED && - start >= devices[index].convert_mmap_buf && - (start - devices[index].convert_mmap_buf) % length == 0 && - buffer_index < devices[index].no_frames) { - if (devices[index].frame_map_count[buffer_index] > 0) - devices[index].frame_map_count[buffer_index]--; - unmapped = 1; - } - - pthread_mutex_unlock(&devices[index].stream_lock); - - if (unmapped) { - V4L2_LOG("v4l2 fake buffer munmap %p, %d\n", start, (int)length); - return 0; - } - } - } - - V4L2_LOG("v4l2 unknown munmap %p, %d\n", start, (int)length); - - return syscall(SYS_munmap, _start, length); -} - -/* Misc utility functions */ -int v4l2_set_control(int fd, int cid, int value) -{ - struct v4l2_queryctrl qctrl = { .id = cid }; - struct v4l2_control ctrl = { .id = cid }; - int result; - - if ((result = syscall(SYS_ioctl, fd, VIDIOC_QUERYCTRL, &qctrl))) - return result; - - if (!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED) && - !(qctrl.flags & V4L2_CTRL_FLAG_GRABBED)) { - if (qctrl.type == V4L2_CTRL_TYPE_BOOLEAN) - ctrl.value = value? 1:0; - else - ctrl.value = (value * (qctrl.maximum - qctrl.minimum) + 32767) / 65535 + - qctrl.minimum; - - result = syscall(SYS_ioctl, fd, VIDIOC_S_CTRL, &ctrl); - } - - return result; -} - -int v4l2_get_control(int fd, int cid) -{ - struct v4l2_queryctrl qctrl = { .id = cid }; - struct v4l2_control ctrl = { .id = cid }; - - if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCTRL, &qctrl)) - return 0; - - if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) - return 0; - - if (syscall(SYS_ioctl, fd, VIDIOC_G_CTRL, &ctrl)) - return 0; - - return ((ctrl.value - qctrl.minimum) * 65535 + - (qctrl.maximum - qctrl.minimum) / 2) / - (qctrl.maximum - qctrl.minimum); -} diff --git a/v4l2-apps/lib/libv4l/libv4l2/log.c b/v4l2-apps/lib/libv4l/libv4l2/log.c deleted file mode 100644 index 6237d55ec..000000000 --- a/v4l2-apps/lib/libv4l/libv4l2/log.c +++ /dev/null @@ -1,148 +0,0 @@ -/* -# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# 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 -# 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 -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <linux/ioctl.h> -/* These headers are not needed by us, but by linux/videodev2.h, - which is broken on some systems and doesn't include them itself :( */ -#include <sys/time.h> -#include <asm/types.h> -/* end broken header workaround includes */ -#include <linux/videodev2.h> -#include "libv4l2.h" -#include "libv4l2-priv.h" - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) - -FILE *v4l2_log_file = NULL; - -static const char *v4l2_ioctls[] = { - /* start v4l2 ioctls */ - [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", - [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", - [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", - [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", - [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", - [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", - [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", - [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", - [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", - [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", - [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", - [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", - [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", - [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", - [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", - [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", - [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", - [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", - [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", - [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", - [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", - [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", - [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", - [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", - [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", - [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", - [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", - [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", - [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", - [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", - [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", - [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", - [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", - [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", - [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", - [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", - [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", - [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", - [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", - [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", - [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", - [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", - [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", - [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", - [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", - [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", - [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", - [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", - [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", - [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", - [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", - [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", - [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", - [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", - [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", -}; - -void v4l2_log_ioctl(unsigned long int request, void *arg, int result) -{ - const char *ioctl_str; - char buf[40]; - - if (!v4l2_log_file) - return; - - if (_IOC_TYPE(request) == 'V' && _IOC_NR(request) < ARRAY_SIZE(v4l2_ioctls)) - ioctl_str = v4l2_ioctls[_IOC_NR(request)]; - else { - snprintf(buf, sizeof(buf), "unknown request: %c %d\n", - (int)_IOC_TYPE(request), (int)_IOC_NR(request)); - ioctl_str = buf; - } - - fprintf(v4l2_log_file, "request == %s\n", ioctl_str); - - switch (request) { - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: - { - struct v4l2_format* fmt = arg; - int pixfmt = fmt->fmt.pix.pixelformat; - - if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - fprintf(v4l2_log_file, " pixelformat: %c%c%c%c %ux%u\n", - pixfmt & 0xff, - (pixfmt >> 8) & 0xff, - (pixfmt >> 16) & 0xff, - pixfmt >> 24, - fmt->fmt.pix.width, - fmt->fmt.pix.height); - fprintf(v4l2_log_file, " field: %d bytesperline: %d imagesize%d\n", - (int)fmt->fmt.pix.field, (int)fmt->fmt.pix.bytesperline, - (int)fmt->fmt.pix.sizeimage); - fprintf(v4l2_log_file, " colorspace: %d, priv: %x\n", - (int)fmt->fmt.pix.colorspace, (int)fmt->fmt.pix.priv); - } - } - break; - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *req = arg; - - fprintf(v4l2_log_file, " count: %u type: %d memory: %d\n", - req->count, (int)req->type, (int)req->memory); - } - break; - } - - fprintf(v4l2_log_file, "result == %d\n", result); - fflush(v4l2_log_file); -} diff --git a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c b/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c deleted file mode 100644 index 307a03ce5..000000000 --- a/v4l2-apps/lib/libv4l/libv4l2/v4l2convert.c +++ /dev/null @@ -1,166 +0,0 @@ -/* -# open/close/ioctl/mmap/munmap library call wrapper doing format conversion -# for v4l2 applications which want to be able to simply capture bgr24 / yuv420 -# from v4l2 devices with more exotic frame formats. - -# (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl> - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# 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 -# 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 -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#define _LARGEFILE64_SOURCE 1 - -#include <stdarg.h> -#include <stdlib.h> -#include <syscall.h> -#include <fcntl.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -/* These headers are not needed by us, but by linux/videodev2.h, - which is broken on some systems and doesn't include them itself :( */ -#include <sys/time.h> -#include <asm/types.h> -#include <linux/ioctl.h> -/* end broken header workaround includes */ -#include <linux/videodev2.h> -#include <libv4l2.h> - -/* Check that open/read/mmap is not a define */ -#if defined open || defined read || defined mmap -#error open/read/mmap is a prepocessor macro !! -#endif - -#if __GNUC__ >= 4 -#define LIBV4L_PUBLIC __attribute__ ((visibility("default"))) -#else -#define LIBV4L_PUBLIC -#endif - -LIBV4L_PUBLIC int open (const char *file, int oflag, ...) -{ - int fd; - struct v4l2_capability cap; - int v4l_device = 0; - - /* check if we're opening a video4linux2 device */ - if (!strncmp(file, "/dev/video", 10) || !strncmp(file, "/dev/v4l/", 9)) { - /* Some apps open the device read only, but we need rw rights as the - buffers *MUST* be mapped rw */ - oflag = (oflag & ~O_ACCMODE) | O_RDWR; - v4l_device = 1; - } - - /* original open code */ - if (oflag & O_CREAT) - { - va_list ap; - mode_t mode; - - va_start (ap, oflag); - mode = va_arg (ap, mode_t); - - fd = syscall(SYS_open, file, oflag, mode); - - va_end(ap); - } else - fd = syscall(SYS_open, file, oflag); - /* end of original open code */ - - if (fd == -1 || !v4l_device) - return fd; - - /* check that this is an v4l2 device, libv4l2 only supports v4l2 devices */ - if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap)) - return fd; - - /* libv4l2 only adds functionality to capture capable devices */ - if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) - return fd; - - /* Try to Register with libv4l2 (in case of failure pass the fd to the - application as is) */ - v4l2_fd_open(fd, V4L2_ENABLE_ENUM_FMT_EMULATION); - - return fd; -} - -LIBV4L_PUBLIC int open64(const char *file, int oflag, ...) -{ - int fd; - - /* original open code */ - if (oflag & O_CREAT) - { - va_list ap; - mode_t mode; - - va_start (ap, oflag); - mode = va_arg (ap, mode_t); - - fd = open(file, oflag | O_LARGEFILE, mode); - - va_end(ap); - } else - fd = open(file, oflag | O_LARGEFILE); - /* end of original open code */ - - return fd; -} - -LIBV4L_PUBLIC int close(int fd) -{ - return v4l2_close(fd); -} - -LIBV4L_PUBLIC int dup(int fd) -{ - return v4l2_dup(fd); -} - -LIBV4L_PUBLIC int ioctl (int fd, unsigned long int request, ...) -{ - void *arg; - va_list ap; - - va_start (ap, request); - arg = va_arg (ap, void *); - va_end (ap); - - return v4l2_ioctl (fd, request, arg); -} - -LIBV4L_PUBLIC ssize_t read (int fd, void* buffer, size_t n) -{ - return v4l2_read (fd, buffer, n); -} - -LIBV4L_PUBLIC 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); -} - -LIBV4L_PUBLIC 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); -} - -LIBV4L_PUBLIC int munmap(void *start, size_t length) -{ - return v4l2_munmap(start, length); -} - |