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

Reply via email to