From patchwork Fri Apr 24 01:16:54 2020 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: 3509 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 34269603F9 for ; Fri, 24 Apr 2020 03:17:06 +0200 (CEST) X-Halon-ID: 48f292dc-85c9-11ea-aeed-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2392.dip0.t-ipconnect.de [79.202.35.146]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 48f292dc-85c9-11ea-aeed-005056917f90; Fri, 24 Apr 2020 03:16:54 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 24 Apr 2020 03:16:54 +0200 Message-Id: <20200424011656.2889720-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200424011656.2889720-1-niklas.soderlund@ragnatech.se> References: <20200424011656.2889720-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/3] cam: Add helper class to parse stream configuration X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Apr 2020 01:17:06 -0000 Create a new helper class StreamOptionsParser to parse command line options describing stream configurations. The goal is to share this new class between cam and qcam. The parser inherits from OptionsParser which it aims to replace and allows for a common command line argument syntax to be inserted anywhere in the argument list with addStreamOptions(), still allowing for any short and long option name. The Options data carrier returned inherits from OptionsParser::Options and extends it with new functions; roles() and applyCameraParameters(). The new functions makes it easy to generate and override the default values of a camera configuration. Signed-off-by: Niklas Söderlund --- src/cam/meson.build | 1 + src/cam/stream_options.cpp | 116 +++++++++++++++++++++++++++++++++++++ src/cam/stream_options.h | 63 ++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 src/cam/stream_options.cpp create mode 100644 src/cam/stream_options.h diff --git a/src/cam/meson.build b/src/cam/meson.build index 2419d648bc17e02b..162d6333f94e4851 100644 --- a/src/cam/meson.build +++ b/src/cam/meson.build @@ -4,6 +4,7 @@ cam_sources = files([ 'event_loop.cpp', 'main.cpp', 'options.cpp', + 'stream_options.cpp', ]) cam = executable('cam', cam_sources, diff --git a/src/cam/stream_options.cpp b/src/cam/stream_options.cpp new file mode 100644 index 0000000000000000..22bf61f2c13d10c1 --- /dev/null +++ b/src/cam/stream_options.cpp @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020, Raspberry Pi (Trading) Ltd. + * + * stream_options.cpp - Helper to parse options for stremas + */ +#include "stream_options.h" + +#include + +using namespace libcamera; + +int StreamOptionsParser::Options::applyCameraParameters(CameraConfiguration *config) const +{ + if (!config) { + std::cerr << "No configuration provided" << std::endl; + return -EINVAL; + } + + if (config->size() != streamParameters_.size()) { + std::cerr + << "Number of streams in configuration " + << config->size() + << " does not match number of streams parsed " + << streamParameters_.size() + << std::endl; + return -EINVAL; + } + + unsigned int i = 0; + for (auto const ¶m : streamParameters_) { + StreamConfiguration &cfg = config->at(i++); + + if (param.size.width && param.size.height) + cfg.size = param.size; + + if (param.pixelFormat.isValid()) + cfg.pixelFormat = param.pixelFormat; + } + + return 0; +} + +int StreamOptionsParser::addStreamOptions(int opt, const char *name) +{ + if (opt_) + return -EINVAL; + + opt_ = opt; + + streamKeyValue_.addOption("role", OptionString, + "Role for the stream (viewfinder, video, still, stillraw)", + ArgumentRequired); + streamKeyValue_.addOption("width", OptionInteger, "Width in pixels", + ArgumentRequired); + streamKeyValue_.addOption("height", OptionInteger, "Height in pixels", + ArgumentRequired); + streamKeyValue_.addOption("pixelformat", OptionInteger, "Pixel format", + ArgumentRequired); + + return addOption(opt_, &streamKeyValue_, + "Set configuration of a camera stream", name, true); +} + +StreamOptionsParser::Options StreamOptionsParser::parse(int argc, char *argv[]) +{ + OptionsParser::Options options = OptionsParser::parse(argc, argv); + + if (!opt_ || !options.isSet(opt_)) + return Options(options, {StreamRole::Viewfinder}); + + StreamRoles roles; + std::vector parameters; + + for (auto const &value : options[opt_].toArray()) { + KeyValueParser::Options opts = value.toKeyValues(); + Options::Parameters param; + + if (opts.isSet("width") && opts.isSet("height")) { + param.size.width = opts["width"]; + param.size.height = opts["height"]; + } + + /* TODO: Translate 4CC string to ID. */ + if (opts.isSet("pixelformat")) + param.pixelFormat = PixelFormat(opts["pixelformat"]); + + roles.push_back(parseRole(opts)); + parameters.push_back(param); + } + + return Options(options, roles, parameters); +} + +StreamRole StreamOptionsParser::parseRole(KeyValueParser::Options opts) +{ + if (!opts.isSet("role")) + return StreamRole::Viewfinder; + + std::string role = opts["role"].toString(); + + if (role == "viewfinder") + return StreamRole::Viewfinder; + if (role == "video") + return StreamRole::VideoRecording; + if (role == "still") + return StreamRole::StillCapture; + if (role == "stillraw") + return StreamRole::StillCaptureRaw; + + /* No stream role found, warn and default to viewfinder. */ + std::cerr << "Unknown stream role " << role + << ", adjusted to viewfinder" << std::endl; + + return StreamRole::Viewfinder; +} diff --git a/src/cam/stream_options.h b/src/cam/stream_options.h new file mode 100644 index 0000000000000000..a0f8a456b44fe275 --- /dev/null +++ b/src/cam/stream_options.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020, Raspberry Pi (Trading) Ltd. + * + * stream_options.h - Helper to parse options for stremas + */ +#ifndef __CAM_STREAM_OPTIONS_H__ +#define __CAM_STREAM_OPTIONS_H__ + +#include +#include + +#include "options.h" + +using namespace libcamera; + +class StreamOptionsParser : public OptionsParser +{ +public: + class Options : public OptionsParser::Options + { + public: + struct Parameters { + PixelFormat pixelFormat; + Size size; + }; + + Options() + : OptionsParser::Options() + { + } + + Options(OptionsParser::Options options, StreamRoles roles = {}, + std::vector parameters = {}) + : OptionsParser::Options(options), roles_(roles), + streamParameters_(parameters) + { + } + + const StreamRoles &roles() const { return roles_; } + int applyCameraParameters(CameraConfiguration *config) const; + + private: + StreamRoles roles_; + std::vector streamParameters_; + }; + + StreamOptionsParser() + : opt_(0) + { + } + + int addStreamOptions(int opt, const char *name = nullptr); + Options parse(int argc, char *argv[]); + +private: + StreamRole parseRole(KeyValueParser::Options opts); + + int opt_; + KeyValueParser streamKeyValue_; +}; + +#endif /* __CAM_STREAM_OPTIONS_H__ */