aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2018-12-13 14:34:27 +0100
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2018-12-13 14:34:27 +0100
commit0d4d3f598d4a1f81ca3d56c033c6ae9ec864dbef (patch)
tree55b543d38056040a05cb4189bc9a8b9105c027fa /utils
parent4662614de0872a620c2ec7c6daf956e45300f49b (diff)
Add property compliance supportprops2
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Diffstat (limited to 'utils')
-rw-r--r--utils/common/media-info.cpp76
-rw-r--r--utils/v4l2-compliance/v4l2-compliance.cpp5
-rw-r--r--utils/v4l2-compliance/v4l2-test-media.cpp100
3 files changed, 178 insertions, 3 deletions
diff --git a/utils/common/media-info.cpp b/utils/common/media-info.cpp
index 033821ed..a3e6c873 100644
--- a/utils/common/media-info.cpp
+++ b/utils/common/media-info.cpp
@@ -412,6 +412,35 @@ std::string mi_linkflags2s(__u32 flags)
}
}
+static void show_props(const media_v2_prop *props, unsigned num_props,
+ const media_v2_prop &prop, std::string prefix)
+{
+ for (unsigned i = 0; i < num_props; i++) {
+ if (props[i].owner_id != prop.id)
+ continue;
+
+ printf("%sProperty 0x%08x '%s'", prefix.c_str(), props[i].id, props[i].name);
+ switch (props[i].type) {
+ case MEDIA_PROP_TYPE_U64:
+ printf(": 0x%016llx %llu\n", media_prop2u64(props + i),
+ media_prop2u64(props + i));
+ break;
+ case MEDIA_PROP_TYPE_S64:
+ printf(": 0x%016llx %lld\n", media_prop2s64(props + i),
+ media_prop2s64(props + i));
+ break;
+ case MEDIA_PROP_TYPE_STRING:
+ printf(": '%s'\n", media_prop2string(props + i));
+ break;
+ case MEDIA_PROP_TYPE_GROUP:
+ printf(" {\n");
+ show_props(props, num_props, props[i], prefix + "\t");
+ printf("%s}\n", prefix.c_str());
+ break;
+ }
+ }
+}
+
static __u32 read_topology(int media_fd, __u32 major, __u32 minor,
__u32 media_version, bool *is_invalid)
{
@@ -426,11 +455,15 @@ static __u32 read_topology(int media_fd, __u32 major, __u32 minor,
media_v2_interface v2_ifaces[topology.num_interfaces];
media_v2_pad v2_pads[topology.num_pads];
media_v2_link v2_links[topology.num_links];
+ __u8 props[topology.num_props * sizeof(media_v2_prop) +
+ topology.props_payload_size];
+ media_v2_prop *v2_props = (media_v2_prop *)props;
topology.ptr_entities = (__u64)v2_ents;
topology.ptr_interfaces = (__u64)v2_ifaces;
topology.ptr_pads = (__u64)v2_pads;
topology.ptr_links = (__u64)v2_links;
+ topology.ptr_props = (__u64)v2_props;
if (ioctl(media_fd, MEDIA_IOC_G_TOPOLOGY, &topology))
return 0;
for (i = 0; i < topology.num_interfaces; i++)
@@ -553,6 +586,49 @@ static __u32 read_topology(int media_fd, __u32 major, __u32 minor,
remote_ent->name, mi_linkflags2s(link.flags).c_str());
}
}
+
+ for (i = 0; i < topology.num_props; i++) {
+ media_v2_prop &prop = v2_props[i];
+ media_v2_entity *ent_ptr = NULL;
+ media_v2_pad *pad_ptr = NULL;
+
+ if (prop.owner_id == ent.id) {
+ ent_ptr = &ent;
+ } else {
+ for (unsigned j = 0; j < topology.num_pads; j++) {
+ if (prop.owner_id == v2_pads[j].id) {
+ pad_ptr = &v2_pads[j];
+ break;
+ }
+ }
+ if (pad_ptr && pad_ptr->entity_id != ent.id)
+ pad_ptr = NULL;
+ }
+ if (!ent_ptr && !pad_ptr)
+ continue;
+
+ printf("\tProperty 0x%08x '%s'", prop.id, prop.name);
+ if (pad_ptr)
+ printf(" (pad 0x%08x)", prop.owner_id);
+ switch (prop.type) {
+ case MEDIA_PROP_TYPE_U64:
+ printf(": 0x%016llx %llu\n", media_prop2u64(&prop),
+ media_prop2u64(&prop));
+ break;
+ case MEDIA_PROP_TYPE_S64:
+ printf(": 0x%016llx %lld\n", media_prop2s64(&prop),
+ media_prop2s64(&prop));
+ break;
+ case MEDIA_PROP_TYPE_STRING:
+ printf(": '%s'\n", media_prop2string(&prop));
+ break;
+ case MEDIA_PROP_TYPE_GROUP:
+ printf(" {\n");
+ show_props(v2_props, topology.num_props, prop, "\t\t");
+ printf("\t}\n");
+ break;
+ }
+ }
return ent.id;
}
diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp
index a53fcc50..5e68defb 100644
--- a/utils/v4l2-compliance/v4l2-compliance.cpp
+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
@@ -816,11 +816,12 @@ void testNode(struct node &node, struct node &expbuf_node, media_type type,
printf("Media Controller ioctls:\n");
printf("\ttest MEDIA_IOC_G_TOPOLOGY: %s\n", ok(testMediaTopology(&node)));
if (node.topology)
- printf("\tEntities: %u Interfaces: %u Pads: %u Links: %u\n",
+ printf("\tEntities: %u Interfaces: %u Pads: %u Links: %u Properties: %u\n",
node.topology->num_entities,
node.topology->num_interfaces,
node.topology->num_pads,
- node.topology->num_links);
+ node.topology->num_links,
+ node.topology->num_props);
printf("\ttest MEDIA_IOC_ENUM_ENTITIES/LINKS: %s\n", ok(testMediaEnum(&node)));
printf("\ttest MEDIA_IOC_SETUP_LINK: %s\n", ok(testMediaSetupLink(&node)));
printf("\n");
diff --git a/utils/v4l2-compliance/v4l2-test-media.cpp b/utils/v4l2-compliance/v4l2-test-media.cpp
index ae5f0c8b..36fdb00c 100644
--- a/utils/v4l2-compliance/v4l2-test-media.cpp
+++ b/utils/v4l2-compliance/v4l2-test-media.cpp
@@ -79,12 +79,15 @@ static media_v2_pad *v2_pads;
static id_set v2_pads_set;
static media_v2_link *v2_links;
static id_set v2_links_set;
+static media_v2_prop *v2_props;
+static id_set v2_props_set;
static std::map<__u32, __u32> entity_num_pads;
static std::map<__u32, media_v2_entity *> v2_entity_map;
static std::set<std::string> v2_entity_names_set;
static std::map<__u32, media_v2_interface *> v2_iface_map;
static std::map<__u32, media_v2_pad *> v2_pad_map;
static std::set<__u64> v2_entity_pad_idx_set;
+static std::map<__u32, media_v2_prop *> v2_prop_map;
static unsigned num_data_links;
static int checkFunction(__u32 function, bool v2_api)
@@ -111,13 +114,25 @@ int testMediaTopology(struct node *node)
topology.ptr_interfaces = 0;
topology.ptr_pads = 0;
topology.ptr_links = 0;
+ //fail_on_test(doioctl(node, MEDIA_IOC_G_TOPOLOGY_OLD, &topology));
+ //fail_on_test(topology.ptr_props != ~0ULL);
+
+ memset(&topology, 0xff, sizeof(topology));
+ topology.ptr_entities = 0;
+ topology.ptr_interfaces = 0;
+ topology.ptr_pads = 0;
+ topology.ptr_links = 0;
+ topology.ptr_props = 0;
fail_on_test(doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology));
+
fail_on_test(!topology.num_entities);
fail_on_test(topology.topology_version == ~0ULL);
fail_on_test(topology.num_entities == ~0U);
fail_on_test(topology.num_interfaces == ~0U);
fail_on_test(topology.num_pads == ~0U);
fail_on_test(topology.num_links == ~0U);
+ fail_on_test(topology.num_props == ~0U);
+ fail_on_test(topology.props_payload_size == ~0U);
fail_on_test(topology.reserved1);
fail_on_test(topology.reserved2);
fail_on_test(topology.reserved3);
@@ -137,6 +152,10 @@ int testMediaTopology(struct node *node)
fail_on_test(topology.num_links &&
doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
topology.ptr_links = 0;
+ topology.ptr_props = 4;
+ fail_on_test(topology.num_props &&
+ doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
+ topology.ptr_props = 0;
v2_ents = new media_v2_entity[topology.num_entities];
memset(v2_ents, 0xff, topology.num_entities * sizeof(*v2_ents));
topology.ptr_entities = (__u64)v2_ents;
@@ -149,11 +168,18 @@ int testMediaTopology(struct node *node)
v2_links = new media_v2_link[topology.num_links];
memset(v2_links, 0xff, topology.num_links * sizeof(*v2_links));
topology.ptr_links = (__u64)v2_links;
+ __u8 *props = new __u8[topology.num_props * sizeof(media_v2_prop) +
+ topology.props_payload_size];
+ memset(props, 0xff, topology.num_props * sizeof(media_v2_prop) +
+ topology.props_payload_size);
+ v2_props = (media_v2_prop *)props;
+ topology.ptr_props = (__u64)v2_props;
fail_on_test(doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology));
fail_on_test(v2_ents != (media_v2_entity *)topology.ptr_entities);
fail_on_test(v2_ifaces != (media_v2_interface *)topology.ptr_interfaces);
fail_on_test(v2_pads != (media_v2_pad *)topology.ptr_pads);
fail_on_test(v2_links != (media_v2_link *)topology.ptr_links);
+ fail_on_test(v2_props != (media_v2_prop *)topology.ptr_props);
for (unsigned i = 0; i < topology.num_entities; i++) {
media_v2_entity &ent = v2_ents[i];
@@ -194,7 +220,6 @@ int testMediaTopology(struct node *node)
fail_on_test(!iface.intf_type);
fail_on_test(iface.intf_type < MEDIA_INTF_T_DVB_BASE);
fail_on_test(iface.intf_type > MEDIA_INTF_T_V4L_BASE + 0xff);
- fail_on_test(iface.flags);
fail_on_test(v2_interfaces_set.find(iface.id) != v2_interfaces_set.end());
v2_interfaces_set.insert(iface.id);
v2_iface_map[iface.id] = &iface;
@@ -270,6 +295,79 @@ int testMediaTopology(struct node *node)
}
}
+ for (unsigned i = 0; i < topology.num_props; i++) {
+ media_v2_prop &prop = v2_props[i];
+
+ if (show_info) {
+ printf("\t\tProperty: 0x%08x '%s' (Owner: 0x%08x): ",
+ prop.id, prop.name, prop.owner_id);
+ switch (prop.type) {
+ case MEDIA_PROP_TYPE_GROUP:
+ printf("group\n");
+ break;
+ case MEDIA_PROP_TYPE_U64:
+ printf("0x%016llx %llu\n", media_prop2u64(&prop),
+ media_prop2u64(&prop));
+ break;
+ case MEDIA_PROP_TYPE_S64:
+ printf("0x%016llx %lld\n", media_prop2s64(&prop),
+ media_prop2s64(&prop));
+ break;
+ case MEDIA_PROP_TYPE_STRING:
+ printf("'%s'\n", media_prop2string(&prop));
+ break;
+ }
+ }
+ fail_on_test(check_0(prop.reserved, sizeof(prop.reserved)));
+ fail_on_test(!prop.id);
+ fail_on_test(!prop.owner_id);
+ fail_on_test(v2_entities_set.find(prop.owner_id) == v2_entities_set.end() &&
+ v2_pads_set.find(prop.owner_id) == v2_pads_set.end() &&
+ v2_props_set.find(prop.owner_id) == v2_props_set.end());
+ if (prop.payload_size)
+ fail_on_test(!prop.payload_offset);
+ else
+ fail_on_test(prop.payload_offset);
+
+ switch (prop.owner_type) {
+ case MEDIA_OWNER_TYPE_ENTITY:
+ fail_on_test(v2_entities_set.find(prop.owner_id) == v2_entities_set.end());
+ break;
+ case MEDIA_OWNER_TYPE_PAD:
+ fail_on_test(v2_pads_set.find(prop.owner_id) == v2_pads_set.end());
+ break;
+ case MEDIA_OWNER_TYPE_LINK:
+ fail_on_test(v2_links_set.find(prop.owner_id) == v2_links_set.end());
+ break;
+ case MEDIA_OWNER_TYPE_INTF:
+ fail_on_test(v2_interfaces_set.find(prop.owner_id) == v2_interfaces_set.end());
+ break;
+ case MEDIA_OWNER_TYPE_PROP:
+ fail_on_test(v2_props_set.find(prop.owner_id) == v2_props_set.end());
+ break;
+ default:
+ return fail("unknown property owner");
+ }
+
+ switch (prop.type) {
+ case MEDIA_PROP_TYPE_GROUP:
+ fail_on_test(prop.payload_size);
+ break;
+ case MEDIA_PROP_TYPE_U64:
+ case MEDIA_PROP_TYPE_S64:
+ fail_on_test(prop.payload_size != 8);
+ break;
+ case MEDIA_PROP_TYPE_STRING:
+ fail_on_test(!prop.payload_size);
+ break;
+ default:
+ return fail("unknown property type\n");
+ }
+ fail_on_test(v2_props_set.find(prop.id) != v2_props_set.end());
+ v2_props_set.insert(prop.id);
+ v2_prop_map[prop.id] = &prop;
+ }
+
for (unsigned i = 0; i < topology.num_entities; i++) {
media_v2_entity &ent = v2_ents[i];

Privacy Policy