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

Unified Diff: extensions/browser/api/webcam_private/v4l2_webcam.cc

Issue 1136883004: Move V4L2 code into a webcam helper class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 7 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 | « extensions/browser/api/webcam_private/v4l2_webcam.h ('k') | extensions/browser/api/webcam_private/webcam.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/browser/api/webcam_private/v4l2_webcam.cc
diff --git a/extensions/browser/api/webcam_private/v4l2_webcam.cc b/extensions/browser/api/webcam_private/v4l2_webcam.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f6d53c50c0dbb60bc5328b89a2965587c6c9e258
--- /dev/null
+++ b/extensions/browser/api/webcam_private/v4l2_webcam.cc
@@ -0,0 +1,172 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/api/webcam_private/v4l2_webcam.h"
+
+#include <fcntl.h>
+#include <linux/uvcvideo.h>
+#include <linux/videodev2.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include "base/posix/eintr_wrapper.h"
+
+#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32)
+#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33)
+#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE+34)
+
+// GUID of the Extension Unit for Logitech CC3300e motor control:
+// {212de5ff-3080-2c4e-82d9-f587d00540bd}
+#define UVC_GUID_LOGITECH_CC3000E_MOTORS \
+ {0x21, 0x2d, 0xe5, 0xff, 0x30, 0x80, 0x2c, 0x4e, \
+ 0x82, 0xd9, 0xf5, 0x87, 0xd0, 0x05, 0x40, 0xbd}
+
+#define LOGITECH_MOTORCONTROL_PANTILT_CMD 2
+
+namespace {
+const int kLogitechMenuIndexGoHome = 2;
+
+const uvc_menu_info kLogitechCmdMenu[] = {
+ {1, "Set Preset"}, {2, "Get Preset"}, {3, "Go Home"}
+};
+
+const uvc_xu_control_mapping kLogitechCmdMapping = {
+ V4L2_CID_PANTILT_CMD,
+ "Pan/Tilt Go",
+ UVC_GUID_LOGITECH_CC3000E_MOTORS,
+ LOGITECH_MOTORCONTROL_PANTILT_CMD,
+ 8,
+ 0,
+ V4L2_CTRL_TYPE_MENU,
+ UVC_CTRL_DATA_TYPE_ENUM,
+ const_cast<uvc_menu_info*>(&kLogitechCmdMenu[0]),
+ arraysize(kLogitechCmdMenu),
+};
+} // namespace
+
+namespace extensions {
+
+V4L2Webcam::V4L2Webcam(const std::string& device_id) : device_id_(device_id) {
+}
+
+V4L2Webcam::~V4L2Webcam() {
+}
+
+bool V4L2Webcam::Open() {
+ fd_.reset(HANDLE_EINTR(open(device_id_.c_str(), 0)));
+ return fd_.is_valid();
+}
+
+bool V4L2Webcam::EnsureLogitechCommandsMapped() {
+ int res =
+ HANDLE_EINTR(ioctl(fd_.get(), UVCIOC_CTRL_MAP, &kLogitechCmdMapping));
+ // If mapping is successful or it's already mapped, this is a Logitech
+ // camera.
+ // NOTE: On success, occasionally EFAULT is returned. On a real error,
+ // ENOMEM, EPERM, EINVAL, or EOVERFLOW should be returned.
+ return res >= 0 || errno == EEXIST || errno == EFAULT;
+}
+
+bool V4L2Webcam::SetWebcamParameter(int fd, uint32_t control_id, int value) {
+ struct v4l2_control v4l2_ctrl = {control_id, value};
+ int res = HANDLE_EINTR(ioctl(fd, VIDIOC_S_CTRL, &v4l2_ctrl)) >= 0;
+ return res >= 0;
+}
+
+bool V4L2Webcam::GetWebcamParameter(int fd, uint32_t control_id, int* value) {
+ struct v4l2_control v4l2_ctrl = {control_id};
+
+ if (HANDLE_EINTR(ioctl(fd, VIDIOC_G_CTRL, &v4l2_ctrl)))
+ return false;
+
+ *value = v4l2_ctrl.value;
+ return true;
+}
+
+void V4L2Webcam::Reset(bool pan, bool tilt, bool zoom) {
+ if (pan || tilt) {
+ if (EnsureLogitechCommandsMapped()) {
+ SetWebcamParameter(fd_.get(), V4L2_CID_PANTILT_CMD,
+ kLogitechMenuIndexGoHome);
+ } else {
+ if (pan) {
+ struct v4l2_control v4l2_ctrl = {V4L2_CID_PAN_RESET};
+ HANDLE_EINTR(ioctl(fd_.get(), VIDIOC_S_CTRL, &v4l2_ctrl));
+ }
+
+ if (tilt) {
+ struct v4l2_control v4l2_ctrl = {V4L2_CID_TILT_RESET};
+ HANDLE_EINTR(ioctl(fd_.get(), VIDIOC_S_CTRL, &v4l2_ctrl));
+ }
+ }
+ }
+
+ if (zoom) {
+ const int kDefaultZoom = 100;
+ SetWebcamParameter(fd_.get(), V4L2_CID_ZOOM_ABSOLUTE, kDefaultZoom);
+ }
+}
+
+bool V4L2Webcam::GetPan(int* value) {
+ return GetWebcamParameter(fd_.get(), V4L2_CID_PAN_ABSOLUTE, value);
+}
+
+bool V4L2Webcam::GetTilt(int* value) {
+ return GetWebcamParameter(fd_.get(), V4L2_CID_TILT_ABSOLUTE, value);
+}
+
+bool V4L2Webcam::GetZoom(int* value) {
+ return GetWebcamParameter(fd_.get(), V4L2_CID_ZOOM_ABSOLUTE, value);
+}
+
+bool V4L2Webcam::SetPan(int value) {
+ return SetWebcamParameter(fd_.get(), V4L2_CID_PAN_ABSOLUTE, value);
+}
+
+bool V4L2Webcam::SetTilt(int value) {
+ return SetWebcamParameter(fd_.get(), V4L2_CID_TILT_ABSOLUTE, value);
+}
+
+bool V4L2Webcam::SetZoom(int value) {
+ return SetWebcamParameter(fd_.get(), V4L2_CID_ZOOM_ABSOLUTE, value);
+}
+
+bool V4L2Webcam::SetPanDirection(PanDirection direction) {
+ int direction_value = 0;
+ switch (direction) {
+ case PAN_STOP:
+ direction_value = 0;
+ break;
+
+ case PAN_RIGHT:
+ direction_value = 1;
+ break;
+
+ case PAN_LEFT:
+ direction_value = -1;
+ break;
+ }
+ return SetWebcamParameter(fd_.get(), V4L2_CID_PAN_SPEED, direction_value);
+}
+
+bool V4L2Webcam::SetTiltDirection(TiltDirection direction) {
+ int direction_value = 0;
+ switch (direction) {
+ case TILT_STOP:
+ direction_value = 0;
+ break;
+
+ case TILT_UP:
+ direction_value = 1;
+ break;
+
+ case TILT_DOWN:
+ direction_value = -1;
+ break;
+ }
+ return SetWebcamParameter(fd_.get(), V4L2_CID_TILT_SPEED, direction_value);
+}
+
+} // namespace extensions
« no previous file with comments | « extensions/browser/api/webcam_private/v4l2_webcam.h ('k') | extensions/browser/api/webcam_private/webcam.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698