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 -M option to test all /dev/mediaX interfaces
Author:  Hans Verkuil <hans.verk...@cisco.com>
Date:    Sun Feb 4 18:28:10 2018 +0100

Add a new -M option to test all interfaces defines in the media
controller.

Also moved v4l2_type back from v4l2-info to media-info since the
media device defines more than just v4l2 interfaces. It makes
more sense to put this in media-info.

Signed-off-by: Hans Verkuil <hans.verk...@cisco.com>

 utils/common/media-info.cpp               | 89 +++++++++++++++++++++++++++++++
 utils/common/media-info.h                 | 26 +++++++++
 utils/common/v4l2-info.cpp                | 50 -----------------
 utils/common/v4l2-info.h                  | 17 ------
 utils/v4l2-compliance/v4l2-compliance.cpp | 48 +++++++++--------
 utils/v4l2-compliance/v4l2-compliance.h   |  4 ++
 utils/v4l2-compliance/v4l2-test-media.cpp | 77 ++++++++++++++++++++++++--
 utils/v4l2-ctl/v4l2-ctl.cpp               | 23 ++++++--
 8 files changed, 238 insertions(+), 96 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=0561fdb4a972c4a169c121de4e866684d562c9ad
diff --git a/utils/common/media-info.cpp b/utils/common/media-info.cpp
index 0588b3467302..eef743e152f5 100644
--- a/utils/common/media-info.cpp
+++ b/utils/common/media-info.cpp
@@ -33,6 +33,7 @@
 #include <linux/media.h>
 
 #include <fstream>
+#include <media-info.h>
 
 static std::string num2s(unsigned num, bool is_hex = true)
 {
@@ -45,6 +46,94 @@ static std::string num2s(unsigned num, bool is_hex = true)
        return buf;
 }
 
