aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2018-11-29 16:18:30 +0100
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2018-11-29 16:18:30 +0100
commit767eb8be92cd04917885ddf82235ea539a6c0644 (patch)
tree11db5a6fb70cda648a6fafa43c4147ee2268169f
parent6b861cec32436495418eeaaa6bf384c60dcd3a31 (diff)
v4l2-compliance: fix multiple issues when testing vivid
'v4l2-compliance -m0' for the vivid driver resulted in several failures that are now fixed: 1) The bus_info argument to mi_get_media_fd() wasn't used for every call, causing problems for multiple vivid instances. 2) Various capability values (e.g. valid_buftypes) that differ for different inputs were not reset to 0 when testing a new input. 3) Store the buffer capabilities in the node for easy access. 4) Fix an issue with the EXPBUF test which isn't available in some circumstances (streaming from a VBI device when the input isn't SDTV). 5) Add tests for V4L2_BUF_CAP_SUPPORTS_REQUESTS 6) Fix an issue with selecting the right VBI format (raw vs sliced) 7) Fix an issue with swradio that needs min_bufs buffers before it can start streaming. It was luck that it worked for other devices since they all needed a minimum of 2 buffers, whereas swradio needed 8. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r--utils/v4l2-compliance/v4l2-compliance.cpp8
-rw-r--r--utils/v4l2-compliance/v4l2-compliance.h2
-rw-r--r--utils/v4l2-compliance/v4l2-test-buffers.cpp65
3 files changed, 48 insertions, 27 deletions
diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp
index 4d6a6412..4f09f3a5 100644
--- a/utils/v4l2-compliance/v4l2-compliance.cpp
+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
@@ -719,11 +719,12 @@ void testNode(struct node &node, struct node &expbuf_node, media_type type,
v4l2_info_capability(vcap);
is_vivid = !strcmp((const char *)vcap.driver, "vivid");
+ if (is_vivid)
+ node.bus_info = (const char *)vcap.bus_info;
}
if (!node.is_media())
- media_fd = mi_get_media_fd(node.g_fd(),
- is_vivid ? (const char *)vcap.bus_info : NULL);
+ media_fd = mi_get_media_fd(node.g_fd(), node.bus_info);
__u32 ent_id = 0;
bool is_invalid = false;
@@ -936,6 +937,9 @@ void testNode(struct node &node, struct node &expbuf_node, media_type type,
node.frmsizes.clear();
node.frmsizes_count.clear();
node.has_frmintervals = false;
+ node.valid_buftypes = 0;
+ node.valid_memorytype = 0;
+ node.buf_caps = 0;
for (unsigned idx = 0; idx < V4L2_BUF_TYPE_LAST + 1; idx++)
node.buftype_pixfmts[idx].clear();
diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h
index bb5508f3..b6d3e72c 100644
--- a/utils/v4l2-compliance/v4l2-compliance.h
+++ b/utils/v4l2-compliance/v4l2-compliance.h
@@ -113,6 +113,8 @@ struct base_node {
int frame_interval_pad;
int enum_frame_interval_pad;
__u32 fbuf_caps;
+ __u32 buf_caps;
+ const char *bus_info;
pixfmt_map buftype_pixfmts[V4L2_BUF_TYPE_LAST + 1];
frmsizes_set frmsizes;
frmsizes_count_map frmsizes_count;
diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp
index 592aae4a..39dbee23 100644
--- a/utils/v4l2-compliance/v4l2-test-buffers.cpp
+++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp
@@ -561,7 +561,7 @@ int testReqBufs(struct node *node)
fail_on_test(ret && ret != EINVAL);
mmap_valid = !ret;
if (mmap_valid)
- caps = q.g_capabilities();
+ node->buf_caps = caps = q.g_capabilities();
if (caps)
fail_on_test(mmap_valid ^ !!(caps & V4L2_BUF_CAP_SUPPORTS_MMAP));
@@ -711,17 +711,6 @@ int testExpBuf(struct node *node)
bool have_expbuf = false;
int type;
- if (!(node->valid_memorytype & (1 << V4L2_MEMORY_MMAP))) {
- cv4l_queue q;
-
- if (q.has_expbuf(node)) {
- if (node->valid_buftypes)
- fail("VIDIOC_EXPBUF is supported, but the V4L2_MEMORY_MMAP support is missing or malfunctioning.\n");
- fail("VIDIOC_EXPBUF is supported, but the V4L2_MEMORY_MMAP support is missing, probably due to earlier failing format tests.\n");
- }
- return ENOTTY;
- }
-
for (type = 0; type <= V4L2_BUF_TYPE_LAST; type++) {
if (!(node->valid_buftypes & (1 << type)))
continue;
@@ -733,6 +722,15 @@ int testExpBuf(struct node *node)
cv4l_queue q(type, V4L2_MEMORY_MMAP);
+ if (!(node->valid_memorytype & (1 << V4L2_MEMORY_MMAP))) {
+ if (q.has_expbuf(node)) {
+ if (node->valid_buftypes)
+ fail("VIDIOC_EXPBUF is supported, but the V4L2_MEMORY_MMAP support is missing or malfunctioning.\n");
+ fail("VIDIOC_EXPBUF is supported, but the V4L2_MEMORY_MMAP support is missing, probably due to earlier failing format tests.\n");
+ }
+ return ENOTTY;
+ }
+
fail_on_test(q.reqbufs(node, 2));
if (q.has_expbuf(node)) {
fail_on_test(q.export_bufs(node, q.g_type()));
@@ -1446,7 +1444,7 @@ int testDmaBuf(struct node *expbuf_node, struct node *node, unsigned frame_count
int testRequests(struct node *node, bool test_streaming)
{
- int media_fd = mi_get_media_fd(node->g_fd());
+ int media_fd = mi_get_media_fd(node->g_fd(), node->bus_info);
int req_fd;
qctrl_map::iterator iter;
struct test_query_ext_ctrl valid_qctrl;
@@ -1455,6 +1453,9 @@ int testRequests(struct node *node, bool test_streaming)
bool have_controls;
int ret;
+ if (node->buf_caps & V4L2_BUF_CAP_SUPPORTS_REQUESTS)
+ fail_on_test(media_fd < 0);
+
memset(&valid_qctrl, 0, sizeof(valid_qctrl));
memset(&ctrls, 0, sizeof(ctrls));
memset(&ctrl, 0, sizeof(ctrl));
@@ -1475,7 +1476,8 @@ int testRequests(struct node *node, bool test_streaming)
if (ctrl.id == 0) {
info("could not test the Request API, no suitable control found\n");
- return 0;
+ return (node->buf_caps & V4L2_BUF_CAP_SUPPORTS_REQUESTS) ?
+ 0 : ENOTTY;
}
ctrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
@@ -1483,8 +1485,10 @@ int testRequests(struct node *node, bool test_streaming)
fail_on_test(ret != EINVAL && ret != EACCES && ret != ENOTTY);
have_controls = ret != ENOTTY;
- if (media_fd < 0 || ret == EACCES)
+ if (media_fd < 0 || ret == EACCES) {
+ fail_on_test(node->buf_caps & V4L2_BUF_CAP_SUPPORTS_REQUESTS);
return ENOTTY;
+ }
if (have_controls) {
ctrls.request_fd = 10;
fail_on_test(doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls) != EINVAL);
@@ -1506,7 +1510,7 @@ int testRequests(struct node *node, bool test_streaming)
fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_QUEUE, 0) != EBADF);
fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_REINIT, 0) != EBADF);
- media_fd = mi_get_media_fd(node->g_fd());
+ media_fd = mi_get_media_fd(node->g_fd(), node->bus_info);
fail_on_test(doioctl_fd(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd));
ctrls.count = 1;
ctrls.controls = &ctrl;
@@ -1535,13 +1539,22 @@ int testRequests(struct node *node, bool test_streaming)
close(media_fd);
node->reopen();
- int type = node->is_planar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
- V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (node->can_output)
+ int type = node->g_type();
+ if (node->is_m2m)
type = v4l_type_invert(type);
+ if (v4l_type_is_vbi(type)) {
+ cv4l_fmt fmt;
+
+ node->g_fmt(fmt, type);
+ node->s_fmt(fmt, type);
+ }
- if (!(node->valid_buftypes & (1 << type)))
+ if (!(node->valid_buftypes & (1 << type))) {
+ fail_on_test(node->buf_caps & V4L2_BUF_CAP_SUPPORTS_REQUESTS);
return ENOTTY;
+ }
+
+ fail_on_test(!(node->buf_caps & V4L2_BUF_CAP_SUPPORTS_REQUESTS));
buffer_info.clear();
@@ -1550,12 +1563,14 @@ int testRequests(struct node *node, bool test_streaming)
q.init(type, V4L2_MEMORY_MMAP);
fail_on_test(q.reqbufs(node, 2));
- fail_on_test(q.reqbufs(node, q.g_buffers() + 2));
+
+ unsigned min_bufs = q.g_buffers();
+ fail_on_test(q.reqbufs(node, min_bufs + 4));
unsigned num_bufs = q.g_buffers();
unsigned num_requests = 2 * num_bufs;
last_seq.init();
- media_fd = mi_get_media_fd(node->g_fd());
+ media_fd = mi_get_media_fd(node->g_fd(), node->bus_info);
for (unsigned i = 0; i < num_requests; i++) {
fail_on_test(doioctl_fd(media_fd, MEDIA_IOC_REQUEST_ALLOC, &buf_req_fds[i]));
@@ -1667,11 +1682,11 @@ int testRequests(struct node *node, bool test_streaming)
fail_on_test(!(buf.g_flags() & V4L2_BUF_FLAG_QUEUED));
fail_on_test(doioctl_fd(buf_req_fds[i], MEDIA_REQUEST_IOC_REINIT, 0) != EBUSY);
fail_on_test(doioctl_fd(buf_req_fds[i], MEDIA_REQUEST_IOC_QUEUE, 0) != EBUSY);
- if (i >= num_bufs - 2) {
+ if (i >= min_bufs) {
close(buf_req_fds[i]);
buf_req_fds[i] = -1;
}
- if (i == num_bufs / 2) {
+ if (i == min_bufs - 1) {
if (node->inject_error(VIVID_CID_START_STR_ERROR))
fail_on_test(!node->streamon(q.g_type()));
fail_on_test(node->streamon(q.g_type()));
@@ -1687,7 +1702,7 @@ int testRequests(struct node *node, bool test_streaming)
}
fail_on_test(node->streamoff(q.g_type()));
- for (unsigned i = 0; test_streaming && i < num_bufs - 2; i++) {
+ for (unsigned i = 0; test_streaming && i < min_bufs; i++) {
buffer buf(q);
ctrls.request_fd = buf_req_fds[i];

Privacy Policy