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-ctl: add -z option to make it possible to use entity names
Author:  Hans Verkuil <hverkuil-ci...@xs4all.nl>
Date:    Fri Feb 1 14:29:26 2019 +0100

The -z option refers to a media device by bus_info, and if this is
known, then device nodes can be found with G_TOPOLOGY and the name
of the entity associated with the interface link or the interface ID.

This uniquely identifies a device node, independently of how it is
named.

Signed-off-by: Hans Verkuil <hverkuil-ci...@xs4all.nl>

 utils/v4l2-ctl/v4l2-ctl-common.cpp |  13 ++++
 utils/v4l2-ctl/v4l2-ctl.1.in       |  19 +++++-
 utils/v4l2-ctl/v4l2-ctl.cpp        | 132 +++++++++++++++++++++++++++++++------
 utils/v4l2-ctl/v4l2-ctl.h          |   1 +
 4 files changed, 142 insertions(+), 23 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=73b8d3eb769241f7f81e67b73a9ce6e6c167baeb
diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp 
b/utils/v4l2-ctl/v4l2-ctl-common.cpp
index c660d15f22fc..11fe602ebc7f 100644
--- a/utils/v4l2-ctl/v4l2-ctl-common.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp
@@ -65,11 +65,24 @@ void common_usage(void)
               "  -D, --info         show driver info [VIDIOC_QUERYCAP]\n"
               "  -d, --device <dev> use device <dev> instead of /dev/video0\n"
               "                     if <dev> starts with a digit, then 
/dev/video<dev> is used\n"
+              "                     Otherwise if -z was specified earlier, 
then <dev> is the entity name\n"
+              "                     or interface ID (if prefixed with 0x) as 
found in the topology of the\n"
+              "                     media device with the bus info string as 
specified by the -z option.\n"
               "  -e, --out-device <dev> use device <dev> for output streams 
instead of the\n"
               "                     default device as set with --device\n"
               "                     if <dev> starts with a digit, then 
/dev/video<dev> is used\n"
+              "                     Otherwise if -z was specified earlier, 
then <dev> is the entity name\n"
+              "                     or interface ID (if prefixed with 0x) as 
found in the topology of the\n"
+              "                     media device with the bus info string as 
specified by the -z option.\n"
               "  -E, --export-device <dev> use device <dev> for exporting DMA 
buffers\n"
               "                     if <dev> starts with a digit, then 
/dev/video<dev> is used\n"
+              "                     Otherwise if -z was specified earlier, 
then <dev> is the entity name\n"
+              "                     or interface ID (if prefixed with 0x) as 
found in the topology of the\n"
+              "                     media device with the bus info string as 
specified by the -z option.\n"
+              "  -z, --media-bus-info <bus-info>\n"
+              "                     find the media device with the given bus 
info string. If set, then\n"
+              "                     -d, -e and -E options can use the entity 
name or interface ID to refer\n"
+              "                     to the device nodes.\n"
               "  -h, --help         display this help message\n"
               "  --help-all         all options\n"
               "  --help-io          input/output options\n"
diff --git a/utils/v4l2-ctl/v4l2-ctl.1.in b/utils/v4l2-ctl/v4l2-ctl.1.in
index 132f51346db2..f37d6e3d3cf4 100644
--- a/utils/v4l2-ctl/v4l2-ctl.1.in
+++ b/utils/v4l2-ctl/v4l2-ctl.1.in
@@ -12,7 +12,11 @@ devices covering the full V4L2 API.
 .SH OPTIONS
 .TP
 \fB\-d\fR, \fB\-\-device\fR \fI<dev>\fR
-Use device <dev> as the V4L2 device. If <dev> is a number, then 
/dev/video<dev> is used.
+Use device \fI<dev>\fR as the V4L2 device.
+if \fI<dev>\fR starts with a digit, then /dev/video\fI<dev>\fR is used
+Otherwise if \fB-z\fR was specified earlier, then \fI<dev>\fR is the entity 
name
+or interface ID (if prefixed with 0x) as found in the topology of the media 
device
+with the bus info string as specified by the \fB-z\fR option.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
 Turn on verbose reporting.
