From patchwork Mon Apr 8 13:48:10 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: 941 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 98D0D60004 for ; Mon, 8 Apr 2019 15:48:40 +0200 (CEST) X-Halon-ID: f9ac835b-5a04-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id f9ac835b-5a04-11e9-846a-005056917a89; Mon, 08 Apr 2019 15:48:34 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 8 Apr 2019 15:48:10 +0200 Message-Id: <20190408134817.15247-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> References: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 1/8] cam: Rework how streams configuration is prepared 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: Mon, 08 Apr 2019 13:48:40 -0000 In preparation of reworking how a default configuration is retrieved from a camera separate preparation of stream configuration and application into two different functions. Reason for this is that preparation of camera configuration will become more complex. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- src/cam/main.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/cam/main.cpp b/src/cam/main.cpp index e7490c32f99a01ad..b5895fae85699b26 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -78,27 +78,27 @@ static int parseOptions(int argc, char *argv[]) return 0; } -static int configureStreams(Camera *camera, std::set &streams) +static int prepareCameraConfig(std::map *config) { - KeyValueParser::Options format = options[OptFormat]; - Stream *id = *streams.begin(); - - std::map config = - camera->streamConfiguration(streams); + std::set streams = camera->streams(); + *config = camera->streamConfiguration(streams); + Stream *stream = config->begin()->first; if (options.isSet(OptFormat)) { + KeyValueParser::Options format = options[OptFormat]; + if (format.isSet("width")) - config[id].width = format["width"]; + (*config)[stream].width = format["width"]; if (format.isSet("height")) - config[id].height = format["height"]; + (*config)[stream].height = format["height"]; /* TODO: Translate 4CC string to ID. */ if (format.isSet("pixelformat")) - config[id].pixelFormat = format["pixelformat"]; + (*config)[stream].pixelFormat = format["pixelformat"]; } - return camera->configureStreams(config); + return 0; } static void requestComplete(Request *request, const std::map &buffers) @@ -136,18 +136,23 @@ static void requestComplete(Request *request, const std::map static int capture() { - int ret; - - std::set streams = camera->streams(); + std::map config; std::vector requests; + int ret; - ret = configureStreams(camera.get(), streams); + ret = prepareCameraConfig(&config); + if (ret) { + std::cout << "Failed to prepare camera configuration" << std::endl; + return ret; + } + + ret = camera->configureStreams(config); if (ret < 0) { std::cout << "Failed to configure camera" << std::endl; return ret; } - Stream *stream = *streams.begin(); + Stream *stream = config.begin()->first; ret = camera->allocateBuffers(); if (ret) { From patchwork Mon Apr 8 13:48:11 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: 942 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 71CBB60004 for ; Mon, 8 Apr 2019 15:48:53 +0200 (CEST) X-Halon-ID: 011670e1-5a05-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 011670e1-5a05-11e9-846a-005056917a89; Mon, 08 Apr 2019 15:48:47 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 8 Apr 2019 15:48:11 +0200 Message-Id: <20190408134817.15247-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> References: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 2/8] test: camera: Remove streams argument from configurationValid() 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: Mon, 08 Apr 2019 13:48:53 -0000 In preparation of reworking how a default configuration is retrieved from a camera remove the streams and validation using the stream when judging if a camera configuration is valid. This is needed as once stream usage hints are added applications will no longer fetch default configuration based on Stream IDs so using them to verify the returned format is not useful. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- test/camera/camera_test.cpp | 25 ++++++++----------------- test/camera/camera_test.h | 3 +-- test/camera/capture.cpp | 2 +- test/camera/configuration_default.cpp | 2 +- test/camera/configuration_set.cpp | 2 +- 5 files changed, 12 insertions(+), 22 deletions(-) diff --git a/test/camera/camera_test.cpp b/test/camera/camera_test.cpp index a92f2165bf3a53c1..1609c4b02842186a 100644 --- a/test/camera/camera_test.cpp +++ b/test/camera/camera_test.cpp @@ -46,27 +46,18 @@ void CameraTest::cleanup() cm_->stop(); }; -bool CameraTest::configurationValid(const std::set &streams, - const std::map &conf) const +bool CameraTest::configurationValid(const std::map &config) const { - /* Test that the numbers of streams matches that of configuration. */ - if (streams.size() != conf.size()) + /* Test that the configuration is not empty. */ + if (config.empty()) return false; - /* - * Test that stream can be found in configuration and that the - * configuration is valid. - */ - for (Stream *stream : streams) { - std::map::const_iterator it = - conf.find(stream); + /* Test that configuration is valid. */ + for (auto const &it : config) { + const StreamConfiguration &conf = it.second; - if (it == conf.end()) - return false; - - const StreamConfiguration *sconf = &it->second; - if (sconf->width == 0 || sconf->height == 0 || - sconf->pixelFormat == 0 || sconf->bufferCount == 0) + if (conf.width == 0 || conf.height == 0 || + conf.pixelFormat == 0 || conf.bufferCount == 0) return false; } diff --git a/test/camera/camera_test.h b/test/camera/camera_test.h index 48fb47a23fe8f49c..5801fad3281e1653 100644 --- a/test/camera/camera_test.h +++ b/test/camera/camera_test.h @@ -23,8 +23,7 @@ protected: int init(); void cleanup(); - bool configurationValid(const std::set &streams, - const std::map &conf) const; + bool configurationValid(const std::map &config) const; std::shared_ptr camera_; diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index 28eb61405d90a4c7..f6932b7505571712 100644 --- a/test/camera/capture.cpp +++ b/test/camera/capture.cpp @@ -48,7 +48,7 @@ protected: camera_->streamConfiguration(streams); StreamConfiguration *sconf = &conf.begin()->second; - if (!configurationValid(streams, conf)) { + if (!configurationValid(conf)) { cout << "Failed to read default configuration" << endl; return TestFail; } diff --git a/test/camera/configuration_default.cpp b/test/camera/configuration_default.cpp index 71e79844667591b2..53ee021d33ca39b1 100644 --- a/test/camera/configuration_default.cpp +++ b/test/camera/configuration_default.cpp @@ -32,7 +32,7 @@ protected: return TestFail; } - if (!configurationValid(streams, conf)) { + if (!configurationValid(conf)) { cout << "Default configuration invalid" << endl; return TestFail; } diff --git a/test/camera/configuration_set.cpp b/test/camera/configuration_set.cpp index dedb85009335aa46..cac1da959f241bc5 100644 --- a/test/camera/configuration_set.cpp +++ b/test/camera/configuration_set.cpp @@ -23,7 +23,7 @@ protected: camera_->streamConfiguration(streams); StreamConfiguration *sconf = &conf.begin()->second; - if (!configurationValid(streams, conf)) { + if (!configurationValid(conf)) { cout << "Failed to read default configuration" << endl; return TestFail; } From patchwork Mon Apr 8 13:48:12 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: 943 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5F29C60004 for ; Mon, 8 Apr 2019 15:49:06 +0200 (CEST) X-Halon-ID: 0889b844-5a05-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 0889b844-5a05-11e9-846a-005056917a89; Mon, 08 Apr 2019 15:48:59 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 8 Apr 2019 15:48:12 +0200 Message-Id: <20190408134817.15247-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> References: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 3/8] test: camera: Remove test for bad Stream IDs 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: Mon, 08 Apr 2019 13:49:06 -0000 In preparation of reworking how a default configuration is retrieved from a camera remove test that stream IDs must be valid as the data type passed to Camera::streamConfiguration() will change. This change is in preparation for an invasive change. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- test/camera/configuration_default.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/test/camera/configuration_default.cpp b/test/camera/configuration_default.cpp index 53ee021d33ca39b1..856cd415f7a6aec1 100644 --- a/test/camera/configuration_default.cpp +++ b/test/camera/configuration_default.cpp @@ -49,19 +49,6 @@ protected: return TestFail; } - /* - * Test that asking for configuration for an array of bad streams - * returns an empty list of configurations. - */ - Stream *stream_bad = reinterpret_cast(0xdeadbeef); - std::set streams_bad = { stream_bad }; - conf = camera_->streamConfiguration(streams_bad); - if (!conf.empty()) { - cout << "Failed to retrieve configuration for bad streams" - << endl; - return TestFail; - } - return TestPass; } }; From patchwork Mon Apr 8 13:48:13 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: 944 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 4728C60004 for ; Mon, 8 Apr 2019 15:49:17 +0200 (CEST) X-Halon-ID: 0fdf0ff1-5a05-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 0fdf0ff1-5a05-11e9-846a-005056917a89; Mon, 08 Apr 2019 15:49:11 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 8 Apr 2019 15:48:13 +0200 Message-Id: <20190408134817.15247-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> References: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 4/8] libcamera: Make geometry.h a public header 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: Mon, 08 Apr 2019 13:49:17 -0000 Make the geometry header public so it can be used by the API facing applications. Signed-off-by: Niklas Söderlund Reviewed-by: Kieran Bingham Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- {src/libcamera/include => include/libcamera}/geometry.h | 0 include/libcamera/meson.build | 1 + src/libcamera/geometry.cpp | 2 +- src/libcamera/include/formats.h | 2 +- src/libcamera/include/v4l2_subdevice.h | 3 ++- src/libcamera/v4l2_subdevice.cpp | 3 ++- test/v4l2_subdevice/list_formats.cpp | 3 ++- 7 files changed, 9 insertions(+), 5 deletions(-) rename {src/libcamera/include => include/libcamera}/geometry.h (100%) diff --git a/src/libcamera/include/geometry.h b/include/libcamera/geometry.h similarity index 100% rename from src/libcamera/include/geometry.h rename to include/libcamera/geometry.h diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 3f4d1e28208b1084..83d226ac5078bfc7 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -4,6 +4,7 @@ libcamera_api = files([ 'camera_manager.h', 'event_dispatcher.h', 'event_notifier.h', + 'geometry.h', 'libcamera.h', 'object.h', 'request.h', diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp index d0c63c353ab3fc0b..d63eceaf827b99a4 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -7,7 +7,7 @@ #include -#include "geometry.h" +#include /** * \file geometry.h diff --git a/src/libcamera/include/formats.h b/src/libcamera/include/formats.h index 5fcfb11318e749d1..a73772b1eda068b4 100644 --- a/src/libcamera/include/formats.h +++ b/src/libcamera/include/formats.h @@ -11,7 +11,7 @@ #include #include -#include "geometry.h" +#include namespace libcamera { diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h index ee7c72468d21b83b..c71dce7d864494e5 100644 --- a/src/libcamera/include/v4l2_subdevice.h +++ b/src/libcamera/include/v4l2_subdevice.h @@ -11,8 +11,9 @@ #include #include +#include + #include "formats.h" -#include "geometry.h" #include "log.h" #include "media_object.h" diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 0abeaa204eda465b..e34cc1693b46b374 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -14,7 +14,8 @@ #include -#include "geometry.h" +#include + #include "log.h" #include "media_device.h" #include "media_object.h" diff --git a/test/v4l2_subdevice/list_formats.cpp b/test/v4l2_subdevice/list_formats.cpp index db486554b7b5c6a9..47ae3a1c1a28c350 100644 --- a/test/v4l2_subdevice/list_formats.cpp +++ b/test/v4l2_subdevice/list_formats.cpp @@ -9,7 +9,8 @@ #include #include -#include "geometry.h" +#include + #include "v4l2_subdevice.h" #include "v4l2_subdevice_test.h" From patchwork Mon Apr 8 13:48:14 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: 945 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D6D1A60004 for ; Mon, 8 Apr 2019 15:49:24 +0200 (CEST) X-Halon-ID: 16cd7c9c-5a05-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 16cd7c9c-5a05-11e9-846a-005056917a89; Mon, 08 Apr 2019 15:49:18 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 8 Apr 2019 15:48:14 +0200 Message-Id: <20190408134817.15247-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> References: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 5/8] libcamera: stream: Add basic stream usages 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: Mon, 08 Apr 2019 13:49:25 -0000 In preparation of reworking how a default configuration is retrieved from a camera add stream usages. The usages will be used by applications to describe how they intend to use a camera and replace the Stream IDs when retrieving default configuration from the camera using streamConfiguration(). Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- include/libcamera/stream.h | 40 +++++++++++++++++ src/libcamera/stream.cpp | 92 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index 970c479627fab064..d0f7b0e124851f10 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -8,6 +8,7 @@ #define __LIBCAMERA_STREAM_H__ #include +#include namespace libcamera { @@ -21,9 +22,48 @@ struct StreamConfiguration { unsigned int bufferCount; }; +class StreamUsage +{ +public: + enum Role { + StillCapture, + VideoRecording, + Viewfinder, + }; + + Role role() const { return role_; } + const Size &size() const { return size_; } + +protected: + explicit StreamUsage(Role role); + StreamUsage(Role role, int width, int height); + +private: + Role role_; + Size size_; +}; + class Stream final { public: + class StillCapture : public StreamUsage + { + public: + StillCapture(); + }; + + class VideoRecording : public StreamUsage + { + public: + VideoRecording(); + }; + + class Viewfinder : public StreamUsage + { + public: + Viewfinder(int width, int height); + }; + Stream(); BufferPool &bufferPool() { return bufferPool_; } const StreamConfiguration &configuration() const { return configuration_; } diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp index c4943c91b2e6ce13..85cd5256ee2f0aa4 100644 --- a/src/libcamera/stream.cpp +++ b/src/libcamera/stream.cpp @@ -60,6 +60,65 @@ namespace libcamera { * \brief Requested number of buffers to allocate for the stream */ +/** + * \class StreamUsage + * \brief Stream usage information + * + * The StreamUsage class describes how an application intends to use a stream. + * Usages are specified by applications and passed to cameras, that then select + * the most appropriate streams and their default configurations. + */ + +/** + * \enum StreamUsage::Role + * \brief Identify the role a stream is intended to play + * \var StreamUsage::StillCapture + * The stream is intended to capture high-resolution, high-quality still images + * with low frame rate. The captured frames may be exposed with flash. + * \var StreamUsage::VideoRecording + * The stream is intended to capture video for the purpose of recording or + * streaming. The video stream may produce a high frame rate and may be + * enhanced with video stabilization. + * \var StreamUsage::Viewfinder + * The stream is intended to capture video for the purpose of display on the + * local screen. The StreamUsage includes the desired resolution. Trade-offs + * between quality and usage of system resources are acceptable. + */ + +/** + * \fn StreamUsage::role() + * \brief Retrieve the stream role + * + * \return The stream role + */ + +/** + * \fn StreamUsage::size() + * \brief Retrieve desired size + * + * \return The desired size + */ + +/** + * \brief Create a stream usage + * \param[in] role Stream role + */ +StreamUsage::StreamUsage(Role role) + : role_(role) +{ +} + +/** + * \brief Create a stream usage with a desired size + * \param[in] role Stream role + * \param[in] width The desired width + * \param[in] height The desired height + */ +StreamUsage::StreamUsage(Role role, int width, int height) + : role_(role), size_(Size(width, height)) +{ +} + /** * \class Stream * \brief Video stream for a camera @@ -78,6 +137,39 @@ namespace libcamera { * optimal stream for the task. */ +/** + * \class Stream::StillCapture + * \brief Describe a still capture usage + */ +Stream::StillCapture::StillCapture() + : StreamUsage(Role::StillCapture) +{ +} + +/** + * \class Stream::VideoRecording + * \brief Describe a video recording usage + */ +Stream::VideoRecording::VideoRecording() + : StreamUsage(Role::VideoRecording) +{ +} + +/** + * \class Stream::Viewfinder + * \brief Describe a viewfinder usage + */ + +/** + * \brief Create a viewfinder usage with a desired dimension + * \param[in] width The desired viewfinder width + * \param[in] height The desired viewfinder height + */ +Stream::Viewfinder::Viewfinder(int width, int height) + : StreamUsage(Role::Viewfinder, width, height) +{ +} + /** * \brief Construct a stream with default parameters */ From patchwork Mon Apr 8 13:48:15 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: 946 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 347A360004 for ; Mon, 8 Apr 2019 15:49:38 +0200 (CEST) X-Halon-ID: 1b1f14da-5a05-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 1b1f14da-5a05-11e9-846a-005056917a89; Mon, 08 Apr 2019 15:49:27 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 8 Apr 2019 15:48:15 +0200 Message-Id: <20190408134817.15247-7-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> References: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 6/8] libcamera: camera: Add support for stream usages 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: Mon, 08 Apr 2019 13:49:38 -0000 Instead of requesting the default configuration for a set of streams where the application has to figure out which streams provided by the camera is best suited for its intended usage, have the library figure this out by using stream usages. The application asks the library for a list of streams and a suggested default configuration for them by supplying a list of stream usages. Once the list is retrieved the application can fine-tune the returned configuration and then try to apply it to the camera. Currently no pipeline handler is prepared to handle stream usages but nor did it make use of the list of Stream IDs which was the previous interface. The main reason for this is that all cameras currently only provide one stream each. This will still be the case but the API will be prepared to expand both pipeline handlers and applications to support streams usages. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- include/libcamera/camera.h | 3 ++- src/cam/main.cpp | 3 +-- src/libcamera/camera.cpp | 30 ++++++++---------------- src/libcamera/include/pipeline_handler.h | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 4 ++-- src/libcamera/pipeline/uvcvideo.cpp | 6 ++--- src/libcamera/pipeline/vimc.cpp | 6 ++--- src/libcamera/pipeline_handler.cpp | 10 ++++---- src/qcam/main_window.cpp | 5 ++-- test/camera/capture.cpp | 5 ++-- test/camera/configuration_default.cpp | 17 +++++--------- test/camera/configuration_set.cpp | 3 +-- test/camera/statemachine.cpp | 4 +--- 13 files changed, 37 insertions(+), 61 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 77e4cd1ee14c2c61..0386671c902e55e8 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -22,6 +22,7 @@ class PipelineHandler; class Request; class Stream; class StreamConfiguration; +class StreamUsage; class Camera final { @@ -44,7 +45,7 @@ public: const std::set &streams() const; std::map - streamConfiguration(std::set &streams); + streamConfiguration(const std::vector &usage); int configureStreams(std::map &config); int allocateBuffers(); diff --git a/src/cam/main.cpp b/src/cam/main.cpp index b5895fae85699b26..d45ffd372d932d76 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -80,8 +80,7 @@ static int parseOptions(int argc, char *argv[]) static int prepareCameraConfig(std::map *config) { - std::set streams = camera->streams(); - *config = camera->streamConfiguration(streams); + *config = camera->streamConfiguration({ Stream::VideoRecording() }); Stream *stream = config->begin()->first; if (options.isSet(OptFormat)) { diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 8ee9cc0866167ae1..63fde0ffc3d02d6c 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -345,33 +345,23 @@ const std::set &Camera::streams() const } /** - * \brief Retrieve a group of stream configurations - * \param[in] streams A map of stream IDs and configurations to setup + * \brief Retrieve a group of stream configurations according to stream usages + * \param[in] usages A list of stream usages * - * 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. + * Retrieve configuration for a set of desired usages. The caller specifies a + * list of stream usages and the camera returns a map of suitable streams and + * their suggested default configurations. * - * The easiest way to populate the array of streams to fetch configuration from - * is to first retrieve the camera's full array of stream 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. + * \return A map of streams to configurations if the requested usages can be + * satisfied, or an empty map otherwise */ std::map -Camera::streamConfiguration(std::set &streams) +Camera::streamConfiguration(const std::vector &usages) { - if (disconnected_ || !streams.size()) + if (disconnected_ || !usages.size() || usages.size() > streams_.size()) return std::map{}; - for (Stream *stream : streams) { - if (streams_.find(stream) == streams_.end()) - return std::map{}; - } - - return pipe_->streamConfiguration(this, streams); + return pipe_->streamConfiguration(this, usages); } /** diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index acb376e07030ae03..8a1706fad5377bf4 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -53,7 +53,7 @@ public: virtual bool match(DeviceEnumerator *enumerator) = 0; virtual std::map - streamConfiguration(Camera *camera, std::set &streams) = 0; + streamConfiguration(Camera *camera, const std::vector &usages) = 0; virtual int configureStreams(Camera *camera, std::map &config) = 0; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index fed04ce50387f1d9..5d01504e24471bcf 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -141,7 +141,7 @@ public: std::map streamConfiguration(Camera *camera, - std::set &streams) override; + const std::vector &usages) override; int configureStreams(Camera *camera, std::map &config) override; @@ -206,7 +206,7 @@ PipelineHandlerIPU3::~PipelineHandlerIPU3() std::map PipelineHandlerIPU3::streamConfiguration(Camera *camera, - std::set &streams) + const std::vector &usages) { std::map configs; IPU3CameraData *data = cameraData(camera); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index cc3e0cd9afab38b9..dfff7116bc2aa5d3 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -28,7 +28,7 @@ public: std::map streamConfiguration(Camera *camera, - std::set &streams) override; + const std::vector &usages) override; int configureStreams(Camera *camera, std::map &config) override; @@ -84,14 +84,12 @@ PipelineHandlerUVC::~PipelineHandlerUVC() std::map PipelineHandlerUVC::streamConfiguration(Camera *camera, - std::set &streams) + const std::vector &usages) { UVCCameraData *data = cameraData(camera); - std::map configs; StreamConfiguration config{}; - LOG(UVC, Debug) << "Retrieving default format"; config.width = 640; config.height = 480; config.pixelFormat = V4L2_PIX_FMT_YUYV; diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 2e8c26fb7c0b2708..4da4ca018d4b942a 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -28,7 +28,7 @@ public: std::map streamConfiguration(Camera *camera, - std::set &streams) override; + const std::vector &usages) override; int configureStreams(Camera *camera, std::map &config) override; @@ -84,14 +84,12 @@ PipelineHandlerVimc::~PipelineHandlerVimc() std::map PipelineHandlerVimc::streamConfiguration(Camera *camera, - std::set &streams) + const std::vector &usages) { VimcCameraData *data = cameraData(camera); std::map configs; - StreamConfiguration config{}; - LOG(VIMC, Debug) << "Retrieving default format"; config.width = 640; config.height = 480; config.pixelFormat = V4L2_PIX_FMT_RGB24; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 1a858f2638ceac5f..0574f9904367605c 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -152,13 +152,13 @@ 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 + * \param[in] usages A list of stream usages * * 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. + * use-cases. The caller shall populate the \a usages array with the use-cases it + * wishes to fetch the default configuration for. The map of streams and + * configurations returned can then be examined by the caller to learn about + * the default parameters for the specified streams. * * The intended companion to this is \a configureStreams() which can be used to * change the group of streams parameters. diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index fea701422015ce67..faa3bc5739dd8453 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -97,9 +97,8 @@ int MainWindow::startCapture() { int ret; - Stream *stream = *camera_->streams().begin(); - std::set streams{ stream }; - config_ = camera_->streamConfiguration(streams); + config_ = camera_->streamConfiguration({ Stream::VideoRecording() }); + Stream *stream = config_.begin()->first; ret = camera_->configureStreams(config_); if (ret < 0) { std::cout << "Failed to configure camera" << std::endl; diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index f6932b7505571712..b8dbdb62f9a50a33 100644 --- a/test/camera/capture.cpp +++ b/test/camera/capture.cpp @@ -42,10 +42,9 @@ protected: int run() { - Stream *stream = *camera_->streams().begin(); - std::set streams = { stream }; std::map conf = - camera_->streamConfiguration(streams); + camera_->streamConfiguration({ Stream::VideoRecording() }); + Stream *stream = conf.begin()->first; StreamConfiguration *sconf = &conf.begin()->second; if (!configurationValid(conf)) { diff --git a/test/camera/configuration_default.cpp b/test/camera/configuration_default.cpp index 856cd415f7a6aec1..09861716973d752c 100644 --- a/test/camera/configuration_default.cpp +++ b/test/camera/configuration_default.cpp @@ -20,14 +20,10 @@ protected: { std::map conf; - /* - * Test that asking for default configuration for a valid - * array of streams returns something valid. - */ - std::set streams = { *camera_->streams().begin() }; - conf = camera_->streamConfiguration(streams); + /* Test asking for configuration for a video stream. */ + conf = camera_->streamConfiguration({ Stream::VideoRecording() }); if (conf.empty()) { - cout << "Failed to retrieve configuration for valid streams" + cout << "Failed to retrieve configuration for video streams" << endl; return TestFail; } @@ -39,12 +35,11 @@ protected: /* * Test that asking for configuration for an empty array of - * streams returns an empty list of configurations. + * stream usages returns an empty list of configurations. */ - std::set streams_empty = {}; - conf = camera_->streamConfiguration(streams_empty); + conf = camera_->streamConfiguration({}); if (!conf.empty()) { - cout << "Failed to retrieve configuration for empty streams" + cout << "Failed to retrieve configuration for empty usage list" << endl; return TestFail; } diff --git a/test/camera/configuration_set.cpp b/test/camera/configuration_set.cpp index cac1da959f241bc5..1bc01e66625eedf0 100644 --- a/test/camera/configuration_set.cpp +++ b/test/camera/configuration_set.cpp @@ -18,9 +18,8 @@ class ConfigurationSet : public CameraTest protected: int run() { - std::set streams = { *camera_->streams().begin() }; std::map conf = - camera_->streamConfiguration(streams); + camera_->streamConfiguration({ Stream::VideoRecording() }); StreamConfiguration *sconf = &conf.begin()->second; if (!configurationValid(conf)) { diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp index f4395f2b1bfed698..ab3c6fb5bea38c36 100644 --- a/test/camera/statemachine.cpp +++ b/test/camera/statemachine.cpp @@ -235,9 +235,7 @@ protected: int run() { - Stream *stream = *camera_->streams().begin(); - std::set streams = { stream }; - defconf_ = camera_->streamConfiguration(streams); + defconf_ = camera_->streamConfiguration({ Stream::VideoRecording() }); if (testAvailable() != TestPass) { cout << "State machine in Available state failed" << endl; From patchwork Mon Apr 8 13:48:16 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: 947 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 7374E60004 for ; Mon, 8 Apr 2019 15:49:45 +0200 (CEST) X-Halon-ID: 2119dee3-5a05-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 2119dee3-5a05-11e9-846a-005056917a89; Mon, 08 Apr 2019 15:49:39 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 8 Apr 2019 15:48:16 +0200 Message-Id: <20190408134817.15247-8-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> References: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 7/8] libcamera: camera: Add CameraConfiguration 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: Mon, 08 Apr 2019 13:49:45 -0000 To properly support both multiple streams and stream usages the library must provide a method to map the stream usages to the returned streams configurations. Add a camera configuration object to handle this mapping. Applications can iterate over the returned camera configuration to retrieve the streams selected by the library in the same order as the usages it provided to the library. Application can use the operator[] to retrieve the stream pointer and the stream configuration. Using a numerical index retrieves the stream pointer, the numerical indexes corresponds to the insertion order of usages by the application, using the stream pointer retrieves the stream's configuration. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- include/libcamera/camera.h | 29 ++++++ src/libcamera/camera.cpp | 192 +++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 0386671c902e55e8..6038da63e9c5c67f 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -24,6 +24,35 @@ class Stream; class StreamConfiguration; class StreamUsage; +class CameraConfiguration +{ +public: + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; + + CameraConfiguration(); + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + bool isValid() const; + bool isEmpty() const; + std::size_t size() const; + + Stream *front(); + const Stream *front() const; + + Stream *operator[](unsigned int index) const; + StreamConfiguration &operator[](Stream *stream); + const StreamConfiguration &operator[](Stream *stream) const; + +private: + std::vector order_; + std::map config_; +}; + class Camera final { public: diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 63fde0ffc3d02d6c..c1b9561304b04ab5 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -39,6 +39,198 @@ namespace libcamera { LOG_DECLARE_CATEGORY(Camera) +/** + * \class CameraConfiguration + * \brief Hold configuration for streams of the camera + + * The CameraConfiguration holds an ordered list of streams and their associated + * StreamConfiguration. From a data storage point of view, the class operates as + * a map of Stream pointers to StreamConfiguration, with entries accessed with + * operator[](Stream *). Accessing an entry for a Stream pointer not yet stored + * in the configuration inserts a new empty entry. + * + * The class also suppors iterators, and from that point of view operates as a + * vector of Stream pointers. The streams are iterated in insertion order, and + * the operator[](int) returns the Stream pointer based on its insertion index. + * Accessing a stream with an invalid index returns a null pointer. + */ + +/** + * \typedef CameraConfiguration::iterator + * \brief Iterator for the streams in the configuration + */ + +/** + * \typedef CameraConfiguration::const_iterator + * \brief Const iterator for the streams in the configuration + */ + +/** + * \brief Create an empty camera configuration + */ +CameraConfiguration::CameraConfiguration() + : order_({}), config_({}) +{ +} + +/** + * \brief Retrieve an iterator to the first stream in the sequence + * + * \return An iterator to the first stream + */ +std::vector::iterator CameraConfiguration::begin() +{ + return order_.begin(); +} + +/** + * \brief Retrieve an iterator pointing to the past-the-end stream in the + * sequence + * + * \return An iterator to the element following the last stream + */ +std::vector::iterator CameraConfiguration::end() +{ + return order_.end(); +} + +/** + * \brief Retrieve a const iterator to the first element of the streams + * + * \return A const iterator to the first stream + */ +std::vector::const_iterator CameraConfiguration::begin() const +{ + return order_.begin(); +} + +/** + * \brief Retrieve a const iterator pointing to the past-the-end stream in the + * sequence + * + * \return A const iterator to the element following the last stream + */ +std::vector::const_iterator CameraConfiguration::end() const +{ + return order_.end(); +} + +/** + * \brief Check if the camera configuration is valid + * + * A camera configuration is deemed to be valid if it contains at least one + * stream configuration and that all stream configurations contain valid + * information. Stream configurations are deemed to be valid if all fields are + * none zero. + * + * \return True if the configuration is valid + */ +bool CameraConfiguration::isValid() const +{ + if (isEmpty()) + return false; + + for (auto const &it : config_) { + const StreamConfiguration &conf = it.second; + + if (conf.width == 0 || conf.height == 0 || + conf.pixelFormat == 0 || conf.bufferCount == 0) + return false; + } + + return true; +} + +/** + * \brief Check if the camera configuration is empty + * + * \return True if the configuration is empty + */ +bool CameraConfiguration::isEmpty() const +{ + return order_.empty(); +} + +/** + * \brief Retrieve the number of stream configurations + * + * \return Number of stream configurations + */ +std::size_t CameraConfiguration::size() const +{ + return order_.size(); +} + +/** + * \brief Access the first stream in the configuration + * + * \return The first stream in the configuration + */ +Stream *CameraConfiguration::front() +{ + return order_.front(); +} + +/** + * \brief Access the first stream in the configuration + * + * \return The first const stream pointer in the configuration + */ +const Stream *CameraConfiguration::front() const +{ + return order_.front(); +} + +/** + * \brief Retrieve a stream pointer from index + * \param[in] index Numerical index + * + * The \a index represents the zero based insertion order of stream and stream + * configuration into the camera configuration. + * + * \return The stream pointer at index, or a nullptr if the index is out of + * bounds + */ +Stream *CameraConfiguration::operator[](unsigned int index) const +{ + if (index >= order_.size()) + return nullptr; + + return order_.at(index); +} + +/** + * \brief Retrieve a reference to a stream configuration + * \param[in] stream Stream to retrieve configuration for + * + * If the camera configuration does not yet contain a configuration for + * the requested stream, create and return an empty stream configuration. + * + * \return The configuration for the stream + */ +StreamConfiguration &CameraConfiguration::operator[](Stream *stream) +{ + if (config_.find(stream) == config_.end()) + order_.push_back(stream); + + return config_[stream]; +} + +/** + * \brief Retrieve a const reference to a stream configuration + * \param[in] stream Stream to retrieve configuration for + * + * No new stream configuration is created if called with \a stream that is not + * already part of the camera configuration, doing so is an invalid operation + * and results in undefined behaviour. + * + * \return The configuration for the stream + */ +const StreamConfiguration &CameraConfiguration::operator[](Stream *stream) const +{ + return config_.at(stream); +} + /** * \class Camera * \brief Camera device From patchwork Mon Apr 8 13:48:17 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: 948 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 3388360004 for ; Mon, 8 Apr 2019 15:49:56 +0200 (CEST) X-Halon-ID: 27938546-5a05-11e9-846a-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 27938546-5a05-11e9-846a-005056917a89; Mon, 08 Apr 2019 15:49:49 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 8 Apr 2019 15:48:17 +0200 Message-Id: <20190408134817.15247-9-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> References: <20190408134817.15247-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 8/8] libcamera: Switch to CameraConfiguration 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: Mon, 08 Apr 2019 13:49:56 -0000 Implement the camera configuration thru out the library, tests, cam and qcam tools. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- include/libcamera/camera.h | 4 ++-- src/cam/main.cpp | 8 ++++---- src/libcamera/camera.cpp | 25 ++++++++++++------------ src/libcamera/include/pipeline_handler.h | 6 +++--- src/libcamera/pipeline/ipu3/ipu3.cpp | 10 +++++----- src/libcamera/pipeline/uvcvideo.cpp | 12 ++++++------ src/libcamera/pipeline/vimc.cpp | 12 ++++++------ src/libcamera/pipeline_handler.cpp | 6 +++--- src/qcam/main_window.cpp | 2 +- src/qcam/main_window.h | 2 +- test/camera/camera_test.cpp | 18 ----------------- test/camera/camera_test.h | 2 -- test/camera/capture.cpp | 8 ++++---- test/camera/configuration_default.cpp | 12 +++--------- test/camera/configuration_set.cpp | 6 +++--- test/camera/statemachine.cpp | 2 +- 16 files changed, 54 insertions(+), 81 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 6038da63e9c5c67f..b2dafda342fe6244 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -73,9 +73,9 @@ public: int release(); const std::set &streams() const; - std::map + CameraConfiguration streamConfiguration(const std::vector &usage); - int configureStreams(std::map &config); + int configureStreams(const CameraConfiguration &config); int allocateBuffers(); int freeBuffers(); diff --git a/src/cam/main.cpp b/src/cam/main.cpp index d45ffd372d932d76..99ce564afd695b07 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -78,10 +78,10 @@ static int parseOptions(int argc, char *argv[]) return 0; } -static int prepareCameraConfig(std::map *config) +static int prepareCameraConfig(CameraConfiguration *config) { *config = camera->streamConfiguration({ Stream::VideoRecording() }); - Stream *stream = config->begin()->first; + Stream *stream = config->front(); if (options.isSet(OptFormat)) { KeyValueParser::Options format = options[OptFormat]; @@ -135,7 +135,7 @@ static void requestComplete(Request *request, const std::map static int capture() { - std::map config; + CameraConfiguration config; std::vector requests; int ret; @@ -151,7 +151,7 @@ static int capture() return ret; } - Stream *stream = config.begin()->first; + Stream *stream = config.front(); ret = camera->allocateBuffers(); if (ret) { diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index c1b9561304b04ab5..e056a1232b1b1cd2 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -544,21 +544,21 @@ const std::set &Camera::streams() const * list of stream usages and the camera returns a map of suitable streams and * their suggested default configurations. * - * \return A map of streams to configurations if the requested usages can be - * satisfied, or an empty map otherwise + * \return A valid CameraConfiguration if the requested usages can be satisfied, + * or a invalid one otherwise */ -std::map +CameraConfiguration Camera::streamConfiguration(const std::vector &usages) { if (disconnected_ || !usages.size() || usages.size() > streams_.size()) - return std::map{}; + return CameraConfiguration(); return pipe_->streamConfiguration(this, usages); } /** * \brief Configure the camera's streams prior to capture - * \param[in] config A map of stream IDs and configurations to setup + * \param[in] config The camera 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. @@ -580,7 +580,7 @@ Camera::streamConfiguration(const std::vector &usages) * \retval -EACCES The camera is not in a state where it can be configured * \retval -EINVAL The configuration is not valid */ -int Camera::configureStreams(std::map &config) +int Camera::configureStreams(const CameraConfiguration &config) { int ret; @@ -590,14 +590,14 @@ int Camera::configureStreams(std::map &config) if (!stateBetween(CameraAcquired, CameraConfigured)) return -EACCES; - if (!config.size()) { + if (!config.isValid()) { LOG(Camera, Error) - << "Can't configure streams without a configuration"; + << "Can't configure camera with invalid configuration"; return -EINVAL; } - for (auto const &iter : config) { - if (streams_.find(iter.first) == streams_.end()) + for (Stream *stream : config) { + if (streams_.find(stream) == streams_.end()) return -EINVAL; } @@ -606,9 +606,8 @@ int Camera::configureStreams(std::map &config) return ret; activeStreams_.clear(); - for (auto const &iter : config) { - Stream *stream = iter.first; - const StreamConfiguration &cfg = iter.second; + for (Stream *stream : config) { + const StreamConfiguration &cfg = config[stream]; stream->configuration_ = cfg; activeStreams_.insert(stream); diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index 8a1706fad5377bf4..b6cbd3bae51b08dc 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -18,6 +18,7 @@ namespace libcamera { class Buffer; class BufferPool; class Camera; +class CameraConfiguration; class CameraManager; class DeviceEnumerator; class MediaDevice; @@ -52,10 +53,9 @@ public: virtual bool match(DeviceEnumerator *enumerator) = 0; - virtual std::map + virtual CameraConfiguration streamConfiguration(Camera *camera, const std::vector &usages) = 0; - virtual int configureStreams(Camera *camera, - std::map &config) = 0; + virtual int configureStreams(Camera *camera, const CameraConfiguration &config) = 0; virtual int allocateBuffers(Camera *camera, Stream *stream) = 0; virtual int freeBuffers(Camera *camera, Stream *stream) = 0; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 5d01504e24471bcf..ca09da753b908448 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -139,11 +139,11 @@ public: PipelineHandlerIPU3(CameraManager *manager); ~PipelineHandlerIPU3(); - std::map + CameraConfiguration streamConfiguration(Camera *camera, const std::vector &usages) override; int configureStreams(Camera *camera, - std::map &config) override; + const CameraConfiguration &config) override; int allocateBuffers(Camera *camera, Stream *stream) override; int freeBuffers(Camera *camera, Stream *stream) override; @@ -204,11 +204,11 @@ PipelineHandlerIPU3::~PipelineHandlerIPU3() imguMediaDev_->release(); } -std::map +CameraConfiguration PipelineHandlerIPU3::streamConfiguration(Camera *camera, const std::vector &usages) { - std::map configs; + CameraConfiguration configs; IPU3CameraData *data = cameraData(camera); StreamConfiguration *config = &configs[&data->stream_]; @@ -234,7 +234,7 @@ PipelineHandlerIPU3::streamConfiguration(Camera *camera, } int PipelineHandlerIPU3::configureStreams(Camera *camera, - std::map &config) + const CameraConfiguration &config) { IPU3CameraData *data = cameraData(camera); const StreamConfiguration &cfg = config[&data->stream_]; diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index dfff7116bc2aa5d3..cd472cfadd86b7ba 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -26,11 +26,11 @@ public: PipelineHandlerUVC(CameraManager *manager); ~PipelineHandlerUVC(); - std::map + CameraConfiguration streamConfiguration(Camera *camera, const std::vector &usages) override; int configureStreams(Camera *camera, - std::map &config) override; + const CameraConfiguration &config) override; int allocateBuffers(Camera *camera, Stream *stream) override; int freeBuffers(Camera *camera, Stream *stream) override; @@ -82,12 +82,12 @@ PipelineHandlerUVC::~PipelineHandlerUVC() media_->release(); } -std::map +CameraConfiguration PipelineHandlerUVC::streamConfiguration(Camera *camera, const std::vector &usages) { UVCCameraData *data = cameraData(camera); - std::map configs; + CameraConfiguration configs; StreamConfiguration config{}; config.width = 640; @@ -101,10 +101,10 @@ PipelineHandlerUVC::streamConfiguration(Camera *camera, } int PipelineHandlerUVC::configureStreams(Camera *camera, - std::map &config) + const CameraConfiguration &config) { UVCCameraData *data = cameraData(camera); - StreamConfiguration *cfg = &config[&data->stream_]; + const StreamConfiguration *cfg = &config[&data->stream_]; int ret; LOG(UVC, Debug) << "Configure the camera for resolution " diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 4da4ca018d4b942a..c8bbe2a19847ba1e 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -26,11 +26,11 @@ public: PipelineHandlerVimc(CameraManager *manager); ~PipelineHandlerVimc(); - std::map + CameraConfiguration streamConfiguration(Camera *camera, const std::vector &usages) override; int configureStreams(Camera *camera, - std::map &config) override; + const CameraConfiguration &config) override; int allocateBuffers(Camera *camera, Stream *stream) override; int freeBuffers(Camera *camera, Stream *stream) override; @@ -82,12 +82,12 @@ PipelineHandlerVimc::~PipelineHandlerVimc() media_->release(); } -std::map +CameraConfiguration PipelineHandlerVimc::streamConfiguration(Camera *camera, const std::vector &usages) { VimcCameraData *data = cameraData(camera); - std::map configs; + CameraConfiguration configs; StreamConfiguration config{}; config.width = 640; @@ -101,10 +101,10 @@ PipelineHandlerVimc::streamConfiguration(Camera *camera, } int PipelineHandlerVimc::configureStreams(Camera *camera, - std::map &config) + const CameraConfiguration &config) { VimcCameraData *data = cameraData(camera); - StreamConfiguration *cfg = &config[&data->stream_]; + const StreamConfiguration *cfg = &config[&data->stream_]; int ret; LOG(VIMC, Debug) << "Configure the camera for resolution " diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 0574f9904367605c..43550c0e0210b7b3 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -163,15 +163,15 @@ PipelineHandler::~PipelineHandler() * 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. + * \return A valid CameraConfiguration if the requested usages can be satisfied, + * or a invalid configuration otherwise */ /** * \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 + * \param[in] config The camera configurations to setup * * Configure the specified group of streams for \a camera according to the * configuration specified in \a configs. The intended caller of this interface diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index faa3bc5739dd8453..4bc0440370410525 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -98,7 +98,7 @@ int MainWindow::startCapture() int ret; config_ = camera_->streamConfiguration({ Stream::VideoRecording() }); - Stream *stream = config_.begin()->first; + Stream *stream = config_.front(); ret = camera_->configureStreams(config_); if (ret < 0) { std::cout << "Failed to configure camera" << std::endl; diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 5e27a8fd6b4eb8f3..9b31da2bf4b75a03 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -46,7 +46,7 @@ private: std::shared_ptr camera_; bool isCapturing_; - std::map config_; + CameraConfiguration config_; ViewFinder *viewfinder_; }; diff --git a/test/camera/camera_test.cpp b/test/camera/camera_test.cpp index 1609c4b02842186a..24ff5fe0c64d331e 100644 --- a/test/camera/camera_test.cpp +++ b/test/camera/camera_test.cpp @@ -45,21 +45,3 @@ void CameraTest::cleanup() cm_->stop(); }; - -bool CameraTest::configurationValid(const std::map &config) const -{ - /* Test that the configuration is not empty. */ - if (config.empty()) - return false; - - /* Test that configuration is valid. */ - for (auto const &it : config) { - const StreamConfiguration &conf = it.second; - - if (conf.width == 0 || conf.height == 0 || - conf.pixelFormat == 0 || conf.bufferCount == 0) - return false; - } - - return true; -} diff --git a/test/camera/camera_test.h b/test/camera/camera_test.h index 5801fad3281e1653..ffc8a485bfaff836 100644 --- a/test/camera/camera_test.h +++ b/test/camera/camera_test.h @@ -23,8 +23,6 @@ protected: int init(); void cleanup(); - bool configurationValid(const std::map &config) const; - std::shared_ptr camera_; private: diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index b8dbdb62f9a50a33..4e75a75c5b714c58 100644 --- a/test/camera/capture.cpp +++ b/test/camera/capture.cpp @@ -42,12 +42,12 @@ protected: int run() { - std::map conf = + CameraConfiguration conf = camera_->streamConfiguration({ Stream::VideoRecording() }); - Stream *stream = conf.begin()->first; - StreamConfiguration *sconf = &conf.begin()->second; + Stream *stream = conf.front(); + StreamConfiguration *sconf = &conf[stream]; - if (!configurationValid(conf)) { + if (!conf.isValid()) { cout << "Failed to read default configuration" << endl; return TestFail; } diff --git a/test/camera/configuration_default.cpp b/test/camera/configuration_default.cpp index 09861716973d752c..dd5106689f090921 100644 --- a/test/camera/configuration_default.cpp +++ b/test/camera/configuration_default.cpp @@ -18,17 +18,11 @@ class ConfigurationDefault : public CameraTest protected: int run() { - std::map conf; + CameraConfiguration conf; /* Test asking for configuration for a video stream. */ conf = camera_->streamConfiguration({ Stream::VideoRecording() }); - if (conf.empty()) { - cout << "Failed to retrieve configuration for video streams" - << endl; - return TestFail; - } - - if (!configurationValid(conf)) { + if (!conf.isValid()) { cout << "Default configuration invalid" << endl; return TestFail; } @@ -38,7 +32,7 @@ protected: * stream usages returns an empty list of configurations. */ conf = camera_->streamConfiguration({}); - if (!conf.empty()) { + if (conf.isValid()) { cout << "Failed to retrieve configuration for empty usage list" << endl; return TestFail; diff --git a/test/camera/configuration_set.cpp b/test/camera/configuration_set.cpp index 1bc01e66625eedf0..5ac2a7a908c8903d 100644 --- a/test/camera/configuration_set.cpp +++ b/test/camera/configuration_set.cpp @@ -18,11 +18,11 @@ class ConfigurationSet : public CameraTest protected: int run() { - std::map conf = + CameraConfiguration conf = camera_->streamConfiguration({ Stream::VideoRecording() }); - StreamConfiguration *sconf = &conf.begin()->second; + StreamConfiguration *sconf = &conf[conf.front()]; - if (!configurationValid(conf)) { + if (!conf.isValid()) { cout << "Failed to read default configuration" << endl; return TestFail; } diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp index ab3c6fb5bea38c36..8ae93bee7ca178d4 100644 --- a/test/camera/statemachine.cpp +++ b/test/camera/statemachine.cpp @@ -265,7 +265,7 @@ protected: return TestPass; } - std::map defconf_; + CameraConfiguration defconf_; }; } /* namespace */