This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/v4l-utils.git tree:

Subject: v4l2-ctl: share capture/output format updates
Author:  Hans Verkuil <[email protected]>
Date:    Tue Oct 6 09:30:20 2026 +0200

Add a video_format_request, shared capture/output updater using cv4l_fmt,
and consolidated FOURCC parsing. Capture-only CSC flags and streaming
reconfiguration behavior are preserved. Also fixed numeric frame-interval
parsing, bounded repeated plane values, and updated the man page.

Signed-off-by: Hans Verkuil <[email protected]>
Assisted-by: GPT-6.1 Sol

 utils/v4l2-ctl/meson.build         |   1 +
 utils/v4l2-ctl/v4l2-ctl-format.cpp |  85 +++++++++++++++++++
 utils/v4l2-ctl/v4l2-ctl-meta.cpp   |   3 +-
 utils/v4l2-ctl/v4l2-ctl-sdr.cpp    |   3 +-
 utils/v4l2-ctl/v4l2-ctl-vidcap.cpp | 164 ++-----------------------------------
 utils/v4l2-ctl/v4l2-ctl-vidout.cpp | 109 ++----------------------
 utils/v4l2-ctl/v4l2-ctl.1.in       |   6 ++
 utils/v4l2-ctl/v4l2-ctl.cpp        |  94 ++++++++++-----------
 utils/v4l2-ctl/v4l2-ctl.h          |  25 +++++-
 9 files changed, 173 insertions(+), 317 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=1616bf9e3c8111d3c8f3995d26bc6d0402cc77c3
