v4l2-ctl: the colorspace can now be set for outputs.
authorHans Verkuil <hans.verkuil@cisco.com>
Mon, 24 Feb 2014 15:07:27 +0000 (16:07 +0100)
committerHans Verkuil <hans.verkuil@cisco.com>
Mon, 24 Feb 2014 15:41:02 +0000 (16:41 +0100)
The colorspace field can now be specified for output formats.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
utils/v4l2-ctl/v4l2-ctl-vidcap.cpp
utils/v4l2-ctl/v4l2-ctl-vidout.cpp
utils/v4l2-ctl/v4l2-ctl.cpp
utils/v4l2-ctl/v4l2-ctl.h

index d60d461..c979b22 100644 (file)
@@ -43,15 +43,9 @@ void vidcap_usage(void)
               "  --list-fields      list supported fields for the current format\n"
               "  -V, --get-fmt-video\n"
               "                     query the video capture format [VIDIOC_G_FMT]\n"
-              "  -v, --set-fmt-video=width=<w>,height=<h>,pixelformat=<pf>,field=<f>\n"
-              "                     set the video capture format [VIDIOC_S_FMT]\n"
-              "                     pixelformat is either the format index as reported by\n"
-              "                     --list-formats, or the fourcc value as a string.\n"
-              "                     <f> can be one of:\n"
-              "                     any, none, top, bottom, interlaced, seq_tb, seq_bt,\n"
-              "                     alternate, interlaced_tb, interlaced_bt\n"
+              "  -v, --set-fmt-video\n"
               "  --try-fmt-video=width=<w>,height=<h>,pixelformat=<pf>,field=<f>\n"
-              "                     try the video capture format [VIDIOC_TRY_FMT]\n"
+              "                     set/try the video capture format [VIDIOC_S/TRY_FMT]\n"
               "                     pixelformat is either the format index as reported by\n"
               "                     --list-formats, or the fourcc value as a string.\n"
               "                     <f> can be one of:\n"
@@ -191,27 +185,29 @@ static void print_video_fields(int fd)
 
 void vidcap_cmd(int ch, char *optarg)
 {
-       __u32 width, height, field, pixfmt;
+       __u32 width, height, pixfmt, field, colorspace;
        char *value, *subs;
 
        switch (ch) {
        case OptSetVideoFormat:
        case OptTryVideoFormat:
-               set_fmts = parse_fmt(optarg, width, height, field, pixfmt);
-               if (!set_fmts) {
+               set_fmts = parse_fmt(optarg, width, height, pixfmt, field, colorspace);
+               if (!set_fmts || (set_fmts & FmtColorspace)) {
                        vidcap_usage();
                        exit(1);
                }
                if (is_multiplanar) {
                        vfmt_cap.fmt.pix_mp.width = width;
                        vfmt_cap.fmt.pix_mp.height = height;
-                       vfmt_cap.fmt.pix_mp.field = field;
                        vfmt_cap.fmt.pix_mp.pixelformat = pixfmt;
+                       vfmt_cap.fmt.pix_mp.field = field;
+                       vfmt_cap.fmt.pix_mp.colorspace = colorspace;
                } else {
                        vfmt_cap.fmt.pix.width = width;
                        vfmt_cap.fmt.pix.height = height;
-                       vfmt_cap.fmt.pix.field = field;
                        vfmt_cap.fmt.pix.pixelformat = pixfmt;
+                       vfmt_cap.fmt.pix.field = field;
+                       vfmt_cap.fmt.pix.colorspace = colorspace;
                }
                break;
        case OptListFrameSizes:
@@ -277,6 +273,8 @@ void vidcap_set(int fd)
                                                                        false, true);
                                        }
                                }
+                               if (set_fmts & FmtField)
+                                       vfmt.fmt.pix_mp.field = vfmt_cap.fmt.pix_mp.field;
                                /* 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. */
@@ -295,6 +293,8 @@ void vidcap_set(int fd)
                                                                        false, false);
                                        }
                                }
+                               if (set_fmts & FmtField)
+                                       vfmt.fmt.pix.field = vfmt_cap.fmt.pix.field;
                                /* 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. */
index 5ab05d1..1d99f4a 100644 (file)
@@ -32,13 +32,15 @@ void vidout_usage(void)
               "  --get-fmt-video-out\n"
               "                     query the video output format [VIDIOC_G_FMT]\n"
               "  --set-fmt-video-out\n"
-              "  --try-fmt-video-out=width=<w>,height=<h>,pixelformat=<pf>,field=<f>\n"
-              "                     set/try the video output format [VIDIOC_TRY_FMT]\n"
+              "  --try-fmt-video-out=width=<w>,height=<h>,pixelformat=<pf>,field=<f>,colorspace=<c>\n"
+              "                     set/try the video output format [VIDIOC_S/TRY_FMT]\n"
               "                     pixelformat is either the format index as reported by\n"
               "                     --list-formats-out, or the fourcc value as a string.\n"
               "                     <f> can be one of:\n"
               "                     any, none, top, bottom, interlaced, seq_tb, seq_bt,\n"
               "                     alternate, interlaced_tb, interlaced_bt\n"
+              "                     <c> can be one of:\n"
+              "                     smpte170m, smpte240m, rec709, bt878, 470m, 470bg, jpeg, srgb\n"
               );
 }
 
