| /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| /* |
| * Copyright (C) 2020, Raspberry Pi Ltd |
| * |
| * stream_options.cpp - Helper to parse options for streams |
| */ |
| #include "stream_options.h" |
| |
| #include <iostream> |
| |
| #include <libcamera/color_space.h> |
| |
| using namespace libcamera; |
| |
| StreamKeyValueParser::StreamKeyValueParser() |
| { |
| addOption("role", OptionString, |
| "Role for the stream (viewfinder, video, still, raw)", |
| ArgumentRequired); |
| addOption("width", OptionInteger, "Width in pixels", |
| ArgumentRequired); |
| addOption("height", OptionInteger, "Height in pixels", |
| ArgumentRequired); |
| addOption("pixelformat", OptionString, "Pixel format name", |
| ArgumentRequired); |
| addOption("colorspace", OptionString, "Color space", |
| ArgumentRequired); |
| } |
| |
| KeyValueParser::Options StreamKeyValueParser::parse(const char *arguments) |
| { |
| KeyValueParser::Options options = KeyValueParser::parse(arguments); |
| |
| if (options.valid() && options.isSet("role") && !parseRole(options)) { |
| std::cerr << "Unknown stream role " |
| << options["role"].toString() << std::endl; |
| options.invalidate(); |
| } |
| |
| return options; |
| } |
| |
| std::vector<StreamRole> StreamKeyValueParser::roles(const OptionValue &values) |
| { |
| /* If no configuration values to examine default to viewfinder. */ |
| if (values.empty()) |
| return { StreamRole::Viewfinder }; |
| |
| const std::vector<OptionValue> &streamParameters = values.toArray(); |
| |
| std::vector<StreamRole> roles; |
| for (auto const &value : streamParameters) { |
| /* If a role is invalid default it to viewfinder. */ |
| roles.push_back(parseRole(value.toKeyValues()).value_or(StreamRole::Viewfinder)); |
| } |
| |
| return roles; |
| } |
| |
| int StreamKeyValueParser::updateConfiguration(CameraConfiguration *config, |
| const OptionValue &values) |
| { |
| if (!config) { |
| std::cerr << "No configuration provided" << std::endl; |
| return -EINVAL; |
| } |
| |
| /* If no configuration values nothing to do. */ |
| if (values.empty()) |
| return 0; |
| |
| const std::vector<OptionValue> &streamParameters = values.toArray(); |
| |
| 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 &value : streamParameters) { |
| KeyValueParser::Options opts = value.toKeyValues(); |
| StreamConfiguration &cfg = config->at(i++); |
| |
| if (opts.isSet("width") && opts.isSet("height")) { |
| cfg.size.width = opts["width"]; |
| cfg.size.height = opts["height"]; |
| } |
| |
| if (opts.isSet("pixelformat")) |
| cfg.pixelFormat = PixelFormat::fromString(opts["pixelformat"].toString()); |
| |
| if (opts.isSet("colorspace")) |
| cfg.colorSpace = ColorSpace::fromString(opts["colorspace"].toString()); |
| } |
| |
| return 0; |
| } |
| |
| std::optional<libcamera::StreamRole> StreamKeyValueParser::parseRole(const KeyValueParser::Options &options) |
| { |
| if (!options.isSet("role")) |
| return {}; |
| |
| std::string name = options["role"].toString(); |
| |
| if (name == "viewfinder") |
| return StreamRole::Viewfinder; |
| else if (name == "video") |
| return StreamRole::VideoRecording; |
| else if (name == "still") |
| return StreamRole::StillCapture; |
| else if (name == "raw") |
| return StreamRole::Raw; |
| |
| return {}; |
| } |