diff options
-rw-r--r-- | v4l2-apps/libv4l/ChangeLog | 6 | ||||
-rw-r--r-- | v4l2-apps/libv4l/Makefile | 2 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4l2/libv4l2.c | 5 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4l2/log.c | 71 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c | 53 |
5 files changed, 127 insertions, 10 deletions
diff --git a/v4l2-apps/libv4l/ChangeLog b/v4l2-apps/libv4l/ChangeLog index a2c598d08..e2c8c43c4 100644 --- a/v4l2-apps/libv4l/ChangeLog +++ b/v4l2-apps/libv4l/ChangeLog @@ -1,3 +1,9 @@ +libv4l-0.5.7 +------------ +* Fix a nasty (and stupid) bug in the special try_fmt handling for UVC cams +* Add some more verbose logging of various calls when asking libv4l to log + calls to a file, to assist in (future) debugging + libv4l-0.5.6 ------------ * Always do a s_fmt on uvc cams even if this changes nothing, as not doing diff --git a/v4l2-apps/libv4l/Makefile b/v4l2-apps/libv4l/Makefile index 55b3744ea..09177aabb 100644 --- a/v4l2-apps/libv4l/Makefile +++ b/v4l2-apps/libv4l/Makefile @@ -1,5 +1,5 @@ LIB_RELEASE=0 -V4L2_LIB_VERSION=$(LIB_RELEASE).5.6 +V4L2_LIB_VERSION=$(LIB_RELEASE).5.7 all clean install: $(MAKE) -C libv4lconvert V4L2_LIB_VERSION=$(V4L2_LIB_VERSION) $@ diff --git a/v4l2-apps/libv4l/libv4l2/libv4l2.c b/v4l2-apps/libv4l/libv4l2/libv4l2.c index 720e91975..b6ddef6e8 100644 --- a/v4l2-apps/libv4l/libv4l2/libv4l2.c +++ b/v4l2-apps/libv4l/libv4l2/libv4l2.c @@ -760,6 +760,9 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) case VIDIOC_ENUM_FRAMEINTERVALS: result = v4lconvert_enum_frameintervals(devices[index].convert, arg); + if (result) + V4L2_LOG("ENUM_FRAMEINTERVALS Error: %s", + v4lconvert_get_error_message(devices[index].convert)); break; case VIDIOC_TRY_FMT: @@ -949,7 +952,7 @@ int v4l2_ioctl (int fd, unsigned long int request, ...) but we need the buffer _now_ to write our converted data to it! */ if (devices[index].convert_mmap_buf == MAP_FAILED) { - devices[index].convert_mmap_buf = (void *)syscall(SYS_mmap2, + devices[index].convert_mmap_buf = (void *)syscall(SYS_mmap2, NULL, (size_t)( devices[index].no_frames * V4L2_FRAME_BUF_SIZE), diff --git a/v4l2-apps/libv4l/libv4l2/log.c b/v4l2-apps/libv4l/libv4l2/log.c index 437b51d3e..c086ef736 100644 --- a/v4l2-apps/libv4l/libv4l2/log.c +++ b/v4l2-apps/libv4l/libv4l2/log.c @@ -91,6 +91,10 @@ static const char *v4l2_ioctls[] = { [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", +#ifdef VIDIOC_ENUM_FRAMESIZES + [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", + [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", +#endif }; void v4l2_log_ioctl(unsigned long int request, void *arg, int result) @@ -105,7 +109,7 @@ void v4l2_log_ioctl(unsigned long int request, void *arg, int result) if (_IOC_TYPE(request) == 'V' && _IOC_NR(request) < ARRAY_SIZE(v4l2_ioctls)) ioctl_str = v4l2_ioctls[_IOC_NR(request)]; else { - snprintf(buf, sizeof(buf), "unknown request: %c %d\n", + snprintf(buf, sizeof(buf), "unknown request: %c %d", (int)_IOC_TYPE(request), (int)_IOC_NR(request)); ioctl_str = buf; } @@ -113,11 +117,18 @@ void v4l2_log_ioctl(unsigned long int request, void *arg, int result) fprintf(v4l2_log_file, "request == %s\n", ioctl_str); switch (request) { + case VIDIOC_ENUM_FMT: + { + struct v4l2_fmtdesc *fmt = arg; + fprintf(v4l2_log_file, " index: %u, description: %s\n", + fmt->index, (result < 0) ? "" : fmt->description); + } + break; case VIDIOC_G_FMT: case VIDIOC_S_FMT: case VIDIOC_TRY_FMT: { - struct v4l2_format* fmt = arg; + struct v4l2_format *fmt = arg; int pixfmt = fmt->fmt.pix.pixelformat; if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { @@ -144,6 +155,62 @@ void v4l2_log_ioctl(unsigned long int request, void *arg, int result) req->count, (int)req->type, (int)req->memory); } break; +#ifdef VIDIOC_ENUM_FRAMESIZES + case VIDIOC_ENUM_FRAMESIZES: + { + struct v4l2_frmsizeenum *frmsize = arg; + int pixfmt = frmsize->pixel_format; + + fprintf(v4l2_log_file, " index: %u pixelformat: %c%c%c%c", + frmsize->index, + pixfmt & 0xff, + (pixfmt >> 8) & 0xff, + (pixfmt >> 16) & 0xff, + pixfmt >> 24); + switch (frmsize->type) { + case V4L2_FRMSIZE_TYPE_DISCRETE: + fprintf(v4l2_log_file, " %ux%u\n", frmsize->discrete.width, + frmsize->discrete.height); + break; + case V4L2_FRMSIZE_TYPE_CONTINUOUS: + case V4L2_FRMSIZE_TYPE_STEPWISE: + fprintf(v4l2_log_file, " %ux%u -> %ux%u\n", + frmsize->stepwise.min_width, frmsize->stepwise.min_height, + frmsize->stepwise.max_width, frmsize->stepwise.max_height); + break; + } + } + break; + case VIDIOC_ENUM_FRAMEINTERVALS: + { + struct v4l2_frmivalenum *frmival = arg; + int pixfmt = frmival->pixel_format; + + fprintf(v4l2_log_file, " index: %u pixelformat: %c%c%c%c %ux%u: ", + frmival->index, + pixfmt & 0xff, + (pixfmt >> 8) & 0xff, + (pixfmt >> 16) & 0xff, + pixfmt >> 24, + frmival->width, + frmival->height); + switch (frmival->type) { + case V4L2_FRMIVAL_TYPE_DISCRETE: + fprintf(v4l2_log_file, "%u/%u\n", frmival->discrete.numerator, + frmival->discrete.denominator); + break; + case V4L2_FRMIVAL_TYPE_CONTINUOUS: + case V4L2_FRMIVAL_TYPE_STEPWISE: + fprintf(v4l2_log_file, "%u/%u -> %u/%u\n", + frmival->stepwise.min.numerator, + frmival->stepwise.min.denominator, + frmival->stepwise.max.numerator, + frmival->stepwise.max.denominator); + break; + } + } + break; +#endif } if (result < 0) diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c index 6ec525769..889f7463a 100644 --- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c +++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c @@ -209,8 +209,11 @@ static int v4lconvert_do_try_format_uvc(struct v4lconvert_data *data, data->framesizes[i].discrete.height; unsigned int size_diff = size_x_diff * size_x_diff + size_y_diff * size_y_diff; - if (size_diff < closest_fmt_size_diff) + + if (size_diff < closest_fmt_size_diff) { + closest_fmt_size_diff = size_diff; best_framesize = i; + } } } @@ -452,7 +455,7 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, /* Check for (pixart) rotated JPEG */ if (header_width == height && header_height == width) { if (!(data->flags & V4LCONVERT_ROTATE_90)) { - V4LCONVERT_ERR("JPEG needs 90 degree rotation"); + V4LCONVERT_ERR("JPEG needs 90 degree rotation\n"); data->flags |= V4LCONVERT_ROTATE_90; errno = EAGAIN; return -1; @@ -497,7 +500,7 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, the upper layer this is an intermediate fault and it should try again with a new buffer by setting errno to EAGAIN */ if (src_pix_fmt == V4L2_PIX_FMT_PJPG) { - V4LCONVERT_ERR("Error decompressing JPEG: %s", + V4LCONVERT_ERR("decompressing JPEG: %s", tinyjpeg_get_errorstring(data->jdec)); errno = EAGAIN; return -1; @@ -923,8 +926,12 @@ int v4lconvert_enum_frameintervals(struct v4lconvert_data *data, int res; struct v4l2_format src_fmt, dest_fmt; - if (!v4lconvert_supported_dst_format(frmival->pixel_format)) - return syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMEINTERVALS, frmival); + if (!v4lconvert_supported_dst_format(frmival->pixel_format)) { + res = syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMEINTERVALS, frmival); + if (res) + V4LCONVERT_ERR("%s\n", strerror(errno)); + return res; + } /* Check which format we will be using to convert to frmival->pixel_format */ memset(&dest_fmt, 0, sizeof(dest_fmt)); @@ -932,13 +939,30 @@ int v4lconvert_enum_frameintervals(struct v4lconvert_data *data, dest_fmt.fmt.pix.pixelformat = frmival->pixel_format; dest_fmt.fmt.pix.width = frmival->width; dest_fmt.fmt.pix.height = frmival->height; - if ((res = v4lconvert_try_format(data, &dest_fmt, &src_fmt))) + if ((res = v4lconvert_try_format(data, &dest_fmt, &src_fmt))) { + if (res) + V4LCONVERT_ERR("trying format: %s\n", strerror(errno)); return res; + } /* Check the requested format is supported exactly as requested */ if (dest_fmt.fmt.pix.pixelformat != frmival->pixel_format || dest_fmt.fmt.pix.width != frmival->width || dest_fmt.fmt.pix.height != frmival->height) { + int frmival_pixformat = frmival->pixel_format; + int dest_pixformat = dest_fmt.fmt.pix.pixelformat; + V4LCONVERT_ERR("Could not find matching framesize for: %c%c%c%c %dx%d " + "closest match: %c%c%c%c %dx%d\n", + frmival_pixformat & 0xff, + (frmival_pixformat >> 8) & 0xff, + (frmival_pixformat >> 16) & 0xff, + frmival_pixformat >> 24, + frmival->width, frmival->height, + dest_pixformat & 0xff, + (dest_pixformat >> 8) & 0xff, + (dest_pixformat >> 16) & 0xff, + dest_pixformat >> 24, + dest_fmt.fmt.pix.width , dest_fmt.fmt.pix.height); errno = EINVAL; return -1; } @@ -948,6 +972,23 @@ int v4lconvert_enum_frameintervals(struct v4lconvert_data *data, frmival->width = src_fmt.fmt.pix.width; frmival->height = src_fmt.fmt.pix.height; res = syscall(SYS_ioctl, data->fd, VIDIOC_ENUM_FRAMEINTERVALS, frmival); + if (res) { + int dest_pixfmt = dest_fmt.fmt.pix.pixelformat; + int src_pixfmt = src_fmt.fmt.pix.pixelformat; + V4LCONVERT_ERR("Could not enum frameival index: %d for: %c%c%c%c %dx%d " + "using src: %c%c%c%c %dx%d, error: %s\n", + frmival->index, + dest_pixfmt & 0xff, + (dest_pixfmt >> 8) & 0xff, + (dest_pixfmt >> 16) & 0xff, + dest_pixfmt >> 24, + dest_fmt.fmt.pix.width , dest_fmt.fmt.pix.height, + src_pixfmt & 0xff, + (src_pixfmt >> 8) & 0xff, + (src_pixfmt >> 16) & 0xff, + src_pixfmt >> 24, + src_fmt.fmt.pix.width, src_fmt.fmt.pix.height, strerror(errno)); + } /* Restore the requested format in the frmival struct */ frmival->pixel_format = dest_fmt.fmt.pix.pixelformat; |