summaryrefslogtreecommitdiff
path: root/src/libcamera/v4l2_device.cpp
diff options
context:
space:
mode:
authorKieran Bingham <kieran.bingham@ideasonboard.com>2018-12-14 13:49:20 +0000
committerKieran Bingham <kieran.bingham@ideasonboard.com>2019-01-17 21:55:21 +0000
commite74f3eebb498634f438a005b2ad5b7f1778091e8 (patch)
treefbfac530688d24ec3ab58c6ab27863d3d734824b /src/libcamera/v4l2_device.cpp
parente399a0745b0c306757c8f7c38f5b2864d442db7e (diff)
libcamera: Add V4L2 Device object
Provide a helper V4L2 device object capable of interacting with the V4L2 Linux Kernel APIs. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'src/libcamera/v4l2_device.cpp')
-rw-r--r--src/libcamera/v4l2_device.cpp186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
new file mode 100644
index 00000000..54b53de3
--- /dev/null
+++ b/src/libcamera/v4l2_device.cpp
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * v4l2_device.cpp - V4L2 Device
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "v4l2_device.h"
+
+/**
+ * \file v4l2_device.h
+ * \brief V4L2 Device API
+ */
+namespace libcamera {
+
+/**
+ * \struct V4L2Capability
+ * \brief struct v4l2_capability object wrapper and helpers
+ *
+ * The V4L2Capability structure manages the information returned by the
+ * VIDIOC_QUERYCAP ioctl.
+ */
+
+/**
+ * \fn const char *V4L2Capability::driver()
+ * \brief Retrieve the driver module name
+ * \return The string containing the name of the driver module
+ */
+
+/**
+ * \fn const char *V4L2Capability::card()
+ * \brief Retrieve the device card name
+ * \return The string containing the device name
+ */
+
+/**
+ * \fn const char *V4L2Capability::bus_info()
+ * \brief Retrieve the location of the device in the system
+ * \return The string containing the device location
+ */
+
+/**
+ * \fn bool V4L2Capability::isCapture()
+ * \brief Identify if the device is capable of capturing video
+ * \return True if the device can capture video frames
+ */
+
+/**
+ * \fn bool V4L2Capability::isOutput()
+ * \brief Identify if the device is capable of outputting video
+ * \return True if the device can output video frames
+ */
+
+/**
+ * \fn bool V4L2Capability::hasStreaming()
+ * \brief Determine if the device can perform Streaming I/O
+ * \return True if the device provides Streaming I/O IOCTLs
+ */
+
+/**
+ * \class V4L2Device
+ * \brief V4L2Device object and API
+ *
+ * The V4L2 Device API class models an instance of a V4L2 device node.
+ * It is constructed with the path to a V4L2 video device node. The device node
+ * is only opened upon a call to open() which must be checked for success.
+ *
+ * The device capabilities are validated when the device is opened and the
+ * device is rejected if it is not a suitable V4L2 capture or output device, or
+ * if the device does not support streaming I/O.
+ *
+ * No API call other than open(), isOpen() and close() shall be called on an
+ * unopened device instance.
+ *
+ * Upon destruction any device left open will be closed, and any resources
+ * released.
+ */
+
+/**
+ * \brief Construct a V4L2Device
+ * \param devnode The file-system path to the video device node
+ */
+V4L2Device::V4L2Device(const std::string &devnode)
+ : devnode_(devnode), fd_(-1)
+{
+}
+
+V4L2Device::~V4L2Device()
+{
+ close();
+}
+
+/**
+ * \brief Open a V4L2 device and query its capabilities
+ * \return 0 on success, or a negative error code otherwise
+ */
+int V4L2Device::open()
+{
+ int ret;
+
+ if (isOpen()) {
+ LOG(Error) << "Device already open";
+ return -EBUSY;
+ }
+
+ ret = ::open(devnode_.c_str(), O_RDWR);
+ if (ret < 0) {
+ ret = -errno;
+ LOG(Error) << "Failed to open V4L2 device '" << devnode_
+ << "': " << strerror(-ret);
+ return ret;
+ }
+ fd_ = ret;
+
+ ret = ioctl(fd_, VIDIOC_QUERYCAP, &caps_);
+ if (ret < 0) {
+ ret = -errno;
+ LOG(Error) << "Failed to query device capabilities: "
+ << strerror(-ret);
+ return ret;
+ }
+
+ LOG(Debug) << "Opened '" << devnode_ << "' "
+ << caps_.bus_info() << ": " << caps_.driver()
+ << ": " << caps_.card();
+
+ if (!caps_.isCapture() && !caps_.isOutput()) {
+ LOG(Debug) << "Device is not a supported type";
+ return -EINVAL;
+ }
+
+ if (!caps_.hasStreaming()) {
+ LOG(Error) << "Device does not support streaming I/O";
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * \brief Check if device is successfully opened
+ * \return True if the device is open, false otherwise
+ */
+bool V4L2Device::isOpen() const
+{
+ return fd_ != -1;
+}
+
+/**
+ * \brief Close the device, releasing any resources acquired by open()
+ */
+void V4L2Device::close()
+{
+ if (fd_ < 0)
+ return;
+
+ ::close(fd_);
+ fd_ = -1;
+}
+
+/**
+ * \fn const char *V4L2Device::driverName()
+ * \brief Retrieve the name of the V4L2 device driver
+ * \return The string containing the driver name
+ */
+
+/**
+ * \fn const char *V4L2Device::deviceName()
+ * \brief Retrieve the name of the V4L2 device
+ * \return The string containing the device name
+ */
+
+/**
+ * \fn const char *V4L2Device::busName()
+ * \brief Retrieve the location of the device in the system
+ * \return The string containing the device location
+ */
+
+} /* namespace libcamera */