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-compliance: add initial support for testing the MC Author: Hans Verkuil <hans.verk...@cisco.com> Date: Fri Feb 2 15:53:04 2018 +0100 Add simple support for the media controller. One could argue that this should go to a media-compliance test, but that will just need to call v4l2-compliance in turn when you want to test all the constituent devices in the topology. And since we currently use it for 90% for V4L2, we might as well add it here. Perhaps at some point v4l2-compliance will be renamed to media-compliance. At least now we have a starting point that we can build on top of. Signed-off-by: Hans Verkuil <hans.verk...@cisco.com> utils/v4l2-compliance/Makefile.am | 2 +- utils/v4l2-compliance/v4l2-compliance.1.in | 3 + utils/v4l2-compliance/v4l2-compliance.cpp | 100 +++++++++++++++++++++++------ utils/v4l2-compliance/v4l2-compliance.h | 3 + utils/v4l2-compliance/v4l2-test-media.cpp | 50 +++++++++++++++ 5 files changed, 139 insertions(+), 19 deletions(-) --- http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=6efe3c2be3b3e26c29bb4a7d94788273193b05d8 diff --git a/utils/v4l2-compliance/Makefile.am b/utils/v4l2-compliance/Makefile.am index aeb640d9f3c4..3af8b3f450e9 100644 --- a/utils/v4l2-compliance/Makefile.am +++ b/utils/v4l2-compliance/Makefile.am @@ -4,7 +4,7 @@ DEFS := v4l2_compliance_SOURCES = v4l2-compliance.cpp v4l2-test-debug.cpp v4l2-test-input-output.cpp \ v4l2-test-controls.cpp v4l2-test-io-config.cpp v4l2-test-formats.cpp v4l2-test-buffers.cpp \ - v4l2-test-codecs.cpp v4l2-test-subdevs.cpp v4l2-test-colors.cpp v4l2-compliance.h + v4l2-test-codecs.cpp v4l2-test-subdevs.cpp v4l2-test-media.cpp v4l2-test-colors.cpp v4l2-compliance.h v4l2_compliance_CPPFLAGS = -I$(top_srcdir)/utils/common if WITH_V4L2_COMPLIANCE_LIBV4L diff --git a/utils/v4l2-compliance/v4l2-compliance.1.in b/utils/v4l2-compliance/v4l2-compliance.1.in index d8efe9a0191a..0f0c72e99ede 100644 --- a/utils/v4l2-compliance/v4l2-compliance.1.in +++ b/utils/v4l2-compliance/v4l2-compliance.1.in @@ -71,6 +71,9 @@ Use device <dev> as the touch device. If <dev> is a number, then /dev/v4l-touch< \fB\-u\fR, \fB\-\-subdev-device\fR=\fI<dev>\fR Use device <dev> as the v4l-subdevX device. If <dev> is a number, then /dev/v4l-subdev<dev> is used. .TP +\fB\-m\fR, \fB\-\-media-device\fR=\fI<dev>\fR +Use device <dev> as the media controller device. If <dev> is a number, then /dev/media<dev> is used. +.TP \fB\-e\fR, \fB\-\-exp-buf-device\fR=\fI<dev>\fR Use device <dev> as the video device used to export DMABUFfers for doing DMABUF streaming tests. If <dev> is a number, then /dev/video<dev> is used. If this option diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index d19c5f0f121b..4b73c0e16711 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -59,6 +59,7 @@ enum Option { OptSetExpBufDevice = 'e', OptStreamAllFormats = 'f', OptHelp = 'h', + OptSetMediaDevice = 'm', OptNoWarnings = 'n', OptSetRadioDevice = 'r', OptStreaming = 's', @@ -118,6 +119,7 @@ static struct option long_options[] = { {"subdev-device", required_argument, 0, OptSetSubDevDevice}, {"expbuf-device", required_argument, 0, OptSetExpBufDevice}, {"touch-device", required_argument, 0, OptSetTouchDevice}, + {"media-device", required_argument, 0, OptSetMediaDevice}, {"help", no_argument, 0, OptHelp}, {"verbose", no_argument, 0, OptVerbose}, {"no-warnings", no_argument, 0, OptNoWarnings}, @@ -153,6 +155,9 @@ static void usage(void) printf(" -u, --subdev-device=<dev>\n"); printf(" Use device <dev> as the v4l-subdev device.\n"); printf(" If <dev> starts with a digit, then /dev/v4l-subdev<dev> is used.\n"); + printf(" -m, --media-device=<dev>\n"); + printf(" Use device <dev> as the media controller device.\n"); + printf(" If <dev> starts with a digit, then /dev/media<dev> is used.\n"); printf(" -e, --expbuf-device=<dev>\n"); printf(" Use device <dev> to obtain DMABUF handles.\n"); printf(" If <dev> starts with a digit, then /dev/video<dev> is used.\n"); @@ -742,10 +747,8 @@ static int get_media_fd(int fd) DIR *dp; struct dirent *ep; dp = opendir(media_path); - if (dp == NULL) { - perror("Couldn't open the directory"); - exit(1); - } + if (dp == NULL) + return -1; media_path[0] = 0; while ((ep = readdir(dp))) { if (!memcmp(ep->d_name, "media", 5) && isdigit(ep->d_name[5])) { @@ -879,7 +882,7 @@ static void mdev_info(int fd, int media_fd) struct media_device_info mdinfo; struct stat sb; - if (fstat(fd, &sb) == -1) { + if (fd >= 0 && fstat(fd, &sb) == -1) { fprintf(stderr, "failed to stat file\n"); exit(1); } @@ -906,6 +909,9 @@ static void mdev_info(int fd, int media_fd) (mdinfo.driver_version >> 8) & 0xff, mdinfo.driver_version & 0xff); + if (fd < 0) + return; + memset(&ent, 0, sizeof(ent)); ent.id = MEDIA_ENT_ID_FLAG_NEXT; while (!ioctl(media_fd, MEDIA_IOC_ENUM_ENTITIES, &ent)) { @@ -967,6 +973,8 @@ int main(int argc, char **argv) struct node touch_node2; struct node subdev_node; struct node subdev_node2; + struct node media_node; + struct node media_node2; struct node expbuf_node; /* command args */ @@ -978,6 +986,7 @@ int main(int argc, char **argv) const char *sdr_device = NULL; /* -S device */ const char *touch_device = NULL; /* -t device */ const char *subdev_device = NULL; /* -u device */ + const char *media_device = NULL; /* -m device */ const char *expbuf_device = NULL; /* --expbuf-device device */ struct v4l2_capability vcap; /* list_cap */ unsigned frame_count = 60; @@ -1064,6 +1073,15 @@ int main(int argc, char **argv) subdev_device = newdev; } break; + case OptSetMediaDevice: + media_device = optarg; + if (media_device[0] >= '0' && media_device[0] <= '9' && strlen(media_device) <= 3) { + static char newdev[20]; + + sprintf(newdev, "/dev/media%s", media_device); + media_device = newdev; + } + break; case OptSetExpBufDevice: expbuf_device = optarg; if (expbuf_device[0] >= '0' && expbuf_device[0] <= '9' && strlen(expbuf_device) <= 3) { @@ -1154,7 +1172,7 @@ int main(int argc, char **argv) kernel_version = v3; if (!video_device && !vbi_device && !radio_device && - !sdr_device && !touch_device && !subdev_device) + !sdr_device && !touch_device && !subdev_device && !media_device) video_device = "/dev/video0"; if (video_device) { @@ -1223,6 +1241,17 @@ int main(int argc, char **argv) } } + if (media_device) { + media_node.s_trace(options[OptTrace]); + media_node.s_direct(true); + fd = media_node.media_open(media_device, false); + if (fd < 0) { + fprintf(stderr, "Failed to open %s: %s\n", media_device, + strerror(errno)); + exit(1); + } + } + if (expbuf_device) { expbuf_node.s_trace(options[OptTrace]); expbuf_node.s_direct(true); @@ -1257,13 +1286,16 @@ int main(int argc, char **argv) } else if (subdev_node.g_fd() >= 0) { node = subdev_node; device = subdev_device; + } else if (media_node.g_fd() >= 0) { + node = media_node; + device = media_device; } node.device = device; - if (node.is_subdev()) - memset(&vcap, 0, sizeof(vcap)); - else + if (node.is_v4l2()) doioctl(&node, VIDIOC_QUERYCAP, &vcap); + else + memset(&vcap, 0, sizeof(vcap)); if (node.g_caps() & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_SLICED_VBI_CAPTURE)) node.has_inputs = true; @@ -1301,9 +1333,10 @@ int main(int argc, char **argv) if (kernel_version) printf("Running on 2.6.%d\n", kernel_version); - media_fd = get_media_fd(node.g_fd()); + if (!node.is_media()) + media_fd = get_media_fd(node.g_fd()); - if (!node.is_subdev()) { + if (node.is_v4l2()) { printf("\nDriver Info:\n"); printf("\tDriver name : %s\n", vcap.driver); printf("\tCard type : %s\n", vcap.card); @@ -1319,7 +1352,9 @@ int main(int argc, char **argv) printf("%s", cap2s(vcap.device_caps).c_str()); } } - if (media_fd >= 0) + if (node.is_media()) + mdev_info(-1, node.g_fd()); + else if (media_fd >= 0) mdev_info(node.g_fd(), media_fd); printf("\nCompliance test for device %s%s:\n\n", @@ -1327,12 +1362,19 @@ int main(int argc, char **argv) /* Required ioctls */ - if (!node.is_subdev()) { + if (node.is_v4l2()) { printf("Required ioctls:\n"); printf("\ttest VIDIOC_QUERYCAP: %s\n", ok(testCap(&node))); printf("\n"); } + if (node.is_media()) { + printf("Required ioctls:\n"); + printf("\ttest MEDIA_IOC_DEVICE_INFO: %s\n", + ok(testMediaDeviceInfo(&node))); + printf("\n"); + } + /* Multiple opens */ printf("Allow for multiple opens:\n"); @@ -1398,6 +1440,15 @@ int main(int argc, char **argv) if (subdev_node2.g_fd() >= 0) node.node2 = &subdev_node2; } + if (media_device) { + media_node2 = node; + printf("\ttest second media open: %s\n", + ok(media_node2.media_open(media_device, false) >= 0 ? 0 : errno)); + if (media_node2.g_fd() >= 0) { + printf("\ttest MEDIA_IOC_DEVICE_INFO: %s\n", ok(testMediaDeviceInfo(&media_node2))); + node.node2 = &media_node2; + } + } printf("\ttest for unlimited opens: %s\n", ok(testUnlimitedOpens(&node))); printf("\n"); @@ -1407,10 +1458,22 @@ int main(int argc, char **argv) /* register signal handler for interrupt signal, to exit gracefully */ signal(SIGINT, signal_handler_interrupt); + unsigned cur_io = 0; + unsigned min_io = 0; + unsigned max_io = 0; + + /* Media ioctls */ + + if (node.is_media()) { + printf("Media Controller ioctls:\n"); + printf("\n"); + goto done; + } + /* Debug ioctls */ printf("Debug ioctls:\n"); - if (!node.is_subdev()) + if (node.is_v4l2()) printf("\ttest VIDIOC_DBG_G/S_REGISTER: %s\n", ok(testRegister(&node))); printf("\ttest VIDIOC_LOG_STATUS: %s\n", ok(testLogStatus(&node))); printf("\n"); @@ -1458,7 +1521,7 @@ int main(int argc, char **argv) printf("\n"); } - unsigned max_io = node.inputs > node.outputs ? node.inputs : node.outputs; + max_io = node.inputs > node.outputs ? node.inputs : node.outputs; for (unsigned io = 0; io < (max_io ? max_io : 1); io++) { const char *prefix = ""; @@ -1537,8 +1600,8 @@ int main(int argc, char **argv) printf("\n"); } - unsigned cur_io = node.has_inputs ? state.input.index : state.output.index; - unsigned min_io = 0; + cur_io = node.has_inputs ? state.input.index : state.output.index; + min_io = 0; if (!options[OptStreamAllIO]) { min_io = cur_io; @@ -1548,7 +1611,7 @@ int main(int argc, char **argv) for (unsigned io = min_io; io < (max_io ? max_io : 1); io++) { restoreState(); - if (node.is_subdev()) + if (!node.is_v4l2()) break; if (options[OptStreaming] || (node.is_video && options[OptStreamAllFormats]) || @@ -1612,6 +1675,7 @@ int main(int argc, char **argv) * S_SELECTION flags tests */ +done: restoreState(); /* Final test report */ diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index 2c5ee768ac71..7c43db5ba933 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -229,6 +229,9 @@ int testDecoder(struct node *node); // SubDev ioctl tests int testSubDevEnum(struct node *node, unsigned pad); +// Media Controller ioctl tests +int testMediaDeviceInfo(struct node *node); + // Buffer ioctl tests int testReqBufs(struct node *node); int testReadWrite(struct node *node); diff --git a/utils/v4l2-compliance/v4l2-test-media.cpp b/utils/v4l2-compliance/v4l2-test-media.cpp new file mode 100644 index 000000000000..ea66548e6b0f --- /dev/null +++ b/utils/v4l2-compliance/v4l2-test-media.cpp @@ -0,0 +1,50 @@ +/* + V4L2 API subdev ioctl tests. + + Copyright (C) 2018 Hans Verkuil <hans.verk...@cisco.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + */ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <ctype.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <assert.h> +#include <linux/media.h> +#include "v4l2-compliance.h" + +int testMediaDeviceInfo(struct node *node) +{ + struct media_device_info mdinfo; + + memset(&mdinfo, 0xff, sizeof(mdinfo)); + fail_on_test(doioctl(node, MEDIA_IOC_DEVICE_INFO, &mdinfo)); + fail_on_test(check_0(mdinfo.reserved, sizeof(mdinfo.reserved))); + fail_on_test(check_string(mdinfo.driver, sizeof(mdinfo.driver))); + fail_on_test(mdinfo.model[0] && check_string(mdinfo.model, sizeof(mdinfo.model))); + fail_on_test(mdinfo.serial[0] && check_string(mdinfo.serial, sizeof(mdinfo.serial))); + fail_on_test(mdinfo.bus_info[0] && check_string(mdinfo.bus_info, sizeof(mdinfo.bus_info))); + fail_on_test(mdinfo.media_version == 0); + fail_on_test(mdinfo.driver_version != mdinfo.media_version); + return 0; +} _______________________________________________ linuxtv-commits mailing list linuxtv-commits@linuxtv.org https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits