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

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

Issue 877193005: Reland (2): Linux Video Capture: Add support for multiplanar YUV420 format enumeration (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Bug fix Created 5 years, 11 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/video/capture/linux/video_capture_device_factory_linux.cc
diff --git a/media/video/capture/linux/video_capture_device_factory_linux.cc b/media/video/capture/linux/video_capture_device_factory_linux.cc
index c33c6b78fab5696e5ee8b5569ef0cbaec47c9015..9bbc50a7f9c1f26af89030e4547a6b5e23a0d621 100644
--- a/media/video/capture/linux/video_capture_device_factory_linux.cc
+++ b/media/video/capture/linux/video_capture_device_factory_linux.cc
@@ -24,21 +24,105 @@
namespace media {
-static bool HasUsableFormats(int fd) {
+static bool HasUsableFormats(int fd, uint32 capabilities) {
const std::list<int>& usable_fourccs =
VideoCaptureDeviceLinux::GetListOfUsableFourCCs(false);
- v4l2_fmtdesc fmtdesc = {};
- fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- for (; HANDLE_EINTR(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0;
- ++fmtdesc.index) {
- if (std::find(usable_fourccs.begin(), usable_fourccs.end(),
- fmtdesc.pixelformat) != usable_fourccs.end())
- return true;
+ static const struct {
+ int capability;
+ v4l2_buf_type buf_type;
+ } kCapabilityAndBufferTypes[] = {
+ {V4L2_CAP_VIDEO_CAPTURE, V4L2_BUF_TYPE_VIDEO_CAPTURE},
+ {V4L2_CAP_VIDEO_CAPTURE_MPLANE, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE}
+ };
+
+ for (const auto& capability_and_buffer_type : kCapabilityAndBufferTypes) {
+ v4l2_fmtdesc fmtdesc = {};
+ if (capabilities & capability_and_buffer_type.capability) {
+ fmtdesc.type = capability_and_buffer_type.buf_type;
+ for (; HANDLE_EINTR(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0;
+ ++fmtdesc.index) {
+ if (std::find(usable_fourccs.begin(), usable_fourccs.end(),
+ fmtdesc.pixelformat) != usable_fourccs.end())
+ return true;
+ }
+ }
}
return false;
}
+static std::list<float> GetFrameRateList(int fd,
+ uint32 fourcc,
+ uint32 width,
+ uint32 height) {
+ std::list<float> frame_rates;
+
+ v4l2_frmivalenum frame_interval = {};
+ frame_interval.pixel_format = fourcc;
+ frame_interval.width = width;
+ frame_interval.height = height;
+ for (; HANDLE_EINTR(ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS,
+ &frame_interval)) == 0; ++frame_interval.index) {
+ if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
+ if (frame_interval.discrete.numerator != 0) {
+ frame_rates.push_back(frame_interval.discrete.denominator /
+ static_cast<float>(frame_interval.discrete.numerator));
+ }
+ } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_CONTINUOUS ||
+ frame_interval.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
+ // TODO(mcasas): see http://crbug.com/249953, support these devices.
+ NOTIMPLEMENTED();
+ break;
+ }
+ }
+ // Some devices, e.g. Kinect, do not enumerate any frame rates, see
+ // http://crbug.com/412284. Set their frame_rate to zero.
+ if (frame_rates.empty())
+ frame_rates.push_back(0);
+ return frame_rates;
+}
+
+static void GetSupportedFormatsForV4L2BufferType(
+ int fd,
+ v4l2_buf_type buf_type,
+ media::VideoCaptureFormats* supported_formats) {
+ v4l2_fmtdesc v4l2_format = {};
+ v4l2_format.type = buf_type;
+ for (; HANDLE_EINTR(ioctl(fd, VIDIOC_ENUM_FMT, &v4l2_format)) == 0;
+ ++v4l2_format.index) {
+ VideoCaptureFormat supported_format;
+ supported_format.pixel_format =
+ VideoCaptureDeviceLinux::V4l2FourCcToChromiumPixelFormat(
+ v4l2_format.pixelformat);
+
+ if (supported_format.pixel_format == PIXEL_FORMAT_UNKNOWN)
+ continue;
+
+ v4l2_frmsizeenum frame_size = {};
+ frame_size.pixel_format = v4l2_format.pixelformat;
+ for (; HANDLE_EINTR(ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame_size)) == 0;
+ ++frame_size.index) {
+ if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
+ supported_format.frame_size.SetSize(frame_size.discrete.width,
+ frame_size.discrete.height);
+ } else if (frame_size.type == V4L2_FRMSIZE_TYPE_STEPWISE ||
+ frame_size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
+ // TODO(mcasas): see http://crbug.com/249953, support these devices.
+ NOTIMPLEMENTED();
+ }
+
+ const std::list<float> frame_rates = GetFrameRateList(
+ fd, v4l2_format.pixelformat, frame_size.discrete.width,
+ frame_size.discrete.height);
+ for (const auto& frame_rate : frame_rates) {
+ supported_format.frame_rate = frame_rate;
+ supported_formats->push_back(supported_format);
+ DVLOG(1) << supported_format.ToString();
+ }
+ }
+ }
+}
+
VideoCaptureDeviceFactoryLinux::VideoCaptureDeviceFactoryLinux(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
: ui_task_runner_(ui_task_runner) {
@@ -63,7 +147,7 @@ scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryLinux::Create(
// allocates the camera.
base::ScopedFD fd(HANDLE_EINTR(open(device_name.id().c_str(), O_RDONLY)));
if (!fd.is_valid()) {
- DVLOG(1) << "Cannot open device";
+ DLOG(ERROR) << "Cannot open device";
delete self;
return scoped_ptr<VideoCaptureDevice>();
}
@@ -93,11 +177,14 @@ void VideoCaptureDeviceFactoryLinux::GetDeviceNames(
// http://crbug.com/139356.
v4l2_capability cap;
if ((HANDLE_EINTR(ioctl(fd.get(), VIDIOC_QUERYCAP, &cap)) == 0) &&
- (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE &&
- !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) &&
- HasUsableFormats(fd.get())) {
- device_names->push_front(VideoCaptureDevice::Name(
- base::StringPrintf("%s", cap.card), unique_id));
+ ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE ||
+ cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) &&
+ !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) &&
+ !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)) &&
+ HasUsableFormats(fd.get(), cap.capabilities)) {
+ VideoCaptureDevice::Name device_name(base::StringPrintf("%s", cap.card),
+ unique_id);
+ device_names->push_back(device_name);
}
}
}
@@ -113,65 +200,10 @@ void VideoCaptureDeviceFactoryLinux::GetDeviceSupportedFormats(
return;
supported_formats->clear();
- // Retrieve the caps one by one, first get pixel format, then sizes, then
- // frame rates.
- v4l2_fmtdesc pixel_format = {};
- pixel_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- for (; HANDLE_EINTR(ioctl(fd.get(), VIDIOC_ENUM_FMT, &pixel_format)) == 0;
- ++pixel_format.index) {
- VideoCaptureFormat supported_format;
- supported_format.pixel_format =
- VideoCaptureDeviceLinux::V4l2FourCcToChromiumPixelFormat(
- pixel_format.pixelformat);
- if (supported_format.pixel_format == PIXEL_FORMAT_UNKNOWN)
- continue;
-
- v4l2_frmsizeenum frame_size = {};
- frame_size.pixel_format = pixel_format.pixelformat;
- for (; HANDLE_EINTR(ioctl(fd.get(), VIDIOC_ENUM_FRAMESIZES,
- &frame_size)) == 0;
- ++frame_size.index) {
- if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
- supported_format.frame_size.SetSize(
- frame_size.discrete.width, frame_size.discrete.height);
- } else if (frame_size.type == V4L2_FRMSIZE_TYPE_STEPWISE ||
- 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;
- std::list<float> frame_rates;
- for (; HANDLE_EINTR(ioctl(fd.get(), VIDIOC_ENUM_FRAMEINTERVALS,
- &frame_interval)) == 0;
- ++frame_interval.index) {
- if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
- if (frame_interval.discrete.numerator != 0) {
- frame_rates.push_back(frame_interval.discrete.denominator /
- static_cast<float>(frame_interval.discrete.numerator));
- }
- } else if (frame_interval.type == V4L2_FRMIVAL_TYPE_CONTINUOUS ||
- frame_interval.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
- // TODO(mcasas): see http://crbug.com/249953, support these devices.
- NOTIMPLEMENTED();
- break;
- }
- }
- // Some devices, e.g. Kinect, do not enumerate any frame rates, see
- // http://crbug.com/412284. Set their frame_rate to zero.
- if (frame_rates.empty())
- frame_rates.push_back(0.0f);
-
- for (const auto& it : frame_rates) {
- supported_format.frame_rate = it;
- supported_formats->push_back(supported_format);
- DVLOG(1) << device.name() << " " << supported_format.ToString();
- }
- }
- }
+ const v4l2_buf_type kCaptureTypes[] = {V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE};
+ for (const auto& buf_type : kCaptureTypes)
+ GetSupportedFormatsForV4L2BufferType(fd.get(), buf_type, supported_formats);
return;
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698