From 487d3953700f645dde8277eb3c29445c5fb52149 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 11 Feb 2018 03:01:04 +0200 Subject: Store capture parameters from VIDIOC_S_FMT Some buggy drivers don't implement VIDIOC_G_FMT, preventing yavta from operating as it relies on that ioctl to retrieve capture parameters. Store the capture parameters returned by the previous VIDIOC_S_FMT call (which should be identical) to allow operation even when VIDIOC_G_FMT isn't implemented. Signed-off-by: Laurent Pinchart --- yavta.c | 116 +++++++++++++++++++++++++++++----------------------------------- 1 file changed, 52 insertions(+), 64 deletions(-) diff --git a/yavta.c b/yavta.c index 8318c8b..559872e 100644 --- a/yavta.c +++ b/yavta.c @@ -585,66 +585,76 @@ static void set_control(struct device *dev, unsigned int id, id, old_val, val); } -static int video_get_format(struct device *dev) +static void video_store_format(struct device *dev, const struct v4l2_format *fmt, + bool set) { - struct v4l2_format fmt; unsigned int i; - int ret; - - memset(&fmt, 0, sizeof fmt); - fmt.type = dev->type; - - ret = ioctl(dev->fd, VIDIOC_G_FMT, &fmt); - if (ret < 0) { - printf("Unable to get format: %s (%d).\n", strerror(errno), - errno); - return ret; - } if (video_is_mplane(dev)) { - dev->width = fmt.fmt.pix_mp.width; - dev->height = fmt.fmt.pix_mp.height; - dev->num_planes = fmt.fmt.pix_mp.num_planes; - - printf("Video format: %s (%08x) %ux%u field %s, %u planes: \n", - v4l2_format_name(fmt.fmt.pix_mp.pixelformat), fmt.fmt.pix_mp.pixelformat, - fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, - v4l2_field_name(fmt.fmt.pix_mp.field), - fmt.fmt.pix_mp.num_planes); - - for (i = 0; i < fmt.fmt.pix_mp.num_planes; i++) { + dev->width = fmt->fmt.pix_mp.width; + dev->height = fmt->fmt.pix_mp.height; + dev->num_planes = fmt->fmt.pix_mp.num_planes; + + printf("Video format%s: %s (%08x) %ux%u field %s, %u planes: \n", + set ? " set" : "", + v4l2_format_name(fmt->fmt.pix_mp.pixelformat), fmt->fmt.pix_mp.pixelformat, + fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height, + v4l2_field_name(fmt->fmt.pix_mp.field), + fmt->fmt.pix_mp.num_planes); + + for (i = 0; i < fmt->fmt.pix_mp.num_planes; i++) { dev->plane_fmt[i].bytesperline = - fmt.fmt.pix_mp.plane_fmt[i].bytesperline; + fmt->fmt.pix_mp.plane_fmt[i].bytesperline; dev->plane_fmt[i].sizeimage = - fmt.fmt.pix_mp.plane_fmt[i].bytesperline ? - fmt.fmt.pix_mp.plane_fmt[i].sizeimage : 0; + fmt->fmt.pix_mp.plane_fmt[i].bytesperline ? + fmt->fmt.pix_mp.plane_fmt[i].sizeimage : 0; printf(" * Stride %u, buffer size %u\n", - fmt.fmt.pix_mp.plane_fmt[i].bytesperline, - fmt.fmt.pix_mp.plane_fmt[i].sizeimage); + fmt->fmt.pix_mp.plane_fmt[i].bytesperline, + fmt->fmt.pix_mp.plane_fmt[i].sizeimage); } } else if (video_is_meta(dev)) { dev->width = 0; dev->height = 0; dev->num_planes = 1; - printf("Meta-data format: %s (%08x) buffer size %u\n", - v4l2_format_name(fmt.fmt.meta.dataformat), fmt.fmt.meta.dataformat, - fmt.fmt.meta.buffersize); + printf("Meta-data format%s: %s (%08x) buffer size %u\n", + set ? " set" : "", + v4l2_format_name(fmt->fmt.meta.dataformat), fmt->fmt.meta.dataformat, + fmt->fmt.meta.buffersize); } else { - dev->width = fmt.fmt.pix.width; - dev->height = fmt.fmt.pix.height; + dev->width = fmt->fmt.pix.width; + dev->height = fmt->fmt.pix.height; dev->num_planes = 1; - dev->plane_fmt[0].bytesperline = fmt.fmt.pix.bytesperline; - dev->plane_fmt[0].sizeimage = fmt.fmt.pix.bytesperline ? fmt.fmt.pix.sizeimage : 0; + dev->plane_fmt[0].bytesperline = fmt->fmt.pix.bytesperline; + dev->plane_fmt[0].sizeimage = fmt->fmt.pix.bytesperline ? fmt->fmt.pix.sizeimage : 0; - printf("Video format: %s (%08x) %ux%u (stride %u) field %s buffer size %u\n", - v4l2_format_name(fmt.fmt.pix.pixelformat), fmt.fmt.pix.pixelformat, - fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.bytesperline, - v4l2_field_name(fmt.fmt.pix_mp.field), - fmt.fmt.pix.sizeimage); + printf("Video format%s: %s (%08x) %ux%u (stride %u) field %s buffer size %u\n", + set ? " set" : "", + v4l2_format_name(fmt->fmt.pix.pixelformat), fmt->fmt.pix.pixelformat, + fmt->fmt.pix.width, fmt->fmt.pix.height, fmt->fmt.pix.bytesperline, + v4l2_field_name(fmt->fmt.pix_mp.field), + fmt->fmt.pix.sizeimage); } +} + +static int video_get_format(struct device *dev) +{ + struct v4l2_format fmt; + int ret; + + memset(&fmt, 0, sizeof fmt); + fmt.type = dev->type; + + ret = ioctl(dev->fd, VIDIOC_G_FMT, &fmt); + if (ret < 0) { + printf("Unable to get format: %s (%d).\n", strerror(errno), + errno); + return ret; + } + + video_store_format(dev, &fmt, false); return 0; } @@ -696,29 +706,7 @@ static int video_set_format(struct device *dev, unsigned int w, unsigned int h, return ret; } - if (video_is_mplane(dev)) { - printf("Video format set: %s (%08x) %ux%u field %s, %u planes: \n", - v4l2_format_name(fmt.fmt.pix_mp.pixelformat), fmt.fmt.pix_mp.pixelformat, - fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, - v4l2_field_name(fmt.fmt.pix_mp.field), - fmt.fmt.pix_mp.num_planes); - - for (i = 0; i < fmt.fmt.pix_mp.num_planes; i++) { - printf(" * Stride %u, buffer size %u\n", - fmt.fmt.pix_mp.plane_fmt[i].bytesperline, - fmt.fmt.pix_mp.plane_fmt[i].sizeimage); - } - } else if (video_is_meta(dev)) { - printf("Meta-data format: %s (%08x) buffer size %u\n", - v4l2_format_name(fmt.fmt.meta.dataformat), fmt.fmt.meta.dataformat, - fmt.fmt.meta.buffersize); - } else { - printf("Video format set: %s (%08x) %ux%u (stride %u) field %s buffer size %u\n", - v4l2_format_name(fmt.fmt.pix.pixelformat), fmt.fmt.pix.pixelformat, - fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.bytesperline, - v4l2_field_name(fmt.fmt.pix.field), - fmt.fmt.pix.sizeimage); - } + video_store_format(dev, &fmt, true); return 0; } -- cgit v1.2.3