aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2019-03-29 14:10:28 +0100
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2019-03-29 14:10:28 +0100
commite76a80494b59726e443de9b8e49b4d7a93edd435 (patch)
treedcf7542cd455d53d91df567cad493e8d2ea021ee
parent9e3e533afecd217afa968f3270d25230d367b0cb (diff)
v4l2-ctl: print an error for invalid pixelformats
If the given pixelformat was invalid, then it was silently replaced by the driver with a default format. Give an error instead and bail out. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r--utils/v4l2-ctl/v4l2-ctl-vidcap.cpp71
-rw-r--r--utils/v4l2-ctl/v4l2-ctl-vidout.cpp14
-rw-r--r--utils/v4l2-ctl/v4l2-ctl.cpp37
-rw-r--r--utils/v4l2-ctl/v4l2-ctl.h1
4 files changed, 99 insertions, 24 deletions
diff --git a/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp b/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp
index 7b279d5b..337fb1f2 100644
--- a/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp
@@ -115,15 +115,16 @@ void vidcap_cmd(int ch, char *optarg)
break;
case OptListFrameSizes:
be_pixfmt = strlen(optarg) == 7 && !memcmp(optarg + 4, "-BE", 3);
- if (be_pixfmt)
- optarg[4] = 0;
- if (strlen(optarg) == 4) {
+ if (be_pixfmt || strlen(optarg) == 4) {
frmsize.pixel_format = v4l2_fourcc(optarg[0], optarg[1],
- optarg[2], optarg[3]);
+ optarg[2], optarg[3]);
if (be_pixfmt)
frmsize.pixel_format |= 1 << 31;
- } else {
+ } else if (isdigit(optarg[0])) {
frmsize.pixel_format = strtol(optarg, 0L, 0);
+ } else {
+ fprintf(stderr, "The pixelformat '%s' is invalid\n", optarg);
+ exit(1);
}
break;
case OptListFrameIntervals:
@@ -145,16 +146,17 @@ void vidcap_cmd(int ch, char *optarg)
break;
case 2:
be_pixfmt = strlen(value) == 7 && !memcmp(value + 4, "-BE", 3);
- if (be_pixfmt)
- value[4] = 0;
- if (strlen(value) == 4) {
+ if (be_pixfmt || strlen(value) == 4) {
frmival.pixel_format =
v4l2_fourcc(value[0], value[1],
- value[2], value[3]);
+ value[2], value[3]);
if (be_pixfmt)
frmival.pixel_format |= 1 << 31;
- } else {
+ } else if (isdigit(optarg[0])) {
frmival.pixel_format = strtol(value, 0L, 0);
+ } else {
+ fprintf(stderr, "The pixelformat '%s' is invalid\n", optarg);
+ exit(1);
}
break;
default:
@@ -187,7 +189,7 @@ int vidcap_get_and_update_fmt(cv4l_fd &_fd, struct v4l2_format &vfmt)
if (set_fmts & FmtPixelFormat) {
vfmt.fmt.pix_mp.pixelformat = pixfmt;
if (vfmt.fmt.pix_mp.pixelformat < 256) {
- vfmt.fmt.pix_mp.pixelformat =
+ vfmt.fmt.pix_mp.pixelformat = pixfmt =
find_pixel_format(fd, vfmt.fmt.pix_mp.pixelformat,
false, true);
}
@@ -217,7 +219,7 @@ int vidcap_get_and_update_fmt(cv4l_fd &_fd, struct v4l2_format &vfmt)
if (set_fmts & FmtPixelFormat) {
vfmt.fmt.pix.pixelformat = pixfmt;
if (vfmt.fmt.pix.pixelformat < 256) {
- vfmt.fmt.pix.pixelformat =
+ vfmt.fmt.pix.pixelformat = pixfmt =
find_pixel_format(fd, vfmt.fmt.pix.pixelformat,
false, false);
}
@@ -237,6 +239,16 @@ int vidcap_get_and_update_fmt(cv4l_fd &_fd, struct v4l2_format &vfmt)
vfmt.fmt.pix.bytesperline = 0;
}
}
+
+ if ((set_fmts & FmtPixelFormat) &&
+ !valid_pixel_format(fd, pixfmt, false, is_multiplanar)) {
+ if (pixfmt)
+ fprintf(stderr, "The pixelformat '%s' is invalid\n",
+ fcc2s(pixfmt).c_str());
+ else
+ fprintf(stderr, "The pixelformat index was invalid\n");
+ return -EINVAL;
+ }
return 0;
}
@@ -288,8 +300,24 @@ void vidcap_list(cv4l_fd &fd)
}
if (options[OptListFrameSizes]) {
- printf("ioctl: VIDIOC_ENUM_FRAMESIZES\n");
frmsize.index = 0;
+ if (frmsize.pixel_format < 256) {
+ frmsize.pixel_format =
+ find_pixel_format(fd.g_fd(), frmsize.pixel_format,
+ false, is_multiplanar);
+ if (!frmsize.pixel_format) {
+ fprintf(stderr, "The pixelformat index was invalid\n");
+ exit(1);
+ }
+ }
+ if (!valid_pixel_format(fd.g_fd(), frmsize.pixel_format, false, is_multiplanar) &&
+ !valid_pixel_format(fd.g_fd(), frmsize.pixel_format, true, is_multiplanar)) {
+ fprintf(stderr, "The pixelformat '%s' is invalid\n",
+ fcc2s(frmsize.pixel_format).c_str());
+ exit(1);
+ }
+
+ printf("ioctl: VIDIOC_ENUM_FRAMESIZES\n");
while (test_ioctl(fd.g_fd(), VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0) {
print_frmsize(frmsize, "");
frmsize.index++;
@@ -297,8 +325,23 @@ void vidcap_list(cv4l_fd &fd)
}
if (options[OptListFrameIntervals]) {
- printf("ioctl: VIDIOC_ENUM_FRAMEINTERVALS\n");
frmival.index = 0;
+ if (frmival.pixel_format < 256) {
+ frmival.pixel_format =
+ find_pixel_format(fd.g_fd(), frmival.pixel_format,
+ false, is_multiplanar);
+ if (!frmival.pixel_format) {
+ fprintf(stderr, "The pixelformat index was invalid\n");
+ exit(1);
+ }
+ }
+ if (!valid_pixel_format(fd.g_fd(), frmival.pixel_format, false, is_multiplanar)) {
+ fprintf(stderr, "The pixelformat '%s' is invalid\n",
+ fcc2s(frmival.pixel_format).c_str());
+ exit(1);
+ }
+
+ printf("ioctl: VIDIOC_ENUM_FRAMEINTERVALS\n");
while (test_ioctl(fd.g_fd(), VIDIOC_ENUM_FRAMEINTERVALS, &frmival) >= 0) {
print_frmival(frmival, "");
frmival.index++;
diff --git a/utils/v4l2-ctl/v4l2-ctl-vidout.cpp b/utils/v4l2-ctl/v4l2-ctl-vidout.cpp
index 5823df9c..c90bee54 100644
--- a/utils/v4l2-ctl/v4l2-ctl-vidout.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-vidout.cpp
@@ -122,7 +122,7 @@ void vidout_set(cv4l_fd &_fd)
if (set_fmts_out & FmtPixelFormat) {
vfmt.fmt.pix_mp.pixelformat = pixfmt;
if (vfmt.fmt.pix_mp.pixelformat < 256) {
- vfmt.fmt.pix_mp.pixelformat =
+ vfmt.fmt.pix_mp.pixelformat = pixfmt =
find_pixel_format(fd, vfmt.fmt.pix_mp.pixelformat,
true, true);
}
@@ -158,7 +158,7 @@ void vidout_set(cv4l_fd &_fd)
if (set_fmts_out & FmtPixelFormat) {
vfmt.fmt.pix.pixelformat = pixfmt;
if (vfmt.fmt.pix.pixelformat < 256) {
- vfmt.fmt.pix.pixelformat =
+ vfmt.fmt.pix.pixelformat = pixfmt =
find_pixel_format(fd, vfmt.fmt.pix.pixelformat,
true, false);
}
@@ -185,6 +185,16 @@ void vidout_set(cv4l_fd &_fd)
}
}
+ if ((set_fmts_out & FmtPixelFormat) &&
+ !valid_pixel_format(fd, pixfmt, true, is_multiplanar)) {
+ if (pixfmt)
+ fprintf(stderr, "The pixelformat '%s' is invalid\n",
+ fcc2s(pixfmt).c_str());
+ else
+ fprintf(stderr, "The pixelformat index was invalid\n");
+ exit(1);
+ }
+
if (options[OptSetVideoOutFormat])
ret = doioctl(fd, VIDIOC_S_FMT, &vfmt);
else
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index 7396439d..efc18f87 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -775,16 +775,17 @@ int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat,
break;
case 2:
be_pixfmt = strlen(value) == 7 && !memcmp(value + 4, "-BE", 3);
- if (be_pixfmt)
- value[4] = 0;
- if (strlen(value) == 4) {
+ if (be_pixfmt || strlen(value) == 4) {
pixelformat =
v4l2_fourcc(value[0], value[1],
- value[2], value[3]);
+ value[2], value[3]);
if (be_pixfmt)
pixelformat |= 1 << 31;
- } else {
+ } else if (isdigit(value[0])) {
pixelformat = strtol(value, 0L, 0);
+ } else {
+ fprintf(stderr, "The pixelformat '%s' is invalid\n", value);
+ exit(1);
}
fmts |= FmtPixelFormat;
break;
@@ -943,19 +944,39 @@ static __u32 parse_event(const char *e, const char **name)
return event;
}
+bool valid_pixel_format(int fd, __u32 pixelformat, bool output, bool mplane)
+{
+ struct v4l2_fmtdesc fmt;
+
+ fmt.index = 0;
+ if (output)
+ fmt.type = mplane ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
+ V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ else
+ fmt.type = mplane ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+ V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ while (!ioctl(fd, VIDIOC_ENUM_FMT, &fmt)) {
+ if (fmt.pixelformat == pixelformat)
+ return true;
+ fmt.index++;
+ }
+ return false;
+}
+
__u32 find_pixel_format(int fd, unsigned index, bool output, bool mplane)
{
struct v4l2_fmtdesc fmt;
fmt.index = index;
if (output)
- fmt.type = mplane ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
+ fmt.type = mplane ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
V4L2_BUF_TYPE_VIDEO_OUTPUT;
else
- fmt.type = mplane ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+ fmt.type = mplane ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (doioctl(fd, VIDIOC_ENUM_FMT, &fmt))
+ if (ioctl(fd, VIDIOC_ENUM_FMT, &fmt))
return 0;
return fmt.pixelformat;
}
diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
index 9292c15d..b93311b3 100644
--- a/utils/v4l2-ctl/v4l2-ctl.h
+++ b/utils/v4l2-ctl/v4l2-ctl.h
@@ -314,6 +314,7 @@ int parse_selection_target(const char *s, unsigned int &target);
int parse_selection_flags(const char *s);
void print_selection(const struct v4l2_selection &sel);
__u32 find_pixel_format(int fd, unsigned index, bool output, bool mplane);
+bool valid_pixel_format(int fd, __u32 pixelformat, bool output, bool mplane);
void print_frmsize(const struct v4l2_frmsizeenum &frmsize, const char *prefix);
void print_frmival(const struct v4l2_frmivalenum &frmival, const char *prefix);
void printfmt(int fd, const struct v4l2_format &vfmt);

Privacy Policy