From patchwork Tue Jan 15 16:02:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 242 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AB43660C87 for ; Tue, 15 Jan 2019 17:02:16 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2582D55C; Tue, 15 Jan 2019 17:02:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1547568136; bh=t4B78EX19LzPc5m017d2sAynJs8ktdwFz+pGjbGWmsE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nnq0d21F8y2zb+r5FuN0QLD1fD62BzX96tF+g8NSbG28FoWPOG0Y+9RCXxH8aYN5H fj3A7P6qgQURSF1hwRSFCBqRWkoGn7T85B3EE20+MGnM4zzs0KHpasixash66VhsRj lcJkbMhM6ajRe2m8iShhbhT6YNb5j23ytjChcm3Y= From: Kieran Bingham To: LibCamera Devel Date: Tue, 15 Jan 2019 16:02:11 +0000 Message-Id: <20190115160212.30100-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190115160212.30100-1-kieran.bingham@ideasonboard.com> References: <20190115160212.30100-1-kieran.bingham@ideasonboard.com> Subject: [libcamera-devel] [PATCH v2 1/2] lib: Add V4L2 Device object X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jan 2019 16:02:16 -0000 Provide a helper V4L2 device object capable of interacting with the V4L2 Linux Kernel APIs. Signed-off-by: Kieran Bingham --- 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 + +#include + +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 +#include +#include +#include +#include + +#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 */