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:
@@ -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
129
src/cam/stream_options.cpp
Normal 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
32
src/cam/stream_options.h
Normal 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__ */
|
||||
Reference in New Issue
Block a user