}
}
-static enum v4l2_field parse_field(const char *s)
-{
- if (!strcmp(s, "any")) return V4L2_FIELD_ANY;
- if (!strcmp(s, "none")) return V4L2_FIELD_NONE;
- if (!strcmp(s, "top")) return V4L2_FIELD_TOP;
- if (!strcmp(s, "bottom")) return V4L2_FIELD_BOTTOM;
- if (!strcmp(s, "interlaced")) return V4L2_FIELD_INTERLACED;
- if (!strcmp(s, "seq_tb")) return V4L2_FIELD_SEQ_TB;
- if (!strcmp(s, "seq_bt")) return V4L2_FIELD_SEQ_BT;
- if (!strcmp(s, "alternate")) return V4L2_FIELD_ALTERNATE;
- if (!strcmp(s, "interlaced_tb")) return V4L2_FIELD_INTERLACED_TB;
- if (!strcmp(s, "interlaced_bt")) return V4L2_FIELD_INTERLACED_BT;
- return V4L2_FIELD_ANY;
-}
-
void overlay_cmd(int ch, char *optarg)
{
unsigned int *set_overlay_fmt_ptr = NULL;
" list supported frame intervals for pixelformat <f> and\n"
" the given width and height [VIDIOC_ENUM_FRAMEINTERVALS]\n"
" pixelformat is the fourcc value as a string\n"
+ " --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=<f>\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"
- " --try-fmt-video=width=<w>,height=<h>,pixelformat=<f>\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"
+ " --try-fmt-video=width=<w>,height=<h>,pixelformat=<pf>,field=<f>\n"
" try the video capture format [VIDIOC_TRY_FMT]\n"
" pixelformat is either the format index as reported by\n"
- " --list-formats, or the fourcc value as a string\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"
" --get-fmt-video-mplane\n"
" query the video capture format through the multi-planar API\n"
" [VIDIOC_G_FMT]\n"
" --set-fmt-video-mplane\n"
- " --try-fmt-video-mplane=width=<w>,height=<h>,pixelformat=<f>\n"
+ " --try-fmt-video-mplane=width=<w>,height=<h>,pixelformat=<pf>,field=<f>\n"
" set/try the video capture format using the multi-planar API\n"
" [VIDIOC_S/TRY_FMT]\n"
" pixelformat is either the format index as reported by\n"
- " --list-formats-mplane, or the fourcc value as a string\n"
+ " --list-formats-mplane, 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"
);
}
}
}
+static void print_video_fields(int fd)
+{
+ struct v4l2_format fmt;
+ struct v4l2_format tmp;
+ bool is_mplane = capabilities &
+ (V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+ V4L2_CAP_VIDEO_M2M_MPLANE);
+
+ fmt.type = is_mplane ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
+ V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (test_ioctl(fd, VIDIOC_G_FMT, &fmt) < 0)
+ return;
+
+ printf("Supported Video Fields:\n");
+ for (__u32 f = V4L2_FIELD_NONE; f <= V4L2_FIELD_INTERLACED_BT; f++) {
+ bool ok;
+
+ tmp = fmt;
+ if (is_mplane)
+ tmp.fmt.pix_mp.field = f;
+ else
+ tmp.fmt.pix.field = f;
+ if (test_ioctl(fd, VIDIOC_TRY_FMT, &tmp) < 0)
+ continue;
+ if (is_mplane)
+ ok = tmp.fmt.pix_mp.field == f;
+ else
+ ok = tmp.fmt.pix.field == f;
+ if (ok)
+ printf("\t%s\n", field2s(f).c_str());
+ }
+}
+
void vidcap_cmd(int ch, char *optarg)
{
- __u32 width, height, pixfmt;
+ __u32 width, height, field, pixfmt;
char *value, *subs;
switch (ch) {
case OptSetVideoMplaneFormat:
case OptTryVideoMplaneFormat:
- set_fmts = parse_fmt(optarg, width, height, pixfmt);
+ set_fmts = parse_fmt(optarg, width, height, field, pixfmt);
if (!set_fmts) {
vidcap_usage();
exit(1);
}
vfmt.fmt.pix_mp.width = width;
vfmt.fmt.pix_mp.height = height;
+ vfmt.fmt.pix_mp.field = field;
vfmt.fmt.pix_mp.pixelformat = pixfmt;
break;
case OptSetVideoFormat:
case OptTryVideoFormat:
- set_fmts = parse_fmt(optarg, width, height, pixfmt);
+ set_fmts = parse_fmt(optarg, width, height, field, pixfmt);
if (!set_fmts) {
vidcap_usage();
exit(1);
}
vfmt.fmt.pix.width = width;
vfmt.fmt.pix.height = height;
+ vfmt.fmt.pix.field = field;
vfmt.fmt.pix.pixelformat = pixfmt;
break;
case OptListFrameSizes:
print_video_formats_ext(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
}
+ if (options[OptListFields]) {
+ print_video_fields(fd);
+ }
+
if (options[OptListFrameSizes]) {
printf("ioctl: VIDIOC_ENUM_FRAMESIZES\n");
frmsize.index = 0;
{
printf("\nVideo Output Formats options:\n"
" --list-formats-out display supported video output formats [VIDIOC_ENUM_FMT]\n"
+ " --list-fields-out list supported fields for the current output format\n"
" --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=<f>\n"
+ " --try-fmt-video-out=width=<w>,height=<h>,pixelformat=<pf>,field=<f>\n"
" set/try the video output format [VIDIOC_TRY_FMT]\n"
" pixelformat is either the format index as reported by\n"
- " --list-formats-out, or the fourcc value as a string\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"
" --list-formats-out-mplane\n"
" display supported video output multi-planar formats\n"
" [VIDIOC_ENUM_FMT]\n"
" query the video output format using the multi-planar API\n"
" [VIDIOC_G_FMT]\n"
" --set-fmt-video-out-mplane\n"
- " --try-fmt-video-out-mplane=width=<w>,height=<h>,pixelformat=<f>\n"
+ " --try-fmt-video-out-mplane=width=<w>,height=<h>,pixelformat=<pf>,field=<f>\n"
" set/try the video output format with the multi-planar API\n"
" [VIDIOC_S/TRY_FMT]\n"
" pixelformat is either the format index as reported by\n"
- " --list-formats-out-mplane, or the fourcc value as a string\n"
+ " --list-formats-out-mplane, 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"
);
}
+static void print_video_out_fields(int fd)
+{
+ struct v4l2_format fmt;
+ struct v4l2_format tmp;
+ bool is_mplane = capabilities &
+ (V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+ V4L2_CAP_VIDEO_M2M_MPLANE);
+
+ fmt.type = is_mplane ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
+ V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ if (test_ioctl(fd, VIDIOC_G_FMT, &fmt) < 0)
+ return;
+
+ printf("Supported Video Output Fields:\n");
+ for (__u32 f = V4L2_FIELD_NONE; f <= V4L2_FIELD_INTERLACED_BT; f++) {
+ bool ok;
+
+ tmp = fmt;
+ if (is_mplane)
+ tmp.fmt.pix_mp.field = f;
+ else
+ tmp.fmt.pix.field = f;
+ if (test_ioctl(fd, VIDIOC_TRY_FMT, &tmp) < 0)
+ continue;
+ if (is_mplane)
+ ok = tmp.fmt.pix_mp.field == f;
+ else
+ ok = tmp.fmt.pix.field == f;
+ if (ok)
+ printf("\t%s\n", field2s(f).c_str());
+ }
+}
+
void vidout_cmd(int ch, char *optarg)
{
- __u32 width, height, pixfmt;
+ __u32 width, height, field, pixfmt;
switch (ch) {
case OptSetVideoOutMplaneFormat:
case OptTryVideoOutMplaneFormat:
- set_fmts_out = parse_fmt(optarg, width, height, pixfmt);
+ set_fmts_out = parse_fmt(optarg, width, height, field, pixfmt);
if (!set_fmts_out) {
vidcap_usage();
exit(1);
}
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;
break;
case OptSetVideoOutFormat:
case OptTryVideoOutFormat:
- set_fmts_out = parse_fmt(optarg, width, height, pixfmt);
+ set_fmts_out = parse_fmt(optarg, width, height, field, pixfmt);
if (!set_fmts_out) {
vidcap_usage();
exit(1);
}
vfmt_out.fmt.pix.width = width;
vfmt_out.fmt.pix.height = height;
+ vfmt_out.fmt.pix.field = field;
vfmt_out.fmt.pix.pixelformat = pixfmt;
break;
}
printf("ioctl: VIDIOC_ENUM_FMT\n");
print_video_formats(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
}
+
+ if (options[OptListOutFields]) {
+ print_video_out_fields(fd);
+ }
}
{"list-formats-mplane", no_argument, 0, OptListMplaneFormats},
{"list-formats-ext", no_argument, 0, OptListFormatsExt},
{"list-formats-ext-mplane", no_argument, 0, OptListMplaneFormatsExt},
+ {"list-fields", no_argument, 0, OptListFields},
{"list-framesizes", required_argument, 0, OptListFrameSizes},
{"list-frameintervals", required_argument, 0, OptListFrameIntervals},
{"list-formats-overlay", no_argument, 0, OptListOverlayFormats},
{"list-formats-out", no_argument, 0, OptListOutFormats},
{"list-formats-out-mplane", no_argument, 0, OptListOutMplaneFormats},
+ {"list-fields-out", no_argument, 0, OptListOutFields},
{"get-standard", no_argument, 0, OptGetStandard},
{"set-standard", required_argument, 0, OptSetStandard},
{"get-detected-standard", no_argument, 0, OptQueryStandard},
}
}
-int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat)
+__u32 parse_field(const char *s)
+{
+ if (!strcmp(s, "any")) return V4L2_FIELD_ANY;
+ if (!strcmp(s, "none")) return V4L2_FIELD_NONE;
+ if (!strcmp(s, "top")) return V4L2_FIELD_TOP;
+ if (!strcmp(s, "bottom")) return V4L2_FIELD_BOTTOM;
+ if (!strcmp(s, "interlaced")) return V4L2_FIELD_INTERLACED;
+ if (!strcmp(s, "seq_tb")) return V4L2_FIELD_SEQ_TB;
+ if (!strcmp(s, "seq_bt")) return V4L2_FIELD_SEQ_BT;
+ if (!strcmp(s, "alternate")) return V4L2_FIELD_ALTERNATE;
+ if (!strcmp(s, "interlaced_tb")) return V4L2_FIELD_INTERLACED_TB;
+ if (!strcmp(s, "interlaced_bt")) return V4L2_FIELD_INTERLACED_BT;
+ return V4L2_FIELD_ANY;
+}
+
+int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &field, __u32 &pixelformat)
{
char *value, *subs;
int fmts = 0;
+ field = V4L2_FIELD_ANY;
subs = optarg;
while (*subs != '\0') {
static const char *const subopts[] = {
"width",
"height",
+ "field",
"pixelformat",
NULL
};
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],
OptListMplaneFormats,
OptListFormatsExt,
OptListMplaneFormatsExt,
+ OptListFields,
OptListFrameSizes,
OptListFrameIntervals,
OptListOverlayFormats,
OptListOutFormats,
OptListOutMplaneFormats,
+ OptListOutFields,
OptLogStatus,
OptVerbose,
OptSilent,
std::string service2s(unsigned service);
std::string field2s(int val);
void print_v4lstd(v4l2_std_id std);
-int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &pixelformat);
+__u32 parse_field(const char *s);
+int parse_fmt(char *optarg, __u32 &width, __u32 &height, __u32 &field, __u32 &pixelformat);
__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, enum v4l2_buf_type type);