Check V4L2_CAP_VIDEO_CAPTURE when enumerating capture devices on Linux
The side effect of not filtering on V4L2_CAP_VIDEO_CAPTURE is that every device is enumerated twice. Because we look up devices by name, and the device that supports V4L2_CAP_VIDEO_CAPTURE seems to always appear first in /dev/video, this does not seem to end up with us ever choosing an inappropriate device. We might get away with just filtering device names from the list, but if the order of devices ever changed in /dev/video there could be problems. Bug: webrtc:11641 Change-Id: I16fee4edc873838ed4643ee16a8bbc699d6bbcf5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176460 Reviewed-by: Per Kjellander <perkj@webrtc.org> Commit-Queue: Dan Minor <dminor@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31508}
This commit is contained in:
parent
d592575698
commit
b64ecd9960
@ -47,11 +47,19 @@ uint32_t DeviceInfoLinux::NumberOfDevices() {
|
||||
uint32_t count = 0;
|
||||
char device[20];
|
||||
int fd = -1;
|
||||
struct v4l2_capability cap;
|
||||
|
||||
/* detect /dev/video [0-63]VideoCaptureModule entries */
|
||||
for (int n = 0; n < 64; n++) {
|
||||
sprintf(device, "/dev/video%d", n);
|
||||
if ((fd = open(device, O_RDONLY)) != -1) {
|
||||
// query device capabilities and make sure this is a video capture device
|
||||
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0 ||
|
||||
!(cap.device_caps & V4L2_CAP_VIDEO_CAPTURE)) {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
count++;
|
||||
}
|
||||
@ -74,9 +82,16 @@ int32_t DeviceInfoLinux::GetDeviceName(uint32_t deviceNumber,
|
||||
char device[20];
|
||||
int fd = -1;
|
||||
bool found = false;
|
||||
struct v4l2_capability cap;
|
||||
for (int n = 0; n < 64; n++) {
|
||||
sprintf(device, "/dev/video%d", n);
|
||||
if ((fd = open(device, O_RDONLY)) != -1) {
|
||||
// query device capabilities and make sure this is a video capture device
|
||||
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0 ||
|
||||
!(cap.device_caps & V4L2_CAP_VIDEO_CAPTURE)) {
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
if (count == deviceNumber) {
|
||||
// Found the device
|
||||
found = true;
|
||||
@ -92,7 +107,6 @@ int32_t DeviceInfoLinux::GetDeviceName(uint32_t deviceNumber,
|
||||
return -1;
|
||||
|
||||
// query device capabilities
|
||||
struct v4l2_capability cap;
|
||||
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
|
||||
RTC_LOG(LS_INFO) << "error in querying the device capability for device "
|
||||
<< device << ". errno = " << errno;
|
||||
@ -153,6 +167,11 @@ int32_t DeviceInfoLinux::CreateCapabilityMap(const char* deviceUniqueIdUTF8) {
|
||||
// query device capabilities
|
||||
struct v4l2_capability cap;
|
||||
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == 0) {
|
||||
// skip devices without video capture capability
|
||||
if (!(cap.device_caps & V4L2_CAP_VIDEO_CAPTURE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cap.bus_info[0] != 0) {
|
||||
if (strncmp((const char*)cap.bus_info, (const char*)deviceUniqueIdUTF8,
|
||||
strlen((const char*)deviceUniqueIdUTF8)) ==
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user