diff options
author | Penny MacNeil <pennymac@chromium.org> | 2015-01-15 15:07:03 -0800 |
---|---|---|
committer | Penny MacNeil <pennymac@chromium.org> | 2015-01-15 23:08:56 +0000 |
commit | 1577a17cdb0fe92f3e2dcd1ea2327ea814ca6549 (patch) | |
tree | c8cd3997e7e3f30237360bbb70a4086b953fbae9 | |
parent | cb1e5587b71cc3f57974d2b3ca7ba3be7d238206 (diff) | |
download | chromium_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.cc | 178 |
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; } |