mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
spa: libcamera: source: handle enum controls better
If the `libcamera::ControlInfo` object explicitly lists the values of a control, then use those values when adding `SPA_PROP_INFO_type` to construct an enumerated choice object.
This commit is contained in:
parent
8d9e469e09
commit
e379267274
1 changed files with 77 additions and 30 deletions
|
|
@ -742,6 +742,32 @@ uint32_t prop_id_to_control(uint32_t prop_id)
|
||||||
return SPA_ID_INVALID;
|
return SPA_ID_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
bool control_value_to_pod(spa_pod_builder& b, const libcamera::ControlValue& cv)
|
||||||
|
{
|
||||||
|
if (cv.isArray())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (cv.type()) {
|
||||||
|
case libcamera::ControlTypeBool: {
|
||||||
|
spa_pod_builder_bool(&b, cv.get<bool>());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case libcamera::ControlTypeInteger32: {
|
||||||
|
spa_pod_builder_int(&b, cv.get<int32_t>());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case libcamera::ControlTypeFloat: {
|
||||||
|
spa_pod_builder_float(&b, cv.get<float>());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
std::array<T, 3> control_info_to_range(const libcamera::ControlInfo& cinfo)
|
std::array<T, 3> control_info_to_range(const libcamera::ControlInfo& cinfo)
|
||||||
|
|
@ -775,41 +801,62 @@ spa_pod *control_details_to_pod(spa_pod_builder& b,
|
||||||
SPA_PROP_INFO_description, SPA_POD_String(cid.name().c_str()),
|
SPA_PROP_INFO_description, SPA_POD_String(cid.name().c_str()),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
switch (cid.type()) {
|
if (cinfo.values().empty()) {
|
||||||
case ControlTypeBool: {
|
switch (cid.type()) {
|
||||||
auto min = cinfo.min().get<bool>();
|
case ControlTypeBool: {
|
||||||
auto max = cinfo.max().get<bool>();
|
auto min = cinfo.min().get<bool>();
|
||||||
auto def = !cinfo.def().isNone()
|
auto max = cinfo.max().get<bool>();
|
||||||
? cinfo.def().get<bool>()
|
auto def = !cinfo.def().isNone()
|
||||||
: min;
|
? cinfo.def().get<bool>()
|
||||||
|
: min;
|
||||||
|
spa_pod_frame f;
|
||||||
|
|
||||||
|
spa_pod_builder_prop(&b, SPA_PROP_INFO_type, 0);
|
||||||
|
spa_pod_builder_push_choice(&b, &f, SPA_CHOICE_Enum, 0);
|
||||||
|
spa_pod_builder_bool(&b, def);
|
||||||
|
spa_pod_builder_bool(&b, min);
|
||||||
|
if (max != min)
|
||||||
|
spa_pod_builder_bool(&b, max);
|
||||||
|
spa_pod_builder_pop(&b, &f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ControlTypeFloat: {
|
||||||
|
auto [ min, max, def ] = control_info_to_range<float>(cinfo);
|
||||||
|
|
||||||
|
spa_pod_builder_add(&b,
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(
|
||||||
|
def, min, max),
|
||||||
|
0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ControlTypeInteger32: {
|
||||||
|
auto [ min, max, def ] = control_info_to_range<int32_t>(cinfo);
|
||||||
|
|
||||||
|
spa_pod_builder_add(&b,
|
||||||
|
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(
|
||||||
|
def, min, max),
|
||||||
|
0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
spa_pod_frame f;
|
spa_pod_frame f;
|
||||||
|
|
||||||
spa_pod_builder_prop(&b, SPA_PROP_INFO_type, 0);
|
spa_pod_builder_prop(&b, SPA_PROP_INFO_type, 0);
|
||||||
spa_pod_builder_push_choice(&b, &f, SPA_CHOICE_Enum, 0);
|
spa_pod_builder_push_choice(&b, &f, SPA_CHOICE_Enum, 0);
|
||||||
spa_pod_builder_bool(&b, def);
|
|
||||||
spa_pod_builder_bool(&b, min);
|
if (!control_value_to_pod(b, cinfo.def()))
|
||||||
if (max != min)
|
return nullptr;
|
||||||
spa_pod_builder_bool(&b, max);
|
|
||||||
|
for (const auto& cv : cinfo.values()) {
|
||||||
|
if (!control_value_to_pod(b, cv))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
spa_pod_builder_pop(&b, &f);
|
spa_pod_builder_pop(&b, &f);
|
||||||
} break;
|
|
||||||
case ControlTypeFloat: {
|
|
||||||
auto [ min, max, def ] = control_info_to_range<float>(cinfo);
|
|
||||||
|
|
||||||
spa_pod_builder_add(&b,
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(
|
|
||||||
def, min, max),
|
|
||||||
0);
|
|
||||||
} break;
|
|
||||||
case ControlTypeInteger32: {
|
|
||||||
auto [ min, max, def ] = control_info_to_range<int32_t>(cinfo);
|
|
||||||
|
|
||||||
spa_pod_builder_add(&b,
|
|
||||||
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(
|
|
||||||
def, min, max),
|
|
||||||
0);
|
|
||||||
} break;
|
|
||||||
default:
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return reinterpret_cast<spa_pod *>(spa_pod_builder_pop(&b, &f));
|
return reinterpret_cast<spa_pod *>(spa_pod_builder_pop(&b, &f));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue