Commit f9009e12 authored by Michael Olbrich's avatar Michael Olbrich Committed by Commit Bot

V4L2: handle device capabilities correctly

cap.capabilities describes all capabilities of the whole physical device.
It may contain V4L2_CAP_VIDEO_CAPTURE and V4L2_CAP_VIDEO_OUTPUT if multiple
/dev/video* device nodes are part of the same physical device.
If the V4L2_CAP_DEVICE_CAPS flag is set, then device_caps contains the
capabilities of the currently opened device node.
So this should be checked as well to determine if the device node is a
capture device.

Bug: None
Change-Id: I83c0516c546121a0fac82380b72d1c8f3cb22fc9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537967Reviewed-by: default avatarShik Chen <shik@chromium.org>
Commit-Queue: Shik Chen <shik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828754}
parent a957514d
......@@ -264,10 +264,18 @@ void V4L2CaptureDelegate::AllocateAndStart(
ResetUserAndCameraControlsToDefault();
// In theory, checking for CAPTURE/OUTPUT in caps.capabilities should only
// be done if V4L2_CAP_DEVICE_CAPS is not set. However, this was not done
// in the past and it is unclear if it breaks with existing devices. And if
// a device is accepted incorrectly then it will not have any usable
// formats and is skipped anyways.
v4l2_capability cap = {};
if (!(DoIoctl(VIDIOC_QUERYCAP, &cap) == 0 &&
((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) &&
!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)))) {
(((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) &&
!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) ||
((cap.capabilities & V4L2_CAP_DEVICE_CAPS) &&
(cap.device_caps & V4L2_CAP_VIDEO_CAPTURE) &&
!(cap.device_caps & V4L2_CAP_VIDEO_OUTPUT))))) {
device_fd_.reset();
SetErrorState(VideoCaptureError::kV4L2ThisIsNotAV4L2VideoCaptureDevice,
FROM_HERE, "This is not a V4L2 video capture device");
......
......@@ -205,10 +205,18 @@ void VideoCaptureDeviceFactoryLinux::GetDevicesInfo(
// one supported capture format. Devices that have capture and output
// capabilities at the same time are memory-to-memory and are skipped, see
// http://crbug.com/139356.
// In theory, checking for CAPTURE/OUTPUT in caps.capabilities should only
// be done if V4L2_CAP_DEVICE_CAPS is not set. However, this was not done
// in the past and it is unclear if it breaks with existing devices. And if
// a device is accepted incorrectly then it will not have any usable
// formats and is skipped anyways.
v4l2_capability cap;
if ((DoIoctl(fd.get(), VIDIOC_QUERYCAP, &cap) == 0) &&
(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE &&
!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) &&
((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE &&
!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) ||
(cap.capabilities & V4L2_CAP_DEVICE_CAPS &&
cap.device_caps & V4L2_CAP_VIDEO_CAPTURE &&
!(cap.device_caps & V4L2_CAP_VIDEO_OUTPUT))) &&
HasUsableFormats(fd.get(), cap.capabilities)) {
const std::string model_id =
device_provider_->GetDeviceModelId(unique_id);
......
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