cam: Add helper class to parse stream configuration

Create a new helper class StreamKeyValueParser to parse command line
options describing stream configurations. The goal is to share this new
class between cam and qcam.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Niklas Söderlund
2020-04-24 01:40:46 +02:00
parent cdf7fbe35e
commit 693ab88162
3 changed files with 162 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ cam_sources = files([
'event_loop.cpp',
'main.cpp',
'options.cpp',
'stream_options.cpp',
])
cam = executable('cam', cam_sources,

129
src/cam/stream_options.cpp Normal file
View File

@@ -0,0 +1,129 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2020, Raspberry Pi (Trading) Ltd.
*
* stream_options.cpp - Helper to parse options for streams
*/
#include "stream_options.h"
#include <iostream>
using namespace libcamera;
StreamKeyValueParser::StreamKeyValueParser()
{
addOption("role", OptionString,
"Role for the stream (viewfinder, video, still, stillraw)",
ArgumentRequired);
addOption("width", OptionInteger, "Width in pixels",
ArgumentRequired);
addOption("height", OptionInteger, "Height in pixels",
ArgumentRequired);
addOption("pixelformat", OptionInteger, "Pixel format",
ArgumentRequired);
}
KeyValueParser::Options StreamKeyValueParser::parse(const char *arguments)
{
KeyValueParser::Options options = KeyValueParser::parse(arguments);
StreamRole role;
if (options.valid() && options.isSet("role") &&
!parseRole(&role, options)) {
std::cerr << "Unknown stream role "
<< options["role"].toString() << std::endl;
options.invalidate();
}
return options;
}
StreamRoles StreamKeyValueParser::roles(const OptionValue &values)
{
const std::vector<OptionValue> &streamParameters = values.toArray();
/* If no configuration values to examine default to viewfinder. */
if (streamParameters.empty())
return { StreamRole::Viewfinder };
StreamRoles roles;
for (auto const &value : streamParameters) {
KeyValueParser::Options opts = value.toKeyValues();
StreamRole role;
/* If role is invalid or not set default to viewfinder. */
if (!parseRole(&role, value))
role = StreamRole::Viewfinder;
roles.push_back(role);
}
return roles;
}
int StreamKeyValueParser::updateConfiguration(CameraConfiguration *config,
const OptionValue &values)
{
const std::vector<OptionValue> &streamParameters = values.toArray();
if (!config) {
std::cerr << "No configuration provided" << std::endl;
return -EINVAL;
}
/* If no configuration values nothing to do. */
if (!streamParameters.size())
return 0;
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"];
}
/* \todo Translate 4CC string to pixelformat with modifier. */
if (opts.isSet("pixelformat"))
cfg.pixelFormat = PixelFormat(opts["pixelformat"]);
}
return 0;
}
bool StreamKeyValueParser::parseRole(StreamRole *role,
const KeyValueParser::Options &options)
{
if (!options.isSet("role"))
return false;
std::string name = options["role"].toString();
if (name == "viewfinder") {
*role = StreamRole::Viewfinder;
return true;
} else if (name == "video") {
*role = StreamRole::VideoRecording;
return true;
} else if (name == "still") {
*role = StreamRole::StillCapture;
return true;
} else if (name == "stillraw") {
*role = StreamRole::StillCaptureRaw;
return true;
}
return false;
}

32
src/cam/stream_options.h Normal file
View File

@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2020, Raspberry Pi (Trading) Ltd.
*
* stream_options.h - Helper to parse options for streams
*/
#ifndef __CAM_STREAM_OPTIONS_H__
#define __CAM_STREAM_OPTIONS_H__
#include <libcamera/camera.h>
#include "options.h"
using namespace libcamera;
class StreamKeyValueParser : public KeyValueParser
{
public:
StreamKeyValueParser();
KeyValueParser::Options parse(const char *arguments) override;
static StreamRoles roles(const OptionValue &values);
static int updateConfiguration(CameraConfiguration *config,
const OptionValue &values);
private:
static bool parseRole(StreamRole *role,
const KeyValueParser::Options &options);
};
#endif /* __CAM_STREAM_OPTIONS_H__ */