From 841f02be87dc1c6a150b1e2f562b28e2b0927555 Mon Sep 17 00:00:00 2001 From: fryshorts <leonhard@in-verted.de> Date: Mon, 15 Sep 2014 20:35:07 +0200 Subject: [PATCH] Fix device capability checking in v4l2 input. The capabilities flags that were used previously describe all capabilities the physical device offers. This would cause devices that are accessible through multiple device nodes to show up with all device nodes while only one of the nodes might actually offer the needed video capture capability. If the device has more nodes the CAP_DEVICES_CAP flag might be set in which case the device_caps field is filled with the capabilities that only apply to that specific node that is opened. --- plugins/linux-v4l2/v4l2-input.c | 40 +++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c index 09f157d1f..493b361e6 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c @@ -233,8 +233,6 @@ static void v4l2_device_list(obs_property_t prop, obs_data_t settings) { DIR *dirp; struct dirent *dp; - int fd; - struct v4l2_capability video_cap; struct dstr device; bool first = true; @@ -247,6 +245,10 @@ static void v4l2_device_list(obs_property_t prop, obs_data_t settings) dstr_init_copy(&device, "/dev/"); while ((dp = readdir(dirp)) != NULL) { + int fd; + uint32_t caps; + struct v4l2_capability video_cap; + if (dp->d_type == DT_DIR) continue; @@ -261,23 +263,33 @@ static void v4l2_device_list(obs_property_t prop, obs_data_t settings) if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1) { blog(LOG_INFO, "Failed to query capabilities for %s", device.array); - } else if (video_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { - obs_property_list_add_string(prop, - (char *) video_cap.card, - device.array); - if (first) { - obs_data_set_string(settings, - "device_id", device.array); - first = false; - } - blog(LOG_INFO, "Found device '%s' at %s", - video_cap.card, device.array); + close(fd); + continue; } - else { + + caps = (video_cap.capabilities & V4L2_CAP_DEVICE_CAPS) + ? video_cap.device_caps + : video_cap.capabilities; + + if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { blog(LOG_INFO, "%s seems to not support video capture", device.array); + close(fd); + continue; } + obs_property_list_add_string(prop, (char *) video_cap.card, + device.array); + + if (first) { + obs_data_set_string(settings, "device_id", + device.array); + first = false; + } + + blog(LOG_INFO, "Found device '%s' at %s", video_cap.card, + device.array); + close(fd); } -- GitLab