diff --git a/utils/v4l2-ctl/meson.build b/utils/v4l2-ctl/meson.build
index 8bcf8785878e..28af5a2804b4 100644
--- a/utils/v4l2-ctl/meson.build
+++ b/utils/v4l2-ctl/meson.build
@@ -5,6 +5,7 @@ v4l2_ctl_sources = files(
     'v4l-stream.c',
     'v4l2-ctl-common.cpp',
     'v4l2-ctl-edid.cpp',
+    'v4l2-ctl-format.cpp',
     'v4l2-ctl-io.cpp',
     'v4l2-ctl-meta.cpp',
     'v4l2-ctl-misc.cpp',
diff --git a/utils/v4l2-ctl/v4l2-ctl-format.cpp 
b/utils/v4l2-ctl/v4l2-ctl-format.cpp
new file mode 100644
index 000000000000..0df65cc37abe
--- /dev/null
+++ b/utils/v4l2-ctl/v4l2-ctl-format.cpp
@@ -0,0 +1,85 @@
+#include <cctype>
+
+#include "v4l2-ctl.h"
+
+__u32 parse_pixelformat(const char *value)
+{
+       bool be = strlen(value) == 7 && !memcmp(value + 4, "-BE", 3);
+
+       if (be || strlen(value) == 4) {
+               __u32 pixelformat = v4l2_fourcc(value[0], value[1], value[2], 
value[3]);
+
+               return be ? pixelformat | (1U << 31) : pixelformat;
+       }
+       if (isdigit(value[0]))
+               return strtoul(value, nullptr, 0);
+
+       fprintf(stderr, "The pixelformat '%s' is invalid\n", value);
+       std::exit(EXIT_FAILURE);
+}
+
+int video_get_and_update_fmt(cv4l_fd &fd, struct v4l2_format &vfmt,
+                            __u32 type, __u32 magic, video_format_request 
&request)
+{
+       cv4l_fmt fmt(type);
+       bool output = type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
+                     type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+       bool mplane = V4L2_TYPE_IS_MULTIPLANAR(type);
+       unsigned fields = request.fields;
+
+       fmt.fmt.pix.priv = magic;
+       int ret = doioctl(fd.g_fd(), VIDIOC_G_FMT, &fmt);
+
+       if (ret)
+               return ret;
+
+       if (fields & FmtWidth)
+               fmt.s_width(request.width);
+       if (fields & FmtHeight)
+               fmt.s_height(request.height);
+       if (fields & FmtPixelFormat) {
+               if (request.pixelformat < 256)
+                       request.pixelformat = find_pixel_format(fd.g_fd(),
+                                       request.pixelformat, output, mplane);
+               fmt.s_pixelformat(request.pixelformat);
+       }
+       if (fields & FmtField)
+               fmt.s_field(request.field);
+       if (fields & FmtFlags)
+               fmt.s_flags(request.flags);
+       if (fields & FmtBytesPerLine) {
+               for (unsigned i = 0; i < (mplane ? VIDEO_MAX_PLANES : 1); i++)
+                       fmt.s_bytesperline(request.bytesperline[i], i);
+       } else {
+               // Let the driver recalculate the stride for the new width.
+               for (unsigned i = 0; i < fmt.g_num_planes(); i++)
+                       fmt.s_bytesperline(0, i);
+       }
+       if (fields & FmtSizeImage) {
+               for (unsigned i = 0; i < (mplane ? VIDEO_MAX_PLANES : 1); i++)
+                       fmt.s_sizeimage(request.sizeimage[i], i);
+       }
+       if (fields & FmtColorspace)
+               fmt.s_colorspace(request.colorspace);
+       if (fields & FmtYCbCr)
+               fmt.s_ycbcr_enc(request.ycbcr);
+       if (fields & FmtQuantization)
+               fmt.s_quantization(request.quantization);
+       if (fields & FmtXferFunc)
+               fmt.s_xfer_func(request.xfer_func);
+       if (!output && (fields & (FmtColorspace | FmtYCbCr |
+                                FmtQuantization | FmtXferFunc)))
+               fmt.s_flags(fmt.g_flags() | V4L2_PIX_FMT_FLAG_SET_CSC);
+
+       vfmt = fmt;
+       if ((fields & FmtPixelFormat) &&
+           !valid_pixel_format(fd.g_fd(), request.pixelformat, output, 
mplane)) {
+               if (request.pixelformat)
+                       fprintf(stderr, "The pixelformat '%s' is invalid\n",
+                               fcc2s(request.pixelformat).c_str());
+               else
+                       fprintf(stderr, "The pixelformat index was invalid\n");
+               return -EINVAL;
+       }
+       return 0;
+}
diff --git a/utils/v4l2-ctl/v4l2-ctl-meta.cpp b/utils/v4l2-ctl/v4l2-ctl-meta.cpp
index 634aba8ce0ca..7c173d76d7fc 100644
--- a/utils/v4l2-ctl/v4l2-ctl-meta.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-meta.cpp
@@ -53,8 +53,7 @@ void meta_cmd(int ch, char *optarg)
                        meta_usage();
                        std::exit(EXIT_FAILURE);
                } else if (strlen(optarg) == 4) {
-                       vfmt.fmt.meta.dataformat = v4l2_fourcc(optarg[0],
-                                       optarg[1], optarg[2], optarg[3]);
+                       vfmt.fmt.meta.dataformat = parse_pixelformat(optarg);
                } else {
                        vfmt.fmt.meta.dataformat = strtoul(optarg, nullptr, 0);
                }
diff --git a/utils/v4l2-ctl/v4l2-ctl-sdr.cpp b/utils/v4l2-ctl/v4l2-ctl-sdr.cpp
index 35e7885e188e..5dce72937afe 100644
--- a/utils/v4l2-ctl/v4l2-ctl-sdr.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-sdr.cpp
@@ -38,8 +38,7 @@ void sdr_cmd(int ch, char *optarg)
                        sdr_usage();
                        std::exit(EXIT_FAILURE);
                } else if (strlen(optarg) == 4) {
-                       vfmt.fmt.sdr.pixelformat = v4l2_fourcc(optarg[0],
-                                       optarg[1], optarg[2], optarg[3]);
+                       vfmt.fmt.sdr.pixelformat = parse_pixelformat(optarg);
                } else {
                        vfmt.fmt.sdr.pixelformat = strtoul(optarg, nullptr, 0);
                }
diff --git a/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp 
b/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp
index a16443f4d682..11402202dcbe 100644
--- a/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp
@@ -1,16 +1,10 @@
-#include <cctype>
-
 #include <endian.h>
 
 #include "v4l2-ctl.h"
 
 static struct v4l2_frmsizeenum frmsize; /* list frame sizes */
 static struct v4l2_frmivalenum frmival; /* list frame intervals */
