diff options
Diffstat (limited to 'v4l2-apps/lib')
-rw-r--r-- | v4l2-apps/lib/libv4l/ChangeLog | 10 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/Makefile | 8 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l1/Makefile | 17 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l2/Makefile | 17 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h | 9 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 67 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4lconvert/Makefile | 17 |
7 files changed, 106 insertions, 39 deletions
diff --git a/v4l2-apps/lib/libv4l/ChangeLog b/v4l2-apps/lib/libv4l/ChangeLog index 9d642da7c..8dabf5361 100644 --- a/v4l2-apps/lib/libv4l/ChangeLog +++ b/v4l2-apps/lib/libv4l/ChangeLog @@ -1,3 +1,13 @@ +libv4l-0.3.8 +------------ +* work around wrong REQUEST_BUFFERS ioctl return code from certain drivers +* add pkg-config (.pc) files for easier detection if libv4l is available +* check capabilities for streaming, if the driver cannot do streaming don't + insert ourselves between the application and the driver +* intercept get capabilites and report read capability (which we always offer) +* query buffer: indicate the mapping state of our (fake) buffer in the flags + + libv4l-0.3.7 ------------ * Add spca505/6 and spca508 cam specific formats (YUYV per line variations) diff --git a/v4l2-apps/lib/libv4l/Makefile b/v4l2-apps/lib/libv4l/Makefile index 3497fdbf2..ee6d555c3 100644 --- a/v4l2-apps/lib/libv4l/Makefile +++ b/v4l2-apps/lib/libv4l/Makefile @@ -1,10 +1,10 @@ LIB_RELEASE=0 -V4L2_LIB_VERSION=$(LIB_RELEASE).3.7 +V4L2_LIB_VERSION=$(LIB_RELEASE).3.8 all clean install: - $(MAKE) -C libv4lconvert $@ - $(MAKE) -C libv4l2 $@ - $(MAKE) -C libv4l1 $@ + $(MAKE) -C libv4lconvert V4L2_LIB_VERSION=$(V4L2_LIB_VERSION) $@ + $(MAKE) -C libv4l2 V4L2_LIB_VERSION=$(V4L2_LIB_VERSION) $@ + $(MAKE) -C libv4l1 V4L2_LIB_VERSION=$(V4L2_LIB_VERSION) $@ export: clean mkdir /tmp/libv4l-$(V4L2_LIB_VERSION) diff --git a/v4l2-apps/lib/libv4l/libv4l1/Makefile b/v4l2-apps/lib/libv4l/libv4l1/Makefile index 8cb064cd4..4e9206bf6 100644 --- a/v4l2-apps/lib/libv4l/libv4l1/Makefile +++ b/v4l2-apps/lib/libv4l/libv4l1/Makefile @@ -12,7 +12,7 @@ V4L1_OBJS = libv4l1.o log.o ../libv4l2/libv4l2.so V4L1_LIB = libv4l1.so V4L1COMPAT = v4l1compat.so V4L1COMPAT_O = v4l1compat.o libv4l1.so -TARGETS = $(V4L1_LIB) $(V4L1COMPAT) +TARGETS = $(V4L1_LIB) $(V4L1COMPAT) libv4l1.pc INCLUDES = ../include/libv4l1.h ifeq ($(LIB_RELEASE),) @@ -34,6 +34,16 @@ $(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 'Libs: -L$${libdir} -lv4l1' >> libv4l1.pc + echo 'Cflags: -I$${prefix}/include' >> libv4l1.pc + install: all mkdir -p $(DESTDIR)$(PREFIX)/include install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include @@ -43,10 +53,11 @@ install: all ln -f -s $(V4L1_LIB).$(LIB_RELEASE) $(V4L1_LIB) install -m 755 $(V4L1COMPAT).$(LIB_RELEASE) \ $(DESTDIR)$(LIBDIR)/libv4l/$(V4L1COMPAT) + mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig + install -m 644 libv4l1.pc $(DESTDIR)$(LIBDIR)/pkgconfig clean:: - rm -f *.so* *.o log *~ - rm -f *.d + rm -f *.so* *.o *.d libv4l1.pc log *~ %.o: %.c $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< diff --git a/v4l2-apps/lib/libv4l/libv4l2/Makefile b/v4l2-apps/lib/libv4l/libv4l2/Makefile index 1258e379b..0e63eae71 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/Makefile +++ b/v4l2-apps/lib/libv4l/libv4l2/Makefile @@ -12,7 +12,7 @@ V4L2_OBJS = libv4l2.o log.o ../libv4lconvert/libv4lconvert.so V4L2_LIB = libv4l2.so V4L2CONVERT = v4l2convert.so V4L2CONVERT_O = v4l2convert.o libv4l2.so -TARGETS = $(V4L2_LIB) $(V4L2CONVERT) +TARGETS = $(V4L2_LIB) $(V4L2CONVERT) libv4l2.pc INCLUDES = ../include/libv4l2.h ifeq ($(LIB_RELEASE),) @@ -33,6 +33,16 @@ $(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 + install: all mkdir -p $(DESTDIR)$(PREFIX)/include install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include @@ -42,10 +52,11 @@ install: all ln -f -s $(V4L2_LIB).$(LIB_RELEASE) $(V4L2_LIB) install -m 755 $(V4L2CONVERT).$(LIB_RELEASE) \ $(DESTDIR)$(LIBDIR)/libv4l/$(V4L2CONVERT) + mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig + install -m 644 libv4l2.pc $(DESTDIR)$(LIBDIR)/pkgconfig clean:: - rm -f *.so* *.o log *~ - rm -f *.d + rm -f *.so* *.o *.d libv4l2.pc log *~ %.o: %.c $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h b/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h index 203dcffaf..fb6f9718e 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h @@ -88,13 +88,8 @@ struct v4l2_dev_info { 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, todo this - perfect we should use a map counter per frame, this is a good - approximation but there are scenarios thinkable where this doesn't work. - However no normal application not even a buggy one is likely to exhibit - the patterns needed to fail this somewhat simplified tracking */ - int frame_mapped; /* 1 status bit per frame */ - int frame_map_count; /* total number of maps of (fake) buffers combined */ + /* mapping tracking of our fake (converting mmap) frame buffers */ + unsigned char frame_map_count[V4L2_MAX_NO_FRAMES]; }; /* From log.c */ diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index 8dfcf9b71..f71d176b5 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -97,7 +97,7 @@ static int v4l2_request_read_buffers(int index) req.count = 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))){ + 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)); errno = saved_err; @@ -121,7 +121,7 @@ static int v4l2_unrequest_read_buffers(int index) 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))) { + 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; @@ -386,8 +386,10 @@ int v4l2_fd_open(int fd, int v4l2_flags) return -1; } - /* we only add functionality for video capture devices */ - if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) + /* 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 */ @@ -433,10 +435,9 @@ int v4l2_fd_open(int fd, int v4l2_flags) 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; - devices[index].frame_mapped = 0; - devices[index].frame_map_count = 0; if (index >= devices_used) devices_used = index + 1; @@ -468,7 +469,7 @@ static int v4l2_get_index(int fd) int v4l2_close(int fd) { - int index, result; + int index, result, i; if ((index = v4l2_get_index(fd)) == -1) return syscall(SYS_close, fd); @@ -487,11 +488,12 @@ int v4l2_close(int fd) v4l2_unmap_buffers(index); v4lconvert_destroy(devices[index].convert); if (devices[index].convert_mmap_buf != MAP_FAILED) { - if (devices[index].frame_mapped || devices[index].frame_map_count) - V4L2_LOG( - "v4l2 mmap buffers still mapped on close(), mask: %08x, count: %d\n", - (unsigned int)devices[index].frame_mapped, - devices[index].frame_map_count); + 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"); else syscall(SYS_munmap, devices[index].convert_mmap_buf, devices[index].no_frames * V4L2_FRAME_BUF_SIZE); @@ -548,6 +550,9 @@ int v4l2_ioctl (int fd, unsigned long 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) is_capture_request = 1; @@ -603,6 +608,17 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) 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; @@ -688,6 +704,7 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) case VIDIOC_REQBUFS: { + int i; struct v4l2_requestbuffers *req = arg; /* Don't allow mixing read / mmap io, either we control the buffers @@ -700,7 +717,11 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) } /* Are any of our fake (convert_mmap_buf) buffers still mapped ? */ - if (devices[index].frame_mapped || devices[index].frame_map_count) { + 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; @@ -723,8 +744,9 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) v4l2_unmap_buffers(index); result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_REQBUFS, req); - if (result) + 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) @@ -751,6 +773,10 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) 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; @@ -810,7 +836,12 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) } 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; } @@ -943,8 +974,7 @@ void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, } } - devices[index].frame_mapped |= 1 << buffer_index; - devices[index].frame_map_count++; + devices[index].frame_map_count[buffer_index]++; result = devices[index].convert_mmap_buf + buffer_index * V4L2_FRAME_BUF_SIZE; @@ -985,9 +1015,8 @@ int v4l2_munmap(void *_start, size_t length) start >= devices[index].convert_mmap_buf && (start - devices[index].convert_mmap_buf) % length == 0 && buffer_index < devices[index].no_frames) { - devices[index].frame_mapped &= ~(1 << buffer_index); - if (devices[index].frame_map_count > 0) - devices[index].frame_map_count--; + if (devices[index].frame_map_count[buffer_index] > 0) + devices[index].frame_map_count[buffer_index]--; unmapped = 1; } diff --git a/v4l2-apps/lib/libv4l/libv4lconvert/Makefile b/v4l2-apps/lib/libv4l/libv4lconvert/Makefile index 38071de94..3fd561f4e 100644 --- a/v4l2-apps/lib/libv4l/libv4lconvert/Makefile +++ b/v4l2-apps/lib/libv4l/libv4lconvert/Makefile @@ -11,7 +11,7 @@ LDFLAGS = -shared CONVERT_LIB = libv4lconvert.so CONVERT_OBJS = libv4lconvert.o tinyjpeg.o sn9c10x.o pac207.o \ jidctflt.o spca561-decompress.o rgbyuv.o spca501.o bayer.o -TARGETS = $(CONVERT_LIB) +TARGETS = $(CONVERT_LIB) libv4lconvert.pc INCLUDES = ../include/libv4lconvert.h ifeq ($(LIB_RELEASE),) @@ -30,6 +30,16 @@ all: $(TARGETS) $(CONVERT_LIB): $(CONVERT_OBJS) +libv4lconvert.pc: + echo prefix=$(PREFIX) > libv4lconvert.pc + echo libdir=$(LIBDIR) >> libv4lconvert.pc + echo >> libv4lconvert.pc + echo 'Name: libv4lconvert' >> libv4lconvert.pc + echo 'Description: v4l format conversion library' >> libv4lconvert.pc + echo 'Version: '$(V4L2_LIB_VERSION) >> libv4lconvert.pc + echo 'Libs: -L$${libdir} -lv4lconvert' >> libv4lconvert.pc + echo 'Cflags: -I$${prefix}/include' >> libv4lconvert.pc + install: all mkdir -p $(DESTDIR)$(PREFIX)/include install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include @@ -37,10 +47,11 @@ install: all install -m 755 $(CONVERT_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR) cd $(DESTDIR)$(LIBDIR) && \ ln -f -s $(CONVERT_LIB).$(LIB_RELEASE) $(CONVERT_LIB) + mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig + install -m 644 libv4lconvert.pc $(DESTDIR)$(LIBDIR)/pkgconfig clean:: - rm -f *.so* *.o log *~ - rm -f *.d + rm -f *.so* *.o *.d libv4lconvert.pc log *~ %.o: %.c $(CC) -c -MMD $(CPPFLAGS) $(CFLAGS) -o $@ $< |