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
This commit is contained in:
wu@webrtc.org 2011-09-21 16:57:15 +00:00
parent c389aa2615
commit 221b522118

View File

@ -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)