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: the -z/-u options failed to find the media device Author: Hans Verkuil <[email protected]> Date: Thu Jul 16 09:37:55 2026 +0200 Finding the right media device based on the bus_info and the /dev/v4l-subdevX device failed since it tried to rely on sysfs information instead of just walking the /dev/mediaX devices and finding the media device with a matching bus_info. Fix this. Signed-off-by: Hans Verkuil <[email protected]> Tested-by: Laurent Pinchart <[email protected]> utils/common/media-info.cpp | 38 ++++++++++++++++++++++++++--- utils/common/media-info.h | 13 ++++++---- utils/v4l2-compliance/v4l2-compliance.cpp | 18 +++++++++++--- utils/v4l2-compliance/v4l2-test-buffers.cpp | 6 ++--- utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 4 +-- utils/v4l2-ctl/v4l2-ctl.cpp | 5 +++- 6 files changed, 65 insertions(+), 19 deletions(-) --- http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=3b412f2890e7554a5be67c434c61c01c34173c30 diff --git a/utils/common/media-info.cpp b/utils/common/media-info.cpp index 95e4c74f84bd..6d6d79047c8c 100644 --- a/utils/common/media-info.cpp +++ b/utils/common/media-info.cpp @@ -216,7 +216,7 @@ std::string mi_get_devpath_from_dev_t(dev_t dev) return devpath; } -int mi_get_media_fd(int fd, const char *bus_info) +int mi_get_media_fd(int fd) { int media_fd = -1; dev_t dev; @@ -243,9 +243,39 @@ int mi_get_media_fd(int fd, const char *bus_info) devname += ep->d_name; media_fd = open(devname.c_str(), O_RDWR); - if (bus_info && - (ioctl(media_fd, MEDIA_IOC_DEVICE_INFO, &mdinfo) || - strcmp(mdinfo.bus_info, bus_info))) { + if (ioctl(media_fd, MEDIA_IOC_DEVICE_INFO, &mdinfo)) { + close(media_fd); + continue; + } + break; + } + } + closedir(dp); + return media_fd; +} + +int mi_get_media_bus_info(const char *bus_info) +{ + int media_fd = -1; + DIR *dp; + struct dirent *ep; + + if (!bus_info) + return -1; + + dp = opendir("/dev"); + if (dp == nullptr) + return -1; + while ((ep = readdir(dp))) { + if (!memcmp(ep->d_name, "media", 5) && isdigit(ep->d_name[5])) { + struct media_device_info mdinfo; + std::string devname("/dev/"); + + devname += ep->d_name; + media_fd = open(devname.c_str(), O_RDWR); + + if (ioctl(media_fd, MEDIA_IOC_DEVICE_INFO, &mdinfo) || + strcmp(mdinfo.bus_info, bus_info)) { close(media_fd); continue; } diff --git a/utils/common/media-info.h b/utils/common/media-info.h index c0dd63043d8f..75eb29b4e22a 100644 --- a/utils/common/media-info.h +++ b/utils/common/media-info.h @@ -51,12 +51,15 @@ std::string mi_get_devpath_from_dev_t(dev_t dev); /* * For a given device fd return the corresponding media device - * or -1 if there is none. - * - * If bus_info is not NULL, then find the media device that - * matches the given bus_info. + * or -1 if there is none. This only works if the media device + * is discoverable from where fd sits in /sys. + */ +int mi_get_media_fd(int fd); + +/* + * Find the media device that matches the given bus_info. */ -int mi_get_media_fd(int fd, const char *bus_info = NULL); +int mi_get_media_bus_info(const char *bus_info); /* Return entity flags description */ std::string mi_entflags2s(__u32 flags); diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index 9e0b5c3f9fa1..d6c2f61d61ff 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -1000,8 +1000,7 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_ driver = reinterpret_cast<const char *>(vcap.driver); is_uvcvideo = driver == "uvcvideo"; is_vivid = driver == "vivid"; - if (is_vivid) - node.bus_info = reinterpret_cast<const char *>(vcap.bus_info); + node.bus_info = reinterpret_cast<const char *>(vcap.bus_info); determine_codec_mask(node); } else if (node.is_subdev()) { doioctl(&node, VIDIOC_SUBDEV_QUERYCAP, &subdevcap); @@ -1016,7 +1015,7 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_ if (parent_media_fd >= 0) media_fd = parent_media_fd; else - media_fd = mi_get_media_fd(node.g_fd(), node.bus_info); + media_fd = mi_get_media_bus_info(node.bus_info); } int fd = node.is_media() ? node.g_fd() : media_fd; @@ -1662,6 +1661,7 @@ int main(int argc, char **argv) std::string media_bus_info; struct node expbuf_node; std::string expbuf_media_bus_info; + int media_fd = -1; const char *env_media_apps_color = getenv("MEDIA_APPS_COLOR"); /* command args */ @@ -1910,6 +1910,16 @@ int main(int argc, char **argv) strerror(errno)); std::exit(EXIT_FAILURE); } + if (type != MEDIA_TYPE_MEDIA && !media_bus_info.empty()) { + std::string media_devname; + + media_fd = open_media_bus_info(media_bus_info, media_devname); + if (media_fd < 0) { + fprintf(stderr, "Failed to find media device for %s: %s\n", + media_bus_info.c_str(), strerror(errno)); + std::exit(EXIT_FAILURE); + } + } if (!expbuf_device.empty()) { expbuf_node.s_trace(options[OptTrace]); @@ -1922,7 +1932,7 @@ int main(int argc, char **argv) } } - testNode(node, node, expbuf_node, type, frame_count, all_fmt_frame_count); + testNode(node, node, expbuf_node, type, frame_count, all_fmt_frame_count, media_fd); if (!expbuf_device.empty()) expbuf_node.close(); diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp index 1d4fdf6d7337..dba471e5b488 100644 --- a/utils/v4l2-compliance/v4l2-test-buffers.cpp +++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp @@ -2312,7 +2312,7 @@ int testDmaBuf(struct node *expbuf_node, struct node *node, struct node *node_m2 int testRequests(struct node *node, bool test_streaming) { filehandles fhs; - int media_fd = fhs.add(mi_get_media_fd(node->g_fd(), node->bus_info)); + int media_fd = fhs.add(mi_get_media_bus_info(node->bus_info)); int req_fd; struct test_query_ext_ctrl valid_qctrl; v4l2_ext_controls ctrls; @@ -2448,7 +2448,7 @@ int testRequests(struct node *node, bool test_streaming) fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_REINIT, nullptr) != EBADF); // Open media_fd and alloc a request again - media_fd = fhs.add(mi_get_media_fd(node->g_fd(), node->bus_info)); + media_fd = fhs.add(mi_get_media_bus_info(node->bus_info)); fail_on_test(doioctl_fd(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd)); fhs.add(req_fd); ctrls.count = 1; @@ -2523,7 +2523,7 @@ int testRequests(struct node *node, bool test_streaming) unsigned num_requests = 2 * num_bufs; last_seq.init(); - media_fd = fhs.add(mi_get_media_fd(node->g_fd(), node->bus_info)); + media_fd = fhs.add(mi_get_media_bus_info(node->bus_info)); // Allocate the requests for (unsigned i = 0; i < num_requests; i++) { diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp index 517fc7f209f5..fe5d0dfee397 100644 --- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp @@ -1346,10 +1346,10 @@ static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue &q, FILE *fin, bool qbuf if (fmt.g_pixelformat() == V4L2_PIX_FMT_FWHT_STATELESS) { struct v4l2_capability vcap = {}; fd.querycap(vcap); - int media_fd = mi_get_media_fd(fd.g_fd(), (const char *)vcap.bus_info); + int media_fd = mi_get_media_bus_info((const char *)vcap.bus_info); if (media_fd < 0) { - fprintf(stderr, "%s: mi_get_media_fd failed\n", __func__); + fprintf(stderr, "%s: mi_get_media_bus_info failed\n", __func__); return media_fd; } diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp index 842e22fd939a..14f5c51fc070 100644 --- a/utils/v4l2-ctl/v4l2-ctl.cpp +++ b/utils/v4l2-ctl/v4l2-ctl.cpp @@ -1382,7 +1382,10 @@ int main(int argc, char **argv) capabilities = vcap.device_caps; } - media_fd = mi_get_media_fd(fd, is_subdev ? 0 : (const char *)vcap.bus_info); + if (is_subdev) + media_fd = mi_get_media_fd(fd); + else + media_fd = mi_get_media_bus_info((const char *)vcap.bus_info); priv_magic = (capabilities & V4L2_CAP_EXT_PIX_FORMAT) ? V4L2_PIX_FMT_PRIV_MAGIC : 0; _______________________________________________ linuxtv-commits mailing list -- [email protected] To unsubscribe send an email to [email protected]
