spa: libcamera: source: unify control range logic

If libcamera does not provide a default value, then the average of the
minimum and maximum values is taken. The same logic is duplicated for
`float` and `int32_t`, so move it into a function template.

(cherry picked from commit 8d9e469e09)
This commit is contained in:
Barnabás Pőcze 2025-07-23 14:23:00 +02:00 committed by Robert Mader
parent 337d3b3daf
commit b8bbcfdb96

View file

@ -4,10 +4,12 @@
/* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */ /* SPDX-FileCopyrightText: Copyright © 2021 Wim Taymans <wim.taymans@gmail.com> */
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
#include <array>
#include <cstddef> #include <cstddef>
#include <deque> #include <deque>
#include <limits> #include <limits>
#include <optional> #include <optional>
#include <type_traits>
#include <utility> #include <utility>
#include <sys/mman.h> #include <sys/mman.h>
@ -739,6 +741,23 @@ uint32_t prop_id_to_control(uint32_t prop_id)
return SPA_ID_INVALID; return SPA_ID_INVALID;
} }
template<typename T>
[[nodiscard]]
std::array<T, 3> control_info_to_range(const libcamera::ControlInfo& cinfo)
{
static_assert(std::is_arithmetic_v<T>);
auto min = cinfo.min().get<T>();
auto max = cinfo.max().get<T>();
spa_assert(min <= max);
auto def = !cinfo.def().isNone()
? cinfo.def().get<T>()
: (min + ((max - min) / 2));
return {{ min, max, def }};
}
[[nodiscard]] [[nodiscard]]
spa_pod *control_details_to_pod(spa_pod_builder& b, spa_pod *control_details_to_pod(spa_pod_builder& b,
const libcamera::ControlId& cid, const libcamera::ControlInfo& cinfo) const libcamera::ControlId& cid, const libcamera::ControlInfo& cinfo)
@ -773,14 +792,7 @@ spa_pod *control_details_to_pod(spa_pod_builder& b,
spa_pod_builder_pop(&b, &f); spa_pod_builder_pop(&b, &f);
} break; } break;
case ControlTypeFloat: { case ControlTypeFloat: {
float min = cinfo.min().get<float>(); auto [ min, max, def ] = control_info_to_range<float>(cinfo);
float max = cinfo.max().get<float>();
float def;
if (cinfo.def().isNone())
def = (min + max) / 2;
else
def = cinfo.def().get<float>();
spa_pod_builder_add(&b, spa_pod_builder_add(&b,
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float( SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(
@ -788,14 +800,7 @@ spa_pod *control_details_to_pod(spa_pod_builder& b,
0); 0);
} break; } break;
case ControlTypeInteger32: { case ControlTypeInteger32: {
int32_t min = cinfo.min().get<int32_t>(); auto [ min, max, def ] = control_info_to_range<int32_t>(cinfo);
int32_t max = cinfo.max().get<int32_t>();
int32_t def;
if (cinfo.def().isNone())
def = (min + max) / 2;
else
def = cinfo.def().get<int32_t>();
spa_pod_builder_add(&b, spa_pod_builder_add(&b,
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int( SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Int(