Index: media/video/capture/linux/video_capture_device_linux.cc |
diff --git a/media/video/capture/linux/video_capture_device_linux.cc b/media/video/capture/linux/video_capture_device_linux.cc |
index 7a9ed69f759f4470119c3916fdab34ea48a9081e..fa3f83b3d00fab1499306d991ef48870dddb6bc7 100644 |
--- a/media/video/capture/linux/video_capture_device_linux.cc |
+++ b/media/video/capture/linux/video_capture_device_linux.cc |
@@ -19,7 +19,6 @@ |
#include "base/bind.h" |
#include "base/files/file_enumerator.h" |
-#include "base/files/scoped_file.h" |
#include "base/posix/eintr_wrapper.h" |
#include "base/strings/stringprintf.h" |
@@ -120,18 +119,19 @@ |
base::FileEnumerator::FileInfo info = enumerator.GetInfo(); |
std::string unique_id = path.value() + info.GetName().value(); |
- base::ScopedFD fd(HANDLE_EINTR(open(unique_id.c_str(), O_RDONLY))); |
- if (!fd.is_valid()) { |
+ int fd; |
+ if ((fd = HANDLE_EINTR(open(unique_id.c_str() , O_RDONLY))) < 0) { |
// Failed to open this device. |
continue; |
} |
+ file_util::ScopedFD fd_closer(&fd); |
// Test if this is a V4L2 capture device. |
v4l2_capability cap; |
- if ((HANDLE_EINTR(ioctl(fd.get(), VIDIOC_QUERYCAP, &cap)) == 0) && |
+ if ((HANDLE_EINTR(ioctl(fd, VIDIOC_QUERYCAP, &cap)) == 0) && |
(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) && |
!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { |
// This is a V4L2 video capture device |
- if (HasUsableFormats(fd.get())) { |
+ if (HasUsableFormats(fd)) { |
Name device_name(base::StringPrintf("%s", cap.card), unique_id); |
device_names->push_back(device_name); |
} else { |
@@ -146,18 +146,19 @@ |
VideoCaptureFormats* supported_formats) { |
if (device.id().empty()) |
return; |
- base::ScopedFD fd(HANDLE_EINTR(open(device.id().c_str(), O_RDONLY))); |
- if (!fd.is_valid()) { |
+ int fd; |
+ if ((fd = HANDLE_EINTR(open(device.id().c_str(), O_RDONLY))) < 0) { |
// Failed to open this device. |
return; |
} |
+ file_util::ScopedFD fd_closer(&fd); |
supported_formats->clear(); |
// Retrieve the caps one by one, first get pixel format, then sizes, then |
// frame rates. See http://linuxtv.org/downloads/v4l-dvb-apis for reference. |
v4l2_fmtdesc pixel_format = {}; |
pixel_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
- while (HANDLE_EINTR(ioctl(fd.get(), VIDIOC_ENUM_FMT, &pixel_format)) == 0) { |
+ while (HANDLE_EINTR(ioctl(fd, VIDIOC_ENUM_FMT, &pixel_format)) == 0) { |
VideoCaptureFormat supported_format; |
supported_format.pixel_format = |
V4l2ColorToVideoCaptureColorFormat((int32)pixel_format.pixelformat); |
@@ -168,8 +169,7 @@ |
v4l2_frmsizeenum frame_size = {}; |
frame_size.pixel_format = pixel_format.pixelformat; |
- while (HANDLE_EINTR(ioctl(fd.get(), VIDIOC_ENUM_FRAMESIZES, &frame_size)) == |
- 0) { |
+ while (HANDLE_EINTR(ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame_size)) == 0) { |
if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) { |
supported_format.frame_size.SetSize( |
frame_size.discrete.width, frame_size.discrete.height); |
@@ -184,8 +184,8 @@ |
frame_interval.pixel_format = pixel_format.pixelformat; |
frame_interval.width = frame_size.discrete.width; |
frame_interval.height = frame_size.discrete.height; |
- while (HANDLE_EINTR(ioctl( |
- fd.get(), VIDIOC_ENUM_FRAMEINTERVALS, &frame_interval)) == 0) { |
+ while (HANDLE_EINTR( |
+ ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frame_interval)) == 0) { |
if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) { |
if (frame_interval.discrete.numerator != 0) { |
supported_format.frame_rate = |
@@ -255,12 +255,13 @@ |
// Test opening the device driver. This is to make sure it is available. |
// We will reopen it again in our worker thread when someone |
// allocates the camera. |
- base::ScopedFD fd(HANDLE_EINTR(open(device_name.id().c_str(), O_RDONLY))); |
- if (!fd.is_valid()) { |
+ int fd = HANDLE_EINTR(open(device_name.id().c_str(), O_RDONLY)); |
+ if (fd < 0) { |
DVLOG(1) << "Cannot open device"; |
delete self; |
return NULL; |
} |
+ close(fd); |
return self; |
} |
@@ -268,6 +269,7 @@ |
VideoCaptureDeviceLinux::VideoCaptureDeviceLinux(const Name& device_name) |
: state_(kIdle), |
device_name_(device_name), |
+ device_fd_(-1), |
v4l2_thread_("V4L2Thread"), |
buffer_pool_(NULL), |
buffer_pool_size_(0), |
@@ -322,19 +324,21 @@ |
client_ = client.Pass(); |
// Need to open camera with O_RDWR after Linux kernel 3.3. |
- device_fd_.reset(HANDLE_EINTR(open(device_name_.id().c_str(), O_RDWR))); |
- if (!device_fd_.is_valid()) { |
+ device_fd_ = HANDLE_EINTR(open(device_name_.id().c_str(), O_RDWR)); |
+ if (device_fd_ < 0) { |
SetErrorState("Failed to open V4L2 device driver."); |
return; |
} |
+ device_fd_closer_.reset(&device_fd_); |
// Test if this is a V4L2 capture device. |
v4l2_capability cap; |
- if (!((HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QUERYCAP, &cap)) == 0) && |
+ if (!((HANDLE_EINTR(ioctl(device_fd_, VIDIOC_QUERYCAP, &cap)) == 0) && |
(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) && |
!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT))) { |
// This is not a V4L2 video capture device. |
- device_fd_.reset(); |
+ device_fd_closer_.reset(); |
+ device_fd_ = -1; |
SetErrorState("This is not a V4L2 video capture device"); |
return; |
} |
@@ -351,8 +355,7 @@ |
// Enumerate image formats. |
std::list<int>::iterator best = v4l2_formats.end(); |
- while (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_ENUM_FMT, &fmtdesc)) == |
- 0) { |
+ while (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_ENUM_FMT, &fmtdesc)) == 0) { |
best = std::find(v4l2_formats.begin(), best, fmtdesc.pixelformat); |
fmtdesc.index++; |
} |
@@ -371,7 +374,7 @@ |
video_fmt.fmt.pix.height = height; |
video_fmt.fmt.pix.pixelformat = *best; |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_FMT, &video_fmt)) < 0) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_S_FMT, &video_fmt)) < 0) { |
SetErrorState("Failed to set camera format"); |
return; |
} |
@@ -381,15 +384,14 @@ |
memset(&streamparm, 0, sizeof(v4l2_streamparm)); |
streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
// The following line checks that the driver knows about framerate get/set. |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_PARM, &streamparm)) >= 0) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_G_PARM, &streamparm)) >= 0) { |
// Now check if the device is able to accept a capture framerate set. |
if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) { |
streamparm.parm.capture.timeperframe.numerator = 1; |
streamparm.parm.capture.timeperframe.denominator = |
(frame_rate) ? frame_rate : kTypicalFramerate; |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_PARM, &streamparm)) < |
- 0) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_S_PARM, &streamparm)) < 0) { |
SetErrorState("Failed to set camera framerate"); |
return; |
} |
@@ -417,7 +419,7 @@ |
// Start UVC camera. |
v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_STREAMON, &type)) == -1) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_STREAMON, &type)) == -1) { |
SetErrorState("VIDIOC_STREAMON failed"); |
return; |
} |
@@ -434,7 +436,7 @@ |
DCHECK_EQ(v4l2_thread_.message_loop(), base::MessageLoop::current()); |
v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_STREAMOFF, &type)) < 0) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_STREAMOFF, &type)) < 0) { |
SetErrorState("VIDIOC_STREAMOFF failed"); |
return; |
} |
@@ -445,7 +447,8 @@ |
// We need to close and open the device if we want to change the settings |
// Otherwise VIDIOC_S_FMT will return error |
// Sad but true. |
- device_fd_.reset(); |
+ device_fd_closer_.reset(); |
+ device_fd_ = -1; |
state_ = kIdle; |
client_.reset(); |
} |
@@ -459,7 +462,7 @@ |
fd_set r_set; |
FD_ZERO(&r_set); |
- FD_SET(device_fd_.get(), &r_set); |
+ FD_SET(device_fd_, &r_set); |
timeval timeout; |
timeout.tv_sec = 0; |
@@ -468,7 +471,7 @@ |
// First argument to select is the highest numbered file descriptor +1. |
// Refer to http://linux.die.net/man/2/select for more information. |
int result = |
- HANDLE_EINTR(select(device_fd_.get() + 1, &r_set, NULL, NULL, &timeout)); |
+ HANDLE_EINTR(select(device_fd_ + 1, &r_set, NULL, NULL, &timeout)); |
// Check if select have failed. |
if (result < 0) { |
// EINTR is a signal. This is not really an error. |
@@ -497,13 +500,13 @@ |
} |
// Check if the driver have filled a buffer. |
- if (FD_ISSET(device_fd_.get(), &r_set)) { |
+ if (FD_ISSET(device_fd_, &r_set)) { |
v4l2_buffer buffer; |
memset(&buffer, 0, sizeof(buffer)); |
buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
buffer.memory = V4L2_MEMORY_MMAP; |
// Dequeue a buffer. |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_DQBUF, &buffer)) == 0) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_DQBUF, &buffer)) == 0) { |
client_->OnIncomingCapturedData( |
static_cast<uint8*>(buffer_pool_[buffer.index].start), |
buffer.bytesused, |
@@ -512,7 +515,7 @@ |
base::TimeTicks::Now()); |
// Enqueue the buffer again. |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QBUF, &buffer)) == -1) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_QBUF, &buffer)) == -1) { |
SetErrorState(base::StringPrintf( |
"Failed to enqueue capture buffer errno %d", errno)); |
} |
@@ -537,7 +540,7 @@ |
r_buffer.memory = V4L2_MEMORY_MMAP; |
r_buffer.count = kMaxVideoBuffers; |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_REQBUFS, &r_buffer)) < 0) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_REQBUFS, &r_buffer)) < 0) { |
return false; |
} |
@@ -556,20 +559,20 @@ |
buffer.memory = V4L2_MEMORY_MMAP; |
buffer.index = i; |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QUERYBUF, &buffer)) < 0) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_QUERYBUF, &buffer)) < 0) { |
return false; |
} |
// Some devices require mmap() to be called with both READ and WRITE. |
// See crbug.com/178582. |
buffer_pool_[i].start = mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, |
- MAP_SHARED, device_fd_.get(), buffer.m.offset); |
+ MAP_SHARED, device_fd_, buffer.m.offset); |
if (buffer_pool_[i].start == MAP_FAILED) { |
return false; |
} |
buffer_pool_[i].length = buffer.length; |
// Enqueue the buffer in the drivers incoming queue. |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QBUF, &buffer)) < 0) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_QBUF, &buffer)) < 0) { |
return false; |
} |
} |
@@ -590,7 +593,7 @@ |
r_buffer.memory = V4L2_MEMORY_MMAP; |
r_buffer.count = 0; |
- if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_REQBUFS, &r_buffer)) < 0) { |
+ if (HANDLE_EINTR(ioctl(device_fd_, VIDIOC_REQBUFS, &r_buffer)) < 0) { |
SetErrorState("Failed to reset buf."); |
} |