From patchwork Thu Jun 13 07:49:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1422 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CCE1A61BE2 for ; Thu, 13 Jun 2019 09:48:50 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id CBF641BF207; Thu, 13 Jun 2019 07:48:49 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 13 Jun 2019 09:49:54 +0200 Message-Id: <20190613074955.14512-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190613074955.14512-1-jacopo@jmondi.org> References: <20190613074955.14512-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 1/2] libcamera: Rename V4L2Device to V4L2VideoDevice 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: Thu, 13 Jun 2019 07:48:51 -0000 In preparation of creating a new V4L2Device base class, rename V4L2Device to V4L2VideoDevice. This is a project wide rename without any intended functional change. Signed-off-by: Jacopo Mondi Signed-off-by: Kieran Bingham Reviewed-by: Kieran Bingham Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- include/libcamera/buffer.h | 2 +- .../{v4l2_device.h => v4l2_videodevice.h} | 24 ++--- src/libcamera/meson.build | 4 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 24 ++--- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 6 +- src/libcamera/pipeline/uvcvideo.cpp | 6 +- src/libcamera/pipeline/vimc.cpp | 6 +- src/libcamera/v4l2_subdevice.cpp | 2 +- .../{v4l2_device.cpp => v4l2_videodevice.cpp} | 101 +++++++++--------- test/meson.build | 2 +- .../buffer_sharing.cpp | 18 ++-- .../capture_async.cpp | 6 +- .../double_open.cpp | 8 +- .../formats.cpp | 8 +- .../meson.build | 8 +- .../request_buffers.cpp | 6 +- .../stream_on_off.cpp | 6 +- .../v4l2_videodevice_test.cpp} | 8 +- .../v4l2_videodevice_test.h} | 8 +- 19 files changed, 127 insertions(+), 126 deletions(-) rename src/libcamera/include/{v4l2_device.h => v4l2_videodevice.h} (86%) rename src/libcamera/{v4l2_device.cpp => v4l2_videodevice.cpp} (90%) rename test/{v4l2_device => v4l2_videodevice}/buffer_sharing.cpp (90%) rename test/{v4l2_device => v4l2_videodevice}/capture_async.cpp (91%) rename test/{v4l2_device => v4l2_videodevice}/double_open.cpp (75%) rename test/{v4l2_device => v4l2_videodevice}/formats.cpp (85%) rename test/{v4l2_device => v4l2_videodevice}/meson.build (74%) rename test/{v4l2_device => v4l2_videodevice}/request_buffers.cpp (77%) rename test/{v4l2_device => v4l2_videodevice}/stream_on_off.cpp (78%) rename test/{v4l2_device/v4l2_device_test.cpp => v4l2_videodevice/v4l2_videodevice_test.cpp} (90%) rename test/{v4l2_device/v4l2_device_test.h => v4l2_videodevice/v4l2_videodevice_test.h} (81%) diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h index 8f9b42e39339..260a62e9e77e 100644 --- a/include/libcamera/buffer.h +++ b/include/libcamera/buffer.h @@ -59,7 +59,7 @@ private: friend class BufferPool; friend class PipelineHandler; friend class Request; - friend class V4L2Device; + friend class V4L2VideoDevice; void cancel(); diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_videodevice.h similarity index 86% rename from src/libcamera/include/v4l2_device.h rename to src/libcamera/include/v4l2_videodevice.h index bdecc087fe5a..6ecdb64e5f3c 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_videodevice.h @@ -2,10 +2,10 @@ /* * Copyright (C) 2019, Google Inc. * - * v4l2_device.h - V4L2 Device + * v4l2_videodevice.h - V4L2 Video Device */ -#ifndef __LIBCAMERA_V4L2_DEVICE_H__ -#define __LIBCAMERA_V4L2_DEVICE_H__ +#ifndef __LIBCAMERA_V4L2_VIDEODEVICE_H__ +#define __LIBCAMERA_V4L2_VIDEODEVICE_H__ #include #include @@ -111,15 +111,15 @@ public: const std::string toString() const; }; -class V4L2Device : protected Loggable +class V4L2VideoDevice : protected Loggable { public: - explicit V4L2Device(const std::string &deviceNode); - explicit V4L2Device(const MediaEntity *entity); - V4L2Device(const V4L2Device &) = delete; - ~V4L2Device(); + explicit V4L2VideoDevice(const std::string &deviceNode); + explicit V4L2VideoDevice(const MediaEntity *entity); + V4L2VideoDevice(const V4L2VideoDevice &) = delete; + ~V4L2VideoDevice(); - V4L2Device &operator=(const V4L2Device &) = delete; + V4L2VideoDevice &operator=(const V4L2VideoDevice &) = delete; int open(); bool isOpen() const; @@ -143,8 +143,8 @@ public: int streamOn(); int streamOff(); - static V4L2Device *fromEntityName(const MediaDevice *media, - const std::string &entity); + static V4L2VideoDevice *fromEntityName(const MediaDevice *media, + const std::string &entity); protected: std::string logPrefix() const; @@ -181,4 +181,4 @@ private: } /* namespace libcamera */ -#endif /* __LIBCAMERA_V4L2_DEVICE_H__ */ +#endif /* __LIBCAMERA_V4L2_VIDEODEVICE_H__ */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 1ca1083cf5c7..15ab53b1abbe 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -23,8 +23,8 @@ libcamera_sources = files([ 'stream.cpp', 'timer.cpp', 'utils.cpp', - 'v4l2_device.cpp', 'v4l2_subdevice.cpp', + 'v4l2_videodevice.cpp', ]) libcamera_headers = files([ @@ -41,8 +41,8 @@ libcamera_headers = files([ 'include/media_object.h', 'include/pipeline_handler.h', 'include/utils.h', - 'include/v4l2_device.h', 'include/v4l2_subdevice.h', + 'include/v4l2_videodevice.h', ]) libcamera_internal_includes = include_directories('include') diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index f2bdecbac20f..1c0a9825b4cd 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -22,8 +22,8 @@ #include "media_device.h" #include "pipeline_handler.h" #include "utils.h" -#include "v4l2_device.h" #include "v4l2_subdevice.h" +#include "v4l2_videodevice.h" namespace libcamera { @@ -39,7 +39,7 @@ public: /* ImgU output descriptor: group data specific to an ImgU output. */ struct ImgUOutput { - V4L2Device *dev; + V4L2VideoDevice *dev; unsigned int pad; std::string name; BufferPool *pool; @@ -85,7 +85,7 @@ public: MediaDevice *media_; V4L2Subdevice *imgu_; - V4L2Device *input_; + V4L2VideoDevice *input_; ImgUOutput output_; ImgUOutput viewfinder_; ImgUOutput stat_; @@ -125,7 +125,7 @@ public: static int mediaBusToFormat(unsigned int code); - V4L2Device *output_; + V4L2VideoDevice *output_; V4L2Subdevice *csi2_; CameraSensor *sensor_; @@ -943,7 +943,7 @@ void IPU3CameraData::cio2BufferReady(Buffer *buffer) * Create and open the V4L2 devices and subdevices of the ImgU instance * with \a index. * - * In case of errors the created V4L2Device and V4L2Subdevice instances + * In case of errors the created V4L2VideoDevice and V4L2Subdevice instances * are destroyed at pipeline handler delete time. * * \return 0 on success or a negative error code otherwise @@ -966,12 +966,12 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index) if (ret) return ret; - input_ = V4L2Device::fromEntityName(media, name_ + " input"); + input_ = V4L2VideoDevice::fromEntityName(media, name_ + " input"); ret = input_->open(); if (ret) return ret; - output_.dev = V4L2Device::fromEntityName(media, name_ + " output"); + output_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " output"); ret = output_.dev->open(); if (ret) return ret; @@ -980,8 +980,8 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index) output_.name = "output"; output_.pool = &outPool_; - viewfinder_.dev = V4L2Device::fromEntityName(media, - name_ + " viewfinder"); + viewfinder_.dev = V4L2VideoDevice::fromEntityName(media, + name_ + " viewfinder"); ret = viewfinder_.dev->open(); if (ret) return ret; @@ -990,7 +990,7 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index) viewfinder_.name = "viewfinder"; viewfinder_.pool = &vfPool_; - stat_.dev = V4L2Device::fromEntityName(media, name_ + " 3a stat"); + stat_.dev = V4L2VideoDevice::fromEntityName(media, name_ + " 3a stat"); ret = stat_.dev->open(); if (ret) return ret; @@ -1067,7 +1067,7 @@ int ImgUDevice::configureInput(const Size &size, int ImgUDevice::configureOutput(ImgUOutput *output, const StreamConfiguration &cfg) { - V4L2Device *dev = output->dev; + V4L2VideoDevice *dev = output->dev; unsigned int pad = output->pad; V4L2SubdeviceFormat imguFormat = {}; @@ -1337,7 +1337,7 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index) return ret; std::string cio2Name = "ipu3-cio2 " + std::to_string(index); - output_ = V4L2Device::fromEntityName(media, cio2Name); + output_ = V4L2VideoDevice::fromEntityName(media, cio2Name); ret = output_->open(); if (ret) return ret; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 9b3eea2f6dd3..4a5898d25f91 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -23,8 +23,8 @@ #include "media_device.h" #include "pipeline_handler.h" #include "utils.h" -#include "v4l2_device.h" #include "v4l2_subdevice.h" +#include "v4l2_videodevice.h" namespace libcamera { @@ -106,7 +106,7 @@ private: MediaDevice *media_; V4L2Subdevice *dphy_; V4L2Subdevice *isp_; - V4L2Device *video_; + V4L2VideoDevice *video_; Camera *activeCamera_; }; @@ -458,7 +458,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) return false; /* Locate and open the capture video node. */ - video_ = V4L2Device::fromEntityName(media_, "rkisp1_mainpath"); + video_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_mainpath"); if (video_->open() < 0) return false; diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 45260f34c8f5..b0d768628a19 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -14,7 +14,7 @@ #include "media_device.h" #include "pipeline_handler.h" #include "utils.h" -#include "v4l2_device.h" +#include "v4l2_videodevice.h" namespace libcamera { @@ -35,7 +35,7 @@ public: void bufferReady(Buffer *buffer); - V4L2Device *video_; + V4L2VideoDevice *video_; Stream stream_; }; @@ -229,7 +229,7 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) /* Locate and open the default video node. */ for (MediaEntity *entity : media->entities()) { if (entity->flags() & MEDIA_ENT_FL_DEFAULT) { - data->video_ = new V4L2Device(entity); + data->video_ = new V4L2VideoDevice(entity); break; } } diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index ad4577acd9d6..6833213650dc 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -20,7 +20,7 @@ #include "media_device.h" #include "pipeline_handler.h" #include "utils.h" -#include "v4l2_device.h" +#include "v4l2_videodevice.h" namespace libcamera { @@ -41,7 +41,7 @@ public: void bufferReady(Buffer *buffer); - V4L2Device *video_; + V4L2VideoDevice *video_; Stream stream_; }; @@ -262,7 +262,7 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator) std::unique_ptr data = utils::make_unique(this); /* Locate and open the capture video node. */ - data->video_ = new V4L2Device(media->getEntityByName("Raw Capture 1")); + data->video_ = new V4L2VideoDevice(media->getEntityByName("Raw Capture 1")); if (data->video_->open()) return false; diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index fceee33156e9..6681c1920065 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -44,7 +44,7 @@ LOG_DEFINE_CATEGORY(V4L2Subdev) * as the "media bus format", and it is identified by a resolution and a pixel * format identification code, known as the "media bus code", not to be confused * with the fourcc code that identify the format of images when stored in memory - * (see V4L2Device::V4L2DeviceFormat). + * (see V4L2VideoDevice::V4L2DeviceFormat). * * Media Bus formats supported by the V4L2 APIs are described in Section * 4.15.3.4.1 of the "Part I - Video for Linux API" chapter of the "Linux Media diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_videodevice.cpp similarity index 90% rename from src/libcamera/v4l2_device.cpp rename to src/libcamera/v4l2_videodevice.cpp index 0821bd75fb42..8957cf8f97d3 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -2,10 +2,10 @@ /* * Copyright (C) 2019, Google Inc. * - * v4l2_device.cpp - V4L2 Device + * v4l2_videodevice.cpp - V4L2 Video Device */ -#include "v4l2_device.h" +#include "v4l2_videodevice.h" #include #include @@ -25,8 +25,8 @@ #include "media_object.h" /** - * \file v4l2_device.h - * \brief V4L2 Device API + * \file v4l2_videodevice.h + * \brief V4L2 Video Device API */ namespace libcamera { @@ -243,8 +243,8 @@ const std::string V4L2DeviceFormat::toString() const } /** - * \class V4L2Device - * \brief V4L2Device object and API + * \class V4L2VideoDevice + * \brief V4L2VideoDevice 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 @@ -257,7 +257,7 @@ const std::string V4L2DeviceFormat::toString() const * No API call other than open(), isOpen() and close() shall be called on an * unopened device instance. * - * The V4L2Device class tracks queued buffers and handles buffer events. It + * The V4L2VideoDevice class tracks queued buffers and handles buffer events. It * automatically dequeues completed buffers and emits the \ref bufferReady * signal. * @@ -266,10 +266,10 @@ const std::string V4L2DeviceFormat::toString() const */ /** - * \brief Construct a V4L2Device + * \brief Construct a V4L2VideoDevice * \param[in] deviceNode The file-system path to the video device node */ -V4L2Device::V4L2Device(const std::string &deviceNode) +V4L2VideoDevice::V4L2VideoDevice(const std::string &deviceNode) : deviceNode_(deviceNode), fd_(-1), bufferPool_(nullptr), queuedBuffersCount_(0), fdEvent_(nullptr) { @@ -282,17 +282,17 @@ V4L2Device::V4L2Device(const std::string &deviceNode) } /** - * \brief Construct a V4L2Device from a MediaEntity + * \brief Construct a V4L2VideoDevice from a MediaEntity * \param[in] entity The MediaEntity to build the device from * - * Construct a V4L2Device from a MediaEntity's device node path. + * Construct a V4L2VideoDevice from a MediaEntity's device node path. */ -V4L2Device::V4L2Device(const MediaEntity *entity) - : V4L2Device(entity->deviceNode()) +V4L2VideoDevice::V4L2VideoDevice(const MediaEntity *entity) + : V4L2VideoDevice(entity->deviceNode()) { } -V4L2Device::~V4L2Device() +V4L2VideoDevice::~V4L2VideoDevice() { close(); } @@ -301,7 +301,7 @@ V4L2Device::~V4L2Device() * \brief Open a V4L2 device and query its capabilities * \return 0 on success or a negative error code otherwise */ -int V4L2Device::open() +int V4L2VideoDevice::open() { int ret; @@ -362,7 +362,7 @@ int V4L2Device::open() return -EINVAL; } - fdEvent_->activated.connect(this, &V4L2Device::bufferAvailable); + fdEvent_->activated.connect(this, &V4L2VideoDevice::bufferAvailable); fdEvent_->setEnabled(false); return 0; @@ -372,7 +372,7 @@ int V4L2Device::open() * \brief Check if device is successfully opened * \return True if the device is open, false otherwise */ -bool V4L2Device::isOpen() const +bool V4L2VideoDevice::isOpen() const { return fd_ != -1; } @@ -380,7 +380,7 @@ bool V4L2Device::isOpen() const /** * \brief Close the device, releasing any resources acquired by open() */ -void V4L2Device::close() +void V4L2VideoDevice::close() { if (fd_ < 0) return; @@ -393,30 +393,30 @@ void V4L2Device::close() } /** - * \fn V4L2Device::driverName() + * \fn V4L2VideoDevice::driverName() * \brief Retrieve the name of the V4L2 device driver * \return The string containing the driver name */ /** - * \fn V4L2Device::deviceName() + * \fn V4L2VideoDevice::deviceName() * \brief Retrieve the name of the V4L2 device * \return The string containing the device name */ /** - * \fn V4L2Device::busName() + * \fn V4L2VideoDevice::busName() * \brief Retrieve the location of the device in the system * \return The string containing the device location */ /** - * \fn V4L2Device::deviceNode() + * \fn V4L2VideoDevice::deviceNode() * \brief Retrieve the video device node path * \return The video device device node path */ -std::string V4L2Device::logPrefix() const +std::string V4L2VideoDevice::logPrefix() const { return deviceNode_ + (V4L2_TYPE_IS_OUTPUT(bufferType_) ? "[out]" : "[cap]"); } @@ -426,7 +426,7 @@ std::string V4L2Device::logPrefix() const * \param[out] format The image format applied on the device * \return 0 on success or a negative error code otherwise */ -int V4L2Device::getFormat(V4L2DeviceFormat *format) +int V4L2VideoDevice::getFormat(V4L2DeviceFormat *format) { if (caps_.isMeta()) return getFormatMeta(format); @@ -441,11 +441,11 @@ int V4L2Device::getFormat(V4L2DeviceFormat *format) * \param[inout] format The image format to apply to the device * * Apply the supplied \a format to the device, and return the actually - * applied format parameters, as \ref V4L2Device::getFormat would do. + * applied format parameters, as \ref V4L2VideoDevice::getFormat would do. * * \return 0 on success or a negative error code otherwise */ -int V4L2Device::setFormat(V4L2DeviceFormat *format) +int V4L2VideoDevice::setFormat(V4L2DeviceFormat *format) { if (caps_.isMeta()) return setFormatMeta(format); @@ -455,7 +455,7 @@ int V4L2Device::setFormat(V4L2DeviceFormat *format) return setFormatSingleplane(format); } -int V4L2Device::getFormatMeta(V4L2DeviceFormat *format) +int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format) { struct v4l2_format v4l2Format = {}; struct v4l2_meta_format *pix = &v4l2Format.fmt.meta; @@ -479,7 +479,7 @@ int V4L2Device::getFormatMeta(V4L2DeviceFormat *format) return 0; } -int V4L2Device::setFormatMeta(V4L2DeviceFormat *format) +int V4L2VideoDevice::setFormatMeta(V4L2DeviceFormat *format) { struct v4l2_format v4l2Format = {}; struct v4l2_meta_format *pix = &v4l2Format.fmt.meta; @@ -509,7 +509,7 @@ int V4L2Device::setFormatMeta(V4L2DeviceFormat *format) return 0; } -int V4L2Device::getFormatMultiplane(V4L2DeviceFormat *format) +int V4L2VideoDevice::getFormatMultiplane(V4L2DeviceFormat *format) { struct v4l2_format v4l2Format = {}; struct v4l2_pix_format_mplane *pix = &v4l2Format.fmt.pix_mp; @@ -536,7 +536,7 @@ int V4L2Device::getFormatMultiplane(V4L2DeviceFormat *format) return 0; } -int V4L2Device::setFormatMultiplane(V4L2DeviceFormat *format) +int V4L2VideoDevice::setFormatMultiplane(V4L2DeviceFormat *format) { struct v4l2_format v4l2Format = {}; struct v4l2_pix_format_mplane *pix = &v4l2Format.fmt.pix_mp; @@ -577,7 +577,7 @@ int V4L2Device::setFormatMultiplane(V4L2DeviceFormat *format) return 0; } -int V4L2Device::getFormatSingleplane(V4L2DeviceFormat *format) +int V4L2VideoDevice::getFormatSingleplane(V4L2DeviceFormat *format) { struct v4l2_format v4l2Format = {}; struct v4l2_pix_format *pix = &v4l2Format.fmt.pix; @@ -601,7 +601,7 @@ int V4L2Device::getFormatSingleplane(V4L2DeviceFormat *format) return 0; } -int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *format) +int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format) { struct v4l2_format v4l2Format = {}; struct v4l2_pix_format *pix = &v4l2Format.fmt.pix; @@ -634,7 +634,7 @@ int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *format) return 0; } -int V4L2Device::requestBuffers(unsigned int count) +int V4L2VideoDevice::requestBuffers(unsigned int count) { struct v4l2_requestbuffers rb = {}; int ret; @@ -663,7 +663,7 @@ int V4L2Device::requestBuffers(unsigned int count) * \param[out] pool BufferPool to populate with buffers * \return 0 on success or a negative error code otherwise */ -int V4L2Device::exportBuffers(BufferPool *pool) +int V4L2VideoDevice::exportBuffers(BufferPool *pool) { unsigned int allocatedBuffers; unsigned int i; @@ -677,7 +677,8 @@ int V4L2Device::exportBuffers(BufferPool *pool) allocatedBuffers = ret; if (allocatedBuffers < pool->count()) { - LOG(V4L2, Error) << "Not enough buffers provided by V4L2Device"; + LOG(V4L2, Error) + << "Not enough buffers provided by V4L2VideoDevice"; requestBuffers(0); return -ENOMEM; } @@ -731,8 +732,8 @@ int V4L2Device::exportBuffers(BufferPool *pool) return 0; } -int V4L2Device::createPlane(Buffer *buffer, unsigned int planeIndex, - unsigned int length) +int V4L2VideoDevice::createPlane(Buffer *buffer, unsigned int planeIndex, + unsigned int length) { struct v4l2_exportbuffer expbuf = {}; int ret; @@ -768,7 +769,7 @@ int V4L2Device::createPlane(Buffer *buffer, unsigned int planeIndex, * \param[in] pool BufferPool of buffers to import * \return 0 on success or a negative error code otherwise */ -int V4L2Device::importBuffers(BufferPool *pool) +int V4L2VideoDevice::importBuffers(BufferPool *pool) { unsigned int allocatedBuffers; int ret; @@ -782,7 +783,7 @@ int V4L2Device::importBuffers(BufferPool *pool) allocatedBuffers = ret; if (allocatedBuffers < pool->count()) { LOG(V4L2, Error) - << "Not enough buffers provided by V4L2Device"; + << "Not enough buffers provided by V4L2VideoDevice"; requestBuffers(0); return -ENOMEM; } @@ -796,7 +797,7 @@ int V4L2Device::importBuffers(BufferPool *pool) /** * \brief Release all internally allocated buffers */ -int V4L2Device::releaseBuffers() +int V4L2VideoDevice::releaseBuffers() { LOG(V4L2, Debug) << "Releasing bufferPool"; @@ -816,7 +817,7 @@ int V4L2Device::releaseBuffers() * * \return 0 on success or a negative error code otherwise */ -int V4L2Device::queueBuffer(Buffer *buffer) +int V4L2VideoDevice::queueBuffer(Buffer *buffer) { struct v4l2_buffer buf = {}; struct v4l2_plane planes[VIDEO_MAX_PLANES] = {}; @@ -877,7 +878,7 @@ int V4L2Device::queueBuffer(Buffer *buffer) * * \return A pointer to the dequeued buffer on success, or nullptr otherwise */ -Buffer *V4L2Device::dequeueBuffer() +Buffer *V4L2VideoDevice::dequeueBuffer() { struct v4l2_buffer buf = {}; struct v4l2_plane planes[VIDEO_MAX_PLANES] = {}; @@ -926,7 +927,7 @@ Buffer *V4L2Device::dequeueBuffer() * For Capture devices the Buffer will contain valid data. * For Output devices the Buffer can be considered empty. */ -void V4L2Device::bufferAvailable(EventNotifier *notifier) +void V4L2VideoDevice::bufferAvailable(EventNotifier *notifier) { Buffer *buffer = dequeueBuffer(); if (!buffer) @@ -939,7 +940,7 @@ void V4L2Device::bufferAvailable(EventNotifier *notifier) } /** - * \var V4L2Device::bufferReady + * \var V4L2VideoDevice::bufferReady * \brief A Signal emitted when a buffer completes */ @@ -947,7 +948,7 @@ void V4L2Device::bufferAvailable(EventNotifier *notifier) * \brief Start the video stream * \return 0 on success or a negative error code otherwise */ -int V4L2Device::streamOn() +int V4L2VideoDevice::streamOn() { int ret; @@ -970,7 +971,7 @@ int V4L2Device::streamOn() * * \return 0 on success or a negative error code otherwise */ -int V4L2Device::streamOff() +int V4L2VideoDevice::streamOff() { int ret; @@ -997,16 +998,16 @@ int V4L2Device::streamOff() * Releasing memory of the newly created instance is responsibility of the * caller of this function. * - * \return A newly created V4L2Device on success, nullptr otherwise + * \return A newly created V4L2VideoDevice on success, nullptr otherwise */ -V4L2Device *V4L2Device::fromEntityName(const MediaDevice *media, - const std::string &entity) +V4L2VideoDevice *V4L2VideoDevice::fromEntityName(const MediaDevice *media, + const std::string &entity) { MediaEntity *mediaEntity = media->getEntityByName(entity); if (!mediaEntity) return nullptr; - return new V4L2Device(mediaEntity); + return new V4L2VideoDevice(mediaEntity); } } /* namespace libcamera */ diff --git a/test/meson.build b/test/meson.build index 609aeab80e7d..82b29d8dc7eb 100644 --- a/test/meson.build +++ b/test/meson.build @@ -4,8 +4,8 @@ subdir('camera') subdir('ipa') subdir('media_device') subdir('pipeline') -subdir('v4l2_device') subdir('v4l2_subdevice') +subdir('v4l2_videodevice') public_tests = [ ['event', 'event.cpp'], diff --git a/test/v4l2_device/buffer_sharing.cpp b/test/v4l2_videodevice/buffer_sharing.cpp similarity index 90% rename from test/v4l2_device/buffer_sharing.cpp rename to test/v4l2_videodevice/buffer_sharing.cpp index e63ddff85689..1bc478fe8f8e 100644 --- a/test/v4l2_device/buffer_sharing.cpp +++ b/test/v4l2_videodevice/buffer_sharing.cpp @@ -4,8 +4,8 @@ * * libcamera V4L2 API tests * - * Validate the function of exporting buffers from a V4L2Device and - * the ability to import them to another V4L2Device instance. + * Validate the function of exporting buffers from a V4L2VideoDevice and + * the ability to import them to another V4L2VideoDevice instance. * Ensure that the Buffers can successfully be queued and dequeued * between both devices. */ @@ -17,19 +17,19 @@ #include #include -#include "v4l2_device_test.h" +#include "v4l2_videodevice_test.h" -class BufferSharingTest : public V4L2DeviceTest +class BufferSharingTest : public V4L2VideoDeviceTest { public: BufferSharingTest() - : V4L2DeviceTest("vivid", "vivid-000-vid-cap"), + : V4L2VideoDeviceTest("vivid", "vivid-000-vid-cap"), output_(nullptr), framesCaptured_(0), framesOutput_(0) {} protected: int init() { - int ret = V4L2DeviceTest::init(); + int ret = V4L2VideoDeviceTest::init(); if (ret) return ret; @@ -38,7 +38,7 @@ protected: if (!entity) return TestSkip; - output_ = new V4L2Device(entity); + output_ = new V4L2VideoDevice(entity); if (!output_) { std::cout << "Failed to create output device" << std::endl; return TestFail; @@ -171,13 +171,13 @@ protected: delete output_; - V4L2DeviceTest::cleanup(); + V4L2VideoDeviceTest::cleanup(); } private: const unsigned int bufferCount = 4; - V4L2Device *output_; + V4L2VideoDevice *output_; unsigned int framesCaptured_; unsigned int framesOutput_; diff --git a/test/v4l2_device/capture_async.cpp b/test/v4l2_videodevice/capture_async.cpp similarity index 91% rename from test/v4l2_device/capture_async.cpp rename to test/v4l2_videodevice/capture_async.cpp index 69b1d5a13ed8..cea4fffbf7a5 100644 --- a/test/v4l2_device/capture_async.cpp +++ b/test/v4l2_videodevice/capture_async.cpp @@ -12,13 +12,13 @@ #include -#include "v4l2_device_test.h" +#include "v4l2_videodevice_test.h" -class CaptureAsyncTest : public V4L2DeviceTest +class CaptureAsyncTest : public V4L2VideoDeviceTest { public: CaptureAsyncTest() - : V4L2DeviceTest("vimc", "Raw Capture 0"), frames(0) {} + : V4L2VideoDeviceTest("vimc", "Raw Capture 0"), frames(0) {} void receiveBuffer(Buffer *buffer) { diff --git a/test/v4l2_device/double_open.cpp b/test/v4l2_videodevice/double_open.cpp similarity index 75% rename from test/v4l2_device/double_open.cpp rename to test/v4l2_videodevice/double_open.cpp index 53850620889b..5768d4043d0b 100644 --- a/test/v4l2_device/double_open.cpp +++ b/test/v4l2_videodevice/double_open.cpp @@ -7,15 +7,15 @@ #include -#include "v4l2_device_test.h" +#include "v4l2_videodevice_test.h" namespace { -class DoubleOpen : public V4L2DeviceTest +class DoubleOpen : public V4L2VideoDeviceTest { public: DoubleOpen() - : V4L2DeviceTest("vimc", "Raw Capture 0") {} + : V4L2VideoDeviceTest("vimc", "Raw Capture 0") {} protected: int run() { @@ -23,7 +23,7 @@ protected: /* * Expect failure: The device has already been opened by the - * V4L2DeviceTest base class + * V4L2VideoDeviceTest base class */ ret = capture_->open(); if (!ret) { diff --git a/test/v4l2_device/formats.cpp b/test/v4l2_videodevice/formats.cpp similarity index 85% rename from test/v4l2_device/formats.cpp rename to test/v4l2_videodevice/formats.cpp index 6be045ff754c..ee7d357de075 100644 --- a/test/v4l2_device/formats.cpp +++ b/test/v4l2_videodevice/formats.cpp @@ -8,18 +8,18 @@ #include #include -#include "v4l2_device.h" +#include "v4l2_videodevice.h" -#include "v4l2_device_test.h" +#include "v4l2_videodevice_test.h" using namespace std; using namespace libcamera; -class Format : public V4L2DeviceTest +class Format : public V4L2VideoDeviceTest { public: Format() - : V4L2DeviceTest("vimc", "Raw Capture 0") {} + : V4L2VideoDeviceTest("vimc", "Raw Capture 0") {} protected: int run() { diff --git a/test/v4l2_device/meson.build b/test/v4l2_videodevice/meson.build similarity index 74% rename from test/v4l2_device/meson.build rename to test/v4l2_videodevice/meson.build index de540b1ba6f5..76be5e142bb6 100644 --- a/test/v4l2_device/meson.build +++ b/test/v4l2_videodevice/meson.build @@ -1,6 +1,6 @@ # Tests are listed in order of complexity. # They are not alphabetically sorted. -v4l2_device_tests = [ +v4l2_videodevice_tests = [ [ 'double_open', 'double_open.cpp' ], [ 'formats', 'formats.cpp' ], [ 'request_buffers', 'request_buffers.cpp' ], @@ -9,10 +9,10 @@ v4l2_device_tests = [ [ 'buffer_sharing', 'buffer_sharing.cpp' ], ] -foreach t : v4l2_device_tests - exe = executable(t[0], [t[1], 'v4l2_device_test.cpp'], +foreach t : v4l2_videodevice_tests + exe = executable(t[0], [t[1], 'v4l2_videodevice_test.cpp'], dependencies : libcamera_dep, link_with : test_libraries, include_directories : test_includes_internal) - test(t[0], exe, suite : 'v4l2_device', is_parallel : false) + test(t[0], exe, suite : 'v4l2_videodevice', is_parallel : false) endforeach diff --git a/test/v4l2_device/request_buffers.cpp b/test/v4l2_videodevice/request_buffers.cpp similarity index 77% rename from test/v4l2_device/request_buffers.cpp rename to test/v4l2_videodevice/request_buffers.cpp index 7b7b06b2b409..c4aedf7b3cd6 100644 --- a/test/v4l2_device/request_buffers.cpp +++ b/test/v4l2_videodevice/request_buffers.cpp @@ -5,13 +5,13 @@ * libcamera V4L2 API tests */ -#include "v4l2_device_test.h" +#include "v4l2_videodevice_test.h" -class RequestBuffersTest : public V4L2DeviceTest +class RequestBuffersTest : public V4L2VideoDeviceTest { public: RequestBuffersTest() - : V4L2DeviceTest("vimc", "Raw Capture 0") {} + : V4L2VideoDeviceTest("vimc", "Raw Capture 0") {} protected: int run() diff --git a/test/v4l2_device/stream_on_off.cpp b/test/v4l2_videodevice/stream_on_off.cpp similarity index 78% rename from test/v4l2_device/stream_on_off.cpp rename to test/v4l2_videodevice/stream_on_off.cpp index b158b8e402c8..7664adc4c1f0 100644 --- a/test/v4l2_device/stream_on_off.cpp +++ b/test/v4l2_videodevice/stream_on_off.cpp @@ -5,13 +5,13 @@ * libcamera V4L2 API tests */ -#include "v4l2_device_test.h" +#include "v4l2_videodevice_test.h" -class StreamOnStreamOffTest : public V4L2DeviceTest +class StreamOnStreamOffTest : public V4L2VideoDeviceTest { public: StreamOnStreamOffTest() - : V4L2DeviceTest("vimc", "Raw Capture 0") {} + : V4L2VideoDeviceTest("vimc", "Raw Capture 0") {} protected: int run() { diff --git a/test/v4l2_device/v4l2_device_test.cpp b/test/v4l2_videodevice/v4l2_videodevice_test.cpp similarity index 90% rename from test/v4l2_device/v4l2_device_test.cpp rename to test/v4l2_videodevice/v4l2_videodevice_test.cpp index baad48f8aa9e..b26d06ad4519 100644 --- a/test/v4l2_device/v4l2_device_test.cpp +++ b/test/v4l2_videodevice/v4l2_videodevice_test.cpp @@ -8,7 +8,7 @@ #include #include -#include "v4l2_device_test.h" +#include "v4l2_videodevice_test.h" #include "device_enumerator.h" #include "media_device.h" @@ -26,7 +26,7 @@ bool exists(const std::string &path) return false; } -int V4L2DeviceTest::init() +int V4L2VideoDeviceTest::init() { enumerator_ = DeviceEnumerator::create(); if (!enumerator_) { @@ -50,7 +50,7 @@ int V4L2DeviceTest::init() if (!entity) return TestSkip; - capture_ = new V4L2Device(entity); + capture_ = new V4L2VideoDevice(entity); if (!capture_) return TestFail; @@ -77,7 +77,7 @@ int V4L2DeviceTest::init() return TestPass; } -void V4L2DeviceTest::cleanup() +void V4L2VideoDeviceTest::cleanup() { capture_->streamOff(); capture_->releaseBuffers(); diff --git a/test/v4l2_device/v4l2_device_test.h b/test/v4l2_videodevice/v4l2_videodevice_test.h similarity index 81% rename from test/v4l2_device/v4l2_device_test.h rename to test/v4l2_videodevice/v4l2_videodevice_test.h index 651c005f4e54..3321b5a4f98f 100644 --- a/test/v4l2_device/v4l2_device_test.h +++ b/test/v4l2_videodevice/v4l2_videodevice_test.h @@ -15,14 +15,14 @@ #include "device_enumerator.h" #include "media_device.h" -#include "v4l2_device.h" +#include "v4l2_videodevice.h" using namespace libcamera; -class V4L2DeviceTest : public Test +class V4L2VideoDeviceTest : public Test { public: - V4L2DeviceTest(const char *driver, const char *entity) + V4L2VideoDeviceTest(const char *driver, const char *entity) : driver_(driver), entity_(entity), capture_(nullptr) { } @@ -35,7 +35,7 @@ protected: std::string entity_; std::unique_ptr enumerator_; std::shared_ptr media_; - V4L2Device *capture_; + V4L2VideoDevice *capture_; BufferPool pool_; }; From patchwork Thu Jun 13 07:49:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1423 Return-Path: Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C5E8E61BE2 for ; Thu, 13 Jun 2019 09:48:51 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 00D2B1BF203; Thu, 13 Jun 2019 07:48:50 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 13 Jun 2019 09:49:55 +0200 Message-Id: <20190613074955.14512-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190613074955.14512-1-jacopo@jmondi.org> References: <20190613074955.14512-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 2/2] libcamera: Introduce V4L2Device base class 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: Thu, 13 Jun 2019 07:48:52 -0000 The V4L2 devices and subdevices share a few common operations,like opening and closing a device node, and perform IOCTLs on the device. With the forthcoming introduction of support for V4L2 controls, the quantity of shared code will drastically increase, as the control implementation is identical for the two. To maximize code re-use and avoid duplications, provide a V4L2Device base class which groups the common operations and members. The newly introduced base class provides methods to open/close a device node, access the file descriptor, and perform IOCTLs on the device. Signed-off-by: Jacopo Mondi Signed-off-by: Kieran Bingham Reviewed-by: Kieran Bingham --- src/libcamera/include/v4l2_device.h | 36 +++++++ src/libcamera/include/v4l2_subdevice.h | 6 +- src/libcamera/include/v4l2_videodevice.h | 5 +- src/libcamera/meson.build | 2 + src/libcamera/v4l2_device.cpp | 131 +++++++++++++++++++++++ src/libcamera/v4l2_subdevice.cpp | 69 +++--------- src/libcamera/v4l2_videodevice.cpp | 84 +++++---------- 7 files changed, 212 insertions(+), 121 deletions(-) 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..a73e1b600500 --- /dev/null +++ b/src/libcamera/include/v4l2_device.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * v4l2_device.h - Common base for V4L2 video devices and subdevices + */ +#ifndef __LIBCAMERA_V4L2_DEVICE_H__ +#define __LIBCAMERA_V4L2_DEVICE_H__ + +#include + +namespace libcamera { + +class V4L2Device +{ +public: + virtual ~V4L2Device() { close(); } + +protected: + V4L2Device(); + + int fd() { return fd_; } + + int open(const std::string &pathname, unsigned int flags); + void close(); + bool isOpen() const; + + int ioctl(unsigned long request, void *argp); + +private: + int fd_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_V4L2_DEVICE_H__ */ diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index 3e4e5107aebe..a34b719f8c52 100644 --- a/src/libcamera/include/v4l2_subdevice.h +++ b/src/libcamera/include/v4l2_subdevice.h @@ -16,6 +16,7 @@ #include "formats.h" #include "log.h" #include "media_object.h" +#include "v4l2_device.h" namespace libcamera { @@ -28,7 +29,7 @@ struct V4L2SubdeviceFormat { const std::string toString() const; }; -class V4L2Subdevice : protected Loggable +class V4L2Subdevice : public V4L2Device, protected Loggable { public: explicit V4L2Subdevice(const MediaEntity *entity); @@ -37,8 +38,6 @@ public: ~V4L2Subdevice(); int open(); - bool isOpen() const; - void close(); const MediaEntity *entity() const { return entity_; } @@ -64,7 +63,6 @@ private: Rectangle *rect); const MediaEntity *entity_; - int fd_; }; } /* namespace libcamera */ diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h index 6ecdb64e5f3c..15a83635b9bf 100644 --- a/src/libcamera/include/v4l2_videodevice.h +++ b/src/libcamera/include/v4l2_videodevice.h @@ -17,6 +17,7 @@ #include #include "log.h" +#include "v4l2_device.h" namespace libcamera { @@ -111,7 +112,7 @@ public: const std::string toString() const; }; -class V4L2VideoDevice : protected Loggable +class V4L2VideoDevice : public V4L2Device, protected Loggable { public: explicit V4L2VideoDevice(const std::string &deviceNode); @@ -122,7 +123,6 @@ public: V4L2VideoDevice &operator=(const V4L2VideoDevice &) = delete; int open(); - bool isOpen() const; void close(); const char *driverName() const { return caps_.driver(); } @@ -167,7 +167,6 @@ private: void bufferAvailable(EventNotifier *notifier); std::string deviceNode_; - int fd_; V4L2Capability caps_; enum v4l2_buf_type bufferType_; diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 15ab53b1abbe..f26ad5b2dc57 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -23,6 +23,7 @@ libcamera_sources = files([ 'stream.cpp', 'timer.cpp', 'utils.cpp', + 'v4l2_device.cpp', 'v4l2_subdevice.cpp', 'v4l2_videodevice.cpp', ]) @@ -41,6 +42,7 @@ libcamera_headers = files([ 'include/media_object.h', 'include/pipeline_handler.h', 'include/utils.h', + 'include/v4l2_device.h', 'include/v4l2_subdevice.h', 'include/v4l2_videodevice.h', ]) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp new file mode 100644 index 000000000000..6cbfc212a725 --- /dev/null +++ b/src/libcamera/v4l2_device.cpp @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * v4l2_device.cpp - Common base for V4L2 video devices and subdevices + */ + +#include "v4l2_device.h" + +#include +#include +#include +#include + +#include "log.h" + +/** + * \file v4l2_device.h + * \brief Common base for V4L2 devices and subdevices + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(V4L2) + +/** + * \class V4L2Device + * \brief Base class for V4L2Videodev and V4L2Subdev + * + * The V4L2Device class groups together the methods and fields common to + * both V4L2Videodev and V4L2Subdev, and provide a base class which + * provides methods to open and close the device node associated with the + * device and to perform IOCTL system calls on it. + * + * The V4L2Device class cannot be instantiated directly, as its constructor + * is protected. Users should use instead one the derived classes to model + * either a V4L2 video device or a V4L2 subdevice. + */ + +/** + * \brief Construct a V4L2Device + * + * The V4L2Device constructor is protected and can only be accessed by the + * V4L2Videodev and V4L2Subdev derived classes. + * + * Initialize the file descriptor to -1. + */ +V4L2Device::V4L2Device() + : fd_(-1) +{ +} + +/** + * \fn V4L2Device::fd() + * \brief Retrieve the V4L2 device file descriptor + * \return The V4L2 device file descriptor, -1 if the device node is not open + */ + +/** + * \brief Open a V4L2 device node + * \param pathname The filesystem path of the device node to open + * \param flags Access mode flags + * + * Initialize the file descriptor, which was initially set to -1. + * + * \return 0 on success or a negative error code otherwise + */ +int V4L2Device::open(const std::string &pathname, unsigned int flags) +{ + if (isOpen()) { + LOG(V4L2, Error) << "Device already open"; + return -EBUSY; + } + + int ret = ::open(pathname.c_str(), flags); + if (ret < 0) { + ret = -errno; + LOG(V4L2, Error) << "Failed to open V4L2 device: " + << strerror(-ret); + return ret; + } + + fd_ = ret; + + return 0; +} + +/** + * \brief Close the device node + * + * Reset the file descriptor to -1 + */ +void V4L2Device::close() +{ + if (fd_ < 0) + return; + + if (::close(fd_) < 0) + LOG(V4L2, Error) << "Failed to close V4L2 device: " + << strerror(errno); + fd_ = -1; +} + +/** + * \brief Check if the V4L2 device node is open + * \return True if the V4L2 device node is open, false otherwise + */ +bool V4L2Device::isOpen() const +{ + return fd_ != -1; +} + +/** + * \brief Perform an IOCTL system call on the device node + * \param request The IOCTL request code + * \param argp A pointer to the IOCTL argument + * \return 0 on success or a negative error code otherwise + */ +int V4L2Device::ioctl(unsigned long request, void *argp) +{ + /* + * Printing out an error message is usually better performed + * in the caller, which can provide more context. + */ + if (::ioctl(fd_, request, argp) < 0) + return -errno; + + return 0; +} + +} /* namespace libcamera */ diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 6681c1920065..52244d2ac3e1 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -29,7 +29,7 @@ namespace libcamera { -LOG_DEFINE_CATEGORY(V4L2Subdev) +LOG_DECLARE_CATEGORY(V4L2) /** * \struct V4L2SubdeviceFormat @@ -102,7 +102,7 @@ const std::string V4L2SubdeviceFormat::toString() const * path */ V4L2Subdevice::V4L2Subdevice(const MediaEntity *entity) - : entity_(entity), fd_(-1) + : V4L2Device(), entity_(entity) { } @@ -117,45 +117,7 @@ V4L2Subdevice::~V4L2Subdevice() */ int V4L2Subdevice::open() { - int ret; - - if (isOpen()) { - LOG(V4L2Subdev, Error) << "Device already open"; - return -EBUSY; - } - - ret = ::open(entity_->deviceNode().c_str(), O_RDWR); - if (ret < 0) { - ret = -errno; - LOG(V4L2Subdev, Error) - << "Failed to open V4L2 subdevice '" - << entity_->deviceNode() << "': " << strerror(-ret); - return ret; - } - fd_ = ret; - - return 0; -} - -/** - * \brief Check if the subdevice is open - * \return True if the subdevice is open, false otherwise - */ -bool V4L2Subdevice::isOpen() const -{ - return fd_ != -1; -} - -/** - * \brief Close the subdevice, releasing any resources acquired by open() - */ -void V4L2Subdevice::close() -{ - if (!isOpen()) - return; - - ::close(fd_); - fd_ = -1; + return V4L2Device::open(entity_->deviceNode(), O_RDWR); } /** @@ -207,7 +169,7 @@ FormatEnum V4L2Subdevice::formats(unsigned int pad) int ret; if (pad >= entity_->pads().size()) { - LOG(V4L2Subdev, Error) << "Invalid pad: " << pad; + LOG(V4L2, Error) << "Invalid pad: " << pad; return formatMap; } @@ -215,7 +177,7 @@ FormatEnum V4L2Subdevice::formats(unsigned int pad) mbusEnum.index = 0; mbusEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; while (true) { - ret = ioctl(fd_, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbusEnum); + ret = ioctl(VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbusEnum); if (ret) break; @@ -229,7 +191,7 @@ FormatEnum V4L2Subdevice::formats(unsigned int pad) if (ret && (errno != EINVAL && errno != ENOTTY)) { ret = -errno; - LOG(V4L2Subdev, Error) + LOG(V4L2, Error) << "Unable to enumerate formats on pad " << pad << ": " << strerror(-ret); formatMap.clear(); @@ -250,10 +212,9 @@ int V4L2Subdevice::getFormat(unsigned int pad, V4L2SubdeviceFormat *format) subdevFmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; subdevFmt.pad = pad; - int ret = ioctl(fd_, VIDIOC_SUBDEV_G_FMT, &subdevFmt); + int ret = ioctl(VIDIOC_SUBDEV_G_FMT, &subdevFmt); if (ret) { - ret = -errno; - LOG(V4L2Subdev, Error) + LOG(V4L2, Error) << "Unable to get format on pad " << pad << ": " << strerror(-ret); return ret; @@ -286,10 +247,9 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format) subdevFmt.format.height = format->size.height; subdevFmt.format.code = format->mbus_code; - int ret = ioctl(fd_, VIDIOC_SUBDEV_S_FMT, &subdevFmt); + int ret = ioctl(VIDIOC_SUBDEV_S_FMT, &subdevFmt); if (ret) { - ret = -errno; - LOG(V4L2Subdev, Error) + LOG(V4L2, Error) << "Unable to set format on pad " << pad << ": " << strerror(-ret); return ret; @@ -339,7 +299,7 @@ int V4L2Subdevice::enumPadSizes(unsigned int pad,unsigned int code, sizeEnum.code = code; sizeEnum.which = V4L2_SUBDEV_FORMAT_ACTIVE; while (true) { - ret = ioctl(fd_, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &sizeEnum); + ret = ioctl(VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &sizeEnum); if (ret) break; @@ -351,7 +311,7 @@ int V4L2Subdevice::enumPadSizes(unsigned int pad,unsigned int code, if (ret && (errno != EINVAL && errno != ENOTTY)) { ret = -errno; - LOG(V4L2Subdev, Error) + LOG(V4L2, Error) << "Unable to enumerate sizes on pad " << pad << ": " << strerror(-ret); sizes->clear(); @@ -377,10 +337,9 @@ int V4L2Subdevice::setSelection(unsigned int pad, unsigned int target, sel.r.width = rect->w; sel.r.height = rect->h; - int ret = ioctl(fd_, VIDIOC_SUBDEV_S_SELECTION, &sel); + int ret = ioctl(VIDIOC_SUBDEV_S_SELECTION, &sel); if (ret < 0) { - ret = -errno; - LOG(V4L2Subdev, Error) + LOG(V4L2, Error) << "Unable to set rectangle " << target << " on pad " << pad << ": " << strerror(-ret); return ret; diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 8957cf8f97d3..2172cf25bfb6 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -30,7 +30,7 @@ */ namespace libcamera { -LOG_DEFINE_CATEGORY(V4L2) +LOG_DECLARE_CATEGORY(V4L2) /** * \struct V4L2Capability @@ -270,7 +270,7 @@ const std::string V4L2DeviceFormat::toString() const * \param[in] deviceNode The file-system path to the video device node */ V4L2VideoDevice::V4L2VideoDevice(const std::string &deviceNode) - : deviceNode_(deviceNode), fd_(-1), bufferPool_(nullptr), + : V4L2Device(), deviceNode_(deviceNode), bufferPool_(nullptr), queuedBuffersCount_(0), fdEvent_(nullptr) { /* @@ -305,23 +305,12 @@ int V4L2VideoDevice::open() { int ret; - if (isOpen()) { - LOG(V4L2, Error) << "Device already open"; - return -EBUSY; - } - - ret = ::open(deviceNode_.c_str(), O_RDWR | O_NONBLOCK); - if (ret < 0) { - ret = -errno; - LOG(V4L2, Error) - << "Failed to open V4L2 device: " << strerror(-ret); + ret = V4L2Device::open(deviceNode_, O_RDWR | O_NONBLOCK); + if (ret < 0) return ret; - } - fd_ = ret; - ret = ioctl(fd_, VIDIOC_QUERYCAP, &caps_); + ret = ioctl(VIDIOC_QUERYCAP, &caps_); if (ret < 0) { - ret = -errno; LOG(V4L2, Error) << "Failed to query device capabilities: " << strerror(-ret); @@ -342,20 +331,20 @@ int V4L2VideoDevice::open() * (POLLIN), and write notifications for OUTPUT devices (POLLOUT). */ if (caps_.isVideoCapture()) { - fdEvent_ = new EventNotifier(fd_, EventNotifier::Read); + fdEvent_ = new EventNotifier(fd(), EventNotifier::Read); bufferType_ = caps_.isMultiplanar() ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_CAPTURE; } else if (caps_.isVideoOutput()) { - fdEvent_ = new EventNotifier(fd_, EventNotifier::Write); + fdEvent_ = new EventNotifier(fd(), EventNotifier::Write); bufferType_ = caps_.isMultiplanar() ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT; } else if (caps_.isMetaCapture()) { - fdEvent_ = new EventNotifier(fd_, EventNotifier::Read); + fdEvent_ = new EventNotifier(fd(), EventNotifier::Read); bufferType_ = V4L2_BUF_TYPE_META_CAPTURE; } else if (caps_.isMetaOutput()) { - fdEvent_ = new EventNotifier(fd_, EventNotifier::Write); + fdEvent_ = new EventNotifier(fd(), EventNotifier::Write); bufferType_ = V4L2_BUF_TYPE_META_OUTPUT; } else { LOG(V4L2, Error) << "Device is not a supported type"; @@ -368,28 +357,18 @@ int V4L2VideoDevice::open() return 0; } -/** - * \brief Check if device is successfully opened - * \return True if the device is open, false otherwise - */ -bool V4L2VideoDevice::isOpen() const -{ - return fd_ != -1; -} - /** * \brief Close the device, releasing any resources acquired by open() */ void V4L2VideoDevice::close() { - if (fd_ < 0) + if (fd() < 0) return; + close(); + releaseBuffers(); delete fdEvent_; - - ::close(fd_); - fd_ = -1; } /** @@ -462,9 +441,8 @@ int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format) int ret; v4l2Format.type = bufferType_; - ret = ioctl(fd_, VIDIOC_G_FMT, &v4l2Format); + ret = ioctl(VIDIOC_G_FMT, &v4l2Format); if (ret) { - ret = -errno; LOG(V4L2, Error) << "Unable to get format: " << strerror(-ret); return ret; } @@ -488,9 +466,8 @@ int V4L2VideoDevice::setFormatMeta(V4L2DeviceFormat *format) v4l2Format.type = bufferType_; pix->dataformat = format->fourcc; pix->buffersize = format->planes[0].size; - ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Format); + ret = ioctl(VIDIOC_S_FMT, &v4l2Format); if (ret) { - ret = -errno; LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret); return ret; } @@ -516,9 +493,8 @@ int V4L2VideoDevice::getFormatMultiplane(V4L2DeviceFormat *format) int ret; v4l2Format.type = bufferType_; - ret = ioctl(fd_, VIDIOC_G_FMT, &v4l2Format); + ret = ioctl(VIDIOC_G_FMT, &v4l2Format); if (ret) { - ret = -errno; LOG(V4L2, Error) << "Unable to get format: " << strerror(-ret); return ret; } @@ -554,9 +530,8 @@ int V4L2VideoDevice::setFormatMultiplane(V4L2DeviceFormat *format) pix->plane_fmt[i].sizeimage = format->planes[i].size; } - ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Format); + ret = ioctl(VIDIOC_S_FMT, &v4l2Format); if (ret) { - ret = -errno; LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret); return ret; } @@ -584,9 +559,8 @@ int V4L2VideoDevice::getFormatSingleplane(V4L2DeviceFormat *format) int ret; v4l2Format.type = bufferType_; - ret = ioctl(fd_, VIDIOC_G_FMT, &v4l2Format); + ret = ioctl(VIDIOC_G_FMT, &v4l2Format); if (ret) { - ret = -errno; LOG(V4L2, Error) << "Unable to get format: " << strerror(-ret); return ret; } @@ -613,9 +587,8 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format) pix->pixelformat = format->fourcc; pix->bytesperline = format->planes[0].bpl; pix->field = V4L2_FIELD_NONE; - ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Format); + ret = ioctl(VIDIOC_S_FMT, &v4l2Format); if (ret) { - ret = -errno; LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret); return ret; } @@ -643,9 +616,8 @@ int V4L2VideoDevice::requestBuffers(unsigned int count) rb.type = bufferType_; rb.memory = memoryType_; - ret = ioctl(fd_, VIDIOC_REQBUFS, &rb); + ret = ioctl(VIDIOC_REQBUFS, &rb); if (ret < 0) { - ret = -errno; LOG(V4L2, Error) << "Unable to request " << count << " buffers: " << strerror(-ret); @@ -695,9 +667,8 @@ int V4L2VideoDevice::exportBuffers(BufferPool *pool) buf.length = VIDEO_MAX_PLANES; buf.m.planes = planes; - ret = ioctl(fd_, VIDIOC_QUERYBUF, &buf); + ret = ioctl(VIDIOC_QUERYBUF, &buf); if (ret < 0) { - ret = -errno; LOG(V4L2, Error) << "Unable to query buffer " << i << ": " << strerror(-ret); @@ -748,9 +719,8 @@ int V4L2VideoDevice::createPlane(Buffer *buffer, unsigned int planeIndex, expbuf.plane = planeIndex; expbuf.flags = O_RDWR; - ret = ioctl(fd_, VIDIOC_EXPBUF, &expbuf); + ret = ioctl(VIDIOC_EXPBUF, &expbuf); if (ret < 0) { - ret = -errno; LOG(V4L2, Error) << "Failed to export buffer: " << strerror(-ret); return ret; @@ -855,9 +825,8 @@ int V4L2VideoDevice::queueBuffer(Buffer *buffer) LOG(V4L2, Debug) << "Queueing buffer " << buf.index; - ret = ioctl(fd_, VIDIOC_QBUF, &buf); + ret = ioctl(VIDIOC_QBUF, &buf); if (ret < 0) { - ret = -errno; LOG(V4L2, Error) << "Failed to queue buffer " << buf.index << ": " << strerror(-ret); @@ -892,9 +861,8 @@ Buffer *V4L2VideoDevice::dequeueBuffer() buf.m.planes = planes; } - ret = ioctl(fd_, VIDIOC_DQBUF, &buf); + ret = ioctl(VIDIOC_DQBUF, &buf); if (ret < 0) { - ret = -errno; LOG(V4L2, Error) << "Failed to dequeue buffer: " << strerror(-ret); return nullptr; @@ -952,9 +920,8 @@ int V4L2VideoDevice::streamOn() { int ret; - ret = ioctl(fd_, VIDIOC_STREAMON, &bufferType_); + ret = ioctl(VIDIOC_STREAMON, &bufferType_); if (ret < 0) { - ret = -errno; LOG(V4L2, Error) << "Failed to start streaming: " << strerror(-ret); return ret; @@ -975,9 +942,8 @@ int V4L2VideoDevice::streamOff() { int ret; - ret = ioctl(fd_, VIDIOC_STREAMOFF, &bufferType_); + ret = ioctl(VIDIOC_STREAMOFF, &bufferType_); if (ret < 0) { - ret = -errno; LOG(V4L2, Error) << "Failed to stop streaming: " << strerror(-ret); return ret;