@@ -86,12 +90,23 @@ Show driver info [VIDIOC_QUERYCAP].
 .TP
 \fB-e\fR, \fB--out-device\fR \fI<dev>\fR
 Use device \fI<dev>\fR for output streams instead of the
-default device as set with --device. If \fI<dev>\fR starts
+default device as set with \fB--device\fR. If \fI<dev>\fR starts
 with a digit, then /dev/video\fI<dev>\fR is used.
+Otherwise if \fB-z\fR was specified earlier, then \fI<dev>\fR is the entity 
name
+or interface ID (if prefixed with 0x) as found in the topology of the media 
device
+with the bus info string as specified by the \fB-z\fR option.
 .TP
 \fB-E\fR, \fB--export-device\fR \fI<dev>\fR
 Use device \fI<dev>\fR for exporting DMA buffers.
 If \fI<dev>\fR starts with a digit, then /dev/video\fI<dev>\fR is used.
+Otherwise if \fB-z\fR was specified earlier, then \fI<dev>\fR is the entity 
name
+or interface ID (if prefixed with 0x) as found in the topology of the media 
device
+with the bus info string as specified by the \fB-z\fR option.
+.TP
+\fB-z\fR, \fB--media-bus-info\fR \fI<bus-info>\fR
+Find the media device with the given \fI<bus-info>\fR string. If set, then
+\fB-d\fR, \fB-e\fR and \fB-E\fR options can use the entity name or interface ID
+to refer to the device nodes. Example: v4l2-ctl -z platform:vivid-000 -d 
vivid-000-vid-cap
 .TP
 \fB-k\fR, \fB--concise\fR
 Be more concise if possible.
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index fc19798c06f3..057b08e34136 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -73,6 +73,7 @@ static struct option long_options[] = {
        {"device", required_argument, 0, OptSetDevice},
        {"out-device", required_argument, 0, OptSetOutDevice},
        {"export-device", required_argument, 0, OptSetExportDevice},
+       {"media-bus-info", required_argument, 0, OptMediaBusInfo},
        {"get-fmt-video", no_argument, 0, OptGetVideoFormat},
        {"set-fmt-video", required_argument, 0, OptSetVideoFormat},
        {"try-fmt-video", required_argument, 0, OptTryVideoFormat},
@@ -947,6 +948,109 @@ __u32 find_pixel_format(int fd, unsigned index, bool 
output, bool mplane)
        return fmt.pixelformat;
 }
 
