mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-12 23:09:45 +03:00
cam: capture_script: Support parsing array controls
Add support for parsing array controls to the cam capture script. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
87f5d12718
commit
b35f04b3c1
2 changed files with 146 additions and 17 deletions
|
@ -454,24 +454,9 @@ void CaptureScript::unpackFailure(const ControlId *id, const std::string &repr)
|
||||||
<< typeName << " control " << id->name() << std::endl;
|
<< typeName << " control " << id->name() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlValue CaptureScript::unpackControl(const ControlId *id)
|
ControlValue CaptureScript::parseScalarControl(const ControlId *id,
|
||||||
|
const std::string repr)
|
||||||
{
|
{
|
||||||
/* Parse complex types. */
|
|
||||||
switch (id->type()) {
|
|
||||||
case ControlTypeRectangle:
|
|
||||||
return parseRectangles();
|
|
||||||
case ControlTypeSize:
|
|
||||||
/* \todo Parse Sizes. */
|
|
||||||
return {};
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse basic types represented by a single scalar. */
|
|
||||||
const std::string repr = parseScalar();
|
|
||||||
if (repr.empty())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
ControlValue value{};
|
ControlValue value{};
|
||||||
|
|
||||||
switch (id->type()) {
|
switch (id->type()) {
|
||||||
|
@ -524,6 +509,145 @@ ControlValue CaptureScript::unpackControl(const ControlId *id)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ControlValue CaptureScript::parseArrayControl(const ControlId *id,
|
||||||
|
const std::vector<std::string> &repr)
|
||||||
|
{
|
||||||
|
ControlValue value{};
|
||||||
|
|
||||||
|
switch (id->type()) {
|
||||||
|
case ControlTypeNone:
|
||||||
|
break;
|
||||||
|
case ControlTypeBool: {
|
||||||
|
/*
|
||||||
|
* This is unpleasant, but we cannot use an std::vector<> as its
|
||||||
|
* boolean type overload does not allow to access the raw data,
|
||||||
|
* as boolean values are stored in a bitmask for efficiency.
|
||||||
|
*
|
||||||
|
* As we need a contiguous memory region to wrap in a Span<>,
|
||||||
|
* use an array instead but be strict about not overflowing it
|
||||||
|
* by limiting the number of controls we can store.
|
||||||
|
*
|
||||||
|
* Be loud but do not fail, as the issue would present at
|
||||||
|
* runtime and it's not fatal.
|
||||||
|
*/
|
||||||
|
static constexpr unsigned int kMaxNumBooleanControls = 1024;
|
||||||
|
std::array<bool, kMaxNumBooleanControls> values;
|
||||||
|
unsigned int idx = 0;
|
||||||
|
|
||||||
|
for (const std::string &s : repr) {
|
||||||
|
bool val;
|
||||||
|
|
||||||
|
if (s == "true") {
|
||||||
|
val = true;
|
||||||
|
} else if (s == "false") {
|
||||||
|
val = false;
|
||||||
|
} else {
|
||||||
|
unpackFailure(id, s);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx == kMaxNumBooleanControls) {
|
||||||
|
std::cerr << "Cannot parse more than "
|
||||||
|
<< kMaxNumBooleanControls
|
||||||
|
<< " boolean controls" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
values[idx++] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = Span<bool>(values.data(), idx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ControlTypeByte: {
|
||||||
|
std::vector<uint8_t> values;
|
||||||
|
for (const std::string &s : repr) {
|
||||||
|
uint8_t val = strtoll(s.c_str(), NULL, 10);
|
||||||
|
values.push_back(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
value = Span<const uint8_t>(values.data(), values.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ControlTypeInteger32: {
|
||||||
|
std::vector<int32_t> values;
|
||||||
|
for (const std::string &s : repr) {
|
||||||
|
int32_t val = strtoll(s.c_str(), NULL, 10);
|
||||||
|
values.push_back(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
value = Span<const int32_t>(values.data(), values.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ControlTypeInteger64: {
|
||||||
|
std::vector<int64_t> values;
|
||||||
|
for (const std::string &s : repr) {
|
||||||
|
int64_t val = strtoll(s.c_str(), NULL, 10);
|
||||||
|
values.push_back(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
value = Span<const int64_t>(values.data(), values.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ControlTypeFloat: {
|
||||||
|
std::vector<float> values;
|
||||||
|
for (const std::string &s : repr)
|
||||||
|
values.push_back(strtof(s.c_str(), NULL));
|
||||||
|
|
||||||
|
value = Span<const float>(values.data(), values.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ControlTypeString: {
|
||||||
|
value = Span<const std::string>(repr.data(), repr.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
std::cerr << "Unsupported control type" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ControlValue CaptureScript::unpackControl(const ControlId *id)
|
||||||
|
{
|
||||||
|
/* Parse complex types. */
|
||||||
|
switch (id->type()) {
|
||||||
|
case ControlTypeRectangle:
|
||||||
|
return parseRectangles();
|
||||||
|
case ControlTypeSize:
|
||||||
|
/* \todo Parse Sizes. */
|
||||||
|
return {};
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the control has a single scalar value or is an array. */
|
||||||
|
EventPtr event = nextEvent();
|
||||||
|
if (!event)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
switch (event->type) {
|
||||||
|
case YAML_SCALAR_EVENT: {
|
||||||
|
const std::string repr = eventScalarValue(event);
|
||||||
|
if (repr.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return parseScalarControl(id, repr);
|
||||||
|
}
|
||||||
|
case YAML_SEQUENCE_START_EVENT: {
|
||||||
|
std::vector<std::string> array = parseSingleArray();
|
||||||
|
if (array.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return parseArrayControl(id, array);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
std::cerr << "Unexpected event type: " << event->type << std::endl;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
libcamera::Rectangle CaptureScript::unpackRectangle(const std::vector<std::string> &strVec)
|
libcamera::Rectangle CaptureScript::unpackRectangle(const std::vector<std::string> &strVec)
|
||||||
{
|
{
|
||||||
int x = strtol(strVec[0].c_str(), NULL, 10);
|
int x = strtol(strVec[0].c_str(), NULL, 10);
|
||||||
|
|
|
@ -56,6 +56,11 @@ private:
|
||||||
int parseFrame(EventPtr event);
|
int parseFrame(EventPtr event);
|
||||||
int parseControl(EventPtr event, libcamera::ControlList &controls);
|
int parseControl(EventPtr event, libcamera::ControlList &controls);
|
||||||
|
|
||||||
|
libcamera::ControlValue parseScalarControl(const libcamera::ControlId *id,
|
||||||
|
const std::string repr);
|
||||||
|
libcamera::ControlValue parseArrayControl(const libcamera::ControlId *id,
|
||||||
|
const std::vector<std::string> &repr);
|
||||||
|
|
||||||
std::string parseScalar();
|
std::string parseScalar();
|
||||||
libcamera::ControlValue parseRectangles();
|
libcamera::ControlValue parseRectangles();
|
||||||
std::vector<std::vector<std::string>> parseArrays();
|
std::vector<std::vector<std::string>> parseArrays();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue