diff options
Diffstat (limited to 'v4l2-apps/lib/libv4l/libv4l1')
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l1/Makefile | 83 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l1/libv4l1-priv.h | 83 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l1/libv4l1.c | 837 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l1/log.c | 145 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l1/v4l1compat.c | 127 |
5 files changed, 0 insertions, 1275 deletions
diff --git a/v4l2-apps/lib/libv4l/libv4l1/Makefile b/v4l2-apps/lib/libv4l/libv4l1/Makefile deleted file mode 100644 index 27848477e..000000000 --- a/v4l2-apps/lib/libv4l/libv4l1/Makefile +++ /dev/null @@ -1,83 +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 - -V4L1_OBJS = libv4l1.o log.o -V4L1COMPAT = v4l1compat.so -V4L1COMPAT_O = v4l1compat.o libv4l1.so -TARGETS = $(V4L1_LIB) libv4l1.pc -INCLUDES = ../include/libv4l1.h - -ifeq ($(LINKTYPE),static) -V4L1_LIB = libv4l1.a -else -V4L1_LIB = libv4l1.so -V4L1_OBJS += ../libv4l2/libv4l2.so -TARGETS += $(V4L1COMPAT) -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) - - -$(V4L1_LIB): $(V4L1_OBJS) - -$(V4L1COMPAT): $(V4L1COMPAT_O) $(V4L1_LIB) - -libv4l1.pc: - @echo prefix=$(PREFIX) > libv4l1.pc - @echo libdir=$(LIBDIR) >> libv4l1.pc - @echo >> libv4l1.pc - @echo 'Name: libv4l1' >> libv4l1.pc - @echo 'Description: v4l1 compatibility library' >> libv4l1.pc - @echo 'Version: '$(V4L2_LIB_VERSION) >> libv4l1.pc - @echo 'Requires: libv4l2' >> libv4l1.pc - @echo 'Libs: -L$${libdir} -lv4l1' >> libv4l1.pc - @echo 'Libs.private: -lpthread' >> libv4l1.pc - @echo 'Cflags: -I$${prefix}/include' >> libv4l1.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 $(V4L1_LIB) $(DESTDIR)$(LIBDIR) -else - mkdir -p $(DESTDIR)$(LIBDIR)/libv4l - install -m 755 $(V4L1_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR) - cd $(DESTDIR)$(LIBDIR) && \ - ln -f -s $(V4L1_LIB).$(LIB_RELEASE) $(V4L1_LIB) - install -m 755 $(V4L1COMPAT).$(LIB_RELEASE) \ - $(DESTDIR)$(LIBDIR)/libv4l/$(V4L1COMPAT) -endif - mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig - install -m 644 libv4l1.pc $(DESTDIR)$(LIBDIR)/pkgconfig - -clean:: - rm -f *.a *.so* *.o *.d libv4l1.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/libv4l1/libv4l1-priv.h b/v4l2-apps/lib/libv4l/libv4l1/libv4l1-priv.h deleted file mode 100644 index 651599255..000000000 --- a/v4l2-apps/lib/libv4l/libv4l1/libv4l1-priv.h +++ /dev/null @@ -1,83 +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 __LIBV4L1_PRIV_H -#define __LIBV4L1_PRIV_H - -#include <stdio.h> -#include <pthread.h> - -/* 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 V4L1_MAX_DEVICES 16 -#define V4L1_NO_FRAMES 4 -#define V4L1_FRAME_BUF_SIZE (4096 * 4096) - -extern FILE *v4l1_log_file; - -#define V4L1_LOG_ERR(...) \ - do { \ - if (v4l1_log_file) { \ - fprintf(v4l1_log_file, "libv4l1: error " __VA_ARGS__); \ - fflush(v4l1_log_file); \ - } else \ - fprintf(stderr, "libv4l1: error " __VA_ARGS__); \ - } while(0) - -#define V4L1_LOG_WARN(...) \ - do { \ - if (v4l1_log_file) { \ - fprintf(v4l1_log_file, "libv4l1: warning " __VA_ARGS__); \ - fflush(v4l1_log_file); \ - } else \ - fprintf(stderr, "libv4l1: warning " __VA_ARGS__); \ - } while(0) - -#define V4L1_LOG(...) \ - do { \ - if (v4l1_log_file) { \ - fprintf(v4l1_log_file, "libv4l1: " __VA_ARGS__); \ - fflush(v4l1_log_file); \ - } \ - } while(0) - -struct v4l1_dev_info { - int fd; - int flags; - int open_count; - int v4l1_frame_buf_map_count; - pthread_mutex_t stream_lock; - unsigned int depth; - unsigned int v4l1_pal; /* VIDEO_PALETTE */ - unsigned int v4l2_pixfmt; /* V4L2_PIX_FMT */ - unsigned int min_width, min_height, max_width, max_height; - unsigned int width, height; - unsigned char *v4l1_frame_pointer; -}; - -/* From log.c */ -void v4l1_log_ioctl(unsigned long int request, void *arg, int result); - -#endif diff --git a/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c b/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c deleted file mode 100644 index 797c8768a..000000000 --- a/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c +++ /dev/null @@ -1,837 +0,0 @@ -/* -# libv4l1 userspace v4l1 api emulation for v4l2 devices - -# (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 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!!! - - Important note to people making changes to this file: All functions - (v4l1_close, v4l1_ioctl, etc.) are designed to function as their regular - counterpart when they get passed a fd that is not "registered" by libv4l1, - there are 2 reasons for this: - 1) This allows us to get completely out of the way when dealing with non - capture only devices, or non v4l2 devices. - 2) libv4l1 is the base of the v4l1compat.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 v4l1_open. Because we - behave as the regular counterpart when the fd is not known (instead of - say throwing an error), v4l1compat.so can simply call the v4l1_ prefixed - function for all wrapped functions. This way the wrapper does not have - to keep track of which fd's are being handled by libv4l1, as libv4l1 - already keeps track of this itself. - - This also means that libv4l1 may not use any of the regular functions - it mimics, as for example open could be a symbol in v4l1compat.so, which - in turn will call v4l1_open, so therefor v4l1_open (for example) may not - use the regular open()! -*/ -#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> -/* 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/videodev.h> -#include <linux/videodev2.h> -#include <libv4l2.h> -#include "libv4l1.h" -#include "libv4l1-priv.h" - -#define V4L1_SUPPORTS_ENUMINPUT 0x01 -#define V4L1_SUPPORTS_ENUMSTD 0x02 -#define V4L1_PIX_FMT_TOUCHED 0x04 -#define V4L1_PIX_SIZE_TOUCHED 0x08 - -static pthread_mutex_t v4l1_open_mutex = PTHREAD_MUTEX_INITIALIZER; -static struct v4l1_dev_info devices[V4L1_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 unsigned int palette_to_pixelformat(unsigned int palette) -{ - switch (palette) { - case VIDEO_PALETTE_GREY: - return V4L2_PIX_FMT_GREY; - case VIDEO_PALETTE_RGB555: - return V4L2_PIX_FMT_RGB555; - case VIDEO_PALETTE_RGB565: - return V4L2_PIX_FMT_RGB565; - case VIDEO_PALETTE_RGB24: - return V4L2_PIX_FMT_BGR24; - case VIDEO_PALETTE_RGB32: - return V4L2_PIX_FMT_BGR32; - case VIDEO_PALETTE_YUYV: - return V4L2_PIX_FMT_YUYV; - case VIDEO_PALETTE_YUV422: - return V4L2_PIX_FMT_YUYV; - case VIDEO_PALETTE_UYVY: - return V4L2_PIX_FMT_UYVY; - case VIDEO_PALETTE_YUV410P: - return V4L2_PIX_FMT_YUV410; - case VIDEO_PALETTE_YUV420: - case VIDEO_PALETTE_YUV420P: - return V4L2_PIX_FMT_YUV420; - case VIDEO_PALETTE_YUV411P: - return V4L2_PIX_FMT_YUV411P; - case VIDEO_PALETTE_YUV422P: - return V4L2_PIX_FMT_YUV422P; - } - return 0; -} - -static unsigned int pixelformat_to_palette(unsigned int pixelformat) -{ - switch (pixelformat) { - case V4L2_PIX_FMT_GREY: - return VIDEO_PALETTE_GREY; - case V4L2_PIX_FMT_RGB555: - return VIDEO_PALETTE_RGB555; - case V4L2_PIX_FMT_RGB565: - return VIDEO_PALETTE_RGB565; - case V4L2_PIX_FMT_BGR24: - return VIDEO_PALETTE_RGB24; - case V4L2_PIX_FMT_BGR32: - return VIDEO_PALETTE_RGB32; - case V4L2_PIX_FMT_YUYV: - return VIDEO_PALETTE_YUYV; - case V4L2_PIX_FMT_UYVY: - return VIDEO_PALETTE_UYVY; - case V4L2_PIX_FMT_YUV410: - case V4L2_PIX_FMT_YUV420: - return VIDEO_PALETTE_YUV420P; - case V4L2_PIX_FMT_YUV411P: - return VIDEO_PALETTE_YUV411P; - case V4L2_PIX_FMT_YUV422P: - return VIDEO_PALETTE_YUV422P; - } - return 0; -} - -static int v4l1_set_format(int index, unsigned int width, - unsigned int height, int v4l1_pal, int width_height_may_differ) -{ - int result; - unsigned int v4l2_pixfmt; - struct v4l2_format fmt2 = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; - - if (v4l1_pal != -1) { - v4l2_pixfmt = palette_to_pixelformat(v4l1_pal); - if (!v4l2_pixfmt) { - V4L1_LOG("Unknown v4l1 palette number: %d\n", v4l1_pal); - errno = EINVAL; - return -1; - } - } else { - v4l2_pixfmt = devices[index].v4l2_pixfmt; - v4l1_pal = devices[index].v4l1_pal; - } - - /* Do we need to change the resolution / format ? */ - if (width == devices[index].width && height == devices[index].height && - v4l2_pixfmt == devices[index].v4l2_pixfmt) - return 0; - - /* Get current settings, apply our changes and try the new setting */ - if ((result = v4l2_ioctl(devices[index].fd, VIDIOC_G_FMT, &fmt2))) { - int saved_err = errno; - V4L1_LOG_ERR("getting pixformat: %s\n", strerror(errno)); - errno = saved_err; - return result; - } - - fmt2.fmt.pix.pixelformat = v4l2_pixfmt; - fmt2.fmt.pix.width = width; - fmt2.fmt.pix.height = height; - if ((result = v4l2_ioctl(devices[index].fd, VIDIOC_TRY_FMT, &fmt2))) - { - int saved_err = errno; - V4L1_LOG("error trying pixformat: %s\n", strerror(errno)); - errno = saved_err; - return result; - } - - /* Check if we get what we asked for */ - if (fmt2.fmt.pix.pixelformat != v4l2_pixfmt || (!width_height_may_differ && - (fmt2.fmt.pix.width != width || fmt2.fmt.pix.height != height))) { - V4L1_LOG("requested fmt, width, height combo not available\n"); - errno = EINVAL; - return -1; - } - - /* Maybe after the TRY_FMT things haven't changed after all ? */ - if (fmt2.fmt.pix.width == devices[index].width && - fmt2.fmt.pix.height == devices[index].height && - fmt2.fmt.pix.pixelformat == devices[index].v4l2_pixfmt) { - devices[index].v4l1_pal = v4l1_pal; - return 0; - } - - if ((result = v4l2_ioctl(devices[index].fd, VIDIOC_S_FMT, &fmt2))) { - int saved_err = errno; - V4L1_LOG_ERR("setting pixformat: %s\n", strerror(errno)); - errno = saved_err; - return result; - } - - devices[index].width = fmt2.fmt.pix.width; - devices[index].height = fmt2.fmt.pix.height; - devices[index].v4l2_pixfmt = v4l2_pixfmt; - devices[index].v4l1_pal = v4l1_pal; - devices[index].depth = ((fmt2.fmt.pix.bytesperline << 3) + - (fmt2.fmt.pix.width - 1)) / fmt2.fmt.pix.width; - - return result; -} - -static void v4l1_find_min_and_max_size(int index, struct v4l2_format *fmt2) -{ - int i; - struct v4l2_fmtdesc fmtdesc2 = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; - - devices[index].min_width = -1; - devices[index].min_height = -1; - devices[index].max_width = 0; - devices[index].max_height = 0; - - for (i = 0; ; i++) { - fmtdesc2.index = i; - - if (syscall(SYS_ioctl, devices[index].fd, VIDIOC_ENUM_FMT, &fmtdesc2)) - break; - - fmt2->fmt.pix.pixelformat = fmtdesc2.pixelformat; - fmt2->fmt.pix.width = 48; - fmt2->fmt.pix.height = 32; - - if (syscall(SYS_ioctl, devices[index].fd, VIDIOC_TRY_FMT, fmt2) == 0) { - if (fmt2->fmt.pix.width < devices[index].min_width) - devices[index].min_width = fmt2->fmt.pix.width; - if (fmt2->fmt.pix.height < devices[index].min_height) - devices[index].min_height = fmt2->fmt.pix.height; - } - - fmt2->fmt.pix.pixelformat = fmtdesc2.pixelformat; - fmt2->fmt.pix.width = 100000; - fmt2->fmt.pix.height = 100000; - - if (syscall(SYS_ioctl, devices[index].fd, VIDIOC_TRY_FMT, fmt2) == 0) { - if (fmt2->fmt.pix.width > devices[index].max_width) - devices[index].max_width = fmt2->fmt.pix.width; - if (fmt2->fmt.pix.height > devices[index].max_height) - devices[index].max_height = fmt2->fmt.pix.height; - } - } -} - - -int v4l1_open (const char *file, int oflag, ...) -{ - int index, fd; - char *lfname; - struct v4l2_capability cap2; - struct v4l2_format fmt2; - struct v4l2_input input2; - struct v4l2_standard standard2; - 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, no need to emulate v4l1 on - a v4l1 device */ - if (syscall(SYS_ioctl, fd, VIDIOC_QUERYCAP, &cap2)) - return fd; - - /* IMPROVEME */ - /* we only support simple video capture devices which do not do overlay */ - if ((cap2.capabilities & 0x0F) != V4L2_CAP_VIDEO_CAPTURE) - return fd; - - /* If no log file was set by the app, see if one was specified through the - environment */ - if (!v4l1_log_file && (lfname = getenv("LIBV4L1_LOG_FILENAME"))) - v4l1_log_file = fopen(lfname, "w"); - - /* redirect libv4l2 log messages to our logfile if no libv4l2 logfile is - specified */ - if (!v4l2_log_file) - v4l2_log_file = v4l1_log_file; - - /* Get initial width, height and pixelformat */ - fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (syscall(SYS_ioctl, fd, VIDIOC_G_FMT, &fmt2)) { - int saved_err = errno; - V4L1_LOG_ERR("getting pixformat: %s\n", strerror(errno)); - syscall(SYS_close, fd); - errno = saved_err; - return -1; - } - - /* Register with libv4l2, as we use that todo format conversion and read() - emulation for us */ - if (v4l2_fd_open(fd, V4L2_ENABLE_ENUM_FMT_EMULATION) == -1) { - int saved_err = errno; - syscall(SYS_close, fd); - errno = saved_err; - return -1; - } - - /* So we have a device on which we can (and want to) emulate v4l1, register - it in our devices array */ - pthread_mutex_lock(&v4l1_open_mutex); - for (index = 0; index < V4L1_MAX_DEVICES; index++) - if(devices[index].fd == -1) { - devices[index].fd = fd; - break; - } - pthread_mutex_unlock(&v4l1_open_mutex); - - if (index == V4L1_MAX_DEVICES) { - V4L1_LOG_ERR("attempting to open more then %d video devices\n", - V4L1_MAX_DEVICES); - v4l2_close(fd); - errno = EBUSY; - return -1; - } - - if (index >= devices_used) - devices_used = index + 1; - - devices[index].flags = 0; - devices[index].open_count = 1; - devices[index].v4l1_frame_buf_map_count = 0; - devices[index].v4l1_frame_pointer = MAP_FAILED; - devices[index].width = fmt2.fmt.pix.width; - devices[index].height = fmt2.fmt.pix.height; - devices[index].v4l2_pixfmt = fmt2.fmt.pix.pixelformat; - devices[index].v4l1_pal = pixelformat_to_palette(fmt2.fmt.pix.pixelformat); - devices[index].depth = ((fmt2.fmt.pix.bytesperline << 3) + - (fmt2.fmt.pix.width - 1)) / fmt2.fmt.pix.width; - - v4l1_find_min_and_max_size(index, &fmt2); - - /* Check ENUM_INPUT and ENUM_STD support */ - input2.index = 0; - if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &input2) == 0) - devices[index].flags |= V4L1_SUPPORTS_ENUMINPUT; - - standard2.index = 0; - if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &input2) == 0) - devices[index].flags |= V4L1_SUPPORTS_ENUMSTD; - - V4L1_LOG("open: %d\n", fd); - - return fd; -} - -/* Is this an fd for which we are emulating v4l1 ? */ -static int v4l1_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 v4l1_close(int fd) { - int index, result; - - if ((index = v4l1_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 v4l2_close(fd); - - /* Free resources */ - if (devices[index].v4l1_frame_pointer != MAP_FAILED) { - if (devices[index].v4l1_frame_buf_map_count) - V4L1_LOG("v4l1 capture buffer still mapped: %d times on close()\n", - devices[index].v4l1_frame_buf_map_count); - else - syscall(SYS_munmap, devices[index].v4l1_frame_pointer, - V4L1_NO_FRAMES * V4L1_FRAME_BUF_SIZE); - devices[index].v4l1_frame_pointer = 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; - - result = v4l2_close(fd); - - V4L1_LOG("close: %d\n", fd); - - return result; -} - -int v4l1_dup(int fd) -{ - int index; - - if ((index = v4l1_get_index(fd)) == -1) - return syscall(SYS_dup, fd); - - devices[index].open_count++; - - return v4l2_dup(fd); -} - - -int v4l1_ioctl (int fd, unsigned long int request, ...) -{ - void *arg; - va_list ap; - int result, index, saved_err, stream_locked = 0; - - va_start (ap, request); - arg = va_arg (ap, void *); - va_end (ap); - - if ((index = v4l1_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; - - /* do we need to take the stream lock for this ioctl? */ - switch (request) { - case VIDIOCSPICT: - case VIDIOCGPICT: - case VIDIOCSWIN: - case VIDIOCGWIN: - case VIDIOCGMBUF: - case VIDIOCMCAPTURE: - case VIDIOCSYNC: - case VIDIOC_S_FMT: - pthread_mutex_lock(&devices[index].stream_lock); - stream_locked = 1; - } - - switch (request) { - - case VIDIOCGCAP: - { - struct video_capability *cap = arg; - - result = syscall(SYS_ioctl, fd, request, arg); - - /* override kernel v4l1 compat min / max size with our own more - accurate values */ - cap->minwidth = devices[index].min_width; - cap->minheight = devices[index].min_height; - cap->maxwidth = devices[index].max_width; - cap->maxheight = devices[index].max_height; - } - break; - - case VIDIOCSPICT: - { - struct video_picture *pic = arg; - - devices[index].flags |= V4L1_PIX_FMT_TOUCHED; - - v4l2_set_control(fd, V4L2_CID_BRIGHTNESS, pic->brightness); - v4l2_set_control(fd, V4L2_CID_HUE, pic->hue); - v4l2_set_control(fd, V4L2_CID_CONTRAST, pic->contrast); - v4l2_set_control(fd, V4L2_CID_SATURATION, pic->colour); - v4l2_set_control(fd, V4L2_CID_WHITENESS, pic->whiteness); - - result = v4l1_set_format(index, devices[index].width, - devices[index].height, pic->palette, 0); - } - break; - - case VIDIOCGPICT: - { - struct video_picture *pic = arg; - - /* If our v4l2 pixformat has no corresponding v4l1 palette, and the - app has not touched the pixformat sofar, try setting a palette which - does (and which we emulate when necessary) so that applications - which just query the current format and then take whatever they get - will work */ - if (!(devices[index].flags & V4L1_PIX_FMT_TOUCHED) && - !pixelformat_to_palette(devices[index].v4l2_pixfmt)) - v4l1_set_format(index, devices[index].width, - devices[index].height, - VIDEO_PALETTE_RGB24, - (devices[index].flags & - V4L1_PIX_SIZE_TOUCHED) ? 0 : 1); - - devices[index].flags |= V4L1_PIX_FMT_TOUCHED; - - pic->depth = devices[index].depth; - pic->palette = devices[index].v4l1_pal; - pic->hue = v4l2_get_control(devices[index].fd, V4L2_CID_HUE); - pic->colour = v4l2_get_control(devices[index].fd, V4L2_CID_SATURATION); - pic->contrast = v4l2_get_control(devices[index].fd, V4L2_CID_CONTRAST); - pic->whiteness = v4l2_get_control(devices[index].fd, - V4L2_CID_WHITENESS); - pic->brightness = v4l2_get_control(devices[index].fd, - V4L2_CID_BRIGHTNESS); - - result = 0; - } - break; - - case VIDIOCSWIN: - { - struct video_window *win = arg; - - devices[index].flags |= V4L1_PIX_SIZE_TOUCHED; - - result = v4l1_set_format(index, win->width, win->height, -1, 1); - if (result == 0) { - win->width = devices[index].width; - win->height = devices[index].height; - } - } - break; - - case VIDIOCGWIN: - devices[index].flags |= V4L1_PIX_SIZE_TOUCHED; - result = syscall(SYS_ioctl, fd, request, arg); - break; - - case VIDIOCGCHAN: - { - struct v4l2_input input2; - struct video_channel *chan = arg; - - if ((devices[index].flags & V4L1_SUPPORTS_ENUMINPUT) && - (devices[index].flags & V4L1_SUPPORTS_ENUMSTD)) { - result = syscall(SYS_ioctl, fd, request, arg); - break; - } - - /* Set some defaults */ - chan->tuners = 0; - chan->flags = 0; - chan->type = VIDEO_TYPE_CAMERA; - chan->norm = 0; - - /* In case of no ENUMSTD support, ignore the norm member of the - channel struct */ - if (devices[index].flags & V4L1_SUPPORTS_ENUMINPUT) { - input2.index = chan->channel; - result = v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &input2); - if (result == 0) { - snprintf(chan->name, sizeof(chan->name), "%s", (char*)input2.name); - if (input2.type == V4L2_INPUT_TYPE_TUNER) { - chan->tuners = 1; - chan->type = VIDEO_TYPE_TV; - chan->flags = VIDEO_VC_TUNER; - } - } - break; - } - - /* No ENUMINPUT support, fake it (assume its a Camera in this case) */ - if (chan->channel == 0) { - snprintf(chan->name, sizeof(chan->name), "Camera"); - result = 0; - } else { - errno = EINVAL; - result = -1; - } - } - break; - - case VIDIOCSCHAN: - { - struct video_channel *chan = arg; - if ((devices[index].flags & V4L1_SUPPORTS_ENUMINPUT) && - (devices[index].flags & V4L1_SUPPORTS_ENUMSTD)) { - result = syscall(SYS_ioctl, fd, request, arg); - break; - } - /* In case of no ENUMSTD support, ignore the norm member of the - channel struct */ - if (devices[index].flags & V4L1_SUPPORTS_ENUMINPUT) { - result = v4l2_ioctl(fd, VIDIOC_S_INPUT, &chan->channel); - break; - } - /* No ENUMINPUT support, fake it (assume its a Camera in this case) */ - if (chan->channel == 0) { - result = 0; - } else { - errno = EINVAL; - result = -1; - } - } - break; - - case VIDIOCGMBUF: - /* When VIDIOCGMBUF is done, we don't necessarrily know the format the - application wants yet (with some apps this is passed for the first - time through VIDIOCMCAPTURE), so we just create an anonymous mapping - that should be large enough to hold any sort of frame. Note this only - takes virtual memory, and does not use memory until actually used. */ - { - int i; - struct video_mbuf *mbuf = arg; - - mbuf->size = V4L1_NO_FRAMES * V4L1_FRAME_BUF_SIZE; - mbuf->frames = V4L1_NO_FRAMES; - for (i = 0; i < mbuf->frames; i++) { - mbuf->offsets[i] = i * V4L1_FRAME_BUF_SIZE; - } - - if (devices[index].v4l1_frame_pointer == MAP_FAILED) { - devices[index].v4l1_frame_pointer = (void *)syscall(SYS_mmap2, NULL, - (size_t)mbuf->size, - PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); - if (devices[index].v4l1_frame_pointer == MAP_FAILED) { - saved_err = errno; - V4L1_LOG_ERR("allocating v4l1 buffer: %s\n", strerror(errno)); - errno = saved_err; - result = -1; - break; - } - V4L1_LOG("allocated v4l1 buffer @ %p\n", - devices[index].v4l1_frame_pointer); - } - result = 0; - } - break; - - case VIDIOCMCAPTURE: - { - struct video_mmap *map = arg; - - devices[index].flags |= V4L1_PIX_FMT_TOUCHED | - V4L1_PIX_SIZE_TOUCHED; - - result = v4l1_set_format(index, map->width, map->height, - map->format, 0); - } - break; - - case VIDIOCSYNC: - { - int *frame_index = arg; - - if (devices[index].v4l1_frame_pointer == MAP_FAILED || - *frame_index < 0 || *frame_index >= V4L1_NO_FRAMES) { - errno = EINVAL; - result = -1; - break; - } - - result = v4l2_read(devices[index].fd, - devices[index].v4l1_frame_pointer + - *frame_index * V4L1_FRAME_BUF_SIZE, - V4L1_FRAME_BUF_SIZE); - result = (result > 0) ? 0:result; - } - break; - - /* We are passing through v4l2 calls to libv4l2 for applications which are - using v4l2 through libv4l1 (possible with the v4l1compat.so wrapper). - - So the application could be calling VIDIOC_S_FMT, in this case update - our own bookkeeping of the cam's format. Note that this really only is - relevant if an application is mixing and matching v4l1 and v4l2 calls, - which is crazy, but better safe then sorry. */ - case VIDIOC_S_FMT: - { - struct v4l2_format *fmt2 = arg; - - result = v4l2_ioctl(fd, request, arg); - - if (result == 0 && fmt2->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - if (devices[index].v4l2_pixfmt != fmt2->fmt.pix.pixelformat) { - devices[index].v4l2_pixfmt = fmt2->fmt.pix.pixelformat; - devices[index].v4l1_pal = - pixelformat_to_palette(fmt2->fmt.pix.pixelformat); - } - devices[index].width = fmt2->fmt.pix.width; - devices[index].height = fmt2->fmt.pix.height; - } - } - break; - - default: - /* Pass through libv4l2 for applications which are using v4l2 through - libv4l1 (this can happen with the v4l1compat.so wrapper preloaded */ - result = v4l2_ioctl(fd, request, arg); - } - - if (stream_locked) - pthread_mutex_unlock(&devices[index].stream_lock); - - saved_err = errno; - v4l1_log_ioctl(request, arg, result); - errno = saved_err; - - return result; -} - - -ssize_t v4l1_read(int fd, void* buffer, size_t n) -{ - int index; - ssize_t result; - - if ((index = v4l1_get_index(fd)) == -1) - return syscall(SYS_read, fd, buffer, n); - - pthread_mutex_lock(&devices[index].stream_lock); - result = v4l2_read(fd, buffer, n); - pthread_mutex_unlock(&devices[index].stream_lock); - - return result; -} - - -void *v4l1_mmap(void *start, size_t length, int prot, int flags, int fd, - __off64_t offset) -{ - int index; - void *result; - - /* Check if the mmap data matches our answer to VIDIOCGMBUF, if not - pass through libv4l2 for applications which are using v4l2 through - libv4l1 (this can happen with the v4l1compat.so wrapper preloaded */ - if ((index = v4l1_get_index(fd)) == -1 || start || offset || - length != (V4L1_NO_FRAMES * V4L1_FRAME_BUF_SIZE)) - return v4l2_mmap(start, length, prot, flags, fd, offset); - - - pthread_mutex_lock(&devices[index].stream_lock); - - /* It could be that we get called with an mmap which seems to match what - we expect, but no VIDIOCGMBUF has been done yet, then it is certainly not - for us so pass it through */ - if (devices[index].v4l1_frame_pointer == MAP_FAILED) { - result = v4l2_mmap(start, length, prot, flags, fd, offset); - goto leave; - } - - devices[index].v4l1_frame_buf_map_count++; - - V4L1_LOG("v4l1 buffer @ %p mapped by application\n", - devices[index].v4l1_frame_pointer); - - result = devices[index].v4l1_frame_pointer; - -leave: - pthread_mutex_unlock(&devices[index].stream_lock); - - return result; -} - -int v4l1_munmap(void *_start, size_t length) -{ - int index; - unsigned char *start = _start; - - /* Is this memory ours? */ - if (start != MAP_FAILED && - length == (V4L1_FRAME_BUF_SIZE * V4L1_NO_FRAMES)) { - for (index = 0; index < devices_used; index++) - if (devices[index].fd != -1 && - start == devices[index].v4l1_frame_pointer) - break; - - if (index != devices_used) { - int unmapped = 0; - - pthread_mutex_lock(&devices[index].stream_lock); - - /* Redo our checks now that we have the lock, things may have changed */ - if (start == devices[index].v4l1_frame_pointer) { - if (devices[index].v4l1_frame_buf_map_count > 0) - devices[index].v4l1_frame_buf_map_count--; - - unmapped = 1; - } - - pthread_mutex_unlock(&devices[index].stream_lock); - - if (unmapped) { - V4L1_LOG("v4l1 buffer munmap %p, %d\n", start, (int)length); - return 0; - } - } - } - - V4L1_LOG("v4l1 unknown munmap %p, %d\n", start, (int)length); - - /* If not pass through libv4l2 for applications which are using v4l2 through - libv4l1 (this can happen with the v4l1compat.so wrapper preloaded */ - return v4l2_munmap(start, length); -} diff --git a/v4l2-apps/lib/libv4l/libv4l1/log.c b/v4l2-apps/lib/libv4l/libv4l1/log.c deleted file mode 100644 index 9ff0cea46..000000000 --- a/v4l2-apps/lib/libv4l/libv4l1/log.c +++ /dev/null @@ -1,145 +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/videodev.h> -#include "libv4l1-priv.h" - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) - -FILE *v4l1_log_file = NULL; - -static const char *v4l1_ioctls[] = { - [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", - [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", - [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", - [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", - [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", - [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", - [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", - [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", - [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", - [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", - [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", - [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", - [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", - [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", - [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", - [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", - [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", - [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", - [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", - [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", - [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", - [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", - [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", - [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", - [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", - [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", - [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", - [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", - [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT", -}; - -void v4l1_log_ioctl(unsigned long int request, void *arg, int result) -{ - const char *ioctl_str = "unknown"; - char buf[40]; - - if (!v4l1_log_file) - return; - - /* Don't log v4l2 ioctl's as unknown we pass them to libv4l2 which will - log them for us */ - if (_IOC_TYPE(request) == 'V') - return; - - if (_IOC_TYPE(request) == 'v' && _IOC_NR(request) < ARRAY_SIZE(v4l1_ioctls)) - ioctl_str = v4l1_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(v4l1_log_file, "request == %s\n", ioctl_str); - - switch(request) - { - case VIDIOCGCAP:fprintf(v4l1_log_file,"name %s\n",( (struct video_capability*)arg)->name ); - fprintf(v4l1_log_file,"type %d\n",( (struct video_capability*)arg)->type ); - fprintf(v4l1_log_file,"channels %d\n",( (struct video_capability*)arg)->channels ); - fprintf(v4l1_log_file,"audios %d\n",( (struct video_capability*)arg)->audios ); - fprintf(v4l1_log_file,"maxwidth %d\n",( (struct video_capability*)arg)->maxwidth ); - fprintf(v4l1_log_file,"maxheight %d\n",( (struct video_capability*)arg)->maxheight ); - fprintf(v4l1_log_file,"minwidth %d\n",( (struct video_capability*)arg)->minwidth ); - fprintf(v4l1_log_file,"minheight %d\n",( (struct video_capability*)arg)->minheight ); - break; - case VIDIOCGWIN: - case VIDIOCSWIN: - fprintf(v4l1_log_file,"width\t%u\n", - ((struct video_window *)arg)->width); - fprintf(v4l1_log_file,"height\t%u\n", - ((struct video_window *)arg)->height); - break; - - case VIDIOCGCHAN: - case VIDIOCSCHAN: - fprintf(v4l1_log_file,"channel %d\n",( (struct video_channel*)arg)->channel ); - fprintf(v4l1_log_file,"name %s\n",( (struct video_channel*)arg)->name ); - break; - - case VIDIOCGPICT: - case VIDIOCSPICT: - fprintf(v4l1_log_file,"brightness %d\n",( (int)((struct video_picture*)arg)->brightness) ); - fprintf(v4l1_log_file,"hue %d\n",( (int)((struct video_picture*)arg)->hue) ); - fprintf(v4l1_log_file,"colour %d\n",( (int)((struct video_picture*)arg)->colour) ); - fprintf(v4l1_log_file,"contrast %d\n",( (int)((struct video_picture*)arg)->contrast) ); - fprintf(v4l1_log_file,"whiteness %d\n",( (int)((struct video_picture*)arg)->whiteness) ); - fprintf(v4l1_log_file,"depth %d\n",( (int)((struct video_picture*)arg)->depth) ); - fprintf(v4l1_log_file,"palette %d\n",( (int)((struct video_picture*)arg)->palette) ); - break; - - case VIDIOCCAPTURE: fprintf(v4l1_log_file,"on/off? %d\n", *((int *)arg) ); - break; - - case VIDIOCSYNC: fprintf(v4l1_log_file,"sync %d\n", *((int *)arg) ); - break; - - case VIDIOCMCAPTURE: - fprintf(v4l1_log_file,"frame %u\n",( (struct video_mmap*)arg)->frame ); - fprintf(v4l1_log_file,"width %d\n",( (struct video_mmap*)arg)->width ); - fprintf(v4l1_log_file,"height %d\n",( (struct video_mmap*)arg)->height ); - fprintf(v4l1_log_file,"format %u\n",( (struct video_mmap*)arg)->format ); - break; - - case VIDIOCGMBUF: - fprintf(v4l1_log_file,"size %d\n",( (struct video_mbuf*)arg)->size ); - fprintf(v4l1_log_file,"frames %d\n",( (struct video_mbuf*)arg)->frames ); - break; - } - fprintf(v4l1_log_file, "result == %d\n", result); - fflush(v4l1_log_file); -} diff --git a/v4l2-apps/lib/libv4l/libv4l1/v4l1compat.c b/v4l2-apps/lib/libv4l/libv4l1/v4l1compat.c deleted file mode 100644 index e4293d2f9..000000000 --- a/v4l2-apps/lib/libv4l/libv4l1/v4l1compat.c +++ /dev/null @@ -1,127 +0,0 @@ -/* -# open/close/ioctl/mmap/munmap library call wrapper doing v4l1 api emulation -# for v4l2 devices - -# (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 <stdlib.h> -#include <stdarg.h> -#include <fcntl.h> -#include <libv4l1.h> - -#include <sys/ioctl.h> -#include <sys/mman.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; - - if (oflag & O_CREAT) - { - va_list ap; - mode_t mode; - - va_start (ap, oflag); - mode = va_arg (ap, mode_t); - - fd = v4l1_open(file, oflag, mode); - - va_end(ap); - } else - fd = v4l1_open(file, oflag); - - return fd; -} - -LIBV4L_PUBLIC int open64 (const char *file, int oflag, ...) -{ - int fd; - - if (oflag & O_CREAT) - { - va_list ap; - mode_t mode; - - va_start (ap, oflag); - mode = va_arg (ap, mode_t); - - fd = v4l1_open(file, oflag | O_LARGEFILE, mode); - - va_end(ap); - } else - fd = v4l1_open(file, oflag | O_LARGEFILE); - - return fd; -} - -LIBV4L_PUBLIC int close(int fd) { - return v4l1_close(fd); -} - -LIBV4L_PUBLIC int dup(int fd) -{ - return v4l1_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 v4l1_ioctl (fd, request, arg); -} - -LIBV4L_PUBLIC ssize_t read(int fd, void* buffer, size_t n) -{ - return v4l1_read (fd, buffer, n); -} - -LIBV4L_PUBLIC void *mmap(void *start, size_t length, int prot, int flags, int fd, - __off_t offset) -{ - return v4l1_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 v4l1_mmap(start, length, prot, flags, fd, offset); -} - -LIBV4L_PUBLIC int munmap(void *start, size_t length) -{ - return v4l1_munmap(start, length); -} - |