1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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;
}
|