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 6e685c381fd83527bb3c5dbe935191d3a61dac2c..00e3dc852edc7514306690558cddf3a2c5fc898f 100644 |
--- a/media/video/capture/linux/video_capture_device_linux.cc |
+++ b/media/video/capture/linux/video_capture_device_linux.cc |
@@ -96,7 +96,7 @@ static bool HasUsableFormats(int fd) { |
fmtdesc.pixelformat) != usable_fourccs.end()) |
return true; |
- fmtdesc.index++; |
+ ++fmtdesc.index; |
} |
return false; |
} |
@@ -252,6 +252,79 @@ const VideoCaptureDevice::Name& VideoCaptureDeviceLinux::device_name() { |
return device_name_; |
} |
+void VideoCaptureDeviceLinux::GetDeviceSupportedFormats( |
+ const std::string& device_name, |
+ VideoCaptureFormats* capture_formats) { |
+ |
+ int fd = open(device_name.c_str(), O_RDONLY); |
+ if (fd < 0) |
+ return; |
+ |
+ media::VideoCaptureCapability capture_format; |
+ |
+ v4l2_capability device; |
+ // Test if this is a V4L2 capture device. |
+ if ((ioctl(fd, VIDIOC_QUERYCAP, &device) == 0) && |
+ (device.capabilities & V4L2_CAP_VIDEO_CAPTURE) && |
+ !(device.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { |
+ // Retrieve the caps one by one, first get colorspace, then sizes, then |
+ // framerates. See http://linuxtv.org/downloads/v4l-dvb-apis for reference. |
+ v4l2_fmtdesc pixel_format = {}; |
+ pixel_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
+ while (ioctl(fd, VIDIOC_ENUM_FMT, &pixel_format) == 0) { |
+ capture_format.color = media::V4l2ColorToVideoCaptureColorFormat( |
+ static_cast<int32>(pixel_format.pixelformat)); |
+ |
+ v4l2_frmsizeenum frame_size = {}; |
+ frame_size.pixel_format = pixel_format.pixelformat; |
+ while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame_size) == 0) { |
+ if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) { |
+ capture_format.width = frame_size.discrete.width; |
+ capture_format.height = frame_size.discrete.height; |
+ } else if (frame_size.type == V4L2_FRMSIZE_TYPE_STEPWISE) { |
+ // What to do here? We get a min-max pair for width and height, and a |
+ // step for each dimensions. Is not a crazy format, ViVi uses it. |
+ // TODO(mcasas) see crbug.com/249953 |
+ NOTIMPLEMENTED(); |
+ } else if (frame_size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) { |
+ // Same here as the case before: TODO(mcasas) see crbug.com/249953 |
+ NOTIMPLEMENTED(); |
+ } |
+ v4l2_frmivalenum frame_interval = {}; |
+ frame_interval.pixel_format = pixel_format.pixelformat; |
+ frame_interval.width = frame_size.discrete.width; |
+ frame_interval.height = frame_size.discrete.height; |
+ while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frame_interval) == 0) { |
+ if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) { |
+ capture_format.frame_rate = |
+ (frame_interval.discrete.numerator != 0) |
+ ? (static_cast<float>(frame_interval.discrete.denominator) / |
+ static_cast<float>(frame_interval.discrete.numerator)) |
+ : 0; |
+ |
+ } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) { |
+ // Same here as the case above: TODO(mcasas) see crbug.com/249953 |
+ NOTIMPLEMENTED(); |
+ break; |
+ } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_STEPWISE) { |
+ // Same here as the case before: TODO(mcasas) see crbug.com/249953 |
+ NOTIMPLEMENTED(); |
+ break; |
+ } |
+ capture_formats->insert(capture_formats->end(), capture_format); |
+ ++frame_interval.index; |
+ } |
+ ++frame_size.index; |
+ } |
+ ++pixel_format.index; |
+ } |
+ } else { |
+ // The selected device is not video capture as we like it. |
+ capture_formats->clear(); |
+ } |
+ close(fd); |
+} |
+ |
void VideoCaptureDeviceLinux::OnAllocate(int width, |
int height, |
int frame_rate, |
@@ -292,7 +365,7 @@ void VideoCaptureDeviceLinux::OnAllocate(int width, |
std::list<int>::iterator best = v4l2_formats.end(); |
while (ioctl(device_fd_, VIDIOC_ENUM_FMT, &fmtdesc) == 0) { |
best = std::find(v4l2_formats.begin(), best, fmtdesc.pixelformat); |
- fmtdesc.index++; |
+ ++fmtdesc.index; |
} |
if (best == v4l2_formats.end()) { |
@@ -449,7 +522,7 @@ void VideoCaptureDeviceLinux::OnCaptureTask() { |
// Check if select timeout. |
if (result == 0) { |
- timeout_count_++; |
+ ++timeout_count_; |
if (timeout_count_ >= kContinuousTimeoutLimit) { |
SetErrorState(base::StringPrintf( |
"Continuous timeout %d times", timeout_count_)); |
@@ -510,7 +583,7 @@ bool VideoCaptureDeviceLinux::AllocateVideoBuffers() { |
// Map the buffers. |
buffer_pool_ = new Buffer[r_buffer.count]; |
- for (unsigned int i = 0; i < r_buffer.count; i++) { |
+ for (unsigned int i = 0; i < r_buffer.count; ++i) { |
v4l2_buffer buffer; |
memset(&buffer, 0, sizeof(buffer)); |
buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
@@ -542,7 +615,7 @@ void VideoCaptureDeviceLinux::DeAllocateVideoBuffers() { |
return; |
// Unmaps buffers. |
- for (int i = 0; i < buffer_pool_size_; i++) { |
+ for (int i = 0; i < buffer_pool_size_; ++i) { |
munmap(buffer_pool_[i].start, buffer_pool_[i].length); |
} |
v4l2_requestbuffers r_buffer; |