Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1570)

Unified Diff: media/video/capture/linux/video_capture_device_linux.cc

Issue 24079003: Add VideoCaptureDevice::GetDeviceSupportedFormats to interface + implementation for Linux and Fake (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: perkj@'s nits Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 b7a2e137ea9e42273c9636a82770f0f87e7314f2..f5c8147e5255580d22b9d27ac02abb190532fb43 100644
--- a/media/video/capture/linux/video_capture_device_linux.cc
+++ b/media/video/capture/linux/video_capture_device_linux.cc
@@ -45,7 +45,7 @@ static const int32 kV4l2RawFmts[] = {
V4L2_PIX_FMT_YUYV
};
-// USB VID and PID are both 4 bytes long
+// USB VID and PID are both 4 bytes long.
static const size_t kVidPidSize = 4;
// /sys/class/video4linux/video{N}/device is a symlink to the corresponding
@@ -55,6 +55,8 @@ static const char kVidPathTemplate[] =
static const char kPidPathTemplate[] =
"/sys/class/video4linux/%s/device/../idProduct";
+// This function translates Video4Linux pixel formats to Chromium pixel formats,
+// should only support those listed in GetListOfUsableFourCCs.
static VideoPixelFormat V4l2ColorToVideoCaptureColorFormat(
int32 v4l2_fourcc) {
VideoPixelFormat result = PIXEL_FORMAT_UNKNOWN;
@@ -69,8 +71,9 @@ static VideoPixelFormat V4l2ColorToVideoCaptureColorFormat(
case V4L2_PIX_FMT_JPEG:
result = PIXEL_FORMAT_MJPEG;
break;
+ default:
+ DVLOG(1) << "Unsupported pixel format " << std::hex << v4l2_fourcc;
}
- DCHECK_NE(result, PIXEL_FORMAT_UNKNOWN);
return result;
}
@@ -141,6 +144,78 @@ void VideoCaptureDevice::GetDeviceNames(Names* device_names) {
}
}
+void VideoCaptureDevice::GetDeviceSupportedFormats(
+ const Name& device,
+ VideoCaptureCapabilities* formats) {
+
+ if (device.id().empty())
+ return;
+ int fd;
+ VideoCaptureCapabilities capture_formats;
+ if ((fd = open(device.id().c_str(), O_RDONLY)) < 0) {
+ // Failed to open this device.
+ return;
+ }
+
+ formats->clear();
+
+ VideoCaptureCapability capture_format;
+ // 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 =
+ V4l2ColorToVideoCaptureColorFormat((int32)pixel_format.pixelformat);
+ if (capture_format.color == PIXEL_FORMAT_UNKNOWN) continue;
+
+ 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) {
+ // TODO(mcasas): see http://crbug.com/249953, support these devices.
+ NOTIMPLEMENTED();
+ } else if (frame_size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
+ // TODO(mcasas): see http://crbug.com/249953, support these devices.
+ 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) {
+ if (frame_interval.discrete.numerator != 0) {
+ capture_format.frame_rate =
+ static_cast<float>(frame_interval.discrete.denominator) /
+ static_cast<float>(frame_interval.discrete.numerator);
+ } else {
+ capture_format.frame_rate = 0;
+ }
+ } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
+ // TODO(mcasas): see http://crbug.com/249953, support these devices.
+ NOTIMPLEMENTED();
+ break;
+ } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
+ // TODO(mcasas): see http://crbug.com/249953, support these devices.
+ NOTIMPLEMENTED();
+ break;
+ }
+ formats->push_back(capture_format);
+ ++frame_interval.index;
+ }
+ ++frame_size.index;
+ }
+ ++pixel_format.index;
+ }
+
+ close(fd);
+ return;
+}
+
static bool ReadIdFile(const std::string path, std::string* id) {
char id_buf[kVidPidSize];
FILE* file = fopen(path.c_str(), "rb");
« no previous file with comments | « media/video/capture/fake_video_capture_device.cc ('k') | media/video/capture/mac/video_capture_device_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698