summaryrefslogtreecommitdiff
path: root/v4l2-apps/lib
diff options
context:
space:
mode:
Diffstat (limited to 'v4l2-apps/lib')
-rw-r--r--v4l2-apps/lib/libv4l/ChangeLog10
-rw-r--r--v4l2-apps/lib/libv4l/Makefile8
-rw-r--r--v4l2-apps/lib/libv4l/libv4l1/Makefile17
-rw-r--r--v4l2-apps/lib/libv4l/libv4l2/Makefile17
-rw-r--r--v4l2-apps/lib/libv4l/libv4l2/libv4l2-priv.h9
-rw-r--r--v4l2-apps/lib/libv4l/libv4l2/libv4l2.c67
-rw-r--r--v4l2-apps/lib/libv4l/libv4lconvert/Makefile17
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 $@ $<