-static unsigned set_fmts;
-static __u32 width, height, pixfmt, field, flags;
-static __u32 ycbcr, quantization, xfer_func, colorspace;
-static __u32 bytesperline[VIDEO_MAX_PLANES];
-static __u32 sizeimage[VIDEO_MAX_PLANES];
+static video_format_request format_request;
 static unsigned mbus_code;
 static bool enum_all;
 
@@ -104,15 +98,11 @@ static void print_video_fields(int fd)
 void vidcap_cmd(int ch, char *optarg)
 {
        char *value, *subs;
-       bool be_pixfmt;
 
        switch (ch) {
        case OptSetVideoFormat:
        case OptTryVideoFormat:
-               set_fmts = parse_fmt(optarg, width, height, pixfmt, field, 
colorspace,
-                               xfer_func, ycbcr, quantization, flags, 
bytesperline,
-                               sizeimage);
-               if (!set_fmts) {
+               if (!parse_fmt(optarg, format_request)) {
                        vidcap_usage();
                        std::exit(EXIT_FAILURE);
                }
@@ -127,18 +117,7 @@ void vidcap_cmd(int ch, char *optarg)
                }
                break;
        case OptListFrameSizes:
-               be_pixfmt = strlen(optarg) == 7 && !memcmp(optarg + 4, "-BE", 
3);
-               if (be_pixfmt || strlen(optarg) == 4) {
-                       frmsize.pixel_format = v4l2_fourcc(optarg[0], optarg[1],
-                                                          optarg[2], 
optarg[3]);
-                       if (be_pixfmt)
-                               frmsize.pixel_format |= 1U << 31;
-               } else if (isdigit(optarg[0])) {
-                       frmsize.pixel_format = strtoul(optarg, nullptr, 0);
-               } else {
-                       fprintf(stderr, "The pixelformat '%s' is invalid\n", 
optarg);
-                       std::exit(EXIT_FAILURE);
-               }
+               frmsize.pixel_format = parse_pixelformat(optarg);
                break;
        case OptListFrameIntervals:
                subs = optarg;
@@ -158,19 +137,7 @@ void vidcap_cmd(int ch, char *optarg)
                                frmival.height = strtoul(value, nullptr, 0);
                                break;
                        case 2:
-                               be_pixfmt = strlen(value) == 7 && !memcmp(value 
+ 4, "-BE", 3);
-                               if (be_pixfmt || strlen(value) == 4) {
-                                       frmival.pixel_format =
-                                               v4l2_fourcc(value[0], value[1],
-                                                           value[2], value[3]);
-                                       if (be_pixfmt)
-                                               frmival.pixel_format |= 1U << 
31;
-                               } else if (isdigit(optarg[0])) {
-                                       frmival.pixel_format = strtoul(value, 
nullptr, 0);
-                               } else {
-                                       fprintf(stderr, "The pixelformat '%s' 
is invalid\n", optarg);
-                                       std::exit(EXIT_FAILURE);
-                               }
+                               frmival.pixel_format = parse_pixelformat(value);
                                break;
                        default:
                                vidcap_usage();
@@ -183,127 +150,8 @@ void vidcap_cmd(int ch, char *optarg)
 
 int vidcap_get_and_update_fmt(cv4l_fd &_fd, struct v4l2_format &vfmt)
 {
-       int fd = _fd.g_fd();
-       int ret;
-
-       memset(&vfmt, 0, sizeof(vfmt));
-       vfmt.fmt.pix.priv = priv_magic;
-       vfmt.type = vidcap_buftype;
-
-       ret = doioctl(fd, VIDIOC_G_FMT, &vfmt);
-       if (ret)
-               return ret;
-
-       if (is_multiplanar) {
-               if (set_fmts & FmtWidth)
-                       vfmt.fmt.pix_mp.width = width;
-               if (set_fmts & FmtHeight)
-                       vfmt.fmt.pix_mp.height = height;
-               if (set_fmts & FmtPixelFormat) {
-                       vfmt.fmt.pix_mp.pixelformat = pixfmt;
-                       if (vfmt.fmt.pix_mp.pixelformat < 256) {
-                               vfmt.fmt.pix_mp.pixelformat = pixfmt =
-                                       find_pixel_format(fd, 
vfmt.fmt.pix_mp.pixelformat,
-                                                         false, true);
-                       }
-               }
-               if (set_fmts & FmtField)
-                       vfmt.fmt.pix_mp.field = field;
-               if (set_fmts & FmtFlags)
-                       vfmt.fmt.pix_mp.flags = flags;
-               if (set_fmts & FmtBytesPerLine) {
-                       for (unsigned i = 0; i < VIDEO_MAX_PLANES; i++)
-                               vfmt.fmt.pix_mp.plane_fmt[i].bytesperline =
-                                       bytesperline[i];
-               } else {
-                       /*
-                        * G_FMT might return bytesperline values > width,
-                        * reset them to 0 to force the driver to update them
-                        * to the closest value for the new width.
-                        */
-                       for (unsigned i = 0; i < vfmt.fmt.pix_mp.num_planes; 
i++)
-                               vfmt.fmt.pix_mp.plane_fmt[i].bytesperline = 0;
-               }
-               if (set_fmts & FmtSizeImage) {
-                       for (unsigned i = 0; i < VIDEO_MAX_PLANES; i++)
-                               vfmt.fmt.pix_mp.plane_fmt[i].sizeimage =
-                                       sizeimage[i];
-               }
-
-               if (set_fmts & FmtColorspace) {
-                       vfmt.fmt.pix_mp.flags |= V4L2_PIX_FMT_FLAG_SET_CSC;
-                       vfmt.fmt.pix_mp.colorspace = colorspace;
-               }
-               if (set_fmts & FmtYCbCr) {
-                       vfmt.fmt.pix_mp.flags |= V4L2_PIX_FMT_FLAG_SET_CSC;
-                       vfmt.fmt.pix_mp.ycbcr_enc = ycbcr;
-               }
-               if (set_fmts & FmtQuantization) {
-                       vfmt.fmt.pix_mp.flags |= V4L2_PIX_FMT_FLAG_SET_CSC;
-                       vfmt.fmt.pix_mp.quantization = quantization;
-               }
-               if (set_fmts & FmtXferFunc) {
-                       vfmt.fmt.pix_mp.flags |= V4L2_PIX_FMT_FLAG_SET_CSC;
-                       vfmt.fmt.pix_mp.xfer_func = xfer_func;
-               }
-       } else {
-               if (set_fmts & FmtWidth)
-                       vfmt.fmt.pix.width = width;
-               if (set_fmts & FmtHeight)
-                       vfmt.fmt.pix.height = height;
-               if (set_fmts & FmtPixelFormat) {
-                       vfmt.fmt.pix.pixelformat = pixfmt;
-                       if (vfmt.fmt.pix.pixelformat < 256) {
-                               vfmt.fmt.pix.pixelformat = pixfmt =
-                                       find_pixel_format(fd, 
vfmt.fmt.pix.pixelformat,
-                                                         false, false);
-                       }
-               }
-               if (set_fmts & FmtField)
-                       vfmt.fmt.pix.field = field;
-               if (set_fmts & FmtFlags)
-                       vfmt.fmt.pix.flags = flags;
-               if (set_fmts & FmtBytesPerLine) {
-                       vfmt.fmt.pix.bytesperline = bytesperline[0];
-               } else {
-                       /*
-                        * G_FMT might return a bytesperline value > width,
-                        * reset this to 0 to force the driver to update it
-                        * to the closest value for the new width.
-                        */
-                       vfmt.fmt.pix.bytesperline = 0;
-               }
-               if (set_fmts & FmtSizeImage)
-                       vfmt.fmt.pix.sizeimage = sizeimage[0];
-               if (set_fmts & FmtColorspace) {
-                       vfmt.fmt.pix.flags |= V4L2_PIX_FMT_FLAG_SET_CSC;
-                       vfmt.fmt.pix.colorspace = colorspace;
-               }
-               if (set_fmts & FmtYCbCr) {
-                       vfmt.fmt.pix.flags |= V4L2_PIX_FMT_FLAG_SET_CSC;
-                       vfmt.fmt.pix.ycbcr_enc = ycbcr;
-               }
-               if (set_fmts & FmtQuantization) {
-                       vfmt.fmt.pix.flags |= V4L2_PIX_FMT_FLAG_SET_CSC;
-                       vfmt.fmt.pix.quantization = quantization;
-               }
-               if (set_fmts & FmtXferFunc) {
-                       vfmt.fmt.pix.flags |= V4L2_PIX_FMT_FLAG_SET_CSC;
-                       vfmt.fmt.pix.xfer_func = xfer_func;
-               }
-
-       }
-
-       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;
+       return video_get_and_update_fmt(_fd, vfmt, vidcap_buftype,
+                                      priv_magic, format_request);
 }
 
 void vidcap_set(cv4l_fd &_fd)
diff --git a/utils/v4l2-ctl/v4l2-ctl-vidout.cpp 
b/utils/v4l2-ctl/v4l2-ctl-vidout.cpp
index bbdbfc451614..20b0b958d22e 100644
--- a/utils/v4l2-ctl/v4l2-ctl-vidout.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-vidout.cpp
@@ -1,9 +1,6 @@
 #include "v4l2-ctl.h"
 
-static unsigned set_fmts_out;
-static __u32 width, height, pixfmt, field, colorspace, xfer_func, ycbcr, 
quantization, flags;
-static __u32 bytesperline[VIDEO_MAX_PLANES];
-static __u32 sizeimage[VIDEO_MAX_PLANES];
+static video_format_request format_request;
 static unsigned mbus_code_out;
 static bool enum_all;
 
@@ -90,11 +87,8 @@ void vidout_cmd(int ch, char *optarg)
        switch (ch) {
        case OptSetVideoOutFormat:
        case OptTryVideoOutFormat:
-               set_fmts_out = parse_fmt(optarg, width, height, pixfmt, field,
-                               colorspace, xfer_func, ycbcr, quantization, 
flags, bytesperline,
-                               sizeimage);
-               if (!set_fmts_out) {
-                       vidcap_usage();
+               if (!parse_fmt(optarg, format_request)) {
+                       vidout_usage();
                        std::exit(EXIT_FAILURE);
                }
                break;
@@ -118,98 +112,11 @@ void vidout_set(cv4l_fd &_fd)
        if (options[OptSetVideoOutFormat] || options[OptTryVideoOutFormat]) {
                struct v4l2_format vfmt;
 
-               memset(&vfmt, 0, sizeof(vfmt));
-               vfmt.fmt.pix.priv = priv_magic;
-               vfmt.type = vidout_buftype;
-               if (doioctl(fd, VIDIOC_G_FMT, &vfmt) == 0) {
-                       if (is_multiplanar) {
-                               if (set_fmts_out & FmtWidth)
-                                       vfmt.fmt.pix_mp.width = width;
-                               if (set_fmts_out & FmtHeight)
-                                       vfmt.fmt.pix_mp.height = height;
-                               if (set_fmts_out & FmtPixelFormat) {
-                                       vfmt.fmt.pix_mp.pixelformat = pixfmt;
-                                       if (vfmt.fmt.pix_mp.pixelformat < 256) {
-                                               vfmt.fmt.pix_mp.pixelformat = 
pixfmt =
-                                                       find_pixel_format(fd, 
vfmt.fmt.pix_mp.pixelformat,
-                                                                       true, 
true);
-                                       }
-                               }
-                               if (set_fmts_out & FmtField)
-                                       vfmt.fmt.pix_mp.field = field;
-                               if (set_fmts_out & FmtColorspace)
-                                       vfmt.fmt.pix_mp.colorspace = colorspace;
-                               if (set_fmts_out & FmtXferFunc)
-                                       vfmt.fmt.pix_mp.xfer_func = xfer_func;
-                               if (set_fmts_out & FmtYCbCr)
-                                       vfmt.fmt.pix_mp.ycbcr_enc = ycbcr;
-                               if (set_fmts_out & FmtQuantization)
-                                       vfmt.fmt.pix_mp.quantization = 
quantization;
-                               if (set_fmts_out & FmtFlags)
-                                       vfmt.fmt.pix_mp.flags = flags;
-                               if (set_fmts_out & FmtBytesPerLine) {
-                                       for (unsigned i = 0; i < 
VIDEO_MAX_PLANES; i++)
-                                               
vfmt.fmt.pix_mp.plane_fmt[i].bytesperline =
-                                                       bytesperline[i];
-                               } else {
-                                       /* G_FMT might return bytesperline 
values > width,
-                                        * reset them to 0 to force the driver 
to update them
-                                        * to the closest value for the new 
width. */
-                                       for (unsigned i = 0; i < 
vfmt.fmt.pix_mp.num_planes; i++)
-                                               
vfmt.fmt.pix_mp.plane_fmt[i].bytesperline = 0;
-                               }
-                               if (set_fmts_out & FmtSizeImage) {
-                                       for (unsigned i = 0; i < 
VIDEO_MAX_PLANES; i++)
-                                               
vfmt.fmt.pix_mp.plane_fmt[i].sizeimage =
-                                                       sizeimage[i];
-                               }
-                       } else {
-                               if (set_fmts_out & FmtWidth)
-                                       vfmt.fmt.pix.width = width;
-                               if (set_fmts_out & FmtHeight)
-                                       vfmt.fmt.pix.height = height;
-                               if (set_fmts_out & FmtPixelFormat) {
-                                       vfmt.fmt.pix.pixelformat = pixfmt;
-                                       if (vfmt.fmt.pix.pixelformat < 256) {
-                                               vfmt.fmt.pix.pixelformat = 
pixfmt =
-                                                       find_pixel_format(fd, 
vfmt.fmt.pix.pixelformat,
-                                                                       true, 
false);
-                                       }
-                               }
-                               if (set_fmts_out & FmtField)
-                                       vfmt.fmt.pix.field = field;
-                               if (set_fmts_out & FmtColorspace)
-                                       vfmt.fmt.pix.colorspace = colorspace;
-                               if (set_fmts_out & FmtXferFunc)
-                                       vfmt.fmt.pix.xfer_func = xfer_func;
-                               if (set_fmts_out & FmtYCbCr)
-                                       vfmt.fmt.pix.ycbcr_enc = ycbcr;
-                               if (set_fmts_out & FmtQuantization)
-                                       vfmt.fmt.pix.quantization = 
quantization;
-                               if (set_fmts_out & FmtFlags)
-                                       vfmt.fmt.pix.flags = flags;
-                               if (set_fmts_out & FmtBytesPerLine) {
-                                       vfmt.fmt.pix.bytesperline = 
bytesperline[0];
-                               } else {
-                                       /* G_FMT might return a bytesperline 
value > width,
-                                        * reset this to 0 to force the driver 
to update it
-                                        * to the closest value for the new 
width. */
-                                       vfmt.fmt.pix.bytesperline = 0;
-                               }
-                               if (set_fmts_out & FmtSizeImage)
-                                       vfmt.fmt.pix.sizeimage = sizeimage[0];
-                       }
-
-                       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");
-                               std::exit(EXIT_FAILURE);
-                       }
-
+               ret = video_get_and_update_fmt(_fd, vfmt, vidout_buftype,
+                                             priv_magic, format_request);
+               if (ret == -EINVAL)
+                       std::exit(EXIT_FAILURE);
+               if (ret == 0) {
                        if (options[OptSetVideoOutFormat])
                                ret = doioctl(fd, VIDIOC_S_FMT, &vfmt);
                        else
diff --git a/utils/v4l2-ctl/v4l2-ctl.1.in b/utils/v4l2-ctl/v4l2-ctl.1.in
index cbb10064684c..3f44d0c84c94 100644
--- a/utils/v4l2-ctl/v4l2-ctl.1.in
+++ b/utils/v4l2-ctl/v4l2-ctl.1.in
@@ -155,6 +155,12 @@ Only set the result code, do not print any messages.
 .TP
 \fB--sleep\fR \fI<secs>\fR
 Sleep \fI<secs>\fR, call QUERYCAP and close the file handle.
+.SH VIDEO FORMATS
+Video pixel formats accept a four-character FOURCC, a FOURCC followed by
+\fB-BE\fR for a big-endian format, or a numeric value. For set/try video
+formats, numeric values below 256 select an index from the enumerated formats.
+The \fBbytesperline\fR and \fBsizeimage\fR suboptions may each be repeated once
+per plane, up to eight values (VIDEO_MAX_PLANES).
 .SH EXIT STATUS
 On success, it returns 0. Otherwise, it will return the error code.
 .SH EXAMPLES
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index 6afb572c9d7c..c52c08fff176 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -767,19 +767,15 @@ __u32 parse_quantization(const char *s)
        return V4L2_QUANTIZATION_DEFAULT;
 }
 
-int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat,
-             __u32 &field, __u32 &colorspace, __u32 &xfer_func, __u32 &ycbcr,
-             __u32 &quantization, __u32 &flags, __u32 *bytesperline,
-             __u32 *sizeimage)
+bool parse_fmt(char *optarg, video_format_request &request)
 {
        char *value, *subs;
-       int fmts = 0;
        unsigned bpl_index = 0;
        unsigned sizeimage_index = 0;
-       bool be_pixfmt;
 
-       field = V4L2_FIELD_ANY;
-       flags = 0;
+       request.fields = 0;
+       request.field = V4L2_FIELD_ANY;
+       request.flags = 0;
        subs = optarg;
        while (*subs != '\0') {
                static constexpr const char *subopts[] = {
@@ -800,82 +796,80 @@ int parse_fmt(char *optarg, __u32 &width, __u32 &height, 
__u32 &pixelformat,
 
                switch (parse_subopt(&subs, subopts, &value)) {
                case 0:
-                       width = strtoul(value, nullptr, 0);
-                       fmts |= FmtWidth;
+                       request.width = strtoul(value, nullptr, 0);
+                       request.fields |= FmtWidth;
                        break;
                case 1:
-                       height = strtoul(value, nullptr, 0);
-                       fmts |= FmtHeight;
+                       request.height = strtoul(value, nullptr, 0);
+                       request.fields |= FmtHeight;
                        break;
                case 2:
-                       be_pixfmt = strlen(value) == 7 && !memcmp(value + 4, 
"-BE", 3);
-                       if (be_pixfmt || strlen(value) == 4) {
-                               pixelformat =
-                                       v4l2_fourcc(value[0], value[1],
-                                                   value[2], value[3]);
-                               if (be_pixfmt)
-                                       pixelformat |= 1U << 31;
-                       } else if (isdigit(value[0])) {
-                               pixelformat = strtoul(value, nullptr, 0);
-                       } else {
-                               fprintf(stderr, "The pixelformat '%s' is 
invalid\n", value);
-                               std::exit(EXIT_FAILURE);
-                       }
-                       fmts |= FmtPixelFormat;
+                       request.pixelformat = parse_pixelformat(value);
+                       request.fields |= FmtPixelFormat;
                        break;
                case 3:
-                       field = parse_field(value);
-                       fmts |= FmtField;
+                       request.field = parse_field(value);
+                       request.fields |= FmtField;
                        break;
                case 4:
-                       colorspace = parse_colorspace(value);
-                       if (colorspace)
-                               fmts |= FmtColorspace;
+                       request.colorspace = parse_colorspace(value);
+                       if (request.colorspace)
+                               request.fields |= FmtColorspace;
                        else
                                fprintf(stderr, "unknown colorspace %s\n", 
value);
                        break;
                case 5:
-                       ycbcr = parse_ycbcr(value);
-                       fmts |= FmtYCbCr;
+                       request.ycbcr = parse_ycbcr(value);
+                       request.fields |= FmtYCbCr;
                        break;
                case 6:
-                       ycbcr = parse_hsv(value);
-                       fmts |= FmtYCbCr;
+                       request.ycbcr = parse_hsv(value);
+                       request.fields |= FmtYCbCr;
                        break;
                case 7:
-                       bytesperline[bpl_index] = strtoul(value, nullptr, 0);
-                       if (bytesperline[bpl_index] > 0xffff) {
+                       if (bpl_index == VIDEO_MAX_PLANES) {
+                               fprintf(stderr, "Too many bytesperline values 
(maximum %u)\n",
+                                       VIDEO_MAX_PLANES);
+                               return false;
+                       }
+                       request.bytesperline[bpl_index] = strtoul(value, 
nullptr, 0);
+                       if (request.bytesperline[bpl_index] > 0xffff) {
                                fprintf(stderr, "bytesperline can't be more 
than 65535\n");
-                               bytesperline[bpl_index] = 0;
+                               request.bytesperline[bpl_index] = 0;
                        }
                        bpl_index++;
-                       fmts |= FmtBytesPerLine;
+                       request.fields |= FmtBytesPerLine;
                        break;
                case 8:
                        if (strtoul(value, nullptr, 0))
-                               flags |= V4L2_PIX_FMT_FLAG_PREMUL_ALPHA;
+                               request.flags |= V4L2_PIX_FMT_FLAG_PREMUL_ALPHA;
                        else
-                               flags &= ~V4L2_PIX_FMT_FLAG_PREMUL_ALPHA;
-                       fmts |= FmtFlags;
+                               request.flags &= 
~V4L2_PIX_FMT_FLAG_PREMUL_ALPHA;
+                       request.fields |= FmtFlags;
                        break;
                case 9:
-                       quantization = parse_quantization(value);
-                       fmts |= FmtQuantization;
+                       request.quantization = parse_quantization(value);
+                       request.fields |= FmtQuantization;
                        break;
                case 10:
-                       xfer_func = parse_xfer_func(value);
-                       fmts |= FmtXferFunc;
+                       request.xfer_func = parse_xfer_func(value);
+                       request.fields |= FmtXferFunc;
                        break;
                case 11:
-                       sizeimage[sizeimage_index] = strtoul(value, nullptr, 0);
+                       if (sizeimage_index == VIDEO_MAX_PLANES) {
+                               fprintf(stderr, "Too many sizeimage values 
(maximum %u)\n",
+                                       VIDEO_MAX_PLANES);
+                               return false;
+                       }
+                       request.sizeimage[sizeimage_index] = strtoul(value, 
nullptr, 0);
                        sizeimage_index++;
-                       fmts |= FmtSizeImage;
+                       request.fields |= FmtSizeImage;
                        break;
                default:
-                       return 0;
+                       return false;
                }
        }
-       return fmts;
+       return request.fields != 0;
 }
 
 int parse_selection_flags(const char *s)
diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
index c4d955deb710..9aacf9274eda 100644
--- a/utils/v4l2-ctl/v4l2-ctl.h
+++ b/utils/v4l2-ctl/v4l2-ctl.h
@@ -297,6 +297,26 @@ extern int verbose;
 #define FmtXferFunc            (1L<<13)
 #define FmtSizeImage           (1L<<14)
 
+struct video_format_request {
+       unsigned fields = 0;
+       __u32 width = 0;
+       __u32 height = 0;
+       __u32 pixelformat = 0;
+       __u32 field = V4L2_FIELD_ANY;
+       __u32 colorspace = 0;
+       __u32 xfer_func = 0;
+       __u32 ycbcr = 0;
+       __u32 quantization = 0;
+       __u32 flags = 0;
+       __u32 bytesperline[VIDEO_MAX_PLANES] = {};
+       __u32 sizeimage[VIDEO_MAX_PLANES] = {};
+};
+
+// v4l2-ctl-format.cpp
+__u32 parse_pixelformat(const char *value);
+int video_get_and_update_fmt(cv4l_fd &fd, struct v4l2_format &vfmt,
+                            __u32 type, __u32 magic, video_format_request 
&request);
+
 // v4l2-ctl.cpp
 int doioctl_name(int fd, unsigned long int request, void *parm, const char 
*name);
 int test_ioctl(int fd, unsigned long cmd, void *arg);
@@ -307,10 +327,7 @@ __u32 parse_xfer_func(const char *s);
 __u32 parse_ycbcr(const char *s);
 __u32 parse_hsv(const char *s);
 __u32 parse_quantization(const char *s);
-int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat,
-             __u32 &field, __u32 &colorspace, __u32 &xfer, __u32 &ycbcr,
-             __u32 &quantization, __u32 &flags, __u32 *bytesperline,
-             __u32 *sizeimage);
+bool parse_fmt(char *optarg, video_format_request &request);
 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);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to