diff options
Diffstat (limited to 'v4l2-apps/lib/libv4l')
-rw-r--r-- | v4l2-apps/lib/libv4l/ChangeLog | 17 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l1/libv4l1.c | 2 | ||||
-rw-r--r-- | v4l2-apps/lib/libv4l/libv4l2/libv4l2.c | 145 |
3 files changed, 71 insertions, 93 deletions
diff --git a/v4l2-apps/lib/libv4l/ChangeLog b/v4l2-apps/lib/libv4l/ChangeLog index e7b899085..0e4a1af33 100644 --- a/v4l2-apps/lib/libv4l/ChangeLog +++ b/v4l2-apps/lib/libv4l/ChangeLog @@ -1,3 +1,20 @@ +libv4l-0.3.1 +------------ +* Only serialize V4L2_BUF_TYPE_VIDEO_CAPTURE type ioctls +* Do not return an uninitialized variable as result code for GPICT + (fixes vlc, but see below) +* Add an apps-patches directory which includes: + * vlc-0.8.6-libv4l1.patch, modify vlc's v4l1 plugin to directly call into + libv4l1, in the end we want all apps todo this as its better then + LD_PRELOAD tricks, but for vlc this is needed as vlc's plugin system + causes LD_PRELOAD to not work on symbols in the plugins + * camorama-0.19-fixes.patch, small bugfixes to camorama's v4l1 support, + this patch only fixes _real_ bugs in camorama and does not change it to + work with v4l1compat. Although it does work better with these bugs fixed + :) With this patch and LD_PRELOAD=<path>/v4l1compat.so it works + flawless. + + libv4l-0.3 ---------- * add extern "C" magic to public header files for c++ usage (Gregor Jasny) diff --git a/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c b/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c index 24feafe4f..f0604e5c9 100644 --- a/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c +++ b/v4l2-apps/lib/libv4l/libv4l1/libv4l1.c @@ -532,6 +532,8 @@ int v4l1_ioctl (int fd, unsigned long int request, ...) V4L2_CID_WHITENESS); pic->brightness = v4l2_get_control(devices[index].fd, V4L2_CID_BRIGHTNESS); + + result = 0; } break; diff --git a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c index 33d9b2891..f97fa09b6 100644 --- a/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/lib/libv4l/libv4l2/libv4l2.c @@ -527,31 +527,13 @@ int v4l2_dup(int fd) return fd; } -static int v4l2_buf_ioctl_pre_check(int index, unsigned long int request, - struct v4l2_buffer *buf, int *result) -{ - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - *result = syscall(SYS_ioctl, devices[index].fd, request, buf); - return 1; - } - - /* IMPROVEME (maybe?) add support for userptr's? */ - if (devices[index].io != v4l2_io_mmap || - buf->memory != V4L2_MEMORY_MMAP || - buf->index >= devices[index].no_frames) { - errno = EINVAL; - *result = -1; - return 1; - } - - return 0; -} int v4l2_ioctl (int fd, unsigned long int request, ...) { void *arg; va_list ap; - int result, converting, index, saved_err, stream_locked = 0; + int result, converting, index, saved_err; + int is_capture_request = 0, stream_needs_locking = 0; va_start (ap, request); arg = va_arg (ap, void *); @@ -560,61 +542,70 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) if ((index = v4l2_get_index(fd)) == -1) return syscall(SYS_ioctl, fd, request, arg); - /* do we need to take the stream lock for this ioctl? */ + /* Is this a capture request and do we need to take the stream lock? */ switch (request) { + case VIDIOC_ENUM_FMT: + if (((struct v4l2_fmtdesc *)arg)->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + 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: - pthread_mutex_lock(&devices[index].stream_lock); - stream_locked = 1; + if (*((enum v4l2_buf_type *)arg) == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + is_capture_request = 1; + stream_needs_locking = 1; + } } + if (!is_capture_request) + return syscall(SYS_ioctl, fd, request, arg); + + + 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; switch (request) { case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmtdesc = arg; - - if (fmtdesc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - !(devices[index].flags & V4L2_ENABLE_ENUM_FMT_EMULATION)) - result = syscall(SYS_ioctl, devices[index].fd, request, arg); - else - result = v4lconvert_enum_fmt(devices[index].convert, fmtdesc); - } + result = v4lconvert_enum_fmt(devices[index].convert, arg); break; case VIDIOC_TRY_FMT: - { - struct v4l2_format *fmt = arg; - - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - (devices[index].flags & V4L2_DISABLE_CONVERSION)) { - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_TRY_FMT, fmt); - break; - } - - result = v4lconvert_try_format(devices[index].convert, fmt, NULL); - } + result = v4lconvert_try_format(devices[index].convert, arg, NULL); break; case VIDIOC_S_FMT: { struct v4l2_format src_fmt, *dest_fmt = arg; - if (dest_fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_S_FMT, - dest_fmt); - break; - } - if (!memcmp(&devices[index].dest_fmt, dest_fmt, sizeof(*dest_fmt))) { result = 0; break; @@ -658,7 +649,7 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) if (v4l2_activate_read_stream(index)) V4L2_LOG_ERR( "reactivating stream after deactivate failure (AAIIEEEE)\n"); - return result; + break; } } @@ -681,11 +672,6 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) { struct v4l2_format* fmt = arg; - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_G_FMT, fmt); - break; - } - *fmt = devices[index].dest_fmt; result = 0; } @@ -695,11 +681,6 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) { struct v4l2_requestbuffers *req = arg; - if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - result = syscall(SYS_ioctl, devices[index].fd, request, arg); - return 1; - } - /* Don't allow mixing read / mmap io, either we control the buffers (read based io), or the app does */ if (devices[index].io == v4l2_io_read) { @@ -753,9 +734,6 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) { struct v4l2_buffer *buf = arg; - if (v4l2_buf_ioctl_pre_check(index, request, buf, &result)) - 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); @@ -768,23 +746,13 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) break; case VIDIOC_QBUF: - { - struct v4l2_buffer *buf = arg; - - if (v4l2_buf_ioctl_pre_check(index, request, buf, &result)) - break; - - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QBUF, buf); - } + result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_QBUF, arg); break; case VIDIOC_DQBUF: { struct v4l2_buffer *buf = arg; - if (v4l2_buf_ioctl_pre_check(index, request, buf, &result)) - break; - result = syscall(SYS_ioctl, devices[index].fd, VIDIOC_DQBUF, buf); if (result || !converting) break; @@ -832,32 +800,23 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) case VIDIOC_STREAMON: case VIDIOC_STREAMOFF: - { - enum v4l2_buf_type *type = arg; - - if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - result = syscall(SYS_ioctl, devices[index].fd, request, type); - break; - } - - if (devices[index].io != v4l2_io_mmap) { - errno = EINVAL; - result = -1; - break; - } - - if (request == VIDIOC_STREAMON) - result = v4l2_streamon(index); - else - result = v4l2_streamoff(index); + if (devices[index].io != v4l2_io_mmap) { + errno = EINVAL; + result = -1; + 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_locked) + if (stream_needs_locking) pthread_mutex_unlock(&devices[index].stream_lock); saved_err = errno; |