From patchwork Tue Jan 29 02:00:43 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: 433 Return-Path: Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6AC6D60C78 for ; Tue, 29 Jan 2019 03:00:57 +0100 (CET) X-Halon-ID: b661710e-2369-11e9-874f-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id b661710e-2369-11e9-874f-005056917f90; Tue, 29 Jan 2019 03:00:55 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 29 Jan 2019 03:00:43 +0100 Message-Id: <20190129020048.16774-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> References: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 1/6] libcamera: stream: add initial 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, 29 Jan 2019 02:00:57 -0000 Add an initial Stream implementation. The idea is that once capability support is added to the library each stream will describe its capabilities using this class. An application will then select one or more streams based on these capabilities and use them to configure the camera and capture. At this stage the Stream class is empty as capabilities are yet to be added. The class is still useful as it will be used to communicate how many streams a Camera object provides. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham --- include/libcamera/libcamera.h | 1 + include/libcamera/meson.build | 1 + include/libcamera/stream.h | 18 +++++++++++++ src/libcamera/meson.build | 1 + src/libcamera/stream.cpp | 51 +++++++++++++++++++++++++++++++++++ 5 files changed, 72 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..4f47d85ed6382b36 --- /dev/null +++ b/include/libcamera/stream.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * stream.h - Video stream for a Camera + */ +#ifndef __LIBCAMERA_STREAM_H__ +#define __LIBCAMERA_STREAM_H__ + +namespace libcamera { + +class Stream final +{ +}; + +} /* 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..01f4e5008af8ac46 --- /dev/null +++ b/src/libcamera/stream.cpp @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * stream.cpp - Video stream for a Camera + */ + +#include + +/** + * \file stream.h + * \brief Video stream for a Camera + * + * 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. + * + * 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 Video stream for a camera + * + * The Stream class models of all static information which are associated + * with a single video stream. Stream are exposed by the Camera object they + * belong to. + * + * Some cameras are capable of supplying more then one stream from the same + * video source. In such cases an application can inspect all available streams + * and select the ones that 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 itself is productive as it allows applications to configure and + * capture from one or more streams even if they won't be able to select the + * optimal stream for the task. + */ + +} /* namespace libcamera */ From patchwork Tue Jan 29 02:00:44 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: 435 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F08EC60C78 for ; Tue, 29 Jan 2019 03:00:57 +0100 (CET) X-Halon-ID: b6caa1e0-2369-11e9-874f-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id b6caa1e0-2369-11e9-874f-005056917f90; Tue, 29 Jan 2019 03:00:55 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 29 Jan 2019 03:00:44 +0100 Message-Id: <20190129020048.16774-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> References: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 2/6] libcamera: stream: add initial StreamConfiguration structure 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, 29 Jan 2019 02:00:58 -0000 Add an initial StreamConfiguration implementation 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 an unsigned int to allow for easy mapping to the V4L2 API. This might be subject to change in the future as we finalize how libcamera shall represent pixel formats. Signed-off-by: Niklas Söderlund --- include/libcamera/stream.h | 6 ++++++ src/libcamera/stream.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index 4f47d85ed6382b36..4b24dd841dd64b64 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -13,6 +13,12 @@ class Stream final { }; +struct StreamConfiguration { + 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 01f4e5008af8ac46..ef55f947574e241c 100644 --- a/src/libcamera/stream.cpp +++ b/src/libcamera/stream.cpp @@ -48,4 +48,30 @@ namespace libcamera { * optimal stream for the task. */ +/** + * \struct StreamConfiguration + * \brief Configuration parameters for a stream + * + * The StreamConfiguration structure models all information which can be + * configured for a single video stream. + */ + +/** + * \var StreamConfiguration::width + * \brief Stream width in pixels + */ + +/** + * \var StreamConfiguration::height + * \brief Stream height in pixels + */ + +/** + * \var StreamConfiguration::pixelFormat + * \brief Stream pixel format + * + * This is a little endian four character code representation of the pixel + * format described in V4L2 using the V4L2_PIX_FMT_* definitions. + */ + } /* namespace libcamera */ From patchwork Tue Jan 29 02:00:45 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: 436 Return-Path: Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CAACC60DC3 for ; Tue, 29 Jan 2019 03:00:58 +0100 (CET) X-Halon-ID: b7246620-2369-11e9-874f-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id b7246620-2369-11e9-874f-005056917f90; Tue, 29 Jan 2019 03:00:56 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 29 Jan 2019 03:00:45 +0100 Message-Id: <20190129020048.16774-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> References: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 3/6] 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, 29 Jan 2019 02:00:59 -0000 From: Laurent Pinchart Exclusive access must be obtained before performing operations that change the device state. Define an internal flag to track ownership and provide a means of protecting functions that change device configuration. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham --- include/libcamera/camera.h | 5 +++++ src/libcamera/camera.cpp | 39 +++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index a2ded62de94814c4..7e358f8c0aa093cf 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -29,6 +29,9 @@ public: Signal disconnected; + int acquire(); + void release(); + private: Camera(PipelineHandler *pipe, const std::string &name); ~Camera(); @@ -38,6 +41,8 @@ private: std::shared_ptr pipe_; std::string name_; + + bool acquired_; }; } /* namespace libcamera */ diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 9cec289282e4797b..500976b237bcbd2d 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -102,12 +102,14 @@ const std::string &Camera::name() const */ Camera::Camera(PipelineHandler *pipe, const std::string &name) - : pipe_(pipe->shared_from_this()), name_(name) + : pipe_(pipe->shared_from_this()), name_(name), acquired_(false) { } Camera::~Camera() { + if (acquired_) + LOG(Camera, Error) << "Removing camera while still in use"; } /** @@ -127,4 +129,39 @@ void Camera::disconnect() disconnected.emit(this); } +/** + * \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. + * + * \todo Implement exclusive access across processes. + * + * \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 29 02:00:46 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: 437 Return-Path: Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E98B260DBC for ; Tue, 29 Jan 2019 03:00:59 +0100 (CET) X-Halon-ID: b7aded40-2369-11e9-874f-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id b7aded40-2369-11e9-874f-005056917f90; Tue, 29 Jan 2019 03:00:57 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 29 Jan 2019 03:00:46 +0100 Message-Id: <20190129020048.16774-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> References: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 4/6] libcamera: camera: extend camera object to support 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, 29 Jan 2019 02:01:00 -0000 A camera consists of one or more video streams originating from the same video source. The different streams could for example have access to different hardware blocks in the video pipeline and therefore be able to process the video source in different ways. All static information describing each stream need to be recorded at camera creation. After a camera is created an application can retrieve the static information about its stream at any time. Update all pipeline handlers to register one stream per camera, this will be extended in the future for some of the pipelines. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham --- include/libcamera/camera.h | 8 ++++++- src/libcamera/camera.cpp | 34 ++++++++++++++++++++++++---- src/libcamera/pipeline/ipu3/ipu3.cpp | 9 ++++++-- src/libcamera/pipeline/uvcvideo.cpp | 5 +++- src/libcamera/pipeline/vimc.cpp | 5 +++- 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 7e358f8c0aa093cf..3ebb8e96cc63b98a 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -15,12 +15,14 @@ namespace libcamera { class PipelineHandler; +class Stream; class Camera final { public: static std::shared_ptr create(PipelineHandler *pipe, - const std::string &name); + const std::string &name, + const std::vector &streams); Camera(const Camera &) = delete; void operator=(const Camera &) = delete; @@ -32,6 +34,8 @@ public: int acquire(); void release(); + std::vector streams() const; + private: Camera(PipelineHandler *pipe, const std::string &name); ~Camera(); @@ -41,8 +45,10 @@ private: std::shared_ptr pipe_; std::string name_; + std::vector streams_; bool acquired_; + bool disconnected_; }; } /* namespace libcamera */ diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 500976b237bcbd2d..c8604ec8a8e6eaf4 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "log.h" #include "pipeline_handler.h" @@ -56,13 +57,15 @@ LOG_DECLARE_CATEGORY(Camera) * \brief Create a camera instance * \param[in] name The name of the camera device * \param[in] pipe The pipeline handler responsible for the camera device + * \param[in] streams Array of streams the camera provides * * The caller is responsible for guaranteeing unicity of the camera name. * * \return A shared pointer to the newly created camera object */ std::shared_ptr Camera::create(PipelineHandler *pipe, - const std::string &name) + const std::string &name, + const std::vector &streams) { struct Allocator : std::allocator { void construct(void *p, PipelineHandler *pipe, @@ -76,7 +79,12 @@ std::shared_ptr Camera::create(PipelineHandler *pipe, } }; - return std::allocate_shared(Allocator(), pipe, name); + std::shared_ptr camera = + std::allocate_shared(Allocator(), pipe, name); + + camera->streams_ = streams; + + return camera; } /** @@ -102,7 +110,8 @@ const std::string &Camera::name() const */ Camera::Camera(PipelineHandler *pipe, const std::string &name) - : pipe_(pipe->shared_from_this()), name_(name), acquired_(false) + : pipe_(pipe->shared_from_this()), name_(name), acquired_(false), + disconnected_(false) { } @@ -125,7 +134,7 @@ void Camera::disconnect() { LOG(Camera, Debug) << "Disconnecting camera " << name_; - /** \todo Block API calls when they will be implemented. */ + disconnected_ = true; disconnected.emit(this); } @@ -164,4 +173,21 @@ void Camera::release() acquired_ = false; } +/** + * \brief Retrieve all the camera's stream information + * + * Retrieve all of the camera's static stream information. The static + * information describes among other things how many streams the camera + * support and each streams capabilities. + * + * \return An array of all the camera's streams valid streams. + */ +std::vector Camera::streams() const +{ + if (disconnected_) + return std::vector{}; + + return streams_; +} + } /* namespace libcamera */ diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index d74655d037728feb..f2029d17b4ad0273 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -9,6 +9,7 @@ #include #include +#include #include "device_enumerator.h" #include "log.h" @@ -37,6 +38,7 @@ private: : dev_(nullptr) {} ~IPU3CameraData() { delete dev_; } V4L2Device *dev_; + Stream stream_; }; std::shared_ptr cio2_; @@ -196,8 +198,11 @@ void PipelineHandlerIPU3::registerCameras() if (link->setEnabled(true)) continue; + IPU3CameraData *data = new IPU3CameraData(); + std::string cameraName = sensor->name() + " " + std::to_string(id); - std::shared_ptr camera = Camera::create(this, cameraName); + std::vector streams{ &data->stream_ }; + std::shared_ptr camera = Camera::create(this, cameraName, streams); /* * If V4L2 device creation fails, the Camera instance won't be @@ -209,10 +214,10 @@ void PipelineHandlerIPU3::registerCameras() LOG(IPU3, Error) << "Failed to register camera[" << numCameras << "] \"" << cameraName << "\""; + delete data; continue; } - IPU3CameraData *data = new IPU3CameraData(); data->dev_ = videoDev; setCameraData(camera.get(), std::move(std::unique_ptr(data))); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index c51e8bc1f2c2bf25..8ea7ac74d2a5395d 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "device_enumerator.h" #include "media_device.h" @@ -25,6 +26,7 @@ public: private: std::shared_ptr media_; V4L2Device *video_; + Stream stream_; }; PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager) @@ -64,7 +66,8 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) return false; } - std::shared_ptr camera = Camera::create(this, media_->model()); + std::vector streams{ &stream_ }; + std::shared_ptr camera = Camera::create(this, media_->model(), streams); registerCamera(std::move(camera)); hotplugMediaDevice(media_.get()); diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index f58a97d51619515d..9e1cf11a20c7a7e3 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "device_enumerator.h" #include "media_device.h" @@ -23,6 +24,7 @@ public: private: std::shared_ptr media_; + Stream stream_; }; PipeHandlerVimc::PipeHandlerVimc(CameraManager *manager) @@ -56,7 +58,8 @@ bool PipeHandlerVimc::match(DeviceEnumerator *enumerator) media_->acquire(); - std::shared_ptr camera = Camera::create(this, "Dummy VIMC Camera"); + std::vector streams{ &stream_ }; + std::shared_ptr camera = Camera::create(this, "Dummy VIMC Camera", streams); registerCamera(std::move(camera)); return true; From patchwork Tue Jan 29 02:00:47 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: 438 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 6A53D60DB7 for ; Tue, 29 Jan 2019 03:01:00 +0100 (CET) X-Halon-ID: b82ac864-2369-11e9-874f-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id b82ac864-2369-11e9-874f-005056917f90; Tue, 29 Jan 2019 03:00:58 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 29 Jan 2019 03:00:47 +0100 Message-Id: <20190129020048.16774-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> References: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 5/6] libcamera: pipeline: extend pipelines to support stream 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, 29 Jan 2019 02:01:00 -0000 All streams which are to be used for capture need to be configured at the same time. This allows the pipeline handler to take any dependencies between the different streams and their configuration into account when setting up the hardware. Extend the pipeline API and all pipeline implementations with two new functions, one to read a default configuration and one to set a new configuration. Both functions operate on a group of streams which the pipeline handler should consider when performing the operations. In the current implemented pipelines this is rather easy as they only have one stream each per camera. Furthermore as there is yet no way for the pipeline handlers to interact with the hardware all they do is return a null format and logs that a default configuration have been requested and log that a new configuration have been requested. Future work based on more components are needed to make the pipelines return a good default format and actually interact with the hardware. Signed-off-by: Niklas Söderlund --- src/libcamera/include/pipeline_handler.h | 7 +++++ src/libcamera/pipeline/ipu3/ipu3.cpp | 36 ++++++++++++++++++++++++ src/libcamera/pipeline/uvcvideo.cpp | 35 +++++++++++++++++++++++ src/libcamera/pipeline/vimc.cpp | 35 +++++++++++++++++++++++ src/libcamera/pipeline_handler.cpp | 34 ++++++++++++++++++++++ 5 files changed, 147 insertions(+) diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index 080997e22e545e01..b4321f0fa0f765be 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -18,6 +18,8 @@ class Camera; class CameraManager; class DeviceEnumerator; class MediaDevice; +class Stream; +class StreamConfiguration; class CameraData { @@ -38,6 +40,11 @@ public: PipelineHandler(CameraManager *manager); virtual ~PipelineHandler(); + virtual std::map + streamConfiguration(Camera *camera, std::vector &streams) = 0; + virtual int configureStreams(Camera *camera, + std::map &config) = 0; + virtual bool match(DeviceEnumerator *enumerator) = 0; protected: diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index f2029d17b4ad0273..ea230c7b691b2848 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -28,6 +28,12 @@ public: PipelineHandlerIPU3(CameraManager *manager); ~PipelineHandlerIPU3(); + std::map + streamConfiguration(Camera *camera, + std::vector &streams); + int configureStreams(Camera *camera, + std::map &config); + bool match(DeviceEnumerator *enumerator); private: @@ -62,6 +68,36 @@ PipelineHandlerIPU3::~PipelineHandlerIPU3() imgu_->release(); } +std::map +PipelineHandlerIPU3::streamConfiguration(Camera *camera, + std::vector &streams) +{ + IPU3CameraData *data = dynamic_cast(cameraData(camera)); + + std::map configs; + + StreamConfiguration config{}; + + LOG(IPU3, Info) << "TODO: Return a good default format"; + + configs[&data->stream_] = config; + + return configs; +} + +int PipelineHandlerIPU3::configureStreams(Camera *camera, + std::map &config) +{ + IPU3CameraData *data = dynamic_cast(cameraData(camera)); + + StreamConfiguration *cfg = &config[&data->stream_]; + + LOG(IPU3, Info) << "TODO: Configure the camera for resolution " << + cfg->width << "x" << cfg->height; + + return 0; +} + bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) { DeviceMatch cio2_dm("ipu3-cio2"); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 8ea7ac74d2a5395d..4647ed95e929940a 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -9,18 +9,27 @@ #include #include "device_enumerator.h" +#include "log.h" #include "media_device.h" #include "pipeline_handler.h" #include "v4l2_device.h" namespace libcamera { +LOG_DEFINE_CATEGORY(UVC) + class PipelineHandlerUVC : public PipelineHandler { public: PipelineHandlerUVC(CameraManager *manager); ~PipelineHandlerUVC(); + std::map + streamConfiguration(Camera *camera, + std::vector &streams); + int configureStreams(Camera *camera, + std::map &config); + bool match(DeviceEnumerator *enumerator); private: @@ -43,6 +52,32 @@ PipelineHandlerUVC::~PipelineHandlerUVC() media_->release(); } +std::map +PipelineHandlerUVC::streamConfiguration(Camera *camera, + std::vector &streams) +{ + std::map configs; + + StreamConfiguration config{}; + + LOG(UVC, Info) << "TODO: Return a good default format"; + + configs[&stream_] = config; + + return configs; +} + +int PipelineHandlerUVC::configureStreams(Camera *camera, + std::map &config) +{ + StreamConfiguration *cfg = &config[&stream_]; + + LOG(UVC, Info) << "TODO: Configure the camera for resolution " << + cfg->width << "x" << cfg->height; + + return 0; +} + bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) { DeviceMatch dm("uvcvideo"); diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 9e1cf11a20c7a7e3..835f8f512c4ac53a 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -9,17 +9,26 @@ #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: PipeHandlerVimc(CameraManager *manager); ~PipeHandlerVimc(); + std::map + streamConfiguration(Camera *camera, + std::vector &streams); + int configureStreams(Camera *camera, + std::map &config); + bool match(DeviceEnumerator *enumerator); private: @@ -38,6 +47,32 @@ PipeHandlerVimc::~PipeHandlerVimc() media_->release(); } +std::map +PipeHandlerVimc::streamConfiguration(Camera *camera, + std::vector &streams) +{ + std::map configs; + + StreamConfiguration config{}; + + LOG(VIMC, Info) << "TODO: Return a good default format"; + + configs[&stream_] = config; + + return configs; +} + +int PipeHandlerVimc::configureStreams(Camera *camera, + std::map &config) +{ + StreamConfiguration *cfg = &config[&stream_]; + + LOG(VIMC, Info) << "TODO: Configure the camera for resolution " << + cfg->width << "x" << cfg->height; + + return 0; +} + bool PipeHandlerVimc::match(DeviceEnumerator *enumerator) { DeviceMatch dm("vimc"); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 1c8640799f714686..3a560e10c442717f 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -75,6 +75,40 @@ PipelineHandler::~PipelineHandler() { }; + +/** + * \fn PipelineHandler::streamConfiguration() + * \brief Retrieve a group of stream configurations for a specified camera + * \param[in] camera The camera to fetch default configuration from + * \param[in] streams An array of streams to fetch information about + * + * Retrieve the species camera's default configuration for a specified group of + * streams. The caller shall populate the \a streams array with the streams it + * wish to fetch the configuration from. The map of streams and configuration + * returned can then be examined by the caller to learn about the defualt + * parameters for the specified streams. + * + * The intended companion to this is \a configureStreams() which can be used to + * change the group of streams parameters. + * + * \return A map of successfully retrieved streams and configurations or an + * empty map on error. + */ + +/** + * \fn PipelineHandler::configureStreams() + * \brief Configure a group of streams for capture + * \param[in] camera The camera to configure + * \param[in] config A map of stream configurations to apply + * + * Configure the specified group of streams for \a camera according to the + * configuration specified in \a configs. The intended caller of this interface + * is the Camera class which will receive configuration to apply from the + * application. + * + * \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 29 02:00:48 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: 439 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E252860DB7 for ; Tue, 29 Jan 2019 03:01:00 +0100 (CET) X-Halon-ID: b8a41607-2369-11e9-874f-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id b8a41607-2369-11e9-874f-005056917f90; Tue, 29 Jan 2019 03:00:58 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 29 Jan 2019 03:00:48 +0100 Message-Id: <20190129020048.16774-7-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> References: <20190129020048.16774-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 6/6] libcamera: camera: extend camera object to support configuration of 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, 29 Jan 2019 02:01:01 -0000 Extend the camera to support reading and configuring formats for groups of streams. The implementation in the Camera are minimalistic as the heavy lifting are done by the pipeline handler implementations. The most important functionality the camera provides in this context is validation of data structures passed to it from the application and access control to the pipeline handler. Signed-off-by: Niklas Söderlund --- include/libcamera/camera.h | 4 +++ src/libcamera/camera.cpp | 61 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 3ebb8e96cc63b98a..7a0357f3a2919752 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -7,6 +7,7 @@ #ifndef __LIBCAMERA_CAMERA_H__ #define __LIBCAMERA_CAMERA_H__ +#include #include #include @@ -16,6 +17,7 @@ namespace libcamera { class PipelineHandler; class Stream; +class StreamConfiguration; class Camera final { @@ -35,6 +37,8 @@ public: void release(); std::vector streams() const; + std::map streamConfiguration(std::vector &streams); + int configureStreams(std::map &config); private: Camera(PipelineHandler *pipe, const std::string &name); diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index c8604ec8a8e6eaf4..69d28a10f1f73d0d 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -190,4 +190,65 @@ std::vector Camera::streams() const return streams_; } +/** + * \brief Retrieve a group of stream configurations + * \param[in] streams A map of stream IDs and configurations to setup + * + * Retrieve the camera's configuration for a specified group of streams. The + * caller can specifies which of the camera's streams to retrieve configuration + * from by populating \a streams. + * + * The easiest way to populate the array of streams to fetch configuration from + * is to first retrieve the camera's full array of stream by with streams() and + * then potentially trim it down to only contain the streams the caller + * are interested in. + * + * \return A map of successfully retrieved stream IDs and configurations or an + * empty list on error. + */ +std::map +Camera::streamConfiguration(std::vector &streams) +{ + if (disconnected_ || !streams.size()) + std::map{}; + + return pipe_->streamConfiguration(this, streams); +} + +/** + * \brief Configure the camera's streams prior to capture + * \param[in] config A map of stream IDs and configurations to setup + * + * Prior to starting capture, the camera must be configured to select a + * group of streams to be involved in the capture and their configuration. + * The caller specifies which streams are to be involved and their configuration + * by populating \a config. + * + * The easiest way to populate the array of config is to fetch an initial + * configuration from the camera with streamConfiguration() and then change the + * parameters to fit the caller's need and once all the streams parameters are + * configured hand that over to configureStreams() to actually setup the camera. + * + * Exclusive access to the camera shall be ensured by a call to acquire() prior + * to calling this function, otherwise an -EACCES error is be returned. + * + * \return 0 on success or a negative error code on error. + * \retval -ENODEV The camera is not connected to any hardware + * \retval -EACCES The user have not acquired exclusive access to the camera + * \retval -EINVAL The configuration is not valid + */ +int Camera::configureStreams(std::map &config) +{ + if (disconnected_) + return -ENODEV; + + if (!acquired_) + return -EACCES; + + if (!config.size()) + return -EINVAL; + + return pipe_->configureStreams(this, config); +} + } /* namespace libcamera */