+static int open_media_bus_info(const std::string &bus_info)
+{
+       DIR *dp;
+       struct dirent *ep;
+
+       dp = opendir("/dev");
+       if (dp == NULL)
+               return -1;
+
+       while ((ep = readdir(dp))) {
+               const char *name = ep->d_name;
+
+               if (!memcmp(name, "media", 5) && isdigit(name[5])) {
+                       struct media_device_info mdi;
+                       std::string devname = std::string("/dev/") + name;
+
+                       int fd = open(devname.c_str(), O_RDWR);
+                       if (fd < 0)
+                               continue;
+                       if (!ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi) &&
+                           bus_info == mdi.bus_info) {
+                               closedir(dp);
+                               return fd;
+                       }
+                       close(fd);
+               }
+       }
+       closedir(dp);
+       return -1;
+}
+
+static const char *make_devname(const char *device, const char *devname,
+                               const std::string &media_bus_info)
+{
+       if (device[0] >= '0' && device[0] <= '9' && strlen(device) <= 3) {
+               static char newdev[32];
+
+               sprintf(newdev, "/dev/%s%s", devname, device);
+               return newdev;
+       }
+       if (media_bus_info.empty())
+               return device;
+       int media_fd = open_media_bus_info(media_bus_info);
+       if (media_fd < 0)
+               return device;
+
+       media_v2_topology topology;
+       memset(&topology, 0, sizeof(topology));
+       if (ioctl(media_fd, MEDIA_IOC_G_TOPOLOGY, &topology)) {
+               close(media_fd);
+               return device;
+       }
+
+       media_v2_entity *ents = new media_v2_entity[topology.num_entities];
+       topology.ptr_entities = (__u64)ents;
+       media_v2_link *links = new media_v2_link[topology.num_links];
+       topology.ptr_links = (__u64)links;
+       media_v2_interface *ifaces = new 
media_v2_interface[topology.num_interfaces];
+       topology.ptr_interfaces = (__u64)ifaces;
+
+       unsigned i, ent_id, iface_id = 0;
+
+       if (ioctl(media_fd, MEDIA_IOC_G_TOPOLOGY, &topology))
+               goto err;
+
+       if (device[0] == '0' && device[1] == 'x')
+               iface_id = strtoul(device, NULL, 16);
+
+       if (!iface_id) {
+               for (i = 0; i < topology.num_entities; i++)
+                       if (!strcmp(ents[i].name, device))
+                               break;
+               if (i >= topology.num_entities)
+                       goto err;
+               ent_id = ents[i].id;
+               for (i = 0; i < topology.num_links; i++)
+                       if (links[i].sink_id == ent_id &&
+                           (links[i].flags & MEDIA_LNK_FL_LINK_TYPE) ==
+                           MEDIA_LNK_FL_INTERFACE_LINK)
+                               break;
+               if (i >= topology.num_links)
+                       goto err;
+               iface_id = links[i].source_id;
+       }
+       for (i = 0; i < topology.num_interfaces; i++)
+               if (ifaces[i].id == iface_id)
+                       break;
+       if (i >= topology.num_interfaces)
+               goto err;
+
+       static char newdev[32];
+       sprintf(newdev, "/dev/char/%d:%d",
+               ifaces[i].devnode.major, ifaces[i].devnode.minor);
+       device = newdev;
+       
+err:
+       delete [] ents;
+       delete [] links;
+       delete [] ifaces;
+       close(media_fd);
+       return device;
+}
+
 int main(int argc, char **argv)
 {
        int i;
@@ -958,6 +1062,7 @@ int main(int argc, char **argv)
        int exp_fd = -1;
        int media_fd = -1;
        bool is_subdev = false;
+       std::string media_bus_info;
 
        /* command args */
        int ch;
@@ -1062,31 +1167,16 @@ int main(int argc, char **argv)
                        usage_all();
                        return 0;
                case OptSetDevice:
-                       device = optarg;
-                       if (device[0] >= '0' && device[0] <= '9' && 
strlen(device) <= 3) {
-                               static char newdev[20];
-
-                               sprintf(newdev, "/dev/video%s", device);
-                               device = newdev;
-                       }
+                       device = make_devname(optarg, "video", media_bus_info);
                        break;
                case OptSetOutDevice:
-                       out_device = optarg;
-                       if (out_device[0] >= '0' && out_device[0] <= '9' && 
strlen(out_device) <= 3) {
-                               static char newdev[20];
-
-                               sprintf(newdev, "/dev/video%s", out_device);
-                               out_device = newdev;
-                       }
+                       out_device = make_devname(optarg, "video", 
media_bus_info);
                        break;
                case OptSetExportDevice:
-                       export_device = optarg;
-                       if (export_device[0] >= '0' && export_device[0] <= '9' 
&& strlen(export_device) <= 3) {
-                               static char newdev[20];
-
-                               sprintf(newdev, "/dev/video%s", export_device);
-                               export_device = newdev;
-                       }
+                       export_device = make_devname(optarg, "video", 
media_bus_info);
+                       break;
+               case OptMediaBusInfo:
+                       media_bus_info = optarg;
                        break;
                case OptWaitForEvent:
                        wait_for_event = parse_event(optarg, &wait_event_id);
diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
index 739dc5a9fed2..ef565d5a652f 100644
--- a/utils/v4l2-ctl/v4l2-ctl.h
+++ b/utils/v4l2-ctl/v4l2-ctl.h
@@ -82,6 +82,7 @@ enum Option {
        OptUseWrapper = 'w',
        OptGetVideoOutFormat = 'X',
        OptSetVideoOutFormat = 'x',
+       OptMediaBusInfo = 'z',
 
        OptGetSlicedVbiOutFormat = 128,
        OptGetOverlayFormat,

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to