+static struct {
+       const char *devname;
+       enum media_type type;
+} media_types[] = {
+       { "video", MEDIA_TYPE_VIDEO },
+       { "vbi", MEDIA_TYPE_VBI },
+       { "radio", MEDIA_TYPE_RADIO },
+       { "swradio", MEDIA_TYPE_SDR },
+       { "v4l-subdev", MEDIA_TYPE_SUBDEV },
+       { "v4l-touch", MEDIA_TYPE_TOUCH },
+       { "media", MEDIA_TYPE_MEDIA },
+       { "frontend", MEDIA_TYPE_DVB_FRONTEND },
+       { "demux", MEDIA_TYPE_DVB_DEMUX },
+       { "dvr", MEDIA_TYPE_DVB_DVR },
+       { "net", MEDIA_TYPE_DVB_NET },
+       { NULL, MEDIA_TYPE_UNKNOWN }
+};
+
+media_type media_detect_type(const char *device)
+{
+       struct stat sb;
+
+       if (stat(device, &sb) == -1)
+               return MEDIA_TYPE_CANT_STAT;
+
+       std::string uevent_path("/sys/dev/char/");
+
+       uevent_path += num2s(major(sb.st_rdev), false) + ":" +
+               num2s(minor(sb.st_rdev), false) + "/uevent";
+
+       std::ifstream uevent_file(uevent_path);
+       if (uevent_file.fail())
+               return MEDIA_TYPE_UNKNOWN;
+
+       std::string line;
+
+       while (std::getline(uevent_file, line)) {
+               if (line.compare(0, 8, "DEVNAME="))
+                       continue;
+
+               line.erase(0, 8);
+               if (!line.compare(0, 11, "dvb/adapter")) {
+                       line.erase(0, 11);
+                       unsigned len = 0;
+                       while (line[len] && line[len] != '/')
+                               len++;
+                       line.erase(0, len + 1);
+               }
+               for (size_t i = 0; media_types[i].devname; i++) {
+                       const char *devname = media_types[i].devname;
+                       size_t len = strlen(devname);
+
+                       if (!line.compare(0, len, devname) && 
isdigit(line[0+len])) {
+                               uevent_file.close();
+                               return media_types[i].type;
+                       }
+               }
+       }
+
+       uevent_file.close();
+       return MEDIA_TYPE_UNKNOWN;
+}
+
+std::string media_get_device(__u32 major, __u32 minor)
+{
+       char fmt[32];
+       std::string uevent_path("/sys/dev/char/");
+
+       sprintf(fmt, "%d:%d", major, minor);
+       uevent_path += std::string(fmt) + "/uevent";
+
+       std::ifstream uevent_file(uevent_path);
+       if (uevent_file.fail())
+               return "";
+
+       std::string line;
+
+       while (std::getline(uevent_file, line)) {
+               if (line.compare(0, 8, "DEVNAME="))
+                       continue;
+               uevent_file.close();
+               return std::string("/dev/") + &line[8];
+       }
+
+       uevent_file.close();
+       return "";
+}
+
 typedef struct {
        unsigned flag;
        const char *str;
diff --git a/utils/common/media-info.h b/utils/common/media-info.h
index f0636091b728..80cf7d3f3ce2 100644
--- a/utils/common/media-info.h
+++ b/utils/common/media-info.h
@@ -18,6 +18,32 @@
 #ifndef _MEDIA_INFO_H
 #define _MEDIA_INFO_H
 
+enum media_type {
+       MEDIA_TYPE_CANT_STAT,
+       MEDIA_TYPE_UNKNOWN,
+       MEDIA_TYPE_VIDEO,
+       MEDIA_TYPE_VBI,
+       MEDIA_TYPE_RADIO,
+       MEDIA_TYPE_SDR,
+       MEDIA_TYPE_TOUCH,
+       MEDIA_TYPE_SUBDEV,
+       MEDIA_TYPE_DVB_FRONTEND,
+       MEDIA_TYPE_DVB_DEMUX,
+       MEDIA_TYPE_DVB_DVR,
+       MEDIA_TYPE_DVB_NET,
+       MEDIA_TYPE_MEDIA,
+};
+
+/*
+ * Detect what type the device is.
+ */
+media_type media_detect_type(const char *device);
+
+/*
+ * Return the device name given the major and minor numbers.
+ */
+std::string media_get_device(__u32 major, __u32 minor);
+
 /*
  * For a given device fd return the corresponding media device
  * or -1 if there is none.
diff --git a/utils/common/v4l2-info.cpp b/utils/common/v4l2-info.cpp
index 58feb4de0725..8b5051b97feb 100644
--- a/utils/common/v4l2-info.cpp
+++ b/utils/common/v4l2-info.cpp
@@ -45,56 +45,6 @@ static std::string num2s(unsigned num, bool is_hex = true)
        return buf;
 }
 
-v4l2_type v4l2_detect_type(const char *device)
-{
-       struct stat sb;
-
-       if (stat(device, &sb) == -1)
-               return V4L2_TYPE_CANT_STAT;
-
-       std::string uevent_path("/sys/dev/char/");
-
-       uevent_path += num2s(major(sb.st_rdev), false) + ":" +
-               num2s(minor(sb.st_rdev), false) + "/uevent";
-
-       std::ifstream uevent_file(uevent_path);
-       if (uevent_file.fail())
-               return V4L2_TYPE_UNKNOWN;
-
-       std::string line;
-
-       while (std::getline(uevent_file, line)) {
-               if (line.compare(0, 8, "DEVNAME="))
-                       continue;
-
-               static struct {
-                       const char *devname;
-                       enum v4l2_type type;
-               } devtypes[] = {
-                       { "video", V4L2_TYPE_VIDEO },
-                       { "vbi", V4L2_TYPE_VBI },
-                       { "radio", V4L2_TYPE_RADIO },
-                       { "swradio", V4L2_TYPE_SDR },
-                       { "v4l-subdev", V4L2_TYPE_SUBDEV },
-                       { "v4l-touch", V4L2_TYPE_TOUCH },
-                       { NULL, V4L2_TYPE_UNKNOWN }
-               };
-
-               for (size_t i = 0; devtypes[i].devname; i++) {
-                       const char *devname = devtypes[i].devname;
-                       size_t len = strlen(devname);
-
-                       if (!line.compare(8, len, devname) && 
isdigit(line[8+len])) {
-                               uevent_file.close();
-                               return devtypes[i].type;
-                       }
-               }
-       }
-
-       uevent_file.close();
-       return V4L2_TYPE_UNKNOWN;
-}
-
 typedef struct {
        unsigned flag;
        const char *str;
diff --git a/utils/common/v4l2-info.h b/utils/common/v4l2-info.h
index ac6451adce3b..e66a9abb1950 100644
--- a/utils/common/v4l2-info.h
+++ b/utils/common/v4l2-info.h
@@ -21,23 +21,6 @@
 #include <string>
 #include <linux/videodev2.h>
 
-enum v4l2_type {
-       V4L2_TYPE_CANT_STAT,
-       V4L2_TYPE_UNKNOWN,
-       V4L2_TYPE_VIDEO,
-       V4L2_TYPE_VBI,
-       V4L2_TYPE_RADIO,
-       V4L2_TYPE_SDR,
-       V4L2_TYPE_TOUCH,
-       V4L2_TYPE_SUBDEV,
-       V4L2_TYPE_MEDIA,
-};
-
-/*
- * Detect what type the device is.
- */
-v4l2_type v4l2_detect_type(const char *device);
-
 /* Print capability information */
 void v4l2_info_capability(const v4l2_capability &cap);
 
diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp 
b/utils/v4l2-compliance/v4l2-compliance.cpp
index 11b54a1c09f3..07f23f811d0c 100644
--- a/utils/v4l2-compliance/v4l2-compliance.cpp
+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
@@ -59,6 +59,7 @@ enum Option {
        OptStreamAllFormats = 'f',
        OptHelp = 'h',
        OptSetMediaDevice = 'm',
+       OptMediaTestInterfaces = 'M',
        OptNoWarnings = 'n',
        OptSetRadioDevice = 'r',
        OptStreaming = 's',
@@ -119,6 +120,7 @@ static struct option long_options[] = {
        {"expbuf-device", required_argument, 0, OptSetExpBufDevice},
        {"touch-device", required_argument, 0, OptSetTouchDevice},
        {"media-device", required_argument, 0, OptSetMediaDevice},
+       {"media-test-interfaces", no_argument, 0, OptMediaTestInterfaces},
        {"help", no_argument, 0, OptHelp},
        {"verbose", no_argument, 0, OptVerbose},
        {"no-warnings", no_argument, 0, OptNoWarnings},
@@ -157,6 +159,8 @@ static void usage(void)
        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("  -M, --media-test-interfaces\n");
+       printf("                     Test all interfaces in the media 
controller topology.\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");
@@ -626,17 +630,17 @@ static const char *make_devname(const char *device, const 
char *devname)
        return device;
 }
 
-static void test(struct node &node, struct node &expbuf_node, v4l2_type type,
-                unsigned frame_count)
+void testNode(struct node &node, struct node &expbuf_node, media_type type,
+             unsigned frame_count)
 {
        struct node node2;
        struct v4l2_capability vcap;            /* list_cap */
 
-       node.is_video = type == V4L2_TYPE_VIDEO;
-       node.is_vbi = type == V4L2_TYPE_VBI;
-       node.is_radio = type == V4L2_TYPE_RADIO;
-       node.is_sdr = type == V4L2_TYPE_SDR;
-       node.is_touch = type == V4L2_TYPE_TOUCH;
+       node.is_video = type == MEDIA_TYPE_VIDEO;
+       node.is_vbi = type == MEDIA_TYPE_VBI;
+       node.is_radio = type == MEDIA_TYPE_RADIO;
+       node.is_sdr = type == MEDIA_TYPE_SDR;
+       node.is_touch = type == MEDIA_TYPE_TOUCH;
 
        if (node.is_v4l2())
                doioctl(&node, VIDIOC_QUERYCAP, &vcap);
@@ -743,11 +747,11 @@ static void test(struct node &node, struct node 
&expbuf_node, v4l2_type type,
        printf("Allow for multiple opens:\n");
        node2 = node;
        switch (type) {
-       case V4L2_TYPE_SUBDEV:
+       case MEDIA_TYPE_SUBDEV:
                printf("\ttest second %s open: %s\n", node.device,
                       ok(node2.subdev_open(node.device, false) >= 0 ? 0 : 
errno));
                break;
-       case V4L2_TYPE_MEDIA:
+       case MEDIA_TYPE_MEDIA:
                printf("\ttest second %s open: %s\n", node.device,
                       ok(node2.media_open(node.device, false) >= 0 ? 0 : 
errno));
                if (node2.g_fd() >= 0)
@@ -793,6 +797,8 @@ static void test(struct node &node, struct node 
&expbuf_node, v4l2_type type,
                               node.topology->num_links);
                printf("\ttest MEDIA_IOC_SETUP_LINK: %s\n", 
ok(testMediaSetupLink(&node)));
                printf("\n");
+               if (options[OptMediaTestInterfaces])
+                       walkTopology(node, expbuf_node, frame_count);
                goto done;
        }
 
@@ -1035,11 +1041,9 @@ static void test(struct node &node, struct node 
&expbuf_node, v4l2_type type,
         *       S_SELECTION flags tests
         */
 
-done:
        restoreState();
 
-       /* Final test report */
-
+done:
        node.close();
        if (node.node2)
                node.node2->close();
@@ -1049,7 +1053,7 @@ int main(int argc, char **argv)
 {
        int i;
        struct node node;
-       v4l2_type type = V4L2_TYPE_UNKNOWN;
+       media_type type = MEDIA_TYPE_UNKNOWN;
        struct node expbuf_node;
 
        /* command args */
@@ -1106,7 +1110,7 @@ int main(int argc, char **argv)
                        break;
                case OptSetMediaDevice:
                        device = make_devname(optarg, "media");
-                       type = V4L2_TYPE_MEDIA;
+                       type = MEDIA_TYPE_MEDIA;
                        break;
                case OptSetExpBufDevice:
                        expbuf_device = optarg;
@@ -1189,14 +1193,14 @@ int main(int argc, char **argv)
        bool direct = !options[OptUseWrapper];
        int fd;
 
-       if (type == V4L2_TYPE_UNKNOWN)
-               type = v4l2_detect_type(device);
-       if (type == V4L2_TYPE_CANT_STAT) {
+       if (type == MEDIA_TYPE_UNKNOWN)
+               type = media_detect_type(device);
+       if (type == MEDIA_TYPE_CANT_STAT) {
                fprintf(stderr, "Cannot open device %s, exiting.\n",
                        device);
                exit(1);
        }
-       if (type == V4L2_TYPE_UNKNOWN) {
+       if (type == MEDIA_TYPE_UNKNOWN) {
                fprintf(stderr, "Unable to detect what device %s is, 
exiting.\n",
                        device);
                exit(1);
@@ -1205,11 +1209,11 @@ int main(int argc, char **argv)
        node.device = device;
        node.s_trace(options[OptTrace]);
        switch (type) {
-       case V4L2_TYPE_MEDIA:
+       case MEDIA_TYPE_MEDIA:
                node.s_direct(true);
                fd = node.media_open(device, false);
                break;
-       case V4L2_TYPE_SUBDEV:
+       case MEDIA_TYPE_SUBDEV:
                node.s_direct(true);
                fd = node.subdev_open(device, false);
                break;
@@ -1254,12 +1258,14 @@ int main(int argc, char **argv)
        if (kernel_version)
                printf("Running on 2.6.%d\n", kernel_version);
 
-       test(node, expbuf_node, type, frame_count);
+       testNode(node, expbuf_node, type, frame_count);
 
        if (expbuf_device)
                expbuf_node.close();
        if (media_fd >= 0)
                close(media_fd);
+
+       /* Final test report */
        printf("Total: %d, Succeeded: %d, Failed: %d, Warnings: %d\n",
                        tests_total, tests_ok, tests_total - tests_ok, 
warnings);
        exit(app_result);
diff --git a/utils/v4l2-compliance/v4l2-compliance.h 
b/utils/v4l2-compliance/v4l2-compliance.h
index 3263784b0d66..e29ca33b0f15 100644
--- a/utils/v4l2-compliance/v4l2-compliance.h
+++ b/utils/v4l2-compliance/v4l2-compliance.h
@@ -43,6 +43,7 @@
 
 #include <cv4l-helpers.h>
 #include <v4l2-info.h>
+#include <media-info.h>
 
 #if !defined(ENODATA) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
 #define ENODATA ENOTSUP
@@ -180,12 +181,15 @@ int check_string(const char *s, size_t len);
 int check_ustring(const __u8 *s, int len);
 int check_0(const void *p, int len);
 int restoreFormat(struct node *node);
+void testNode(struct node &node, struct node &expbuf_node, media_type type,
+             unsigned frame_count);
 
 // Media Controller ioctl tests
 int testMediaDeviceInfo(struct node *node);
 int testMediaTopology(struct node *node);
 int testMediaEnum(struct node *node);
 int testMediaSetupLink(struct node *node);
+void walkTopology(struct node &node, struct node &expbuf_node, unsigned 
frame_count);
 
 // Debug ioctl tests
 int testRegister(struct node *node);
diff --git a/utils/v4l2-compliance/v4l2-test-media.cpp 
b/utils/v4l2-compliance/v4l2-test-media.cpp
index 08b5e078060e..23e1ff04c4eb 100644
--- a/utils/v4l2-compliance/v4l2-test-media.cpp
+++ b/utils/v4l2-compliance/v4l2-test-media.cpp
@@ -32,6 +32,7 @@
 #include <sys/ioctl.h>
 #include <assert.h>
 #include <set>
+#include <fstream>
 
 #include "v4l2-compliance.h"
 
@@ -232,8 +233,9 @@ int testMediaEnum(struct node *node)
                if (!(ent.flags & MEDIA_ENT_FL_CONNECTOR)) {
                        fail_on_test(ent.dev.major == ~0U);
                        fail_on_test(ent.dev.minor == ~0U);
-                       fail_on_test(checkDevice(ent.dev.major, ent.dev.minor,
-                                                false, ent.id));
+                       if (ent.dev.major || ent.dev.minor)
+                               fail_on_test(checkDevice(ent.dev.major, 
ent.dev.minor,
+                                                        false, ent.id));
                }
                fail_on_test(doioctl(node, MEDIA_IOC_ENUM_ENTITIES, &ent));
                fail_on_test(entity_num_pads[ent.id] != ent.pads);
@@ -272,12 +274,11 @@ int testMediaEnum(struct node *node)
                        fail_on_test(links.pads[i].index != i);
                        fail_on_test(check_0(links.pads[i].reserved, 
sizeof(links.pads[i].reserved)));
                        __u32 fl = links.pads[i].flags;
-                       fail_on_test(!(fl & (MEDIA_PAD_FL_SINK | 
MEDIA_PAD_FL_SOURCE)));
                        fail_on_test((fl & (MEDIA_PAD_FL_SINK | 
MEDIA_PAD_FL_SOURCE)) ==
                                     (MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_SOURCE));
                        if (fl & MEDIA_PAD_FL_SOURCE)
                                found_source = true;
-                       else
+                       else if (fl & MEDIA_PAD_FL_SINK)
                                fail_on_test(found_source);
                }
                bool found_enabled = false;
@@ -369,3 +370,71 @@ int testMediaSetupLink(struct node *node)
        }
        return 0;
 }
+
+void walkTopology(struct node &node, struct node &expbuf_node, unsigned 
frame_count)
+{
+       if (!node.topology)
+               return;
+
+       for (unsigned i = 0; i < node.topology->num_interfaces; i++) {
+               media_v2_interface &iface = v2_ifaces[i];
+               std::string dev = media_get_device(iface.devnode.major,
+                                                  iface.devnode.minor);
+               if (dev.empty())
+                       continue;
+               media_type type = media_detect_type(dev.c_str());
+               if (type == MEDIA_TYPE_CANT_STAT) {
+                       fprintf(stderr, "Cannot open device %s, skipping.\n\n",
+                               dev.c_str());
+                       continue;
+               }
+
+               switch (type) {
+               // For now we can only handle V4L2 devices
+               case MEDIA_TYPE_VIDEO:
+               case MEDIA_TYPE_VBI:
+               case MEDIA_TYPE_RADIO:
+               case MEDIA_TYPE_SDR:
+               case MEDIA_TYPE_TOUCH:
+               case MEDIA_TYPE_SUBDEV:
+                       break;
+               default:
+                       type = MEDIA_TYPE_UNKNOWN;
+                       break;
+               }
+
+               if (type == MEDIA_TYPE_UNKNOWN) {
+                       fprintf(stderr, "Unable to detect what device %s is, 
skipping.\n\n",
+                               dev.c_str());
+                       continue;
+               }
+
+               struct node test_node;
+               int fd = -1;
+
+               test_node.device = dev.c_str();
+               test_node.s_trace(node.g_trace());
+               switch (type) {
+               case MEDIA_TYPE_MEDIA:
+                       test_node.s_direct(true);
+                       fd = test_node.media_open(dev.c_str(), false);
+                       break;
+               case MEDIA_TYPE_SUBDEV:
+                       test_node.s_direct(true);
+                       fd = test_node.subdev_open(dev.c_str(), false);
+                       break;
+               default:
+                       test_node.s_direct(node.g_direct());
+                       fd = test_node.open(dev.c_str(), false);
+                       break;
+               }
+               if (fd < 0) {
+                       fprintf(stderr, "Failed to open device %s, 
skipping\n\n",
+                               dev.c_str());
+                       continue;
+               }
+
+               testNode(test_node, expbuf_node, type, frame_count);
+               test_node.close();
+       }
+}
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index 78bf4fb7401e..ff5fee4469f2 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -976,18 +976,33 @@ int main(int argc, char **argv)
                return 1;
        }
 
-       v4l2_type type = v4l2_detect_type(device);
-       if (type == V4L2_TYPE_CANT_STAT) {
+       media_type type = media_detect_type(device);
+       if (type == MEDIA_TYPE_CANT_STAT) {
                fprintf(stderr, "Cannot open device %s, exiting.\n",
                        device);
                exit(1);
        }
-       if (type == V4L2_TYPE_UNKNOWN) {
+
+       switch (type) {
+               // For now we can only handle V4L2 devices
+       case MEDIA_TYPE_VIDEO:
+       case MEDIA_TYPE_VBI:
+       case MEDIA_TYPE_RADIO:
+       case MEDIA_TYPE_SDR:
+       case MEDIA_TYPE_TOUCH:
+       case MEDIA_TYPE_SUBDEV:
+               break;
+       default:
+               type = MEDIA_TYPE_UNKNOWN;
+               break;
+       }
+
+       if (type == MEDIA_TYPE_UNKNOWN) {
                fprintf(stderr, "Unable to detect what device %s is, 
exiting.\n",
                        device);
                exit(1);
        }
-       is_subdev = type == V4L2_TYPE_SUBDEV;
+       is_subdev = type == MEDIA_TYPE_SUBDEV;
 
        if ((fd = open(device, O_RDWR)) < 0) {
                fprintf(stderr, "Failed to open %s: %s\n", device,

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

Reply via email to