From 221b5221185b1ef57ae94c70627a9475e239f77b Mon Sep 17 00:00:00 2001 From: "wu@webrtc.org" Date: Wed, 21 Sep 2011 16:57:15 +0000 Subject: [PATCH] Return the number of /dev/video* without trying to open it. Consider the case when there're /dev/video0 and /dev/video1. But for somereason the video0 is not in a correct state and can't be open. As a result, current NumberOfDevices will return 1, which is fine. However, we will then never be able to get the device we really want - /dev/video1. Consider the code below, the GetCaptureDevice will fail because it calls into DeviceInfoLinux::GetDeviceName(0, ...) which will again try to open the /dev/video0. So the root cause is the mismatching of the NumberOfDevices and GetDeviceName. Since we will open the device in DeviceInfoLinux::GetDeviceName anyway, I think we should return the number of /dev/video* in DeviceInfoLinux::NumberOfDevices without trying to open it. Otherwise the DeviceInfoLinux::NumberOfDevices should return more information like which /dev/video* is valid which is not. bool found = false; for (int i = 0; i < vie_capture->NumberOfCaptureDevices(); ++i) { if (vie_capture->GetCaptureDevice(i, ...) == 0) { found = true; break; } } Review URL: http://webrtc-codereview.appspot.com/148004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@635 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../main/source/Linux/device_info_linux.cc | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/modules/video_capture/main/source/Linux/device_info_linux.cc b/src/modules/video_capture/main/source/Linux/device_info_linux.cc index dbdd582617..013b8f9058 100644 --- a/src/modules/video_capture/main/source/Linux/device_info_linux.cc +++ b/src/modules/video_capture/main/source/Linux/device_info_linux.cc @@ -80,7 +80,7 @@ WebRtc_UWord32 DeviceInfoLinux::NumberOfDevices() sprintf(device, "/dev/video%d", n); if (stat(device, &s) == 0) //check validity of path { - if ((fd = open(device, O_RDONLY)) > 0 || errno == EBUSY) + if ((fd = open(device, O_RDONLY)) != -1) { close(fd); count++; @@ -102,22 +102,34 @@ WebRtc_Word32 DeviceInfoLinux::GetDeviceName( { WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideoCapture, _id, "%s", __FUNCTION__); + // Travel through /dev/video [0-63] + WebRtc_UWord32 count = 0; char device[20]; - sprintf(device, "/dev/video%d", (int) deviceNumber); int fd = -1; - - // open video device in RDONLY mode - struct stat s; - if (stat(device, &s) == 0) + bool found = false; + for (int n = 0; n < 64; n++) { - if ((fd = open(device, O_RDONLY)) < 0) + struct stat s; + sprintf(device, "/dev/video%d", n); + if (stat(device, &s) == 0) // Check validity of path { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, - "error in opening video device. errno = %d", errno); - return -1; + if ((fd = open(device, O_RDONLY)) != -1) + { + if (count == deviceNumber) { + // Found the device + found = true; + break; + } else { + close(fd); + count++; + } + } } } + if (!found) + return -1; + // query device capabilities struct v4l2_capability cap; if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0)