summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPenny MacNeil <pennymac@chromium.org>2015-01-15 15:07:03 -0800
committerPenny MacNeil <pennymac@chromium.org>2015-01-15 23:08:56 +0000
commit1577a17cdb0fe92f3e2dcd1ea2327ea814ca6549 (patch)
treec8cd3997e7e3f30237360bbb70a4086b953fbae9
parentcb1e5587b71cc3f57974d2b3ca7ba3be7d238206 (diff)
downloadchromium_src-1577a17cdb0fe92f3e2dcd1ea2327ea814ca6549.zip
chromium_src-1577a17cdb0fe92f3e2dcd1ea2327ea814ca6549.tar.gz
chromium_src-1577a17cdb0fe92f3e2dcd1ea2327ea814ca6549.tar.bz2
Revert "Relanding: Linux Video Capture: Add support for multiplanar YUV420 format enumeration."
This reverts commit 393694864ca15a4bb625bccb792c5dbd693f5ead. The reason is that we think this causes none working devices to be enumerated, see crbug/448599 original code review: https://codereview.chromium.org/802633006 BUG=441836,448599 TBR=mcasas,niklase@chromium.org Review URL: https://codereview.chromium.org/814573008 Cr-Commit-Position: refs/heads/master@{#311690} (cherry picked from commit c0b2e72c64ff86778d623f867311aeaffe4cfdfa) Review URL: https://codereview.chromium.org/814833010 Cr-Commit-Position: refs/branch-heads/2272@{#27} Cr-Branched-From: 827a380cfdb31aa54c8d56e63ce2c3fd8c3ba4d4-refs/heads/master@{#310958}
-rw-r--r--media/video/capture/linux/video_capture_device_factory_linux.cc178
1 files changed, 73 insertions, 105 deletions
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 b89b145..c33c6b7 100644
--- a/media/video/capture/linux/video_capture_device_factory_linux.cc
+++ b/media/video/capture/linux/video_capture_device_factory_linux.cc
@@ -24,105 +24,21 @@
namespace media {
-static bool HasUsableFormats(int fd, uint32 capabilities) {
+static bool HasUsableFormats(int fd) {
const std::list<int>& usable_fourccs =
VideoCaptureDeviceLinux::GetListOfUsableFourCCs(false);
- 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;
- }
- }
+ 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;
}
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) {
@@ -147,7 +63,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()) {
- DLOG(ERROR) << "Cannot open device";
+ DVLOG(1) << "Cannot open device";
delete self;
return scoped_ptr<VideoCaptureDevice>();
}
@@ -177,14 +93,11 @@ 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_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);
+ (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));
}
}
}
@@ -200,10 +113,65 @@ void VideoCaptureDeviceFactoryLinux::GetDeviceSupportedFormats(
return;
supported_formats->clear();
- 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);
+ // 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();
+ }
+ }
+ }
return;
}