Commit 2d01c9a0 authored by Lei Zhang's avatar Lei Zhang Committed by Commit Bot

Add some DoIoctl() helpers in Linux video capture code.

Change-Id: If8bd9653c8ebaffa2d2bd50fad1c1f0a412a5c88
Reviewed-on: https://chromium-review.googlesource.com/1215052Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#590464}
parent 1dd87306
...@@ -76,11 +76,24 @@ class CAPTURE_EXPORT V4L2CaptureDelegate final { ...@@ -76,11 +76,24 @@ class CAPTURE_EXPORT V4L2CaptureDelegate final {
class BufferTracker; class BufferTracker;
bool RunIoctl(int fd, int request, void* argp); // Running DoIoctl() on some devices, especially shortly after (re)opening the
mojom::RangePtr RetrieveUserControlRange(int device_fd, int control_id); // device file descriptor or (re)starting streaming, can fail but works after
void ResetUserAndCameraControlsToDefault(int device_fd); // retrying (https://crbug.com/670262). Returns false if the |request| ioctl
// fails too many times.
// void CloseDevice(); bool RunIoctl(int request, void* argp);
// Simple wrapper to do HANDLE_EINTR(v4l2_->ioctl(device_fd_.get(), ...)).
int DoIoctl(int request, void* argp);
// Creates a mojom::RangePtr with the (min, max, current, step) values of the
// control associated with |control_id|. Returns an empty Range otherwise.
mojom::RangePtr RetrieveUserControlRange(int control_id);
// Sets all user control to their default. Some controls are enabled by
// another flag, usually having the word "auto" in the name, see
// IsSpecialControl() in the .cc file. These flags are preset beforehand, then
// set to their defaults individually afterwards.
void ResetUserAndCameraControlsToDefault();
// VIDIOC_QUERYBUFs a buffer from V4L2, creates a BufferTracker for it and // VIDIOC_QUERYBUFs a buffer from V4L2, creates a BufferTracker for it and
// enqueues it (VIDIOC_QBUF) back into V4L2. // enqueues it (VIDIOC_QBUF) back into V4L2.
......
...@@ -205,7 +205,7 @@ void VideoCaptureDeviceFactoryLinux::GetDeviceDescriptors( ...@@ -205,7 +205,7 @@ void VideoCaptureDeviceFactoryLinux::GetDeviceDescriptors(
// capabilities at the same time are memory-to-memory and are skipped, see // capabilities at the same time are memory-to-memory and are skipped, see
// http://crbug.com/139356. // http://crbug.com/139356.
v4l2_capability cap; v4l2_capability cap;
if ((HANDLE_EINTR(v4l2_->ioctl(fd.get(), VIDIOC_QUERYCAP, &cap)) == 0) && if ((DoIoctl(fd.get(), VIDIOC_QUERYCAP, &cap) == 0) &&
(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE && (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE &&
!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) && !(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) &&
HasUsableFormats(fd.get(), cap.capabilities)) { HasUsableFormats(fd.get(), cap.capabilities)) {
...@@ -250,6 +250,10 @@ void VideoCaptureDeviceFactoryLinux::GetSupportedFormats( ...@@ -250,6 +250,10 @@ void VideoCaptureDeviceFactoryLinux::GetSupportedFormats(
GetSupportedFormatsForV4L2BufferType(fd.get(), supported_formats); GetSupportedFormatsForV4L2BufferType(fd.get(), supported_formats);
} }
int VideoCaptureDeviceFactoryLinux::DoIoctl(int fd, int request, void* argp) {
return HANDLE_EINTR(v4l2_->ioctl(fd, request, argp));
}
bool VideoCaptureDeviceFactoryLinux::HasUsableFormats(int fd, bool VideoCaptureDeviceFactoryLinux::HasUsableFormats(int fd,
uint32_t capabilities) { uint32_t capabilities) {
if (!(capabilities & V4L2_CAP_VIDEO_CAPTURE)) if (!(capabilities & V4L2_CAP_VIDEO_CAPTURE))
...@@ -259,8 +263,7 @@ bool VideoCaptureDeviceFactoryLinux::HasUsableFormats(int fd, ...@@ -259,8 +263,7 @@ bool VideoCaptureDeviceFactoryLinux::HasUsableFormats(int fd,
VideoCaptureDeviceLinux::GetListOfUsableFourCCs(false); VideoCaptureDeviceLinux::GetListOfUsableFourCCs(false);
v4l2_fmtdesc fmtdesc = {}; v4l2_fmtdesc fmtdesc = {};
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
for (; HANDLE_EINTR(v4l2_->ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0; for (; DoIoctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) {
++fmtdesc.index) {
if (base::ContainsValue(usable_fourccs, fmtdesc.pixelformat)) if (base::ContainsValue(usable_fourccs, fmtdesc.pixelformat))
return true; return true;
} }
...@@ -280,8 +283,7 @@ std::vector<float> VideoCaptureDeviceFactoryLinux::GetFrameRateList( ...@@ -280,8 +283,7 @@ std::vector<float> VideoCaptureDeviceFactoryLinux::GetFrameRateList(
frame_interval.pixel_format = fourcc; frame_interval.pixel_format = fourcc;
frame_interval.width = width; frame_interval.width = width;
frame_interval.height = height; frame_interval.height = height;
for (; HANDLE_EINTR(v4l2_->ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, for (; DoIoctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frame_interval) == 0;
&frame_interval)) == 0;
++frame_interval.index) { ++frame_interval.index) {
if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) { if (frame_interval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
if (frame_interval.discrete.numerator != 0) { if (frame_interval.discrete.numerator != 0) {
...@@ -308,8 +310,7 @@ void VideoCaptureDeviceFactoryLinux::GetSupportedFormatsForV4L2BufferType( ...@@ -308,8 +310,7 @@ void VideoCaptureDeviceFactoryLinux::GetSupportedFormatsForV4L2BufferType(
VideoCaptureFormats* supported_formats) { VideoCaptureFormats* supported_formats) {
v4l2_fmtdesc v4l2_format = {}; v4l2_fmtdesc v4l2_format = {};
v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
for (; HANDLE_EINTR(v4l2_->ioctl(fd, VIDIOC_ENUM_FMT, &v4l2_format)) == 0; for (; DoIoctl(fd, VIDIOC_ENUM_FMT, &v4l2_format) == 0; ++v4l2_format.index) {
++v4l2_format.index) {
VideoCaptureFormat supported_format; VideoCaptureFormat supported_format;
supported_format.pixel_format = supported_format.pixel_format =
VideoCaptureDeviceLinux::V4l2FourCcToChromiumPixelFormat( VideoCaptureDeviceLinux::V4l2FourCcToChromiumPixelFormat(
...@@ -320,8 +321,7 @@ void VideoCaptureDeviceFactoryLinux::GetSupportedFormatsForV4L2BufferType( ...@@ -320,8 +321,7 @@ void VideoCaptureDeviceFactoryLinux::GetSupportedFormatsForV4L2BufferType(
v4l2_frmsizeenum frame_size = {}; v4l2_frmsizeenum frame_size = {};
frame_size.pixel_format = v4l2_format.pixelformat; frame_size.pixel_format = v4l2_format.pixelformat;
for (; HANDLE_EINTR( for (; DoIoctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame_size) == 0;
v4l2_->ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame_size)) == 0;
++frame_size.index) { ++frame_size.index) {
if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) { if (frame_size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
supported_format.frame_size.SetSize(frame_size.discrete.width, supported_format.frame_size.SetSize(frame_size.discrete.width,
......
...@@ -64,6 +64,9 @@ class CAPTURE_EXPORT VideoCaptureDeviceFactoryLinux ...@@ -64,6 +64,9 @@ class CAPTURE_EXPORT VideoCaptureDeviceFactoryLinux
VideoCaptureFormats* supported_formats) override; VideoCaptureFormats* supported_formats) override;
private: private:
// Simple wrapper to do HANDLE_EINTR(v4l2_->ioctl(fd, ...)).
int DoIoctl(int fd, int request, void* argp);
bool HasUsableFormats(int fd, uint32_t capabilities); bool HasUsableFormats(int fd, uint32_t capabilities);
std::vector<float> GetFrameRateList(int fd, std::vector<float> GetFrameRateList(int fd,
uint32_t fourcc, uint32_t fourcc,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment