@@ -22,6 +22,7 @@ LOCAL_SRC_FILES := \
v4l2-ctl-io.cpp v4l2-ctl-stds.cpp v4l2-ctl-vidcap.cpp v4l2-ctl-vidout.cpp \
v4l2-ctl-overlay.cpp v4l2-ctl-vbi.cpp v4l2-ctl-selection.cpp v4l2-ctl-misc.cpp \
v4l2-ctl-streaming.cpp v4l2-ctl-sdr.cpp v4l2-ctl-edid.cpp v4l2-ctl-modes.cpp \
- v4l2-ctl-meta.cpp v4l2-ctl-subdev.cpp v4l2-info.cpp media-info.cpp \
+ v4l2-ctl-meta.cpp v4l2-ctl-audio.cpp v4l2-ctl-subdev.cpp \
+ v4l2-info.cpp media-info.cpp \
v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c codec-fwht.c
include $(BUILD_EXECUTABLE)
@@ -7,6 +7,7 @@ v4l2_ctl_sources = files(
'v4l2-ctl-edid.cpp',
'v4l2-ctl-io.cpp',
'v4l2-ctl-meta.cpp',
+ 'v4l2-ctl-audio.cpp',
'v4l2-ctl-misc.cpp',
'v4l2-ctl-modes.cpp',
'v4l2-ctl-overlay.cpp',
new file mode 100644
@@ -0,0 +1,131 @@
+#include <endian.h>
+
+#include "v4l2-ctl.h"
+
+static struct v4l2_format vfmt; /* set_format/get_format */
+static unsigned mbus_code;
+static unsigned mbus_code_out;
+
+void audio_usage()
+{
+ printf("\nAudio Formats options:\n"
+ " --list-formats-audio [<mbus_code>] display supported audio capture formats.\n"
+ " <mbus_code> is an optional media bus code, if the device has\n"
+ " capability V4L2_CAP_IO_MC then only formats that support this\n"
+ " media bus code are listed [VIDIOC_ENUM_FMT]\n"
+ " --get-fmt-audio query the audio capture format [VIDIOC_G_FMT]\n"
+ " --set-fmt-audio <f> set the audio capture format [VIDIOC_S_FMT]\n"
+ " parameter is either the format index as reported by\n"
+ " --list-formats-audio, or the fourcc value as a string\n"
+ " --try-fmt-audio <f> try the audio capture format [VIDIOC_TRY_FMT]\n"
+ " parameter is either the format index as reported by\n"
+ " --list-formats-audio, or the fourcc value as a string\n"
+ " --list-formats-audio-out [<mbus_code>] display supported audio output formats.\n"
+ " <mbus_code> is an optional media bus code, if the device has\n"
+ " capability V4L2_CAP_IO_MC then only formats that support this\n"
+ " media bus code are listed [VIDIOC_ENUM_FMT]\n"
+ " --get-fmt-audio-out query the audio output format [VIDIOC_G_FMT]\n"
+ " --set-fmt-audio-out <f> set the audio output format [VIDIOC_S_FMT]\n"
+ " parameter is either the format index as reported by\n"
+ " --list-formats-audio-out, or the fourcc value as a string\n"
+ " --try-fmt-audio-out <f> try the audio output format [VIDIOC_TRY_FMT]\n"
+ " parameter is either the format index as reported by\n"
+ " --list-formats-audio-out, or the fourcc value as a string\n"
+ );
+}
+
+void audio_cmd(int ch, char *optarg)
+{
+ switch (ch) {
+ case OptSetAudioFormat:
+ case OptTryAudioFormat:
+ case OptSetAudioOutFormat:
+ case OptTryAudioOutFormat:
+ if (strlen(optarg) == 0) {
+ audio_usage();
+ std::exit(EXIT_FAILURE);
+ } else if (strlen(optarg) == 4) {
+ vfmt.fmt.audio.audioformat = v4l2_fourcc(optarg[0],
+ optarg[1], optarg[2], optarg[3]);
+ } else {
+ vfmt.fmt.audio.audioformat = strtol(optarg, nullptr, 0);
+ }
+ break;
+ case OptListAudioFormats:
+ if (optarg)
+ mbus_code = strtoul(optarg, nullptr, 0);
+ break;
+ case OptListAudioOutFormats:
+ if (optarg)
+ mbus_code_out = strtoul(optarg, nullptr, 0);
+ break;
+ }
+}
+
+static void __audio_set(cv4l_fd &_fd, bool set, bool _try, __u32 type)
+{
+ struct v4l2_format in_vfmt;
+ int fd = _fd.g_fd();
+ int ret;
+
+ if (!set && !_try)
+ return;
+
+ in_vfmt.type = type;
+ in_vfmt.fmt.audio.audioformat = vfmt.fmt.audio.audioformat;
+
+ if (in_vfmt.fmt.audio.audioformat < 256) {
+ struct v4l2_fmtdesc fmt = {};
+
+ fmt.index = in_vfmt.fmt.audio.audioformat;
+ fmt.type = in_vfmt.type;
+
+ if (doioctl(fd, VIDIOC_ENUM_FMT, &fmt))
+ fmt.pixelformat = 0;
+
+ in_vfmt.fmt.audio.audioformat = fmt.pixelformat;
+ }
+
+ if (set)
+ ret = doioctl(fd, VIDIOC_S_FMT, &in_vfmt);
+ else
+ ret = doioctl(fd, VIDIOC_TRY_FMT, &in_vfmt);
+ if (ret == 0 && (verbose || _try))
+ printfmt(fd, in_vfmt);
+}
+
+void audio_set(cv4l_fd &_fd)
+{
+ __audio_set(_fd, options[OptSetAudioFormat], options[OptTryAudioFormat],
+ V4L2_BUF_TYPE_AUDIO_CAPTURE);
+ __audio_set(_fd, options[OptSetAudioOutFormat],
+ options[OptTryAudioOutFormat], V4L2_BUF_TYPE_AUDIO_OUTPUT);
+}
+
+static void __audio_get(cv4l_fd &fd, __u32 type)
+{
+ vfmt.type = type;
+ if (doioctl(fd.g_fd(), VIDIOC_G_FMT, &vfmt) == 0)
+ printfmt(fd.g_fd(), vfmt);
+}
+
+void audio_get(cv4l_fd &fd)
+{
+ if (options[OptGetAudioFormat])
+ __audio_get(fd, V4L2_BUF_TYPE_AUDIO_CAPTURE);
+ if (options[OptGetAudioOutFormat])
+ __audio_get(fd, V4L2_BUF_TYPE_AUDIO_OUTPUT);
+}
+
+void audio_list(cv4l_fd &fd)
+{
+ if (options[OptListAudioFormats]) {
+ printf("ioctl: VIDIOC_ENUM_FMT\n");
+ print_video_formats(fd, V4L2_BUF_TYPE_AUDIO_CAPTURE, mbus_code);
+ }
+
+ if (options[OptListAudioOutFormats]) {
+ printf("ioctl: VIDIOC_ENUM_FMT\n");
+ print_video_formats(fd, V4L2_BUF_TYPE_AUDIO_OUTPUT, mbus_code_out);
+ }
+}
@@ -79,6 +79,7 @@ void common_usage()
" --help-all all options\n"
" --help-io input/output options\n"
" --help-meta metadata format options\n"
+ " --help-audio audio format options\n"
" --help-misc miscellaneous options\n"
" --help-overlay overlay format options\n"
" --help-sdr SDR format options\n"
@@ -123,6 +124,7 @@ static const char *prefixes[] = {
"swradio",
"v4l-subdev",
"v4l-touch",
+ "v4l-audio",
"media",
nullptr
};
@@ -1857,7 +1857,8 @@ static void streaming_set_cap(cv4l_fd &fd, cv4l_fd &exp_fd)
if (!(capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE |
V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE |
V4L2_CAP_META_CAPTURE | V4L2_CAP_SDR_CAPTURE |
- V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE))) {
+ V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE |
+ V4L2_CAP_AUDIO_M2M))) {
fprintf(stderr, "unsupported stream type\n");
return;
}
@@ -2155,7 +2156,7 @@ static FILE *open_input_file(cv4l_fd &fd, __u32 type)
static void streaming_set_out(cv4l_fd &fd, cv4l_fd &exp_fd)
{
- __u32 type = fd.has_vid_m2m() ? v4l_type_invert(fd.g_type()) : fd.g_type();
+ __u32 type = fd.has_m2m() ? v4l_type_invert(fd.g_type()) : fd.g_type();
cv4l_queue q(type, out_memory);
cv4l_queue exp_q(exp_fd.g_type(), V4L2_MEMORY_MMAP);
int fd_flags = fcntl(fd.g_fd(), F_GETFL);
@@ -2171,7 +2172,8 @@ static void streaming_set_out(cv4l_fd &fd, cv4l_fd &exp_fd)
if (!(capabilities & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE |
V4L2_CAP_VBI_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT |
V4L2_CAP_SDR_OUTPUT | V4L2_CAP_META_OUTPUT |
- V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE))) {
+ V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE |
+ V4L2_CAP_AUDIO_M2M))) {
fprintf(stderr, "unsupported stream type\n");
return;
}
@@ -2711,7 +2713,7 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
fd.g_fmt(fmt[OUT], out.g_type());
fd.g_fmt(fmt[CAP], in.g_type());
- if (!fd.has_vid_m2m()) {
+ if (!fd.has_m2m()) {
fprintf(stderr, "unsupported m2m stream type\n");
return;
}
@@ -2761,7 +2763,7 @@ static void streaming_set_cap2out(cv4l_fd &fd, cv4l_fd &out_fd)
bool use_poll = options[OptStreamPoll];
bool use_dmabuf = options[OptStreamDmaBuf] || options[OptStreamOutDmaBuf];
bool use_userptr = options[OptStreamUser] && options[OptStreamOutUser];
- __u32 out_type = out_fd.has_vid_m2m() ? v4l_type_invert(out_fd.g_type()) : out_fd.g_type();
+ __u32 out_type = out_fd.has_m2m() ? v4l_type_invert(out_fd.g_type()) : out_fd.g_type();
cv4l_queue in(fd.g_type(), memory);
cv4l_queue out(out_type, out_memory);
fps_timestamps fps_ts[2];
@@ -3000,7 +3002,7 @@ void streaming_list(cv4l_fd &fd, cv4l_fd &out_fd)
list_buffers(fd, fd.g_type());
if (options[OptListBuffersOut])
- list_buffers(*p_out_fd, p_out_fd->has_vid_m2m() ?
+ list_buffers(*p_out_fd, p_out_fd->has_m2m() ?
v4l_type_invert(p_out_fd->g_type()) : p_out_fd->g_type());
if (options[OptStreamBufCaps])
@@ -32,6 +32,10 @@ wrapper library.
\fB\-h\fR, \fB\-\-help\fR
Prints the help message.
.TP
+\fB\-\-help\-audio\fR
+Prints the help message for all options that get/set/list memory-to-memory audio
+formats.
+.TP
\fB\-\-help\-io\fR
Prints the help message for all options that get/set/list inputs and outputs, both
video and audio.
@@ -76,6 +76,7 @@ static struct option long_options[] = {
{"help-vbi", no_argument, nullptr, OptHelpVbi},
{"help-sdr", no_argument, nullptr, OptHelpSdr},
{"help-meta", no_argument, nullptr, OptHelpMeta},
+ {"help-audio", no_argument, nullptr, OptHelpAudio},
{"help-subdev", no_argument, nullptr, OptHelpSubDev},
{"help-selection", no_argument, nullptr, OptHelpSelection},
{"help-misc", no_argument, nullptr, OptHelpMisc},
@@ -111,6 +112,8 @@ static struct option long_options[] = {
{"list-formats-out-ext", optional_argument, nullptr, OptListOutFormatsExt},
{"list-formats-meta", optional_argument, nullptr, OptListMetaFormats},
{"list-formats-meta-out", optional_argument, nullptr, OptListMetaOutFormats},
+ {"list-formats-audio", optional_argument, nullptr, OptListAudioFormats},
+ {"list-formats-audio-out", optional_argument, nullptr, OptListAudioOutFormats},
{"list-subdev-mbus-codes", optional_argument, nullptr, OptListSubDevMBusCodes},
{"list-subdev-framesizes", required_argument, nullptr, OptListSubDevFrameSizes},
{"list-subdev-frameintervals", required_argument, nullptr, OptListSubDevFrameIntervals},
@@ -166,6 +169,12 @@ static struct option long_options[] = {
{"get-fmt-meta-out", no_argument, nullptr, OptGetMetaOutFormat},
{"set-fmt-meta-out", required_argument, nullptr, OptSetMetaOutFormat},
{"try-fmt-meta-out", required_argument, nullptr, OptTryMetaOutFormat},
+ {"get-fmt-audio", no_argument, nullptr, OptGetAudioFormat},
+ {"set-fmt-audio", required_argument, nullptr, OptSetAudioFormat},
+ {"try-fmt-audio", required_argument, nullptr, OptTryAudioFormat},
+ {"get-fmt-audio-out", no_argument, nullptr, OptGetAudioOutFormat},
+ {"set-fmt-audio-out", required_argument, nullptr, OptSetAudioOutFormat},
+ {"try-fmt-audio-out", required_argument, nullptr, OptTryAudioOutFormat},
{"get-subdev-fmt", optional_argument, nullptr, OptGetSubDevFormat},
{"set-subdev-fmt", required_argument, nullptr, OptSetSubDevFormat},
{"try-subdev-fmt", required_argument, nullptr, OptTrySubDevFormat},
@@ -233,6 +242,8 @@ static struct option long_options[] = {
{"list-buffers-sdr-out", no_argument, nullptr, OptListBuffersSdrOut},
{"list-buffers-meta", no_argument, nullptr, OptListBuffersMeta},
{"list-buffers-meta-out", no_argument, nullptr, OptListBuffersMetaOut},
+ {"list-buffers-audio", no_argument, nullptr, OptListBuffersAudio},
+ {"list-buffers-audio-out", no_argument, nullptr, OptListBuffersAudioOut},
{"stream-count", required_argument, nullptr, OptStreamCount},
{"stream-skip", required_argument, nullptr, OptStreamSkip},
{"stream-loop", no_argument, nullptr, OptStreamLoop},
@@ -287,6 +298,7 @@ static void usage_all()
vbi_usage();
sdr_usage();
meta_usage();
+ audio_usage();
subdev_usage();
selection_usage();
misc_usage();
@@ -523,6 +535,13 @@ void printfmt(int fd, const struct v4l2_format &vfmt)
printfmtname(fd, vfmt.type, vfmt.fmt.meta.dataformat).c_str());
printf("\tBuffer Size : %u\n", vfmt.fmt.meta.buffersize);
break;
+ case V4L2_BUF_TYPE_AUDIO_CAPTURE:
+ case V4L2_BUF_TYPE_AUDIO_OUTPUT:
+ printf("\tAudio Format : '%s'%s\n", fcc2s(vfmt.fmt.audio.audioformat).c_str(),
+ printfmtname(fd, vfmt.type, vfmt.fmt.audio.audioformat).c_str());
+ printf("\tChannels : %u\n", vfmt.fmt.audio.channels);
+ printf("\tBuffer Size : %u\n", vfmt.fmt.audio.buffersize);
+ break;
}
}
@@ -1213,6 +1232,9 @@ int main(int argc, char **argv)
case OptHelpMeta:
meta_usage();
return 0;
+ case OptHelpAudio:
+ audio_usage();
+ return 0;
case OptHelpSubDev:
subdev_usage();
return 0;
@@ -1284,6 +1306,7 @@ int main(int argc, char **argv)
vbi_cmd(ch, optarg);
sdr_cmd(ch, optarg);
meta_cmd(ch, optarg);
+ audio_cmd(ch, optarg);
subdev_cmd(ch, optarg);
selection_cmd(ch, optarg);
misc_cmd(ch, optarg);
@@ -1315,6 +1338,7 @@ int main(int argc, char **argv)
case MEDIA_TYPE_RADIO:
case MEDIA_TYPE_SDR:
case MEDIA_TYPE_TOUCH:
+ case MEDIA_TYPE_AUDIO:
case MEDIA_TYPE_SUBDEV:
break;
default:
@@ -1480,6 +1504,7 @@ int main(int argc, char **argv)
vbi_set(c_fd);
sdr_set(c_fd);
meta_set(c_fd);
+ audio_set(c_fd);
subdev_set(c_fd);
selection_set(c_fd);
misc_set(c_fd);
@@ -1497,6 +1522,7 @@ int main(int argc, char **argv)
vbi_get(c_fd);
sdr_get(c_fd);
meta_get(c_fd);
+ audio_get(c_fd);
subdev_get(c_fd);
selection_get(c_fd);
misc_get(c_fd);
@@ -1513,6 +1539,7 @@ int main(int argc, char **argv)
vbi_list(c_fd);
sdr_list(c_fd);
meta_list(c_fd);
+ audio_list(c_fd);
subdev_list(c_fd);
streaming_list(c_fd, c_out_fd);
@@ -86,6 +86,8 @@ enum Option {
OptGetSdrOutFormat,
OptGetMetaFormat,
OptGetMetaOutFormat,
+ OptGetAudioFormat,
+ OptGetAudioOutFormat,
OptGetSubDevFormat,
OptSetSlicedVbiOutFormat,
OptSetOverlayFormat,
@@ -95,6 +97,8 @@ enum Option {
OptSetSdrOutFormat,
OptSetMetaFormat,
OptSetMetaOutFormat,
+ OptSetAudioFormat,
+ OptSetAudioOutFormat,
OptSetSubDevFormat,
OptTryVideoOutFormat,
OptTrySlicedVbiOutFormat,
@@ -107,6 +111,8 @@ enum Option {
OptTrySdrOutFormat,
OptTryMetaFormat,
OptTryMetaOutFormat,
+ OptTryAudioFormat,
+ OptTryAudioOutFormat,
OptTrySubDevFormat,
OptAll,
OptListStandards,
@@ -122,6 +128,8 @@ enum Option {
OptListOutFormatsExt,
OptListMetaFormats,
OptListMetaOutFormats,
+ OptListAudioFormats,
+ OptListAudioOutFormats,
OptListSubDevMBusCodes,
OptListSubDevFrameSizes,
OptListSubDevFrameIntervals,
@@ -210,6 +218,8 @@ enum Option {
OptListBuffersSdrOut,
OptListBuffersMeta,
OptListBuffersMetaOut,
+ OptListBuffersAudio,
+ OptListBuffersAudioOut,
OptStreamCount,
OptStreamSkip,
OptStreamLoop,
@@ -255,6 +265,7 @@ enum Option {
OptHelpVbi,
OptHelpSdr,
OptHelpMeta,
+ OptHelpAudio,
OptHelpSubDev,
OptHelpSelection,
OptHelpMisc,
@@ -418,6 +429,13 @@ void meta_list(cv4l_fd &fd);
void print_meta_buffer(FILE *f, cv4l_buffer &buf, cv4l_fmt &fmt, cv4l_queue &q);
void meta_fillbuffer(cv4l_buffer &buf, cv4l_fmt &fmt, cv4l_queue &q);
+// v4l2-ctl-audio.cpp
+void audio_usage(void);
+void audio_cmd(int ch, char *optarg);
+void audio_set(cv4l_fd &fd);
+void audio_get(cv4l_fd &fd);
+void audio_list(cv4l_fd &fd);
+
// v4l2-ctl-subdev.cpp
void subdev_usage(void);
void subdev_cmd(int ch, char *optarg);
Add support for v4l-audioX devices. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> --- utils/v4l2-ctl/Android.mk | 3 +- utils/v4l2-ctl/meson.build | 1 + utils/v4l2-ctl/v4l2-ctl-audio.cpp | 131 ++++++++++++++++++++++++++ utils/v4l2-ctl/v4l2-ctl-common.cpp | 2 + utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 14 +-- utils/v4l2-ctl/v4l2-ctl.1.in | 4 + utils/v4l2-ctl/v4l2-ctl.cpp | 27 ++++++ utils/v4l2-ctl/v4l2-ctl.h | 18 ++++ 8 files changed, 193 insertions(+), 7 deletions(-) create mode 100644 utils/v4l2-ctl/v4l2-ctl-audio.cpp