diff options
author | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2018-12-13 14:34:27 +0100 |
---|---|---|
committer | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2018-12-13 14:34:27 +0100 |
commit | 0d4d3f598d4a1f81ca3d56c033c6ae9ec864dbef (patch) | |
tree | 55b543d38056040a05cb4189bc9a8b9105c027fa | |
parent | 4662614de0872a620c2ec7c6daf956e45300f49b (diff) |
Add property compliance supportprops2
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r-- | utils/common/media-info.cpp | 76 | ||||
-rw-r--r-- | utils/v4l2-compliance/v4l2-compliance.cpp | 5 | ||||
-rw-r--r-- | utils/v4l2-compliance/v4l2-test-media.cpp | 100 |
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] = ∝ + } + for (unsigned i = 0; i < topology.num_entities; i++) { media_v2_entity &ent = v2_ents[i]; |