@@ -73,12 +75,12 @@ static void print_video_out_fields(int fd)
 
 void vidout_cmd(int ch, char *optarg)
 {
-       __u32 width, height, field, pixfmt;
+       __u32 width, height, pixfmt, field, colorspace;
 
        switch (ch) {
        case OptSetVideoOutFormat:
        case OptTryVideoOutFormat:
-               set_fmts_out = parse_fmt(optarg, width, height, field, pixfmt);
+               set_fmts_out = parse_fmt(optarg, width, height, pixfmt, field, colorspace);
                if (!set_fmts_out) {
                        vidcap_usage();
                        exit(1);
@@ -86,13 +88,15 @@ void vidout_cmd(int ch, char *optarg)
                if (is_multiplanar) {
                        vfmt_out.fmt.pix_mp.width = width;
                        vfmt_out.fmt.pix_mp.height = height;
-                       vfmt_out.fmt.pix_mp.field = field;
                        vfmt_out.fmt.pix_mp.pixelformat = pixfmt;
+                       vfmt_out.fmt.pix_mp.field = field;
+                       vfmt_out.fmt.pix_mp.colorspace = colorspace;
                } else {
                        vfmt_out.fmt.pix.width = width;
                        vfmt_out.fmt.pix.height = height;
-                       vfmt_out.fmt.pix.field = field;
                        vfmt_out.fmt.pix.pixelformat = pixfmt;
+                       vfmt_out.fmt.pix.field = field;
+                       vfmt_out.fmt.pix.colorspace = colorspace;
                }
                break;
        }
@@ -120,6 +124,10 @@ void vidout_set(int fd)
                                                                        true, true);
                                        }
                                }
+                               if (set_fmts_out & FmtField)
+                                       vfmt.fmt.pix_mp.field = vfmt_out.fmt.pix_mp.field;
+                               if (set_fmts_out & FmtColorspace)
+                                       vfmt.fmt.pix_mp.colorspace = vfmt_out.fmt.pix_mp.colorspace;
                                /* 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. */
@@ -138,6 +146,10 @@ void vidout_set(int fd)
                                                                        true, false);
                                        }
                                }
+                               if (set_fmts_out & FmtField)
+                                       vfmt.fmt.pix.field = vfmt_out.fmt.pix.field;
+                               if (set_fmts_out & FmtColorspace)
+                                       vfmt.fmt.pix.colorspace = vfmt_out.fmt.pix.colorspace;
                                /* 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. */
index 09a1782..cbc9e52 100644 (file)
@@ -647,7 +647,21 @@ __u32 parse_field(const char *s)
        return V4L2_FIELD_ANY;
 }
 
-int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &field, __u32 &pixelformat)
+static __u32 parse_colorspace(const char *s)
+{
+       if (!strcmp(s, "smpte170m")) return V4L2_COLORSPACE_SMPTE170M;
+       if (!strcmp(s, "smpte240m")) return V4L2_COLORSPACE_SMPTE240M;
+       if (!strcmp(s, "rec709")) return V4L2_COLORSPACE_REC709;
+       if (!strcmp(s, "bt878")) return V4L2_COLORSPACE_BT878;
+       if (!strcmp(s, "470m")) return V4L2_COLORSPACE_470_SYSTEM_M;
+       if (!strcmp(s, "470bg")) return V4L2_COLORSPACE_470_SYSTEM_BG;
+       if (!strcmp(s, "jpeg")) return V4L2_COLORSPACE_JPEG;
+       if (!strcmp(s, "srgb")) return V4L2_COLORSPACE_SRGB;
+       return 0;
+}
+
+int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat,
+             __u32 &field, __u32 &colorspace)
 {
        char *value, *subs;
        int fmts = 0;
@@ -658,8 +672,9 @@ int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &field, __u32 &pi
                static const char *const subopts[] = {
                        "width",
                        "height",
-                       "field",
                        "pixelformat",
+                       "field",
+                       "colorspace",
                        NULL
                };
 
@@ -673,10 +688,6 @@ int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &field, __u32 &pi
                        fmts |= FmtHeight;
                        break;
                case 2:
-                       field = parse_field(value);
-                       fmts |= FmtField;
-                       break;
-               case 3:
                        if (strlen(value) == 4)
                                pixelformat =
                                        v4l2_fourcc(value[0], value[1],
@@ -685,6 +696,17 @@ int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &field, __u32 &pi
                                pixelformat = strtol(value, 0L, 0);
                        fmts |= FmtPixelFormat;
                        break;
+               case 3:
+                       field = parse_field(value);
+                       fmts |= FmtField;
+                       break;
+               case 4:
+                       colorspace = parse_colorspace(value);
+                       if (colorspace)
+                               fmts |= FmtColorspace;
+                       else
+                               fprintf(stderr, "unknown colorspace %s\n", value);
+                       break;
                default:
                        return 0;
                }
index b976a32..ea983c9 100644 (file)
@@ -178,6 +178,7 @@ typedef struct {
 #define FmtLeft                        (1L<<5)
 #define FmtTop                 (1L<<6)
 #define FmtField               (1L<<7)
+#define FmtColorspace          (1L<<8)
 
 // v4l2-ctl.cpp
 int doioctl_name(int fd, unsigned long int request, void *parm, const char *name);
@@ -193,7 +194,8 @@ std::string service2s(unsigned service);
 std::string field2s(int val);
 void print_v4lstd(v4l2_std_id std);
 __u32 parse_field(const char *s);
-int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &field, __u32 &pixelformat);
+int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat,
+             __u32 &field, __u32 &colorspace);
 __u32 find_pixel_format(int fd, unsigned index, bool output, bool mplane);
 void printfmt(const struct v4l2_format &vfmt);
 void print_video_formats(int fd, __u32 type);