From patchwork Tue Jan 22 23:44:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 335 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C3CE660C7D for ; Wed, 23 Jan 2019 00:46:37 +0100 (CET) X-Halon-ID: e83a2c68-1e9f-11e9-911a-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id e83a2c68-1e9f-11e9-911a-0050569116f7; Wed, 23 Jan 2019 00:46:15 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:44:58 +0100 Message-Id: <20190122234505.32634-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> References: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/8] libcamera: stream: add basic Stream 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: Tue, 22 Jan 2019 23:46:38 -0000 Add a extremely simple Stream implementation. The idea is that once capability support is added to the library each stream would describe it's capabilities using this class. A application would then select one or more streams based on these capabilities and using them to configure and capture. At this stage all the Stream class provides is a way for a Camera object to communicate which stream ID it to operates on. This basically limits the usefulness of the object to cameras which only provides one stream per camera. Signed-off-by: Niklas Söderlund --- include/libcamera/libcamera.h | 1 + include/libcamera/meson.build | 1 + include/libcamera/stream.h | 25 +++++++++++++ src/libcamera/meson.build | 1 + src/libcamera/stream.cpp | 66 +++++++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+) create mode 100644 include/libcamera/stream.h create mode 100644 src/libcamera/stream.cpp diff --git a/include/libcamera/libcamera.h b/include/libcamera/libcamera.h index c0511cf6d662b63f..272dfd5e4a67d5de 100644 --- a/include/libcamera/libcamera.h +++ b/include/libcamera/libcamera.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #endif /* __LIBCAMERA_LIBCAMERA_H__ */ diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index d7cb55ba4a49e1e8..54a680787e5c17aa 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -5,6 +5,7 @@ libcamera_api = files([ 'event_notifier.h', 'libcamera.h', 'signal.h', + 'stream.h', 'timer.h', ]) diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h new file mode 100644 index 0000000000000000..415815ba12c65e47 --- /dev/null +++ b/include/libcamera/stream.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * stream.h - Stream object interface + */ +#ifndef __LIBCAMERA_STREAM_H__ +#define __LIBCAMERA_STREAM_H__ + +namespace libcamera { + +class Stream final +{ +public: + Stream(unsigned int id); + + unsigned int id() const { return id_; }; + +private: + unsigned int id_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_STREAM_H__ */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index f9f25c0ecf1564cc..9f6ff99eebe2f5bc 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -10,6 +10,7 @@ libcamera_sources = files([ 'media_object.cpp', 'pipeline_handler.cpp', 'signal.cpp', + 'stream.cpp', 'timer.cpp', 'v4l2_device.cpp', ]) diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp new file mode 100644 index 0000000000000000..3b44e834ee02b35a --- /dev/null +++ b/src/libcamera/stream.cpp @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * stream.cpp - Stream information handeling + */ + +#include + +/** + * \file stream.h + * \brief Stream information + * + * A camera device can provide frames in different resolutions and formats + * concurrently from a single image source. The Stream class represents + * one of the multiple concurrent streams format. + * + * All streams exposed by a camera device share the same image source and are + * thus not fully independent. Parameters related to the image source, such as + * the exposure time or flash control, are common to all streams. Other + * parameters, such as format or resolution, may be specified per-stream, + * depending on the capabilities of the camera device. + * + * Camera devices expose at least one stream, and may expose additional streams + * based on the device capabilities. This can be used, for instance, to + * implement concurrent viewfinder and video capture, or concurrent viewfinder, + * video capture and still image capture. + */ + +namespace libcamera { + +/** + * \class Stream + * \brief Stream information carrier + * + * The Stream class is a model of all static information which are associated + * with a single video stream. A application should acquire Stream objects from + * the camera. + * + * Some cameras are capable of supplying more then one stream from the same + * video source. In such cases a application will receive a array of streams to + * inspect and select from to best fit its use-case. + * + * \todo Add capabilities to the Stream API. Without this the Stream class + * only serves to reveal how many streams of unknown capabilities a camera + * supports. This in it self is productive as it allows applications to + * configure and capture from one or more streams even if it won't be able + * to select the optimal stream for the task. + */ + +/** + * \brief Create a new stream with a ID + * \param[in] id Numerical ID which should be unique for the camera device the stream belongs to + */ +Stream::Stream(unsigned int id) + : id_(id) +{ +} + +/** + * \fn Stream::id() + * \brief Retrieve the streams ID + * \return The stream ID + */ + +} /* namespace libcamera */ From patchwork Tue Jan 22 23:44:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 336 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 506A660C7D for ; Wed, 23 Jan 2019 00:46:39 +0100 (CET) X-Halon-ID: e8e61eee-1e9f-11e9-911a-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id e8e61eee-1e9f-11e9-911a-0050569116f7; Wed, 23 Jan 2019 00:46:16 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:44:59 +0100 Message-Id: <20190122234505.32634-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> References: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/8] libcamera: stream: add basic StreamConfiguration 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: Tue, 22 Jan 2019 23:46:40 -0000 Add a simple StreamConfiguration class to hold configuration data for a single stream of a Camera. In its current form not many configuration parameters are supported but it's expected the number of options will grow over time. At this stage the pixel format is represented as a unsigned int to allow for a easy mapping to the V4L2 API. This might be subject to change in the future as we finalize how libcamera shall represent pixelformats. A StreamConfiguration objected needs to be created from the Stream object it should configure. As the two objects are so closely related I have at this stage opted to implement them in the same stream.{h,cpp} as the Stream class. Signed-off-by: Niklas Söderlund --- include/libcamera/stream.h | 20 ++++++++++++ src/libcamera/stream.cpp | 64 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index 415815ba12c65e47..8750797c36dd9b42 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -20,6 +20,26 @@ private: unsigned int id_; }; +class StreamConfiguration final +{ +public: + StreamConfiguration(class Stream &stream); + + unsigned int id() const { return id_; }; + unsigned int width() const { return width_; }; + unsigned int height() const { return height_; }; + unsigned int pixelformat() const { return pixelformat_; }; + + void setDimension(unsigned int width, unsigned int height); + void setPixelFormat(unsigned int pixelformat); + +private: + unsigned int id_; + unsigned int width_; + unsigned int height_; + unsigned int pixelformat_; +}; + } /* namespace libcamera */ #endif /* __LIBCAMERA_STREAM_H__ */ diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp index 3b44e834ee02b35a..e40756260c5768f3 100644 --- a/src/libcamera/stream.cpp +++ b/src/libcamera/stream.cpp @@ -63,4 +63,68 @@ Stream::Stream(unsigned int id) * \return The stream ID */ +/** + * \class StreamConfiguration + * \brief Stream configuration object + * + * The StreamConfiguration class is a model of all information which can be + * configured for a single video stream. A application should acquire a all + * Stream object from a camera, select the ones it wish to use, create a + * StreamConfiguration for each of those streams, set the desired parameter on + * the objects and feed them back to the camera object to configure the camera. + */ + +/** + * \fn StreamConfiguration::id() + * \brief Retrieve the streams ID + * \return The stream ID + */ + +/** + * \fn StreamConfiguration::width() + * \brief Retrieve the Stream width + * \return The stream width + */ + +/** + * \fn StreamConfiguration::height() + * \brief Retrieve the Stream height + * \return The stream height + */ + +/** + * \fn StreamConfiguration::pixelformat() + * \brief Retrieve the Stream pixelformat + * \return The stream pixelformat + */ + +/** + * \brief Set desired width and height for the stream + * \param[in] width The desired width of the stream + * \param[in] height The desired height of the stream + */ +void StreamConfiguration::setDimension(unsigned int width, unsigned int height) +{ + width_ = width; + height_ = height; +} + +/** + * \brief Set desired pixelformat for the stream + * \param[in] pixelformat The desired pixelformat of the stream + */ +void StreamConfiguration::setPixelFormat(unsigned int pixelformat) +{ + pixelformat_ = pixelformat; +} + +/** + * \brief Create a new configuration container for a stream + * \param[in] stream The stream object the configuration object should act on + */ +StreamConfiguration::StreamConfiguration(class Stream &stream) + : id_(stream.id()), width_(0), height_(0), pixelformat_(0) +{ +} + } /* namespace libcamera */ From patchwork Tue Jan 22 23:45:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 337 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CB54660C83 for ; Wed, 23 Jan 2019 00:46:39 +0100 (CET) X-Halon-ID: e984f989-1e9f-11e9-911a-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id e984f989-1e9f-11e9-911a-0050569116f7; Wed, 23 Jan 2019 00:46:17 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:45:00 +0100 Message-Id: <20190122234505.32634-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> References: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/8] libcamera: pipelines: add log category for each pipeline 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, 22 Jan 2019 23:46:40 -0000 The VIMC and UVC pipeline handlers lacked a dedicated log category. Signed-off-by: Niklas Söderlund --- src/libcamera/pipeline/uvcvideo.cpp | 3 +++ src/libcamera/pipeline/vimc.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index a02f3671d22c5f79..3e4745ba498e7160 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -9,11 +9,14 @@ #include #include "device_enumerator.h" +#include "log.h" #include "media_device.h" #include "pipeline_handler.h" namespace libcamera { +LOG_DEFINE_CATEGORY(UVC) + class PipelineHandlerUVC : public PipelineHandler { public: diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index d732ac21cae1a84b..e8dbc0932ab0198a 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -9,11 +9,14 @@ #include #include "device_enumerator.h" +#include "log.h" #include "media_device.h" #include "pipeline_handler.h" namespace libcamera { +LOG_DEFINE_CATEGORY(VIMC) + class PipeHandlerVimc : public PipelineHandler { public: From patchwork Tue Jan 22 23:45:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 338 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 61DFF60C7D for ; Wed, 23 Jan 2019 00:46:42 +0100 (CET) X-Halon-ID: e9e8992c-1e9f-11e9-911a-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id e9e8992c-1e9f-11e9-911a-0050569116f7; Wed, 23 Jan 2019 00:46:19 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:45:01 +0100 Message-Id: <20190122234505.32634-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> References: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/8] libcamera: pipelines: add method to retrieve streams 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, 22 Jan 2019 23:46:42 -0000 A Camera object needs to be able to inquire its responsible PipelineHandler for which streams it supports. Add and implement such an interface to the PipelineHandler base class and all pipeline handler implementations. Signed-off-by: Niklas Söderlund --- src/libcamera/include/pipeline_handler.h | 3 +++ src/libcamera/pipeline/ipu3/ipu3.cpp | 27 ++++++++++++++++++++++++ src/libcamera/pipeline/uvcvideo.cpp | 13 ++++++++++++ src/libcamera/pipeline/vimc.cpp | 13 ++++++++++++ src/libcamera/pipeline_handler.cpp | 12 +++++++++++ 5 files changed, 68 insertions(+) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index f05f201f7ca824eb..d4473bf173b815af 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -17,12 +17,15 @@ namespace libcamera { class CameraManager; class DeviceEnumerator; +class Stream; class PipelineHandler { public: virtual ~PipelineHandler() { }; + virtual std::vector streams(const Camera *camera) const = 0; + virtual bool match(CameraManager *manager, DeviceEnumerator *enumerator) = 0; }; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index c6106c538f071058..f73479125ed5e21d 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -10,6 +10,7 @@ #include #include +#include #include "device_enumerator.h" #include "log.h" @@ -26,6 +27,8 @@ public: PipelineHandlerIPU3(); ~PipelineHandlerIPU3(); + std::vector streams(const Camera *camera) const; + bool match(CameraManager *manager, DeviceEnumerator *enumerator); private: @@ -35,6 +38,8 @@ private: std::vector> cameras_; void registerCameras(CameraManager *manager); + + bool handleCamera(const Camera *camera) const; }; PipelineHandlerIPU3::PipelineHandlerIPU3() @@ -59,6 +64,16 @@ PipelineHandlerIPU3::~PipelineHandlerIPU3() imgu_ = nullptr; } +std::vector PipelineHandlerIPU3::streams(const Camera *camera) const +{ + std::vector streams; + + if (handleCamera(camera)) + streams.push_back(Stream(0)); + + return streams; +} + bool PipelineHandlerIPU3::match(CameraManager *manager, DeviceEnumerator *enumerator) { DeviceMatch cio2_dm("ipu3-cio2"); @@ -192,6 +207,18 @@ void PipelineHandlerIPU3::registerCameras(CameraManager *manager) } } +bool PipelineHandlerIPU3::handleCamera(const Camera *camera) const +{ + if (!camera) + return false; + + for (const std::shared_ptr &cam : cameras_) + if (camera == cam.get()) + return true; + + return false; +} + REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3); } /* namespace libcamera */ diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 3e4745ba498e7160..87b556ba0ae17696 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "device_enumerator.h" #include "log.h" @@ -23,6 +24,8 @@ public: PipelineHandlerUVC(); ~PipelineHandlerUVC(); + std::vector streams(const Camera *camera) const; + bool match(CameraManager *manager, DeviceEnumerator *enumerator); private: @@ -46,6 +49,16 @@ PipelineHandlerUVC::~PipelineHandlerUVC() dev_->release(); } +std::vector PipelineHandlerUVC::streams(const Camera *camera) const +{ + std::vector streams; + + if (camera && camera == camera_.get()) + streams.push_back(Stream(0)); + + return streams; +} + bool PipelineHandlerUVC::match(CameraManager *manager, DeviceEnumerator *enumerator) { DeviceMatch dm("uvcvideo"); diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index e8dbc0932ab0198a..e894367ba6706aaf 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "device_enumerator.h" #include "log.h" @@ -23,6 +24,8 @@ public: PipeHandlerVimc(); ~PipeHandlerVimc(); + std::vector streams(const Camera *camera) const; + bool match(CameraManager *manager, DeviceEnumerator *enumerator); private: @@ -46,6 +49,16 @@ PipeHandlerVimc::~PipeHandlerVimc() dev_->release(); } +std::vector PipeHandlerVimc::streams(const Camera *camera) const +{ + std::vector streams; + + if (camera && camera == camera_.get()) + streams.push_back(Stream(0)); + + return streams; +} + bool PipeHandlerVimc::match(CameraManager *manager, DeviceEnumerator *enumerator) { DeviceMatch dm("vimc"); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index c24feeafc503e9b1..c2bed924dece0ac0 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -34,6 +34,18 @@ LOG_DEFINE_CATEGORY(Pipeline) * with the pipelines it supports and creates corresponding Camera devices. */ +/** + * \fn PipelineHandler::streams(const Camera *camera) + * \brief Retrive a array of all streams the camera provides + * \param[in] camera The camera to retrieve streams from + * + * This function is the interface to extract information about streams from a + * PipelineHandler. + * + * \return A array of streams from the camera or a empty list if \a camera + * is not part of the PipelineHandler. + */ + /** * \fn PipelineHandler::match(DeviceEnumerator *enumerator) * \brief Match media devices and create camera instances From patchwork Tue Jan 22 23:45:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 339 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9466C60C98 for ; Wed, 23 Jan 2019 00:46:42 +0100 (CET) X-Halon-ID: eb2ce716-1e9f-11e9-911a-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id eb2ce716-1e9f-11e9-911a-0050569116f7; Wed, 23 Jan 2019 00:46:20 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:45:02 +0100 Message-Id: <20190122234505.32634-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> References: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/8] libcamera: pipelines: add method to configure streams 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, 22 Jan 2019 23:46:42 -0000 All the streams which are to be used needs to be configured at the same time, that is passed from the application to the pipeline handler in a single call. This would allow the pipeline handler to take any dependences between the different streams and there configuration into account when setting up the hardware. This implementation do not interact with any hardware, instead it extends all pipeline handlers with the argument validation needed to make sure the configuration request is sound. It then proceeds to print the requested frame dimensions to the log. Future work based on more components are needed to make the pipeline specific implementations truly useful. Signed-off-by: Niklas Söderlund --- src/libcamera/include/pipeline_handler.h | 3 +++ src/libcamera/pipeline/ipu3/ipu3.cpp | 24 ++++++++++++++++++++++++ src/libcamera/pipeline/uvcvideo.cpp | 24 ++++++++++++++++++++++++ src/libcamera/pipeline/vimc.cpp | 24 ++++++++++++++++++++++++ src/libcamera/pipeline_handler.cpp | 18 ++++++++++++++++++ 5 files changed, 93 insertions(+) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index d4473bf173b815af..751eb4e1bb4bf69b 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -18,6 +18,7 @@ namespace libcamera { class CameraManager; class DeviceEnumerator; class Stream; +class StreamConfiguration; class PipelineHandler { @@ -26,6 +27,8 @@ public: virtual std::vector streams(const Camera *camera) const = 0; + virtual int configure(const Camera *camera, std::vector &config) = 0; + virtual bool match(CameraManager *manager, DeviceEnumerator *enumerator) = 0; }; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index f73479125ed5e21d..5252fab226a1da71 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -29,6 +29,8 @@ public: std::vector streams(const Camera *camera) const; + int configure(const Camera *camera, std::vector &config); + bool match(CameraManager *manager, DeviceEnumerator *enumerator); private: @@ -74,6 +76,28 @@ std::vector PipelineHandlerIPU3::streams(const Camera *camera) const return streams; } +int PipelineHandlerIPU3::configure(const Camera *camera, + std::vector &config) +{ + StreamConfiguration *cfg; + + if (!handleCamera(camera)) + return -EINVAL; + + if (config.size() != 1) + return -EINVAL; + + cfg = config.front(); + + if (!cfg || cfg->id() != 0) + return -EINVAL; + + LOG(IPU3, Info) << "TODO: Configure the camera for resolution " << + cfg->width() << "x" << cfg->height(); + + return 0; +} + bool PipelineHandlerIPU3::match(CameraManager *manager, DeviceEnumerator *enumerator) { DeviceMatch cio2_dm("ipu3-cio2"); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 87b556ba0ae17696..dd494d2599bef813 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -26,6 +26,8 @@ public: std::vector streams(const Camera *camera) const; + int configure(const Camera *camera, std::vector &config); + bool match(CameraManager *manager, DeviceEnumerator *enumerator); private: @@ -59,6 +61,28 @@ std::vector PipelineHandlerUVC::streams(const Camera *camera) const return streams; } +int PipelineHandlerUVC::configure(const Camera *camera, + std::vector &config) +{ + StreamConfiguration *cfg; + + if (!camera || camera != camera_.get()) + return -EINVAL; + + if (config.size() != 1) + return -EINVAL; + + cfg = config.front(); + + if (!cfg || cfg->id() != 0) + return -EINVAL; + + LOG(UVC, Info) << "TODO: Configure the camera for resolution " << + cfg->width() << "x" << cfg->height(); + + return 0; +} + bool PipelineHandlerUVC::match(CameraManager *manager, DeviceEnumerator *enumerator) { DeviceMatch dm("uvcvideo"); diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index e894367ba6706aaf..31b08a766cb32702 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -26,6 +26,8 @@ public: std::vector streams(const Camera *camera) const; + int configure(const Camera *camera, std::vector &config); + bool match(CameraManager *manager, DeviceEnumerator *enumerator); private: @@ -59,6 +61,28 @@ std::vector PipeHandlerVimc::streams(const Camera *camera) const return streams; } +int PipeHandlerVimc::configure(const Camera *camera, + std::vector &config) +{ + StreamConfiguration *cfg; + + if (!camera || camera != camera_.get()) + return -EINVAL; + + if (config.size() != 1) + return -EINVAL; + + cfg = config.front(); + + if (!cfg || cfg->id() != 0) + return -EINVAL; + + LOG(VIMC, Info) << "TODO: Configure the camera for resolution " << + cfg->width() << "x" << cfg->height(); + + return 0; +} + bool PipeHandlerVimc::match(CameraManager *manager, DeviceEnumerator *enumerator) { DeviceMatch dm("vimc"); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index c2bed924dece0ac0..533ee64d6ce318c4 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -46,6 +46,24 @@ LOG_DEFINE_CATEGORY(Pipeline) * is not part of the PipelineHandler. */ +/** + * \fn PipelineHandler::configure(const Camera *camera, std::vector &config) + * \brief Configure a set of streams for a camera + * \param[in] camera The camera to configure streams for + * \param[in] config A array of stream configurations to try and setup + * + * This function is the interface to configure one or more streams of a camera + * for capture. The intended user for this interface is the Camera class which + * will receive the array of configurations to apply from the application. + * + * The caller needs to verify the StreamConfiguration objects in the passed + * array after the call as it might remove one or more to satisfy hardware + * limitations. The call might also alter any or all of the configuration + * parameters of any stream to fit within valid operational conditions. + * + * \return 0 on success or a negative error code on error. + */ + /** * \fn PipelineHandler::match(DeviceEnumerator *enumerator) * \brief Match media devices and create camera instances From patchwork Tue Jan 22 23:45:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 340 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 193A060C7F for ; Wed, 23 Jan 2019 00:46:44 +0100 (CET) X-Halon-ID: ebbfdc7c-1e9f-11e9-911a-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id ebbfdc7c-1e9f-11e9-911a-0050569116f7; Wed, 23 Jan 2019 00:46:21 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:45:03 +0100 Message-Id: <20190122234505.32634-7-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> References: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 6/8] libcamera: camera: Add acquire() and release() 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, 22 Jan 2019 23:46:44 -0000 From: Laurent Pinchart Signed-off-by: Niklas Söderlund --- include/libcamera/camera.h | 5 +++++ src/libcamera/camera.cpp | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index b5d4dfe4b1f6a586..3cb1ab62b791ab87 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -27,12 +27,17 @@ public: void disconnect(); + int acquire(); + void release(); + private: explicit Camera(const std::string &name, class PipelineHandler *pipe); ~Camera(); std::string name_; class PipelineHandler *pipe_; + + bool acquired_; }; } /* namespace libcamera */ diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 496fb1021c4fccf0..ee5e6dedb242a1fd 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -103,7 +103,7 @@ void Camera::disconnect() } Camera::Camera(const std::string &name, class PipelineHandler *pipe) - : name_(name), pipe_(pipe) + : name_(name), pipe_(pipe), acquired_(false) { } @@ -111,4 +111,37 @@ Camera::~Camera() { } +/** + * \brief Acquire the camera device for exclusive access + * + * After opening the device with open(), exclusive access must be obtained + * before performing operations that change the device state. This function is + * not blocking, if the device has already been acquired (by the same or another + * process) the -EBUSY error code is returned. + * + * Once exclusive access isn't needed anymore, the device should be released + * with a call to the release() function. + * + * \return 0 on success or a negative error code on error. + */ +int Camera::acquire() +{ + if (acquired_) + return -EBUSY; + + acquired_ = true; + return 0; +} + +/** + * \brief Release exclusive access to the camera device + * + * Releasing the camera device allows other users to acquire exclusive access + * with the acquire() function. + */ +void Camera::release() +{ + acquired_ = false; +} + } /* namespace libcamera */ From patchwork Tue Jan 22 23:45:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 341 Return-Path: Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 19FE060C9A for ; Wed, 23 Jan 2019 00:46:44 +0100 (CET) X-Halon-ID: ec281263-1e9f-11e9-911a-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id ec281263-1e9f-11e9-911a-0050569116f7; Wed, 23 Jan 2019 00:46:22 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:45:04 +0100 Message-Id: <20190122234505.32634-8-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> References: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 7/8] libcamera: camera: integrate streams and configuration 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, 22 Jan 2019 23:46:44 -0000 Add retrieval and configuration of streams information and configuration. The implementation in the Camera are minimalistic as the heavily lifting are done by the pipeline handler implementations. The single most important thing for the helpers in the Camera object is to perform access control and making sure no request is forwarded to a pipeline handler if the camera have been disconnected. Signed-off-by: Niklas Söderlund --- include/libcamera/camera.h | 7 ++++++ src/libcamera/camera.cpp | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 3cb1ab62b791ab87..9337fa970d26b0df 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -9,10 +9,13 @@ #include #include +#include namespace libcamera { class PipelineHandler; +class Stream; +class StreamConfiguration; class Camera final { @@ -30,6 +33,10 @@ public: int acquire(); void release(); + std::vector streams() const; + + int configure(std::vector &config); + private: explicit Camera(const std::string &name, class PipelineHandler *pipe); ~Camera(); diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index ee5e6dedb242a1fd..6cae82669e454e35 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -6,6 +6,9 @@ */ #include +#include + +#include "pipeline_handler.h" #include "log.h" @@ -144,4 +147,49 @@ void Camera::release() acquired_ = false; } +/** + * \brief Retrieve the supported streams of the camera + * + * \return An array of streams supported by the camera device + */ +std::vector Camera::streams() const +{ + std::vector streams; + + if (pipe_) + streams = pipe_->streams(this); + + return streams; +} + +/** + * \brief Configure the camera device prior to capture + * + * Prior to starting capture, the camera device must be configured to select a + * set of streams. + * + * The requested configuration \a config shall contain at least one stream and + * may contain multiple streams. For each stream an associated StreamFormat + * shall be supplied. Streams supported by the camera device not part of the + * \a config will be disabled. + * + * Exclusive access to the camera device shall be ensured by a call to + * Camera::acquire() before calling this function, otherwise an -EACCES error + * will be returned. + * + * \param[in] config Array of stream configurations to setup + * + * \return 0 on success or a negative error code on error. + */ +int Camera::configure(std::vector &config) +{ + if (!pipe_) + return -ENODEV; + + if (!acquired_) + return -EACCES; + + return pipe_->configure(this, config); +} + } /* namespace libcamera */ From patchwork Tue Jan 22 23:45:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 342 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5AA2060C83 for ; Wed, 23 Jan 2019 00:46:44 +0100 (CET) X-Halon-ID: ec8c39d8-1e9f-11e9-911a-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id ec8c39d8-1e9f-11e9-911a-0050569116f7; Wed, 23 Jan 2019 00:46:22 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:45:05 +0100 Message-Id: <20190122234505.32634-9-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> References: <20190122234505.32634-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 8/8] [POC] cam: add hack option to staticly configure a pipeline 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, 22 Jan 2019 23:46:44 -0000 This is a hack prof of concept to try out the application API to query a camera about its streams and then proceed to use that information to configure a static resolution of 640x480. Not-yet-Signed-off-by: Niklas Söderlund --- src/cam/main.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/cam/main.cpp b/src/cam/main.cpp index 22211670c6250887..6ff6dc978d91d323 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -21,6 +21,7 @@ enum { OptCamera = 'c', OptHelp = 'h', OptList = 'l', + OptStreamsConfig = 'C', }; static int parseOptions(int argc, char *argv[]) @@ -32,6 +33,7 @@ static int parseOptions(int argc, char *argv[]) "camera"); parser.addOption(OptHelp, "Display this help message", "help"); parser.addOption(OptList, "List all cameras", "list"); + parser.addOption(OptStreamsConfig, "Configure the first stream to 640x480", "hack-config"); options = std::move(parser.parse(argc, argv)); if (!options.valid()) @@ -79,6 +81,42 @@ int main(int argc, char **argv) } } + if (options.isSet(OptStreamsConfig)) { + if (!options.isSet(OptCamera)) { + std::cout << "Can't configure stream, no camera selected" << std::endl; + goto out; + } + + std::shared_ptr cam = cm->get(options[OptCamera]); + if (!cam) { + std::cout << "Camera " << options[OptCamera] + << " not found" << std::endl; + goto out; + } + + std::vector streams = cam->streams(); + if (streams.size() != 1) { + std::cout << "Camera have " << streams.size() << + " streams, I only know how to work with 1" << std::endl; + goto out; + } + + StreamConfiguration config = StreamConfiguration(streams.front()); + config.setDimension(640, 480); + + std::vector configs; + configs.push_back(&config); + + if (cam->acquire()) { + std::cout << "Failed to acquire camera" << std::endl; + goto out; + } + + if (cam->configure(configs)) + std::cout << "Failed to configure camera" << std::endl; + } + +out: cm->stop(); return 0;