[libcamera-devel] [PATCH v2 1/2] lib: Add V4L2 Device object
Kieran Bingham
kieran.bingham at ideasonboard.com
Tue Jan 15 17:02:11 CET 2019
Provide a helper V4L2 device object capable of interacting with the
V4L2 Linux Kernel APIs.
Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
---
src/libcamera/include/v4l2_device.h | 43 ++++++++++
src/libcamera/meson.build | 2 +
src/libcamera/v4l2_device.cpp | 127 ++++++++++++++++++++++++++++
3 files changed, 172 insertions(+)
create mode 100644 src/libcamera/include/v4l2_device.h
create mode 100644 src/libcamera/v4l2_device.cpp
diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h
new file mode 100644
index 000000000000..ddcb17af2187
--- /dev/null
+++ b/src/libcamera/include/v4l2_device.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * v4l2_device.h - V4L2 Device API Abstractions
+ */
+#ifndef __LIBCAMERA_V4L2_DEVICE_H__
+#define __LIBCAMERA_V4L2_DEVICE_H__
+
+#include <string>
+
+#include <linux/videodev2.h>
+
+namespace libcamera {
+
+class V4L2Capability : public v4l2_capability
+{
+public:
+ bool isCapture() { return capabilities & V4L2_CAP_VIDEO_CAPTURE; }
+ bool isMplane() { return capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE; }
+ bool hasStreaming() { return capabilities & V4L2_CAP_STREAMING; }
+};
+
+class V4L2Device
+{
+public:
+ V4L2Device() = delete;
+ V4L2Device(const std::string &device);
+ ~V4L2Device();
+
+ int open();
+ bool isOpen() const;
+ void close();
+
+private:
+ std::string device_;
+ int fd_;
+ V4L2Capability caps_;
+};
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_V4L2_DEVICE_H__ */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index abf9a71d4172..f9f25c0ecf15 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -11,6 +11,7 @@ libcamera_sources = files([
'pipeline_handler.cpp',
'signal.cpp',
'timer.cpp',
+ 'v4l2_device.cpp',
])
libcamera_headers = files([
@@ -21,6 +22,7 @@ libcamera_headers = files([
'include/media_object.h',
'include/pipeline_handler.h',
'include/utils.h',
+ 'include/v4l2_device.h',
])
libcamera_internal_includes = include_directories('include')
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
new file mode 100644
index 000000000000..3133bfe4ffb0
--- /dev/null
+++ b/src/libcamera/v4l2_device.cpp
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * v4l2_device.cpp - V4L2 Device API
+ */
+
+#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 {
+
+/**
+ * \class V4L2Capability
+ * \brief struct v4l2_capability object wrapper and helpers
+ *
+ * The V4L2Capability wraps the V4L2 API interactions for capabilities and
+ * device flag parsing.
+ */
+
+/**
+ * \fn bool V4L2Capability::isCapture()
+ * \brief Identify if the device is capable of capturing video
+ * \return boolean true if the device provides video frames
+ */
+
+/**
+ * \fn bool V4L2Capability::isMplane()
+ * \brief Identify if the device uses MPLANE formats
+ * \return boolean true if the device uses multiplanar buffer formats
+ */
+
+/**
+ * \fn bool V4L2Capability::hasStreaming()
+ * \brief Determine if the device can perform Streaming IO
+ * \return boolean true if the device provides Streaming IO IOCTLs
+ */
+
+/**
+ * \class V4L2Device
+ * \brief V4L2Device object and API.
+ *
+ * The V4L2 Device API class models an instance of a v4l2 device node.
+ */
+
+/**
+ * \brief Constructor for a V4L2Device object. The \a device specifies the path
+ * to the video device node.
+ * \param device The file-system path to the video device node
+ */
+V4L2Device::V4L2Device(const std::string &device)
+{
+ device_ = device;
+ fd_ = -1;
+ caps_ = { };
+}
+
+V4L2Device::~V4L2Device()
+{
+ close();
+}
+
+/**
+ * \brief Opens a v4l2 device and queries properties from the device.
+ * \return 0 on success, or a negative errno
+ */
+int V4L2Device::open()
+{
+ int ret;
+
+ if (isOpen()) {
+ LOG(Error) << "Device already open";
+ return -EBUSY;
+ }
+
+ fd_ = ::open(device_.c_str(), O_RDWR);
+ if (fd_ < 0) {
+ LOG(Error) << "Failed to open V4L2 device " << device_
+ << " : " << strerror(errno);
+ return -errno;
+ }
+
+ ret = ioctl(fd_, VIDIOC_QUERYCAP, &caps_);
+ if (ret < 0) {
+ LOG(Error) << "Failed to query device capabilities: " << strerror(errno);
+ return -errno;
+ }
+
+ if (!(caps_.hasStreaming())) {
+ LOG(Error) << "Device does not support streaming IO";
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * \brief Checks to see if we have successfully opened a v4l2 video device.
+ */
+bool V4L2Device::isOpen() const
+{
+ return (fd_ != -1);
+}
+
+/**
+ * \brief Close the device, releasing any resources acquired by \a open().
+ */
+void V4L2Device::close()
+{
+ if (fd_ < 0)
+ return;
+
+ ::close(fd_);
+ fd_ = -1;
+}
+
+} /* namespace libcamera */
--
2.17.1
More information about the libcamera-devel
mailing list