From 1796f8bf24d05544d59ced01c96ae00da13afd7f Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Wed, 1 May 2019 16:37:18 -0400 Subject: configfs: parse mjpeg streaming format The MJPEG descriptor does not have a guidFormat, and so configfs doesn't have it either, but we currently error out if there is no guidFormat. To fix this, extract the stream type part of the real path, and if it is MJPEG then hardcode it, otherwise read the guid if it is uncompressed. This does mean that in configfs the MJPEG format descriptor path must be "mjpeg" for this to work, though this is already guranteed by configfs. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- lib/configfs.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/configfs.c b/lib/configfs.c index 56bff01..26a07bb 100644 --- a/lib/configfs.c +++ b/lib/configfs.c @@ -626,6 +626,8 @@ static int configfs_parse_streaming_format(const char *path, struct uvc_function_config_format *format) { struct dirent **entries; + char link_target[1024]; + char *segment; unsigned int i; int n_entries; int ret; @@ -634,12 +636,37 @@ static int configfs_parse_streaming_format(const char *path, if (ret < 0) return ret; - ret = attribute_read(path, "guidFormat", format->guid, - sizeof(format->guid)); + ret = readlink(path, link_target, sizeof(link_target) - 1); if (ret < 0) return ret; - if (ret != 16) + + link_target[ret] = '\0'; + + /* + * Extract the second-to-last path component of the link target, + * which contains the format descriptor type name as exposed by + * the UVC function driver. + */ + segment = strrchr(link_target, '/'); + if (!segment) return -EINVAL; + *segment = '\0'; + segment = strrchr(link_target, '/'); + if (!segment) + return -EINVAL; + segment++; + + if (!strcmp(segment, "mjpeg")) { + static const uint8_t guid[16] = UVC_GUID_FORMAT_MJPEG; + memcpy(format->guid, guid, 16); + } else if (!strcmp(segment, "uncompressed")) { + ret = attribute_read(path, "guidFormat", format->guid, + sizeof(format->guid)); + if (ret < 0) + return ret; + } else { + return -EINVAL; + } for (i = 0; i < ARRAY_SIZE(uvc_formats); ++i) { if (!memcmp(uvc_formats[i].guid, format->guid, 16)) { -- cgit v1.2.3