From a63e58c8101caacfc5f82b66de79e794adf0ca3a Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Thu, 7 Aug 2008 19:34:10 +0200 Subject: libv4l: add support for fixing upside down images to libv4lconvert From: Hans de Goede Add support to libv4lconvert to flipping the image for upside down mounted sensors, libv4lconvert will do this automatically if the webcam sets a flag in its query_fmt reply indicating that this is necessary, this fixes the upside down image on Philips SPC200NC images Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2/libv4l2.c') diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index a40ab4ffe..dd43d938f 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -614,7 +614,8 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) is_capture_request = 1; break; case VIDIOC_ENUM_FMT: - if (((struct v4l2_fmtdesc *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + 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_TRY_FMT: @@ -663,9 +664,8 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) if (stream_needs_locking) pthread_mutex_lock(&devices[index].stream_lock); - converting = devices[index].src_fmt.fmt.pix.pixelformat != - devices[index].dest_fmt.fmt.pix.pixelformat; - + converting = v4lconvert_needs_conversion(devices[index].convert, + &devices[index].src_fmt, &devices[index].dest_fmt); switch (request) { case VIDIOC_QUERYCAP: @@ -914,8 +914,8 @@ ssize_t v4l2_read (int fd, void* buffer, size_t n) /* When not converting and the device supports read let the kernel handle it */ if ((devices[index].flags & V4L2_SUPPORTS_READ) && - devices[index].src_fmt.fmt.pix.pixelformat == - devices[index].dest_fmt.fmt.pix.pixelformat) { + !v4lconvert_needs_conversion(devices[index].convert, + &devices[index].src_fmt, &devices[index].dest_fmt)) { result = syscall(SYS_read, fd, buffer, n); goto leave; } @@ -988,8 +988,8 @@ void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, buffer_index = offset & 0xff; if (buffer_index >= devices[index].no_frames || /* Got magic offset and not converting ?? */ - devices[index].src_fmt.fmt.pix.pixelformat == - devices[index].dest_fmt.fmt.pix.pixelformat) { + !v4lconvert_needs_conversion(devices[index].convert, + &devices[index].src_fmt, &devices[index].dest_fmt)) { errno = EINVAL; result = MAP_FAILED; goto leave; -- cgit v1.2.3 From a15825844ed72e4b0f13e10de4b7dd0ce31846ac Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Fri, 22 Aug 2008 23:23:50 +0200 Subject: libv4l: add support for Pixart custom JPEG format From: Hans de Goede libv4l: add support for Pixart custom JPEG format Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 117 +++++++++++++++++---------------- 1 file changed, 61 insertions(+), 56 deletions(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2/libv4l2.c') diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index dd43d938f..408f27398 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -252,23 +252,54 @@ static int v4l2_queue_read_buffer(int index, int buffer_index) return 0; } -static int v4l2_dequeue_read_buffer(int index, int *bytesused) +static int v4l2_dequeue_and_convert(int index, struct v4l2_buffer *buf, + unsigned char *dest, int dest_size) { - int result; - struct v4l2_buffer buf; + const int max_tries = 10; + int result, tries = max_tries; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - 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; + /* 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)); } - devices[index].frame_queued &= ~(1 << buf.index); - *bytesused = buf.bytesused; - return buf.index; + return result; } static int v4l2_queue_read_buffers(int index) @@ -815,15 +846,16 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) if ((result = v4l2_deactivate_read_stream(index))) break; - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_DQBUF, buf); - if (result) { - V4L2_LOG_ERR("dequeing buffer: %s\n", strerror(errno)); + 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; } - if (!converting) - 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! */ @@ -844,23 +876,9 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) } } - /* Make sure we have the real v4l2 buffers mapped before trying to - read from them */ - if ((result = v4l2_map_buffers(index))) - break; - - result = v4lconvert_convert(devices[index].convert, - &devices[index].src_fmt, &devices[index].dest_fmt, - devices[index].frame_pointers[buf->index], - buf->bytesused, - devices[index].convert_mmap_buf + - buf->index * V4L2_FRAME_BUF_SIZE, - V4L2_FRAME_BUF_SIZE); - if (result < 0) { - V4L2_LOG_ERR("converting / decoding frame data: %s\n", - v4lconvert_get_error_message(devices[index].convert)); + 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; @@ -901,13 +919,14 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) } -ssize_t v4l2_read (int fd, void* buffer, size_t n) +ssize_t v4l2_read (int fd, void* dest, size_t n) { ssize_t result; int index, bytesused = 0, frame_index; + struct v4l2_buffer buf; if ((index = v4l2_get_index(fd)) == -1) - return syscall(SYS_read, fd, buffer, n); + return syscall(SYS_read, fd, dest, n); pthread_mutex_lock(&devices[index].stream_lock); @@ -916,7 +935,7 @@ ssize_t v4l2_read (int fd, void* buffer, size_t n) 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, buffer, n); + result = syscall(SYS_read, fd, dest, n); goto leave; } @@ -931,26 +950,12 @@ ssize_t v4l2_read (int fd, void* buffer, size_t n) goto leave; } - if ((frame_index = v4l2_dequeue_read_buffer(index, &bytesused)) < 0) { - result = -1; - goto leave; - } - - /* ensure buffers are mapped before using them (they could have been - unmapped by a s_fmt ioctl) */ - if ((result = v4l2_map_buffers(index))) - goto leave; - - result = v4lconvert_convert(devices[index].convert, - &devices[index].src_fmt, &devices[index].dest_fmt, - devices[index].frame_pointers[frame_index], bytesused, - buffer, n); - - v4l2_queue_read_buffer(index, frame_index); + 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_LOG_ERR("converting / decoding frame data: %s\n", - v4lconvert_get_error_message(devices[index].convert)); + if (result >= 0) + v4l2_queue_read_buffer(index, buf.index); leave: pthread_mutex_unlock(&devices[index].stream_lock); -- cgit v1.2.3 From 5bbdc31c65b0843fd17e1d0c13827d9d7ef9c22b Mon Sep 17 00:00:00 2001 From: "hans@localhost.localdomain" Date: Tue, 26 Aug 2008 18:11:09 +0200 Subject: libv4l: fix a few compile warnings From: Hans de Goede libv4l: fix a few compile warnings Priority: normal Signed-off-by: Hans de Goede --- v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'v4l2-apps/lib/libv4l/libv4l2/libv4l2.c') diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index 408f27398..7029f69c3 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -922,7 +922,7 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) ssize_t v4l2_read (int fd, void* dest, size_t n) { ssize_t result; - int index, bytesused = 0, frame_index; + int index; struct v4l2_buffer buf; if ((index = v4l2_get_index(fd)) == -1) -- cgit v1.2.3